void ambdec_init(AmbDecConf *conf) { ALuint i; memset(conf, 0, sizeof(*conf)); AL_STRING_INIT(conf->Description); for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) { AL_STRING_INIT(conf->Speakers[i].Name); AL_STRING_INIT(conf->Speakers[i].Connection); } }
static void add_device(IMMDevice *device, LPCWSTR devid, vector_DevMap *list) { DevMap entry; AL_STRING_INIT(entry.name); entry.devid = strdupW(devid); get_device_name(device, &entry.name); TRACE("Got device \"%s\", \"%ls\"\n", al_string_get_cstr(entry.name), entry.devid); VECTOR_PUSH_BACK(*list, entry); }
static BOOL CALLBACK DSoundEnumDevices(GUID *guid, const WCHAR *desc, const WCHAR* UNUSED(drvname), void *data) { vector_DevMap *devices = data; OLECHAR *guidstr = NULL; DevMap *iter, *end; DevMap entry; HRESULT hr; int count; if(!guid) return TRUE; AL_STRING_INIT(entry.name); count = 0; do { al_string_copy_wcstr(&entry.name, desc); if(count != 0) { char str[64]; snprintf(str, sizeof(str), " #%d", count+1); al_string_append_cstr(&entry.name, str); } count++; iter = VECTOR_ITER_BEGIN(*devices); end = VECTOR_ITER_END(*devices); for(;iter != end;++iter) { if(al_string_cmp(entry.name, iter->name) == 0) break; } } while(iter != end); entry.guid = *guid; hr = StringFromCLSID(guid, &guidstr); if(SUCCEEDED(hr)) { TRACE("Got device \"%s\", GUID \"%ls\"\n", al_string_get_cstr(entry.name), guidstr); CoTaskMemFree(guidstr); } VECTOR_PUSH_BACK(*devices, entry); return TRUE; }
static BOOL CALLBACK DSoundEnumDevices(GUID *guid, const WCHAR *desc, const WCHAR* UNUSED(drvname), void *data) { vector_DevMap *devices = data; OLECHAR *guidstr = NULL; DevMap entry; HRESULT hr; int count; if(!guid) return TRUE; AL_STRING_INIT(entry.name); count = 0; while(1) { const DevMap *iter; al_string_copy_cstr(&entry.name, DEVNAME_HEAD); al_string_append_wcstr(&entry.name, desc); if(count != 0) { char str[64]; snprintf(str, sizeof(str), " #%d", count+1); al_string_append_cstr(&entry.name, str); } #define MATCH_ENTRY(i) (al_string_cmp(entry.name, (i)->name) == 0) VECTOR_FIND_IF(iter, const DevMap, *devices, MATCH_ENTRY); if(iter == VECTOR_END(*devices)) break; #undef MATCH_ENTRY count++; } entry.guid = *guid; hr = StringFromCLSID(guid, &guidstr); if(SUCCEEDED(hr)) { TRACE("Got device \"%s\", GUID \"%ls\"\n", al_string_get_cstr(entry.name), guidstr); CoTaskMemFree(guidstr); } VECTOR_PUSH_BACK(*devices, entry); return TRUE; }
static void ProbePlaybackDevices(void) { al_string *iter, *end; ALuint numdevs; ALuint i; clear_devlist(&PlaybackDevices); numdevs = waveOutGetNumDevs(); VECTOR_RESERVE(PlaybackDevices, numdevs); for(i = 0; i < numdevs; i++) { WAVEOUTCAPSW WaveCaps; al_string dname; AL_STRING_INIT(dname); if(waveOutGetDevCapsW(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR) { ALuint count = 0; do { al_string_copy_wcstr(&dname, WaveCaps.szPname); if(count != 0) { char str[64]; snprintf(str, sizeof(str), " #%d", count+1); al_string_append_cstr(&dname, str); } count++; iter = VECTOR_ITER_BEGIN(PlaybackDevices); end = VECTOR_ITER_END(PlaybackDevices); for(; iter != end; iter++) { if(al_string_cmp(*iter, dname) == 0) break; } } while(iter != end); TRACE("Got device \"%s\", ID %u\n", al_string_get_cstr(dname), i); } VECTOR_PUSH_BACK(PlaybackDevices, dname); } }
static void ProbeCaptureDevices(void) { ALuint numdevs; ALuint i; clear_devlist(&CaptureDevices); numdevs = waveInGetNumDevs(); VECTOR_RESIZE(CaptureDevices, 0, numdevs); for(i = 0;i < numdevs;i++) { WAVEINCAPSW WaveCaps; const al_string *iter; al_string dname; AL_STRING_INIT(dname); if(waveInGetDevCapsW(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR) { ALuint count = 0; while(1) { alstr_copy_cstr(&dname, DEVNAME_HEAD); alstr_append_wcstr(&dname, WaveCaps.szPname); if(count != 0) { char str[64]; snprintf(str, sizeof(str), " #%d", count+1); alstr_append_cstr(&dname, str); } count++; #define MATCH_ENTRY(i) (alstr_cmp(dname, *(i)) == 0) VECTOR_FIND_IF(iter, const al_string, CaptureDevices, MATCH_ENTRY); if(iter == VECTOR_END(CaptureDevices)) break; #undef MATCH_ENTRY } TRACE("Got device \"%s\", ID %u\n", alstr_get_cstr(dname), i); } VECTOR_PUSH_BACK(CaptureDevices, dname); } }
static void add_device(IMMDevice *device, vector_DevMap *list) { LPWSTR devid; HRESULT hr; hr = IMMDevice_GetId(device, &devid); if(SUCCEEDED(hr)) { DevMap entry; AL_STRING_INIT(entry.name); entry.devid = strdupW(devid); get_device_name(device, &entry.name); CoTaskMemFree(devid); TRACE("Got device \"%s\", \"%ls\"\n", al_string_get_cstr(entry.name), entry.devid); VECTOR_PUSH_BACK(*list, entry); } }
void ReadALConfig(void) { al_string confpaths = AL_STRING_INIT_STATIC(); al_string fname = AL_STRING_INIT_STATIC(); const char *str; FILE *f; str = "/etc/openal/alsoft.conf"; TRACE("Loading config %s...\n", str); f = al_fopen(str, "r"); if(f) { LoadConfigFromFile(f); fclose(f); } if(!(str=getenv("XDG_CONFIG_DIRS")) || str[0] == 0) str = "/etc/xdg"; alstr_copy_cstr(&confpaths, str); /* Go through the list in reverse, since "the order of base directories * denotes their importance; the first directory listed is the most * important". Ergo, we need to load the settings from the later dirs * first so that the settings in the earlier dirs override them. */ while(!alstr_empty(confpaths)) { char *next = strrchr(alstr_get_cstr(confpaths), ':'); if(next) { size_t len = next - alstr_get_cstr(confpaths); alstr_copy_cstr(&fname, next+1); VECTOR_RESIZE(confpaths, len, len+1); VECTOR_ELEM(confpaths, len) = 0; } else { alstr_reset(&fname); fname = confpaths; AL_STRING_INIT(confpaths); } if(alstr_empty(fname) || VECTOR_FRONT(fname) != '/') WARN("Ignoring XDG config dir: %s\n", alstr_get_cstr(fname)); else { if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/alsoft.conf"); else alstr_append_cstr(&fname, "alsoft.conf"); TRACE("Loading config %s...\n", alstr_get_cstr(fname)); f = al_fopen(alstr_get_cstr(fname), "r"); if(f) { LoadConfigFromFile(f); fclose(f); } } alstr_clear(&fname); } if((str=getenv("HOME")) != NULL && *str) { alstr_copy_cstr(&fname, str); if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/.alsoftrc"); else alstr_append_cstr(&fname, ".alsoftrc"); TRACE("Loading config %s...\n", alstr_get_cstr(fname)); f = al_fopen(alstr_get_cstr(fname), "r"); if(f) { LoadConfigFromFile(f); fclose(f); } } if((str=getenv("XDG_CONFIG_HOME")) != NULL && str[0] != 0) { alstr_copy_cstr(&fname, str); if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/alsoft.conf"); else alstr_append_cstr(&fname, "alsoft.conf"); } else { alstr_clear(&fname); if((str=getenv("HOME")) != NULL && str[0] != 0) { alstr_copy_cstr(&fname, str); if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/.config/alsoft.conf"); else alstr_append_cstr(&fname, ".config/alsoft.conf"); } } if(!alstr_empty(fname)) { TRACE("Loading config %s...\n", alstr_get_cstr(fname)); f = al_fopen(alstr_get_cstr(fname), "r"); if(f) { LoadConfigFromFile(f); fclose(f); } } alstr_clear(&fname); GetProcBinary(&fname, NULL); if(!alstr_empty(fname)) { if(VECTOR_BACK(fname) != '/') alstr_append_cstr(&fname, "/alsoft.conf"); else alstr_append_cstr(&fname, "alsoft.conf"); TRACE("Loading config %s...\n", alstr_get_cstr(fname)); f = al_fopen(alstr_get_cstr(fname), "r"); if(f) { LoadConfigFromFile(f); fclose(f); } } if((str=getenv("ALSOFT_CONF")) != NULL && *str) { TRACE("Loading config %s...\n", str); f = al_fopen(str, "r"); if(f) { LoadConfigFromFile(f); fclose(f); } } alstr_reset(&fname); alstr_reset(&confpaths); }
static void probe_devices(snd_pcm_stream_t stream, vector_DevMap *DeviceList) { const char *main_prefix = "plughw:"; snd_ctl_t *handle; snd_ctl_card_info_t *info; snd_pcm_info_t *pcminfo; int card, err, dev; DevMap entry; clear_devlist(DeviceList); snd_ctl_card_info_malloc(&info); snd_pcm_info_malloc(&pcminfo); 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(NULL, "alsa", (stream==SND_PCM_STREAM_PLAYBACK) ? "device" : "capture", "default")); VECTOR_PUSH_BACK(*DeviceList, entry); card = -1; if((err=snd_card_next(&card)) < 0) ERR("Failed to find a card: %s\n", snd_strerror(err)); ConfigValueStr(NULL, "alsa", prefix_name(stream), &main_prefix); while(card >= 0) { const char *card_prefix = main_prefix; const char *cardname, *cardid; char name[256]; snprintf(name, sizeof(name), "hw:%d", card); if((err = snd_ctl_open(&handle, name, 0)) < 0) { ERR("control open (hw:%d): %s\n", card, snd_strerror(err)); goto next_card; } if((err = snd_ctl_card_info(handle, info)) < 0) { ERR("control hardware info (hw:%d): %s\n", card, snd_strerror(err)); snd_ctl_close(handle); goto next_card; } cardname = snd_ctl_card_info_get_name(info); cardid = snd_ctl_card_info_get_id(info); snprintf(name, sizeof(name), "%s-%s", prefix_name(stream), cardid); ConfigValueStr(NULL, "alsa", name, &card_prefix); dev = -1; while(1) { const char *device_prefix = card_prefix; const char *devname; char device[128]; if(snd_ctl_pcm_next_device(handle, &dev) < 0) ERR("snd_ctl_pcm_next_device failed\n"); if(dev < 0) break; snd_pcm_info_set_device(pcminfo, dev); snd_pcm_info_set_subdevice(pcminfo, 0); snd_pcm_info_set_stream(pcminfo, stream); if((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { if(err != -ENOENT) ERR("control digital audio info (hw:%d): %s\n", card, snd_strerror(err)); continue; } devname = snd_pcm_info_get_name(pcminfo); snprintf(name, sizeof(name), "%s-%s-%d", prefix_name(stream), cardid, dev); ConfigValueStr(NULL, "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); 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: if(snd_card_next(&card) < 0) { ERR("snd_card_next failed\n"); break; } } snd_pcm_info_free(pcminfo); snd_ctl_card_info_free(info); }