On Tue, Jun 05, 2018 at 08:01:12AM +0200, Alexandre Ratchov wrote: > I installed utox, it doesn't crash with the diff below anymore. The > "Preview" button in the "Audio & Video" settings records my voice. >
Ok, I tested your diff using Toxic at virtual machine. Voice recording works, but when I finish a call, I get segmentation fault (and I got bus error once). > Index: Makefile > =================================================================== > RCS file: /cvs/ports/audio/openal/Makefile,v > retrieving revision 1.50 > diff -u -p -u -p -r1.50 Makefile > --- Makefile 31 Dec 2017 18:46:26 -0000 1.50 > +++ Makefile 5 Jun 2018 05:38:16 -0000 > @@ -10,7 +10,7 @@ DISTNAME = openal-soft-$V > PKGNAME = openal-$V > CATEGORIES = audio > SHARED_LIBS = openal 3.0 > -REVISION = 0 > +REVISION = 1 > > HOMEPAGE = http://kcat.strangesoft.net/openal.html > > Index: patches/patch-Alc_backends_sndio_c > =================================================================== > RCS file: patches/patch-Alc_backends_sndio_c > diff -N patches/patch-Alc_backends_sndio_c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-Alc_backends_sndio_c 5 Jun 2018 05:38:16 -0000 > @@ -0,0 +1,362 @@ > +$OpenBSD$ > + > +Index: Alc/backends/sndio.c > +--- Alc/backends/sndio.c.orig > ++++ Alc/backends/sndio.c > +@@ -42,16 +42,18 @@ static ALCboolean sndio_load(void) > + > + typedef struct { > + struct sio_hdl *sndHandle; > ++ int mode; > + > + ALvoid *mix_data; > + ALsizei data_size; > + > ++ ll_ringbuffer_t *ring; > ++ > + volatile int killNow; > + althrd_t thread; > + } sndio_data; > + > +- > +-static int sndio_proc(void *ptr) > ++static int sndio_proc_playback(void *ptr) > + { > + ALCdevice *device = ptr; > + sndio_data *data = device->ExtraData; > +@@ -89,53 +91,22 @@ static int sndio_proc(void *ptr) > + return 0; > + } > + > +- > +- > +-static ALCenum sndio_open_playback(ALCdevice *device, const ALCchar > *deviceName) > ++static ALCboolean sndio_setparams(ALCdevice *device) > + { > +- sndio_data *data; > +- > +- if(!deviceName) > +- deviceName = sndio_device; > +- else if(strcmp(deviceName, sndio_device) != 0) > +- return ALC_INVALID_VALUE; > +- > +- data = calloc(1, sizeof(*data)); > +- data->killNow = 0; > +- > +- data->sndHandle = sio_open(NULL, SIO_PLAY, 0); > +- if(data->sndHandle == NULL) > +- { > +- free(data); > +- ERR("Could not open device\n"); > +- return ALC_INVALID_VALUE; > +- } > +- > +- al_string_copy_cstr(&device->DeviceName, deviceName); > +- device->ExtraData = data; > +- > +- return ALC_NO_ERROR; > +-} > +- > +-static void sndio_close_playback(ALCdevice *device) > +-{ > + sndio_data *data = device->ExtraData; > +- > +- sio_close(data->sndHandle); > +- free(data); > +- device->ExtraData = NULL; > +-} > +- > +-static ALCboolean sndio_reset_playback(ALCdevice *device) > +-{ > +- sndio_data *data = device->ExtraData; > + struct sio_par par; > ++ unsigned int nch; > + > + sio_initpar(&par); > + > + par.rate = device->Frequency; > +- par.pchan = ((device->FmtChans != DevFmtMono) ? 2 : 1); > ++ nch = ((device->FmtChans != DevFmtMono) ? 2 : 1); > + > ++ if (data->mode & SIO_PLAY) > ++ par.pchan = nch; > ++ else if (data->mode & SIO_REC) > ++ par.rchan = nch; > ++ > + switch(device->FmtType) > + { > + case DevFmtByte: > +@@ -182,8 +153,10 @@ static ALCboolean sndio_reset_playback(ALCdevice *devi > + return ALC_FALSE; > + } > + > ++ nch = (data->mode & SIO_PLAY) ? par.pchan : par.rchan; > ++ > + device->Frequency = par.rate; > +- device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo); > ++ device->FmtChans = ((nch == 1) ? DevFmtMono : DevFmtStereo); > + > + if(par.bits == 8 && par.sig == 1) > + device->FmtType = DevFmtByte; > +@@ -211,6 +184,47 @@ static ALCboolean sndio_reset_playback(ALCdevice *devi > + return ALC_TRUE; > + } > + > ++static ALCenum sndio_open_playback(ALCdevice *device, const ALCchar > *deviceName) > ++{ > ++ sndio_data *data; > ++ > ++ if(!deviceName) > ++ deviceName = sndio_device; > ++ else if(strcmp(deviceName, sndio_device) != 0) > ++ return ALC_INVALID_VALUE; > ++ > ++ data = calloc(1, sizeof(*data)); > ++ data->killNow = 0; > ++ > ++ data->mode = SIO_PLAY; > ++ data->sndHandle = sio_open(NULL, data->mode, 0); > ++ if(data->sndHandle == NULL) > ++ { > ++ free(data); > ++ ERR("Could not open device\n"); > ++ return ALC_INVALID_VALUE; > ++ } > ++ > ++ al_string_copy_cstr(&device->DeviceName, deviceName); > ++ device->ExtraData = data; > ++ > ++ return ALC_NO_ERROR; > ++} > ++ > ++static void sndio_close_playback(ALCdevice *device) > ++{ > ++ sndio_data *data = device->ExtraData; > ++ > ++ sio_close(data->sndHandle); > ++ free(data); > ++ device->ExtraData = NULL; > ++} > ++ > ++static ALCboolean sndio_reset_playback(ALCdevice *device) > ++{ > ++ return sndio_setparams(device); > ++} > ++ > + static ALCboolean sndio_start_playback(ALCdevice *device) > + { > + sndio_data *data = device->ExtraData; > +@@ -225,7 +239,7 @@ static ALCboolean sndio_start_playback(ALCdevice *devi > + data->mix_data = calloc(1, data->data_size); > + > + data->killNow = 0; > +- if(althrd_create(&data->thread, sndio_proc, device) != althrd_success) > ++ if(althrd_create(&data->thread, sndio_proc_playback, device) != > althrd_success) > + { > + sio_stop(data->sndHandle); > + free(data->mix_data); > +@@ -254,19 +268,190 @@ static void sndio_stop_playback(ALCdevice *device) > + data->mix_data = NULL; > + } > + > ++static int sndio_proc_capture(void *ptr) > ++{ > ++ static char dummy[1024]; > ++ ALCdevice *device = ptr; > ++ sndio_data *data = device->ExtraData; > ++ ll_ringbuffer_data_t vec[2], *v; > ++ ALsizei frameSize; > ++ size_t n, todo, len; > ++ char *buf; > + > ++ SetRTPriority(); > ++ althrd_setname(althrd_current(), RECORD_THREAD_NAME); > ++ > ++ frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); > ++ > ++ while(!data->killNow && device->Connected) > ++ { > ++ todo = device->UpdateSize * frameSize; > ++ ll_ringbuffer_get_write_vector(data->ring, vec); > ++ > ++ if (vec[0].len + vec[1].len < device->UpdateSize) { > ++ > ++ /* we're out of free space, drop next block */ > ++ while (todo > 0) { > ++ len = sizeof(dummy); > ++ if (len > todo) > ++ len = todo; > ++ n = sio_read(data->sndHandle, dummy, len); > ++ if (n == 0) { > ++ ERR("sio_read failed\n"); > ++ ALCdevice_Lock(device); > ++ aluHandleDisconnect(device); > ++ ALCdevice_Unlock(device); > ++ } > ++ todo -= n; > ++ } > ++ > ++ } else { > ++ > ++ /* record into the ring */ > ++ v = vec; > ++ buf = NULL; > ++ len = 0; > ++ while (todo > 0) { > ++ if (len == 0) { > ++ buf = v->buf; > ++ len = v->len * frameSize; > ++ v++; > ++ } > ++ n = sio_read(data->sndHandle, buf, len); > ++ if (n == 0) { > ++ ERR("sio_read failed\n"); > ++ ALCdevice_Lock(device); > ++ aluHandleDisconnect(device); > ++ ALCdevice_Unlock(device); > ++ } > ++ len -= n; > ++ buf += n; > ++ todo -= n; > ++ } > ++ ll_ringbuffer_write_advance(data->ring, device->UpdateSize); > ++ > ++ } > ++ } > ++ > ++ return 0; > ++} > ++ > ++static ALCenum sndio_open_capture(ALCdevice *device, const ALCchar > *deviceName) > ++{ > ++ sndio_data *data; > ++ > ++ if(!deviceName) > ++ deviceName = sndio_device; > ++ else if(strcmp(deviceName, sndio_device) != 0) > ++ return ALC_INVALID_VALUE; > ++ > ++ data = calloc(1, sizeof(*data)); > ++ data->killNow = 0; > ++ data->ring = NULL; > ++ data->mode = SIO_REC; > ++ data->sndHandle = sio_open(NULL, data->mode, 0); > ++ if(data->sndHandle == NULL) > ++ { > ++ free(data); > ++ ERR("Could not open device\n"); > ++ return ALC_INVALID_VALUE; > ++ } > ++ > ++ al_string_copy_cstr(&device->DeviceName, deviceName); > ++ device->ExtraData = data; > ++ > ++ if (!sndio_setparams(device)) { > ++ sio_close(data->sndHandle); > ++ free(data); > ++ return ALC_INVALID_VALUE; > ++ } > ++ > ++ return ALC_NO_ERROR; > ++} > ++ > ++static void sndio_close_capture(ALCdevice *device) > ++{ > ++ sndio_data *data = device->ExtraData; > ++ > ++ sio_close(data->sndHandle); > ++ free(data); > ++ device->ExtraData = NULL; > ++} > ++ > ++static void sndio_start_capture(ALCdevice *device) > ++{ > ++ sndio_data *data = device->ExtraData; > ++ int frameSize; > ++ > ++ if(!sio_start(data->sndHandle)) > ++ { > ++ ERR("Error starting capture\n"); > ++ return; > ++ } > ++ > ++ frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); > ++ data->ring = ll_ringbuffer_create(device->UpdateSize * > device->NumUpdates, frameSize); > ++ if (!data->ring) { > ++ sio_stop(data->sndHandle); > ++ return; > ++ } > ++ > ++ data->killNow = 0; > ++ if(althrd_create(&data->thread, sndio_proc_capture, device) != > althrd_success) > ++ { > ++ ll_ringbuffer_free(data->ring); > ++ sio_stop(data->sndHandle); > ++ return; > ++ } > ++ > ++ return; > ++} > ++ > ++static void sndio_stop_capture(ALCdevice *device) > ++{ > ++ sndio_data *data = device->ExtraData; > ++ int res; > ++ > ++ if(data->killNow) > ++ return; > ++ > ++ data->killNow = 1; > ++ althrd_join(data->thread, &res); > ++ > ++ if(!sio_stop(data->sndHandle)) > ++ ERR("Error stopping device\n"); > ++ > ++ ll_ringbuffer_free(data->ring); > ++ data->ring = NULL; > ++} > ++ > ++static ALCenum sndio_captureSamples(ALCdevice *device, ALCvoid *buffer, > ALCuint samples) > ++{ > ++ sndio_data *data = device->ExtraData; > ++ > ++ ll_ringbuffer_read(data->ring, buffer, samples); > ++ return ALC_NO_ERROR; > ++} > ++ > ++static ALCuint sndio_availableSamples(ALCdevice *device) > ++{ > ++ sndio_data *data = device->ExtraData; > ++ > ++ return ll_ringbuffer_read_space(data->ring); > ++} > ++ > + static const BackendFuncs sndio_funcs = { > + sndio_open_playback, > + sndio_close_playback, > + sndio_reset_playback, > + sndio_start_playback, > + sndio_stop_playback, > +- NULL, > +- NULL, > +- NULL, > +- NULL, > +- NULL, > +- NULL > ++ sndio_open_capture, > ++ sndio_close_capture, > ++ sndio_start_capture, > ++ sndio_stop_capture, > ++ sndio_captureSamples, > ++ sndio_availableSamples > + }; > + > + ALCboolean alc_sndio_init(BackendFuncs *func_list) > +@@ -289,6 +474,7 @@ void alc_sndio_probe(enum DevProbe type) > + AppendAllDevicesList(sndio_device); > + break; > + case CAPTURE_DEVICE_PROBE: > ++ AppendCaptureDeviceList(sndio_device); > + break; > + } > + }