Я обычно не имею дело с аудио драйверами, поэтому, пожалуйста, прости меня за любое невежество. У меня есть программа C ++, работающая на Raspberry Pi 3 с Ubuntu 18.04 Server LTS для ОС. ALSA работает с aplay и arecord без проблем.
В моем приложении я настроил ALSA со следующим кодом
int LinuxAudioPlayer::Open(const std::string& device, AudioPlayerFormat format){
//PCM variables
int rc;
int err;
unsigned int val;
int dir;
m_device = device;
//begin PCM setup
/* Open PCM device for playback. */
if ((err = snd_pcm_open(&m_playback_handle, device.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
fprintf(stderr, "cannot open output audio device %s: %s\n", device.c_str(), snd_strerror(err));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(&m_params);
/* Fill it in with default values. */
snd_pcm_hw_params_any(m_playback_handle, m_params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(m_playback_handle, m_params,
SND_PCM_ACCESS_RW_INTERLEAVED);
switch(format){
case AudioPlayerFormat::Mono16khz16bit:
default:
/* Signed 16-bit little-endian format */
fprintf(stdout, "Format = Mono16khz16bit\n");
m_numChannels = 1;
m_bytesPerSample = 2;
m_bitsPerSecond = 16000;
snd_pcm_hw_params_set_format(m_playback_handle, m_params,
SND_PCM_FORMAT_S16_LE);
}
/* set number of Channels */
snd_pcm_hw_params_set_channels(m_playback_handle, m_params, m_numChannels);
/* set bits/second sampling rate */
snd_pcm_hw_params_set_rate_near(m_playback_handle, m_params,
&m_bitsPerSecond, &dir);
/* Set buffer size */
unsigned int bufferSize = 8192;
rc = snd_pcm_hw_params_set_buffer_size_near(m_playback_handle, m_params, (snd_pcm_uframes_t *)&bufferSize);
if(rc < 0){
fprintf(stdout, "snd_pcm_hw_params_set_buffer_size_near failed: %s\n", snd_strerror(rc) );
}
/* Set period size to 32 frames. */
m_frames = 32;
rc = snd_pcm_hw_params_set_period_size_near(m_playback_handle,
m_params, &m_frames, &dir);
if(rc < 0){
fprintf(stdout, "snd_pcm_hw_params_set_period_size_near failed: %s\n", snd_strerror(rc) );
}
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(m_playback_handle, m_params);
if (rc < 0) {
fprintf(stderr,
"unable to set hw parameters: %s %d\n",
snd_strerror(rc), rc);
exit(1);
}
//end PCM setup
Интересно то, что иногда я могу нормально запускать приложение. но примерно 1 из 4 раз я получаю сбои в функциях snd_pcm_hw_params_set_buffer_size_near и snd_pcm_hw_params_set_period_size_near с ошибкой «Неверный аргумент».
Как аргумент может быть недействительным, если иногда он успешно выполняется? Я надеюсь сделать мою программу более стабильной, чтобы ее не нужно было запускать несколько раз для успешного выполнения.