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