diff options
author | Sven Gothel <[email protected]> | 2014-06-10 05:30:02 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-06-10 05:30:02 +0200 |
commit | f95bf4457fbc31112fa82dacbc1b7e094b9fd1cf (patch) | |
tree | 965ba5b8e6fc8e6bfe7a981c1dfb1179bb9adcde /Alc/backends/alsa.c | |
parent | 7297c3214a4c648aaee81a9877da15b88f798197 (diff) | |
parent | c07fb7b45c1e345dbaa439882250de5b2213026f (diff) |
Merge branch 'UPSTREAM' into UPSTREAM_MERGE
Diffstat (limited to 'Alc/backends/alsa.c')
-rw-r--r-- | Alc/backends/alsa.c | 255 |
1 files changed, 118 insertions, 137 deletions
diff --git a/Alc/backends/alsa.c b/Alc/backends/alsa.c index 874b31c3..0712a412 100644 --- a/Alc/backends/alsa.c +++ b/Alc/backends/alsa.c @@ -227,14 +227,27 @@ static ALCboolean alsa_load(void) typedef struct { - ALCchar *name; - char *device; + al_string name; + al_string device_name; } DevMap; +DECL_VECTOR(DevMap) -static DevMap *allDevNameMap; -static ALuint numDevNames; -static DevMap *allCaptureDevNameMap; -static ALuint numCaptureDevNames; +static vector_DevMap PlaybackDevices; +static vector_DevMap CaptureDevices; + +static void clear_devlist(vector_DevMap *devlist) +{ + DevMap *iter, *end; + + iter = VECTOR_ITER_BEGIN(*devlist); + end = VECTOR_ITER_END(*devlist); + for(;iter != end;iter++) + { + AL_STRING_DEINIT(iter->name); + AL_STRING_DEINIT(iter->device_name); + } + VECTOR_RESIZE(*devlist, 0); +} static const char *prefix_name(snd_pcm_stream_t stream) @@ -243,23 +256,26 @@ static const char *prefix_name(snd_pcm_stream_t stream) return (stream==SND_PCM_STREAM_PLAYBACK) ? "device-prefix" : "capture-prefix"; } -static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) +static void probe_devices(snd_pcm_stream_t stream, vector_DevMap *DeviceList) { const char *main_prefix = "plughw:"; snd_ctl_t *handle; - int card, err, dev, idx; snd_ctl_card_info_t *info; snd_pcm_info_t *pcminfo; - DevMap *DevList; + int card, err, dev; + DevMap entry; + + clear_devlist(DeviceList); snd_ctl_card_info_malloc(&info); snd_pcm_info_malloc(&pcminfo); - DevList = malloc(sizeof(DevMap) * 1); - DevList[0].name = strdup(alsaDevice); - DevList[0].device = strdup(GetConfigValue("alsa", (stream==SND_PCM_STREAM_PLAYBACK) ? - "device" : "capture", "default")); - idx = 1; + AL_STRING_INIT(entry.name); + AL_STRING_INIT(entry.device_name); + al_string_copy_cstr(&entry.name, alsaDevice); + al_string_copy_cstr(&entry.device_name, GetConfigValue("alsa", (stream==SND_PCM_STREAM_PLAYBACK) ? + "device" : "capture", "default")); + VECTOR_PUSH_BACK(*DeviceList, entry); card = -1; if((err=snd_card_next(&card)) < 0) @@ -293,8 +309,9 @@ static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) dev = -1; while(1) { + const char *device_prefix = card_prefix; const char *devname; - void *temp; + char device[128]; if(snd_ctl_pcm_next_device(handle, &dev) < 0) ERR("snd_ctl_pcm_next_device failed\n"); @@ -310,28 +327,22 @@ static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) continue; } - temp = realloc(DevList, sizeof(DevMap) * (idx+1)); - if(temp) - { - const char *device_prefix = card_prefix; - char device[128]; - - DevList = temp; - devname = snd_pcm_info_get_name(pcminfo); + devname = snd_pcm_info_get_name(pcminfo); - snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev); - ConfigValueStr("alsa", name, &device_prefix); + snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev); + ConfigValueStr("alsa", name, &device_prefix); - snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)", - cardname, devname, cardid, dev); - snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d", - device_prefix, cardid, dev); + snprintf(name, sizeof(name), "%s, %s (CARD=%s,DEV=%d)", + cardname, devname, cardid, dev); + snprintf(device, sizeof(device), "%sCARD=%s,DEV=%d", + device_prefix, cardid, dev); - TRACE("Got device \"%s\", \"%s\"\n", name, device); - DevList[idx].name = strdup(name); - DevList[idx].device = strdup(device); - idx++; - } + TRACE("Got device \"%s\", \"%s\"\n", name, device); + AL_STRING_INIT(entry.name); + AL_STRING_INIT(entry.device_name); + al_string_copy_cstr(&entry.name, name); + al_string_copy_cstr(&entry.device_name, device); + VECTOR_PUSH_BACK(*DeviceList, entry); } snd_ctl_close(handle); next_card: @@ -343,9 +354,6 @@ static DevMap *probe_devices(snd_pcm_stream_t stream, ALuint *count) snd_pcm_info_free(pcminfo); snd_ctl_card_info_free(info); - - *count = idx; - return DevList; } @@ -390,12 +398,11 @@ typedef struct ALCplaybackAlsa { ALsizei size; volatile int killNow; - althread_t thread; + althrd_t thread; } ALCplaybackAlsa; -DECLARE_ALCBACKEND_VTABLE(ALCplaybackAlsa); -static ALuint ALCplaybackAlsa_mixerProc(ALvoid *ptr); -static ALuint ALCplaybackAlsa_mixerNoMMapProc(ALvoid *ptr); +static int ALCplaybackAlsa_mixerProc(void *ptr); +static int ALCplaybackAlsa_mixerNoMMapProc(void *ptr); static void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device); static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, Destruct) @@ -406,8 +413,12 @@ static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self); static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self); static DECLARE_FORWARD2(ALCplaybackAlsa, ALCbackend, ALCenum, captureSamples, void*, ALCuint) static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, ALCuint, availableSamples) +static ALint64 ALCplaybackAlsa_getLatency(ALCplaybackAlsa *self); static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, lock) static DECLARE_FORWARD(ALCplaybackAlsa, ALCbackend, void, unlock) +DECLARE_DEFAULT_ALLOCATORS(ALCplaybackAlsa) + +DEFINE_ALCBACKEND_VTABLE(ALCplaybackAlsa); static void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device) @@ -417,7 +428,7 @@ static void ALCplaybackAlsa_Construct(ALCplaybackAlsa *self, ALCdevice *device) } -static ALuint ALCplaybackAlsa_mixerProc(ALvoid *ptr) +static int ALCplaybackAlsa_mixerProc(void *ptr) { ALCplaybackAlsa *self = (ALCplaybackAlsa*)ptr; ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; @@ -429,7 +440,7 @@ static ALuint ALCplaybackAlsa_mixerProc(ALvoid *ptr) int err; SetRTPriority(); - SetThreadName(MIXER_THREAD_NAME); + althrd_setname(althrd_current(), MIXER_THREAD_NAME); update_size = device->UpdateSize; num_updates = device->NumUpdates; @@ -509,7 +520,7 @@ static ALuint ALCplaybackAlsa_mixerProc(ALvoid *ptr) return 0; } -static ALuint ALCplaybackAlsa_mixerNoMMapProc(ALvoid *ptr) +static int ALCplaybackAlsa_mixerNoMMapProc(void *ptr) { ALCplaybackAlsa *self = (ALCplaybackAlsa*)ptr; ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; @@ -519,7 +530,7 @@ static ALuint ALCplaybackAlsa_mixerNoMMapProc(ALvoid *ptr) int err; SetRTPriority(); - SetThreadName(MIXER_THREAD_NAME); + althrd_setname(althrd_current(), MIXER_THREAD_NAME); update_size = device->UpdateSize; num_updates = device->NumUpdates; @@ -614,20 +625,22 @@ static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name) if(name) { - size_t idx; + const DevMap *iter, *end; - if(!allDevNameMap) - allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames); + if(VECTOR_SIZE(PlaybackDevices) == 0) + probe_devices(SND_PCM_STREAM_PLAYBACK, &PlaybackDevices); - for(idx = 0;idx < numDevNames;idx++) + iter = VECTOR_ITER_BEGIN(PlaybackDevices); + end = VECTOR_ITER_END(PlaybackDevices); + for(;iter != end;iter++) { - if(strcmp(name, allDevNameMap[idx].name) == 0) + if(al_string_cmp_cstr(iter->name, name) == 0) { - driver = allDevNameMap[idx].device; + driver = al_string_get_cstr(iter->device_name); break; } } - if(idx == numDevNames) + if(iter == end) return ALC_INVALID_VALUE; } else @@ -636,6 +649,7 @@ static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name) driver = GetConfigValue("alsa", "device", "default"); } + TRACE("Opening device \"%s\"\n", driver); err = snd_pcm_open(&self->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if(err < 0) { @@ -646,7 +660,7 @@ static ALCenum ALCplaybackAlsa_open(ALCplaybackAlsa *self, const ALCchar *name) /* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */ snd_config_update_free_global(); - device->DeviceName = strdup(name); + al_string_copy_cstr(&device->DeviceName, name); return ALC_NO_ERROR; } @@ -663,15 +677,14 @@ static ALCboolean ALCplaybackAlsa_reset(ALCplaybackAlsa *self) unsigned int periodLen, bufferLen; snd_pcm_sw_params_t *sp = NULL; snd_pcm_hw_params_t *hp = NULL; + snd_pcm_format_t format = -1; snd_pcm_access_t access; - snd_pcm_format_t format; unsigned int periods; unsigned int rate; const char *funcerr; int allowmmap; int err; - format = -1; switch(device->FmtType) { case DevFmtByte: @@ -809,7 +822,7 @@ error: static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self) { ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - ALuint (*thread_func)(ALvoid*) = NULL; + int (*thread_func)(void*) = NULL; snd_pcm_hw_params_t *hp = NULL; snd_pcm_access_t access; const char *funcerr; @@ -845,7 +858,8 @@ static ALCboolean ALCplaybackAlsa_start(ALCplaybackAlsa *self) } thread_func = ALCplaybackAlsa_mixerProc; } - if(!StartThread(&self->thread, thread_func, self)) + self->killNow = 0; + if(althrd_create(&self->thread, thread_func, self) != althrd_success) { ERR("Could not create playback thread\n"); free(self->buffer); @@ -863,13 +877,14 @@ error: static void ALCplaybackAlsa_stop(ALCplaybackAlsa *self) { - if(self->thread) - { - self->killNow = 1; - StopThread(self->thread); - self->thread = NULL; - } - self->killNow = 0; + int res; + + if(self->killNow) + return; + + self->killNow = 1; + althrd_join(self->thread, &res); + free(self->buffer); self->buffer = NULL; } @@ -889,14 +904,6 @@ static ALint64 ALCplaybackAlsa_getLatency(ALCplaybackAlsa *self) } -static void ALCplaybackAlsa_Delete(ALCplaybackAlsa *self) -{ - free(self); -} - -DEFINE_ALCBACKEND_VTABLE(ALCplaybackAlsa); - - typedef struct ALCcaptureAlsa { DERIVE_FROM_TYPE(ALCbackend); @@ -910,7 +917,6 @@ typedef struct ALCcaptureAlsa { snd_pcm_sframes_t last_avail; } ALCcaptureAlsa; -DECLARE_ALCBACKEND_VTABLE(ALCcaptureAlsa); static void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device); static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, Destruct) @@ -921,8 +927,12 @@ static ALCboolean ALCcaptureAlsa_start(ALCcaptureAlsa *self); static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self); static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buffer, ALCuint samples); static ALCuint ALCcaptureAlsa_availableSamples(ALCcaptureAlsa *self); +static ALint64 ALCcaptureAlsa_getLatency(ALCcaptureAlsa *self); static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, lock) static DECLARE_FORWARD(ALCcaptureAlsa, ALCbackend, void, unlock) +DECLARE_DEFAULT_ALLOCATORS(ALCcaptureAlsa) + +DEFINE_ALCBACKEND_VTABLE(ALCcaptureAlsa); static void ALCcaptureAlsa_Construct(ALCcaptureAlsa *self, ALCdevice *device) @@ -940,26 +950,28 @@ static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name) snd_pcm_uframes_t bufferSizeInFrames; snd_pcm_uframes_t periodSizeInFrames; ALboolean needring = AL_FALSE; - snd_pcm_format_t format; + snd_pcm_format_t format = -1; const char *funcerr; int err; if(name) { - size_t idx; + const DevMap *iter, *end; - if(!allCaptureDevNameMap) - allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); + if(VECTOR_SIZE(CaptureDevices) == 0) + probe_devices(SND_PCM_STREAM_CAPTURE, &CaptureDevices); - for(idx = 0;idx < numCaptureDevNames;idx++) + iter = VECTOR_ITER_BEGIN(CaptureDevices); + end = VECTOR_ITER_END(CaptureDevices); + for(;iter != end;iter++) { - if(strcmp(name, allCaptureDevNameMap[idx].name) == 0) + if(al_string_cmp_cstr(iter->name, name) == 0) { - driver = allCaptureDevNameMap[idx].device; + driver = al_string_get_cstr(iter->device_name); break; } } - if(idx == numCaptureDevNames) + if(iter == end) return ALC_INVALID_VALUE; } else @@ -968,6 +980,7 @@ static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name) driver = GetConfigValue("alsa", "capture", "default"); } + TRACE("Opening device \"%s\"\n", driver); err = snd_pcm_open(&self->pcmHandle, driver, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK); if(err < 0) { @@ -978,7 +991,6 @@ static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name) /* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */ snd_config_update_free_global(); - format = -1; switch(device->FmtType) { case DevFmtByte: @@ -1056,7 +1068,7 @@ static ALCenum ALCcaptureAlsa_open(ALCcaptureAlsa *self, const ALCchar *name) } } - device->DeviceName = strdup(name); + al_string_copy_cstr(&device->DeviceName, name); return ALC_NO_ERROR; @@ -1114,11 +1126,12 @@ static void ALCcaptureAlsa_stop(ALCcaptureAlsa *self) void *ptr; size = snd_pcm_frames_to_bytes(self->pcmHandle, avail); - ptr = realloc(self->buffer, size); + ptr = malloc(size); if(ptr) { + ALCcaptureAlsa_captureSamples(self, ptr, avail); + free(self->buffer); self->buffer = ptr; - ALCcaptureAlsa_captureSamples(self, self->buffer, avail); self->size = size; } } @@ -1150,7 +1163,7 @@ static ALCenum ALCcaptureAlsa_captureSamples(ALCcaptureAlsa *self, ALCvoid *buff if((snd_pcm_uframes_t)amt > samples) amt = samples; amt = snd_pcm_frames_to_bytes(self->pcmHandle, amt); - memmove(buffer, self->buffer, amt); + memcpy(buffer, self->buffer, amt); if(self->size > amt) { @@ -1287,14 +1300,11 @@ static ALint64 ALCcaptureAlsa_getLatency(ALCcaptureAlsa *self) return maxi64((ALint64)delay*1000000000/device->Frequency, 0); } -static void ALCcaptureAlsa_Delete(ALCcaptureAlsa *self) -{ - free(self); -} - -DEFINE_ALCBACKEND_VTABLE(ALCcaptureAlsa); - +static inline void AppendAllDevicesList2(const DevMap *entry) +{ AppendAllDevicesList(al_string_get_cstr(entry->name)); } +static inline void AppendCaptureDeviceList2(const DevMap *entry) +{ AppendCaptureDeviceList(al_string_get_cstr(entry->name)); } typedef struct ALCalsaBackendFactory { DERIVE_FROM_TYPE(ALCbackendFactory); @@ -1303,6 +1313,9 @@ typedef struct ALCalsaBackendFactory { static ALCboolean ALCalsaBackendFactory_init(ALCalsaBackendFactory* UNUSED(self)) { + VECTOR_INIT(PlaybackDevices); + VECTOR_INIT(CaptureDevices); + if(!alsa_load()) return ALC_FALSE; return ALC_TRUE; @@ -1310,25 +1323,11 @@ static ALCboolean ALCalsaBackendFactory_init(ALCalsaBackendFactory* UNUSED(self) static void ALCalsaBackendFactory_deinit(ALCalsaBackendFactory* UNUSED(self)) { - ALuint i; - - for(i = 0;i < numDevNames;++i) - { - free(allDevNameMap[i].name); - free(allDevNameMap[i].device); - } - free(allDevNameMap); - allDevNameMap = NULL; - numDevNames = 0; + clear_devlist(&PlaybackDevices); + VECTOR_DEINIT(PlaybackDevices); - for(i = 0;i < numCaptureDevNames;++i) - { - free(allCaptureDevNameMap[i].name); - free(allCaptureDevNameMap[i].device); - } - free(allCaptureDevNameMap); - allCaptureDevNameMap = NULL; - numCaptureDevNames = 0; + clear_devlist(&CaptureDevices); + VECTOR_DEINIT(CaptureDevices); #ifdef HAVE_DYNLOAD if(alsa_handle) @@ -1346,36 +1345,16 @@ static ALCboolean ALCalsaBackendFactory_querySupport(ALCalsaBackendFactory* UNUS static void ALCalsaBackendFactory_probe(ALCalsaBackendFactory* UNUSED(self), enum DevProbe type) { - ALuint i; - switch(type) { case ALL_DEVICE_PROBE: - for(i = 0;i < numDevNames;++i) - { - free(allDevNameMap[i].name); - free(allDevNameMap[i].device); - } - - free(allDevNameMap); - allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames); - - for(i = 0;i < numDevNames;++i) - AppendAllDevicesList(allDevNameMap[i].name); + probe_devices(SND_PCM_STREAM_PLAYBACK, &PlaybackDevices); + VECTOR_FOR_EACH(const DevMap, PlaybackDevices, AppendAllDevicesList2); break; case CAPTURE_DEVICE_PROBE: - for(i = 0;i < numCaptureDevNames;++i) - { - free(allCaptureDevNameMap[i].name); - free(allCaptureDevNameMap[i].device); - } - - free(allCaptureDevNameMap); - allCaptureDevNameMap = probe_devices(SND_PCM_STREAM_CAPTURE, &numCaptureDevNames); - - for(i = 0;i < numCaptureDevNames;++i) - AppendCaptureDeviceList(allCaptureDevNameMap[i].name); + probe_devices(SND_PCM_STREAM_CAPTURE, &CaptureDevices); + VECTOR_FOR_EACH(const DevMap, CaptureDevices, AppendCaptureDeviceList2); break; } } @@ -1386,8 +1365,9 @@ static ALCbackend* ALCalsaBackendFactory_createBackend(ALCalsaBackendFactory* UN { ALCplaybackAlsa *backend; - backend = calloc(1, sizeof(*backend)); + backend = ALCplaybackAlsa_New(sizeof(*backend)); if(!backend) return NULL; + memset(backend, 0, sizeof(*backend)); ALCplaybackAlsa_Construct(backend, device); @@ -1397,8 +1377,9 @@ static ALCbackend* ALCalsaBackendFactory_createBackend(ALCalsaBackendFactory* UN { ALCcaptureAlsa *backend; - backend = calloc(1, sizeof(*backend)); + backend = ALCcaptureAlsa_New(sizeof(*backend)); if(!backend) return NULL; + memset(backend, 0, sizeof(*backend)); ALCcaptureAlsa_Construct(backend, device); |