Monday, June 04, 2018

Re: [patch] audio/openal: ugly update to 1.18.2

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

No comments:

Post a Comment