[英]ALSA: non-interleaved access not supported?
ALSA 的snd_pcm_hw_params_set_access函數在使用SND_PCM_ACCESS_RW_NONINTERLEAVED 訪問類型調用時失敗,報告存在無效參數。 相同的代碼適用於SND_PCM_ACCESS_RW_INTERLEAVED access 。
我試圖更改對 snd_pcm_hw_params_* 函數的調用順序,但沒有任何效果。
接下來我認為我的硬件可能不支持非交錯播放,但根據這篇文章,如果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
hw_params_set_*
函數只接受設備支持的那些值。
大多數默認設備( plughw
、 default
等)支持自動轉換,因此接受所有格式。 hw
設備沒有。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.