ALSA:不支持非交错访问?

时间:2012-11-15 11:19:44

标签: c alsa

当使用snd_pcm_hw_params_set_access调用时,ALSA的SND_PCM_ACCESS_RW_NONINTERLEAVED access type函数失败,并报告存在无效参数。相同的代码适用于SND_PCM_ACCESS_RW_INTERLEAVED access

我试图改变对snd_pcm_hw_params_ *函数的调用顺序,但没有效果。

接下来我认为我的硬件可能不支持非交错播放,但根据this post 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

1 个答案:

答案 0 :(得分:3)

hw_params_set_*函数仅接受设备支持的值。

大多数默认设备(plughwdefault等)支持自动转换,因此接受所有格式。 hw设备没有。