diff options
author | Sven Gothel <[email protected]> | 2015-11-12 18:12:26 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-11-12 18:12:26 +0100 |
commit | 542c4804aafe3f3879cee56d19d7353ed49ee154 (patch) | |
tree | 9c89aeda9ec5d368a1fb016422448e6418fc87db /Alc/backends/qsa.c | |
parent | 2e8f6a1704dfa0048dbfc2f826847a4aaea3cbe8 (diff) | |
parent | 5d039309b355c350fd087a48c4b896d31871d174 (diff) |
Merge branch 'UPSTREAM'
Diffstat (limited to 'Alc/backends/qsa.c')
-rw-r--r-- | Alc/backends/qsa.c | 460 |
1 files changed, 108 insertions, 352 deletions
diff --git a/Alc/backends/qsa.c b/Alc/backends/qsa.c index 9258e4e5..291e49fc 100644 --- a/Alc/backends/qsa.c +++ b/Alc/backends/qsa.c @@ -13,8 +13,8 @@ * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Or go to http://www.gnu.org/copyleft/lgpl.html */ @@ -53,12 +53,12 @@ typedef struct { int card; int dev; } DevMap; +TYPEDEF_VECTOR(DevMap, vector_DevMap) + +static vector_DevMap DeviceNameMap; +static vector_DevMap CaptureNameMap; static const ALCchar qsaDevice[] = "QSA Default"; -static DevMap* allDevNameMap; -static ALuint numDevNames; -static DevMap* allCaptureDevNameMap; -static ALuint numCaptureDevNames; static const struct { int32_t format; @@ -104,69 +104,57 @@ static const struct { {0}, }; -static DevMap *deviceList(int type, ALuint *count) +static void deviceList(int type, vector_DevMap *devmap) { snd_ctl_t* handle; snd_pcm_info_t pcminfo; - int max_cards, card, err, dev, num_devices, idx; - DevMap* dev_list; + int max_cards, card, err, dev; + DevMap entry; char name[1024]; struct snd_ctl_hw_info info; - void* temp; - idx=0; - num_devices=0; - max_cards=snd_cards(); + max_cards = snd_cards(); + if(max_cards < 0) + return; - if (max_cards<=0) - { - return 0; - } + VECTOR_RESERVE(*devmap, max_cards+1); + VECTOR_RESIZE(*devmap, 0); - dev_list=malloc(sizeof(DevMap)*1); - dev_list[0].name=strdup(qsaDevice); - num_devices=1; + entry.name = strdup(qsaDevice); + entry.card = 0; + entry.dev = 0; + VECTOR_PUSH_BACK(*devmap, entry); - for (card=0; card<max_cards; card++) + for(card = 0;card < max_cards;card++) { - if ((err=snd_ctl_open(&handle, card))<0) - { + if((err=snd_ctl_open(&handle, card)) < 0) continue; - } - if ((err=snd_ctl_hw_info(handle, &info))<0) + + if((err=snd_ctl_hw_info(handle, &info)) < 0) { snd_ctl_close(handle); continue; } - for (dev=0; dev<(int)info.pcmdevs; dev++) + for(dev = 0;dev < (int)info.pcmdevs;dev++) { - if ((err=snd_ctl_pcm_info(handle, dev, &pcminfo)) < 0) - { + if((err=snd_ctl_pcm_info(handle, dev, &pcminfo)) < 0) continue; - } - if ((type==SND_PCM_CHANNEL_PLAYBACK && (pcminfo.flags&SND_PCM_INFO_PLAYBACK)) || - (type==SND_PCM_CHANNEL_CAPTURE && (pcminfo.flags&SND_PCM_INFO_CAPTURE))) + if((type==SND_PCM_CHANNEL_PLAYBACK && (pcminfo.flags&SND_PCM_INFO_PLAYBACK)) || + (type==SND_PCM_CHANNEL_CAPTURE && (pcminfo.flags&SND_PCM_INFO_CAPTURE))) { - temp=realloc(dev_list, sizeof(DevMap)*(num_devices+1)); - if (temp) - { - dev_list=temp; - snprintf(name, sizeof(name), "%s [%s] (hw:%d,%d)", info.name, pcminfo.name, card, dev); - dev_list[num_devices].name=strdup(name); - dev_list[num_devices].card=card; - dev_list[num_devices].dev=dev; - num_devices++; - } + snprintf(name, sizeof(name), "%s [%s] (hw:%d,%d)", info.name, pcminfo.name, card, dev); + entry.name = strdup(name); + entry.card = card; + entry.dev = dev; + + VECTOR_PUSH_BACK(*devmap, entry); + TRACE("Got device \"%s\", card %d, dev %d\n", name, card, dev); } } - snd_ctl_close (handle); + snd_ctl_close(handle); } - - *count=num_devices; - - return dev_list; } @@ -266,71 +254,48 @@ FORCE_ALIGN static int qsa_proc_playback(void* ptr) static ALCenum qsa_open_playback(ALCdevice* device, const ALCchar* deviceName) { - qsa_data* data; - char driver[64]; - int status; + qsa_data *data; int card, dev; + int status; - strncpy(driver, GetConfigValue("qsa", "device", qsaDevice), sizeof(driver)-1); - driver[sizeof(driver)-1]=0; - - data=(qsa_data*)calloc(1, sizeof(qsa_data)); - if (data==NULL) - { + data = (qsa_data*)calloc(1, sizeof(qsa_data)); + if(data == NULL) return ALC_OUT_OF_MEMORY; - } - if (!deviceName) - { - deviceName=driver; - } + if(!deviceName) + deviceName = qsaDevice; - if (strcmp(deviceName, qsaDevice)==0) - { - if (!deviceName) - { - deviceName=qsaDevice; - } - - status=snd_pcm_open_preferred(&data->pcmHandle, &card, &dev, SND_PCM_OPEN_PLAYBACK); - } + if(strcmp(deviceName, qsaDevice) == 0) + status = snd_pcm_open_preferred(&data->pcmHandle, &card, &dev, SND_PCM_OPEN_PLAYBACK); else { - size_t idx; + const DevMap *iter; - if (!allDevNameMap) - { - allDevNameMap=deviceList(SND_PCM_CHANNEL_PLAYBACK, &numDevNames); - } + if(VECTOR_SIZE(DeviceNameMap) == 0) + deviceList(SND_PCM_CHANNEL_PLAYBACK, &DeviceNameMap); - for (idx=0; idx<numDevNames; idx++) - { - if (allDevNameMap[idx].name && strcmp(deviceName, allDevNameMap[idx].name)==0) - { - if (idx>0) - { - break; - } - } - } - if (idx==numDevNames) +#define MATCH_DEVNAME(iter) ((iter)->name && strcmp(deviceName, (iter)->name)==0) + VECTOR_FIND_IF(iter, const DevMap, DeviceNameMap, MATCH_DEVNAME); +#undef MATCH_DEVNAME + if(iter == VECTOR_ITER_END(DeviceNameMap)) { free(data); return ALC_INVALID_DEVICE; } - status=snd_pcm_open(&data->pcmHandle, allDevNameMap[idx].card, allDevNameMap[idx].dev, SND_PCM_OPEN_PLAYBACK); + status = snd_pcm_open(&data->pcmHandle, iter->card, iter->dev, SND_PCM_OPEN_PLAYBACK); } - if (status<0) + if(status < 0) { free(data); return ALC_INVALID_DEVICE; } - data->audio_fd=snd_pcm_file_descriptor(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK); - if (data->audio_fd<0) + data->audio_fd = snd_pcm_file_descriptor(data->pcmHandle, SND_PCM_CHANNEL_PLAYBACK); + if(data->audio_fd < 0) { + snd_pcm_close(data->pcmHandle); free(data); return ALC_INVALID_DEVICE; } @@ -633,72 +598,51 @@ static void qsa_stop_playback(ALCdevice* device) static ALCenum qsa_open_capture(ALCdevice* device, const ALCchar* deviceName) { - qsa_data* data; - int format=-1; - char driver[64]; + qsa_data *data; int card, dev; + int format=-1; int status; - strncpy(driver, GetConfigValue("qsa", "capture", qsaDevice), sizeof(driver)-1); - driver[sizeof(driver)-1]=0; - data=(qsa_data*)calloc(1, sizeof(qsa_data)); if (data==NULL) { return ALC_OUT_OF_MEMORY; } - if (!deviceName) - { - deviceName=driver; - } + if(!deviceName) + deviceName = qsaDevice; - if (strcmp(deviceName, qsaDevice)==0) - { - if (!deviceName) - { - deviceName=qsaDevice; - } - - status=snd_pcm_open_preferred(&data->pcmHandle, &card, &dev, SND_PCM_OPEN_CAPTURE); - } + if(strcmp(deviceName, qsaDevice) == 0) + status = snd_pcm_open_preferred(&data->pcmHandle, &card, &dev, SND_PCM_OPEN_CAPTURE); else { - size_t idx; + const DevMap *iter; - if (!allCaptureDevNameMap) - { - allCaptureDevNameMap=deviceList(SND_PCM_CHANNEL_CAPTURE, &numDevNames); - } + if(VECTOR_SIZE(CaptureNameMap) == 0) + deviceList(SND_PCM_CHANNEL_CAPTURE, &CaptureNameMap); - for (idx=0; idx<numDevNames; idx++) - { - if (allCaptureDevNameMap[idx].name && strcmp(deviceName, allCaptureDevNameMap[idx].name)==0) - { - if (idx>0) - { - break; - } - } - } - if (idx==numDevNames) +#define MATCH_DEVNAME(iter) ((iter)->name && strcmp(deviceName, (iter)->name)==0) + VECTOR_FIND_IF(iter, const DevMap, CaptureNameMap, MATCH_DEVNAME); +#undef MATCH_DEVNAME + if(iter == VECTOR_ITER_END(CaptureNameMap)) { free(data); return ALC_INVALID_DEVICE; } - status=snd_pcm_open(&data->pcmHandle, allCaptureDevNameMap[idx].card, allCaptureDevNameMap[idx].dev, SND_PCM_OPEN_CAPTURE); + status = snd_pcm_open(&data->pcmHandle, iter->card, iter->dev, SND_PCM_OPEN_CAPTURE); } - if (status<0) + if(status < 0) { free(data); return ALC_INVALID_DEVICE; } - data->audio_fd=snd_pcm_file_descriptor(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE); - if (data->audio_fd<0) + data->audio_fd = snd_pcm_file_descriptor(data->pcmHandle, SND_PCM_CHANNEL_CAPTURE); + if(data->audio_fd < 0) { + snd_pcm_close(data->pcmHandle); free(data); return ALC_INVALID_DEVICE; } @@ -753,170 +697,13 @@ static ALCenum qsa_open_capture(ALCdevice* device, const ALCchar* deviceName) data->cparams.format.voices=ChannelsFromDevFmt(device->FmtChans); data->cparams.format.format=format; - if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0) - { - int original_rate=data->cparams.format.rate; - int original_voices=data->cparams.format.voices; - int original_format=data->cparams.format.format; - int it; - int jt; - - for (it=0; it<1; it++) - { - /* Check for second pass */ - if (it==1) - { - original_rate=ratelist[0].rate; - original_voices=channellist[0].channels; - original_format=formatlist[0].format; - } - - do { - /* At first downgrade sample format */ - jt=0; - do { - if (formatlist[jt].format==data->cparams.format.format) - { - data->cparams.format.format=formatlist[jt+1].format; - break; - } - if (formatlist[jt].format==0) - { - data->cparams.format.format=0; - break; - } - jt++; - } while(1); - - if (data->cparams.format.format==0) - { - data->cparams.format.format=original_format; - - /* At secod downgrade sample rate */ - jt=0; - do { - if (ratelist[jt].rate==data->cparams.format.rate) - { - data->cparams.format.rate=ratelist[jt+1].rate; - break; - } - if (ratelist[jt].rate==0) - { - data->cparams.format.rate=0; - break; - } - jt++; - } while(1); - - if (data->cparams.format.rate==0) - { - data->cparams.format.rate=original_rate; - data->cparams.format.format=original_format; - - /* At third downgrade channels number */ - jt=0; - do { - if(channellist[jt].channels==data->cparams.format.voices) - { - data->cparams.format.voices=channellist[jt+1].channels; - break; - } - if (channellist[jt].channels==0) - { - data->cparams.format.voices=0; - break; - } - jt++; - } while(1); - } - - if (data->cparams.format.voices==0) - { - break; - } - } - - data->cparams.buf.block.frag_size=device->UpdateSize* - data->cparams.format.voices* - snd_pcm_format_width(data->cparams.format.format)/8; - data->cparams.buf.block.frags_max=device->NumUpdates; - data->cparams.buf.block.frags_min=device->NumUpdates; - if ((snd_pcm_plugin_params(data->pcmHandle, &data->cparams))<0) - { - continue; - } - else - { - break; - } - } while(1); - - if (data->cparams.format.voices!=0) - { - break; - } - } - - if (data->cparams.format.voices==0) - { - return ALC_INVALID_VALUE; - } - } - - /* now fill back to the our AL device */ - device->Frequency=data->cparams.format.rate; - - switch (data->cparams.format.voices) + if(snd_pcm_plugin_params(data->pcmHandle, &data->cparams) < 0) { - case 1: - device->FmtChans=DevFmtMono; - break; - case 2: - device->FmtChans=DevFmtStereo; - break; - case 4: - device->FmtChans=DevFmtQuad; - break; - case 6: - device->FmtChans=DevFmtX51; - break; - case 7: - device->FmtChans=DevFmtX61; - break; - case 8: - device->FmtChans=DevFmtX71; - break; - default: - device->FmtChans=DevFmtMono; - break; - } + snd_pcm_close(data->pcmHandle); + free(data); + device->ExtraData=NULL; - switch (data->cparams.format.format) - { - case SND_PCM_SFMT_S8: - device->FmtType=DevFmtByte; - break; - case SND_PCM_SFMT_U8: - device->FmtType=DevFmtUByte; - break; - case SND_PCM_SFMT_S16_LE: - device->FmtType=DevFmtShort; - break; - case SND_PCM_SFMT_U16_LE: - device->FmtType=DevFmtUShort; - break; - case SND_PCM_SFMT_S32_LE: - device->FmtType=DevFmtInt; - break; - case SND_PCM_SFMT_U32_LE: - device->FmtType=DevFmtUInt; - break; - case SND_PCM_SFMT_FLOAT_LE: - device->FmtType=DevFmtFloat; - break; - default: - device->FmtType=DevFmtShort; - break; + return ALC_INVALID_VALUE; } return ALC_NO_ERROR; @@ -927,9 +714,8 @@ static void qsa_close_capture(ALCdevice* device) qsa_data* data=(qsa_data*)device->ExtraData; if (data->pcmHandle!=NULL) - { snd_pcm_close(data->pcmHandle); - } + free(data); device->ExtraData=NULL; } @@ -954,10 +740,6 @@ static void qsa_start_capture(ALCdevice* device) } snd_pcm_capture_go(data->pcmHandle); - - device->UpdateSize=data->csetup.buf.block.frag_size/ - (ChannelsFromDevFmt(device->FmtChans)*BytesFromDevFmt(device->FmtType)); - device->NumUpdates=data->csetup.buf.block.frags; } static void qsa_stop_capture(ALCdevice* device) @@ -1073,16 +855,7 @@ static ALCenum qsa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint s return ALC_NO_ERROR; } -static ALint64 qsa_get_latency(ALCdevice* device) -{ - ALint frame_size=FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - - return (ALint64)(device->UpdateSize*device->NumUpdates/frame_size)* - 1000000000/device->Frequency; -} - -BackendFuncs qsa_funcs= -{ +static const BackendFuncs qsa_funcs= { qsa_open_playback, qsa_close_playback, qsa_reset_playback, @@ -1093,69 +866,52 @@ BackendFuncs qsa_funcs= qsa_start_capture, qsa_stop_capture, qsa_capture_samples, - qsa_available_samples, - qsa_get_latency, + qsa_available_samples }; ALCboolean alc_qsa_init(BackendFuncs* func_list) { - *func_list=qsa_funcs; - + *func_list = qsa_funcs; return ALC_TRUE; } void alc_qsa_deinit(void) { - ALuint i; - - for (i=0; i<numDevNames; ++i) - { - free(allDevNameMap[i].name); - } - free(allDevNameMap); - allDevNameMap=NULL; - numDevNames=0; +#define FREE_NAME(iter) free((iter)->name) + VECTOR_FOR_EACH(DevMap, DeviceNameMap, FREE_NAME); + VECTOR_DEINIT(DeviceNameMap); - for (i=0; i<numCaptureDevNames; ++i) - { - free(allCaptureDevNameMap[i].name); - } - free(allCaptureDevNameMap); - allCaptureDevNameMap=NULL; - numCaptureDevNames=0; + VECTOR_FOR_EACH(DevMap, CaptureNameMap, FREE_NAME); + VECTOR_DEINIT(CaptureNameMap); +#undef FREE_NAME } void alc_qsa_probe(enum DevProbe type) { - ALuint i; - switch (type) { case ALL_DEVICE_PROBE: - for (i=0; i<numDevNames; ++i) - { - free(allDevNameMap[i].name); - } - free(allDevNameMap); - - allDevNameMap=deviceList(SND_PCM_CHANNEL_PLAYBACK, &numDevNames); - for (i=0; i<numDevNames; ++i) - { - AppendAllDevicesList(allDevNameMap[i].name); - } - break; +#define FREE_NAME(iter) free((iter)->name) + VECTOR_FOR_EACH(DevMap, DeviceNameMap, FREE_NAME); +#undef FREE_NAME + VECTOR_RESIZE(DeviceNameMap, 0); + + deviceList(SND_PCM_CHANNEL_PLAYBACK, &DeviceNameMap); +#define APPEND_DEVICE(iter) AppendAllDevicesList((iter)->name) + VECTOR_FOR_EACH(const DevMap, DeviceNameMap, APPEND_DEVICE); +#undef APPEND_DEVICE + break; + case CAPTURE_DEVICE_PROBE: - for (i=0; i<numCaptureDevNames; ++i) - { - free(allCaptureDevNameMap[i].name); - } - free(allCaptureDevNameMap); - - allCaptureDevNameMap=deviceList(SND_PCM_CHANNEL_CAPTURE, &numCaptureDevNames); - for (i=0; i<numCaptureDevNames; ++i) - { - AppendCaptureDeviceList(allCaptureDevNameMap[i].name); - } - break; +#define FREE_NAME(iter) free((iter)->name) + VECTOR_FOR_EACH(DevMap, CaptureNameMap, FREE_NAME); +#undef FREE_NAME + VECTOR_RESIZE(CaptureNameMap, 0); + + deviceList(SND_PCM_CHANNEL_CAPTURE, &CaptureNameMap); +#define APPEND_DEVICE(iter) AppendCaptureDeviceList((iter)->name) + VECTOR_FOR_EACH(const DevMap, CaptureNameMap, APPEND_DEVICE); +#undef APPEND_DEVICE + break; } } |