ALSA usage tweak

This commit is contained in:
Jack Andersen 2016-03-23 15:55:39 -10:00
parent 290d40641d
commit 5cec033f18

View File

@ -98,16 +98,14 @@ struct ALSAAudioVoiceEngine : BaseAudioVoiceEngine
return AudioChannelSet::Unknown; return AudioChannelSet::Unknown;
} }
AudioVoiceEngineMixInfo _getEngineMixInfo() ALSAAudioVoiceEngine()
{ {
if (snd_pcm_open(&m_pcm, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) if (snd_pcm_open(&m_pcm, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0)
{ {
Log.report(logvisor::Error, "unable to allocate ALSA voice"); Log.report(logvisor::Error, "unable to allocate ALSA voice");
return {}; return;
} }
AudioVoiceEngineMixInfo ret = {};
/* Query audio card for best supported format amd sample-rate */ /* Query audio card for best supported format amd sample-rate */
snd_pcm_hw_params_t* hwParams; snd_pcm_hw_params_t* hwParams;
snd_pcm_hw_params_malloc(&hwParams); snd_pcm_hw_params_malloc(&hwParams);
@ -117,68 +115,68 @@ struct ALSAAudioVoiceEngine : BaseAudioVoiceEngine
if (!snd_pcm_hw_params_test_format(m_pcm, hwParams, SND_PCM_FORMAT_S32)) if (!snd_pcm_hw_params_test_format(m_pcm, hwParams, SND_PCM_FORMAT_S32))
{ {
bestFmt = SND_PCM_FORMAT_S32; bestFmt = SND_PCM_FORMAT_S32;
ret.m_sampleFormat = SOXR_INT32_I; m_mixInfo.m_sampleFormat = SOXR_INT32_I;
ret.m_bitsPerSample = 32; m_mixInfo.m_bitsPerSample = 32;
} }
else if (!snd_pcm_hw_params_test_format(m_pcm, hwParams, SND_PCM_FORMAT_S16)) else if (!snd_pcm_hw_params_test_format(m_pcm, hwParams, SND_PCM_FORMAT_S16))
{ {
bestFmt = SND_PCM_FORMAT_S16; bestFmt = SND_PCM_FORMAT_S16;
ret.m_sampleFormat = SOXR_INT16_I; m_mixInfo.m_sampleFormat = SOXR_INT16_I;
ret.m_bitsPerSample = 16; m_mixInfo.m_bitsPerSample = 16;
} }
else else
{ {
snd_pcm_close(m_pcm); snd_pcm_close(m_pcm);
m_pcm = nullptr; m_pcm = nullptr;
Log.report(logvisor::Fatal, "unsupported audio formats on default ALSA device"); Log.report(logvisor::Fatal, "unsupported audio formats on default ALSA device");
return {}; return;
} }
unsigned int bestRate; unsigned int bestRate;
if (!snd_pcm_hw_params_test_rate(m_pcm, hwParams, 96000, 0)) if (!snd_pcm_hw_params_test_rate(m_pcm, hwParams, 96000, 0))
{ {
bestRate = 96000; bestRate = 96000;
ret.m_sampleRate = 96000.0; m_mixInfo.m_sampleRate = 96000.0;
} }
else if (!snd_pcm_hw_params_test_rate(m_pcm, hwParams, 48000, 0)) else if (!snd_pcm_hw_params_test_rate(m_pcm, hwParams, 48000, 0))
{ {
bestRate = 48000; bestRate = 48000;
ret.m_sampleRate = 48000.0; m_mixInfo.m_sampleRate = 48000.0;
} }
else else
{ {
snd_pcm_close(m_pcm); snd_pcm_close(m_pcm);
m_pcm = nullptr; m_pcm = nullptr;
Log.report(logvisor::Fatal, "unsupported audio sample rates on default ALSA device"); Log.report(logvisor::Fatal, "unsupported audio sample rates on default ALSA device");
return {}; return;
} }
snd_pcm_hw_params_free(hwParams); snd_pcm_hw_params_free(hwParams);
/* Query audio card for channel map */ /* Query audio card for channel map */
ret.m_channels = _getAvailableSet(); m_mixInfo.m_channels = _getAvailableSet();
/* Populate channel map */ /* Populate channel map */
unsigned chCount = ChannelCount(ret.m_channels); unsigned chCount = ChannelCount(m_mixInfo.m_channels);
int err; int err;
while ((err = snd_pcm_set_params(m_pcm, bestFmt, SND_PCM_ACCESS_RW_INTERLEAVED, while ((err = snd_pcm_set_params(m_pcm, bestFmt, SND_PCM_ACCESS_RW_INTERLEAVED,
chCount, bestRate, 0, 100000)) < 0) chCount, bestRate, 0, 100000)) < 0)
{ {
if (ret.m_channels == AudioChannelSet::Stereo) if (m_mixInfo.m_channels == AudioChannelSet::Stereo)
break; break;
ret.m_channels = AudioChannelSet(int(ret.m_channels) - 1); m_mixInfo.m_channels = AudioChannelSet(int(m_mixInfo.m_channels) - 1);
chCount = ChannelCount(ret.m_channels); chCount = ChannelCount(m_mixInfo.m_channels);
} }
if (err < 0) if (err < 0)
{ {
snd_pcm_close(m_pcm); snd_pcm_close(m_pcm);
m_pcm = nullptr; m_pcm = nullptr;
Log.report(logvisor::Error, "unable to set ALSA voice params"); Log.report(logvisor::Error, "unable to set ALSA voice params");
return {}; return;
} }
snd_pcm_chmap_query_t** chmaps = snd_pcm_query_chmaps(m_pcm); snd_pcm_chmap_query_t** chmaps = snd_pcm_query_chmaps(m_pcm);
ChannelMap& chmapOut = ret.m_channelMap; ChannelMap& chmapOut = m_mixInfo.m_channelMap;
if (chmaps) if (chmaps)
{ {
snd_pcm_chmap_t* foundChmap = nullptr; snd_pcm_chmap_t* foundChmap = nullptr;
@ -192,7 +190,7 @@ struct ALSAAudioVoiceEngine : BaseAudioVoiceEngine
chBits |= 1 << chm->pos[c]; chBits |= 1 << chm->pos[c];
bool good = false; bool good = false;
switch (ret.m_channels) switch (m_mixInfo.m_channels)
{ {
case AudioChannelSet::Stereo: case AudioChannelSet::Stereo:
if ((chBits & (1 << SND_CHMAP_FL)) != 0 && if ((chBits & (1 << SND_CHMAP_FL)) != 0 &&
@ -243,7 +241,7 @@ struct ALSAAudioVoiceEngine : BaseAudioVoiceEngine
m_pcm = nullptr; m_pcm = nullptr;
snd_pcm_free_chmaps(chmaps); snd_pcm_free_chmaps(chmaps);
Log.report(logvisor::Error, "unable to find matching ALSA voice chmap"); Log.report(logvisor::Error, "unable to find matching ALSA voice chmap");
return {}; return;
} }
chmapOut.m_channelCount = chCount; chmapOut.m_channelCount = chCount;
for (int c=0 ; c<foundChmap->channels ; ++c) for (int c=0 ; c<foundChmap->channels ; ++c)
@ -258,13 +256,6 @@ struct ALSAAudioVoiceEngine : BaseAudioVoiceEngine
chmapOut.m_channels[1] = AudioChannel::FrontRight; chmapOut.m_channels[1] = AudioChannel::FrontRight;
} }
return ret;
}
ALSAAudioVoiceEngine()
: BaseAudioVoiceEngine(std::bind(&ALSAAudioVoiceEngine::_getEngineMixInfo, this))
{
/* Base class will call _getEngineMixInfo first */
snd_pcm_get_params(m_pcm, &m_bufSize, &m_periodSize); snd_pcm_get_params(m_pcm, &m_bufSize, &m_periodSize);
snd_pcm_prepare(m_pcm); snd_pcm_prepare(m_pcm);
m_mixInfo.m_periodFrames = m_periodSize; m_mixInfo.m_periodFrames = m_periodSize;