ALSA:不支持非交错访问? [英] ALSA: non-interleaved access not supported?

查看:33
本文介绍了ALSA:不支持非交错访问?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ALSA 的 title="nofollow noreferrer"a> 函数在使用 调用时失败SND_PCM_ACCESS_RW_NONINTERLEAVED 访问类型,报告存在无效参数.相同的代码适用于

ALSA's snd_pcm_hw_params_set_access function fails when called with SND_PCM_ACCESS_RW_NONINTERLEAVED access type, reporting that there was an invalid argument. The same code works fine with SND_PCM_ACCESS_RW_INTERLEAVED access.

我尝试更改对 snd_pcm_hw_params_* 函数的调用顺序,但没有任何效果.

I tried to change the order of calls to snd_pcm_hw_params_* functions with no effect.

接下来我以为我的硬件可能不支持非交错播放,但根据这篇文章 ALSA 子系统将在将非交错数据发送到硬件之前对其进行交错,如果它本身不支持非交错播放.因此,非交错访问应该始终可用.

Next I thought that my hardware might not support non-interleaved playback, but according to this post ALSA subsystem will interleave non-interleaved data before sending it to the hardware if it does not support non-interleaved playback itself. Thus, non-interleaved access should always be available.

那么,为什么非交错访问似乎不受支持?

Why is it then, that non-interleaved access seems not be unsupported?

以下代码适用于交错播放,但对于非交错播放会产生此问题:

Following is the code that works fine for interleaved playback, but produces this problem for non-interleaved playback:

int err;
if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
    fprintf(stderr, "ALSA: allocate hw_params error: %s
", 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
", 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
", 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
", 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
", 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
", 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
", snd_strerror(err));
    throw 5;
}

if ((err = snd_pcm_hw_params(pb_dev, hw_params)) < 0) {
    fprintf(stderr, "ALSA: set parameters error: %s
", snd_strerror(err));
    throw 5;
}

执行此操作会产生以下输出:

Executing this yields following output:

ALSA: set access type error: Invalid argument

推荐答案

hw_params_set_* 函数只接受设备支持的那些值.

The hw_params_set_* functions accept only those values that are supported by the device.

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

Most of the default devices (plughw, default, etc.) support automatic conversions, and thus accept all formats. hw devices do not.

这篇关于ALSA:不支持非交错访问?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆