ALSA's snd_pcm_hw_params_set_access http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m___h_w___params.html#ga4c8f1c632931923531ca68ee048a8de8调用时函数失败SND_PCM_ACCESS_RW_NONINTERLEAVED 访问类型 http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#ga661221ba5e8f1d6eaf4ab8e2da57cc1a,报告存在无效参数。相同的代码可以很好地工作SND_PCM_ACCESS_RW_INTERLEAVED 访问 http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#ga661221ba5e8f1d6eaf4ab8e2da57cc1a.
我尝试更改对 snd_pcm_hw_params_* 函数的调用顺序,但没有效果。
接下来我认为我的硬件可能不支持非交错播放,但根据这个帖子 http://mailman.alsa-project.org/pipermail/alsa-devel/2012-October/056321.html如果 ALSA 子系统本身不支持非交错播放,则在将非交错数据发送到硬件之前,它将对其进行交错。因此,非交错访问应该始终可用。
那么为什么非交错访问似乎不受支持呢?
以下代码对于交错播放效果很好,但对于非交错播放会产生此问题:
int err;
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
fprintf(stderr, "ALSA: allocate hw_params error: %s\n", snd_strerror(err));
throw 5;
}
if ((err = snd_pcm_hw_params_any(pb_dev, hw_params)) < 0) {
fprintf(stderr, "ALSA: hw_params_any error: %s\n", snd_strerror(err));
throw 5;
}
if ((err = snd_pcm_hw_params_set_access(pb_dev, hw_params, (pAudioCtx->sample_fmt < AV_SAMPLE_FMT_U8P) ? SND_PCM_ACCESS_RW_INTERLEAVED : SND_PCM_ACCESS_RW_NONINTERLEAVED)) < 0) {
fprintf(stderr, "ALSA: set access type error: %s\n", snd_strerror(err));
throw 5;
}
if ((err = snd_pcm_hw_params_set_channels(pb_dev, hw_params, pAudioCtx->channels)) < 0) {
fprintf(stderr, "ALSA: set channel count error: %s\n", snd_strerror(err));
throw 5;
}
snd_pcm_format_t sample_format;
switch (pAudioCtx->sample_fmt) {
case AV_SAMPLE_FMT_U8: case AV_SAMPLE_FMT_U8P: sample_format = SND_PCM_FORMAT_U8; break;
case AV_SAMPLE_FMT_S16: case AV_SAMPLE_FMT_S16P: sample_format = SND_PCM_FORMAT_S16; break;
case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_S32P: sample_format = SND_PCM_FORMAT_S32; break;
case AV_SAMPLE_FMT_FLT: case AV_SAMPLE_FMT_FLTP: sample_format = SND_PCM_FORMAT_FLOAT; break;
case AV_SAMPLE_FMT_DBL: case AV_SAMPLE_FMT_DBLP: sample_format = SND_PCM_FORMAT_FLOAT64; break;
default: fprintf(stderr, "sampleformat %d is not supported\n", pAudioCtx->sample_fmt);
throw 5;
}
if ((err = snd_pcm_hw_params_set_format(pb_dev, hw_params, sample_format)) < 0) {
fprintf(stderr, "ALSA: set sample format error: %s\n", snd_strerror(err));
throw 5;
}
if ((err = snd_pcm_hw_params_set_rate_near(pb_dev, hw_params, (unsigned int*)&pAudioCtx->sample_rate, 0)) < 0) {
fprintf(stderr, "ALSA: set sample rate error: %s\n", snd_strerror(err));
throw 5;
}
if ((err = snd_pcm_hw_params(pb_dev, hw_params)) < 0) {
fprintf(stderr, "ALSA: set parameters error: %s\n", snd_strerror(err));
throw 5;
}
执行此命令会产生以下输出:
ALSA: set access type error: Invalid argument