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;
> +     }
> + }

Reply via email to