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;
> + }
> + }
No comments:
Post a Comment