On Mon, Jun 04, 2018 at 12:05:58PM +0100, Stuart Henderson wrote:
> On 2018/06/04 10:31, Leonid Bobrov wrote:
> > On Mon, Jun 04, 2018 at 08:07:36AM +0100, David CARLIER wrote:
> > > Ok ... My approach with openal has always been not rushing to update to 
> > > the
> > > newest version especially so many softwares depends on it.
> > > Is the portaudio support of the actual version not working ?
> > >
> > 
> > By actual you mean the current version of this port? It works (I tested
> > it at 1.17.2 first), but I thought why not to try to update to 1.18.2?
> 
> In many languages the words like actual/current are the same, in this
> case a native speaker would say "current" but the words are often mixed up.
> (see 'get it right' tab on 
> http://www.macmillandictionary.com/dictionary/british/actual)
> 
> > Well, if to stay at current version, I provide new diff below.
> 
> Wouldn't it be better to add record support to the sndio backend?
> 

Here's a WIP recording backend. I couldn't quickly find simple tools
to test and debug it, so I never finished it.

If you've simple tools to quickly test recording, I'm very interested.

Index: Makefile
===================================================================
RCS file: /cvs/ports/audio/openal/Makefile,v
retrieving revision 1.50
diff -u -p -r1.50 Makefile
--- Makefile    31 Dec 2017 18:46:26 -0000      1.50
+++ Makefile    4 Jun 2018 16:40:48 -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  4 Jun 2018 16:40:48 -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;
++    }
++
++    if (!sndio_setparams(device)) {
++      sio_close(data->sndHandle);
++        free(data);
++        return ALC_INVALID_VALUE;
++    }
++
++    al_string_copy_cstr(&device->DeviceName, deviceName);
++    device->ExtraData = data;
++
++    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