/* ******************************************************************************* * INCLUDE ******************************************************************************* */ #include "SoundCard.h" #include namespace Video { namespace ALSA { /* ******************************************************************************* * CLASS DEFINE ******************************************************************************* */ SoundCard::SoundCard(int index): _index(index) { initialize(); } SoundCard::~SoundCard() { } void SoundCard::initialize() { _info.device = Poco::format("hw:%d", _index); int rc; snd_ctl_t* handle; if ((rc = snd_ctl_open(&handle, _info.device.c_str(), 0)) < 0) throw Poco::InvalidAccessException("SoundCard: Cannot open device"); snd_ctl_card_info_t* info; snd_ctl_card_info_alloca(&info); if ((rc = snd_ctl_card_info(handle, info)) < 0) throw Poco::InvalidAccessException("SoundCard: Cannot get card info"); _info.id = snd_ctl_card_info_get_id(info); _info.name = snd_ctl_card_info_get_name(info); _info.longname = snd_ctl_card_info_get_longname(info); _info.driver = snd_ctl_card_info_get_driver(info); _info.components = snd_ctl_card_info_get_components(info); _info.mixername = snd_ctl_card_info_get_mixername(info); snd_ctl_close(handle); auto enumerateCapabilities = [](snd_pcm_t* pcm, Info& info) { snd_pcm_hw_params_t* params; snd_pcm_hw_params_alloca(¶ms); snd_pcm_hw_params_any(pcm, params); for (int access = 0; access <= SND_PCM_ACCESS_LAST; access++) info.access[access] = (snd_pcm_hw_params_test_access(pcm, params, (snd_pcm_access_t)access) == 0); for (int format = 0; format <= SND_PCM_FORMAT_LAST; format++) { if (snd_pcm_hw_params_test_format(pcm, params, (snd_pcm_format_t)format) == 0) info.formats.push_back((snd_pcm_format_t)format); } for (unsigned int rate = 1000; rate <= 384000; rate += 1000) { if (snd_pcm_hw_params_test_rate(pcm, params, rate, 0) == 0) info.sampleRates.push_back(rate); } for (int channels = 1; channels <= 16; channels++) { if (snd_pcm_hw_params_test_channels(pcm, params, channels) == 0) { info.channels = channels; break; } } for (snd_pcm_uframes_t val = 16; val <= 1048576; val *= 2) { if (snd_pcm_hw_params_test_buffer_size(pcm, params, val) == 0) info.bufferSizes.push_back(val); } }; snd_pcm_t* pcm; int err = snd_pcm_open(&pcm, _info.device.c_str(), SND_PCM_STREAM_CAPTURE, 0); if (err < 0) _info.supportCapture = false; else { _info.supportCapture = true; enumerateCapabilities(pcm, _info); snd_pcm_close(pcm); } err = snd_pcm_open(&pcm, _info.device.c_str(), SND_PCM_STREAM_PLAYBACK, 0); if (err < 0) _info.supportPlayback = false; else { _info.supportPlayback = true; if (!_info.supportCapture) enumerateCapabilities(pcm, _info); snd_pcm_close(pcm); } } SoundCard::Info& SoundCard::info() { return _info; } SoundCard::SoundCards SoundCard::getSoundCards() { SoundCards cards; int id = -1; while (snd_card_next(&id), id >= 0) cards.push_back(new SoundCard(id)); return cards; } } }