【发布时间】:2021-11-02 03:19:11
【问题描述】:
问题说明了一切。我在这里转圈。我将 snd_pcm_sw_params_set_stop_threshold 设置为边界(为了好玩也设置为零),但我仍然在 snd_pcm_writei 上遇到缓冲区欠载错误。我不明白为什么。文档对此非常清楚:
If the stop threshold is equal to boundary (also software parameter - sw_param) then automatic stop will be disabled
这是一个可重复性极低的示例:
#include <alsa/asoundlib.h>
#include <iostream>
#define AUDIO_DEV "default"
#define AC_FRAME_SIZE 960
#define AC_SAMPLE_RATE 48000
#define AC_CHANNELS 2
//BUILD g++ -o main main.cpp -lasound
using namespace std;
int main() {
int err;
unsigned int i;
snd_pcm_t *handle;
snd_pcm_sframes_t frames;
snd_pcm_uframes_t boundary;
snd_pcm_sw_params_t *sw;
snd_pcm_hw_params_t *params;
unsigned int s_rate;
unsigned int buffer_time;
snd_pcm_uframes_t f_size;
unsigned char buffer[AC_FRAME_SIZE * 2];
int rc;
for (i = 0; i < sizeof(buffer); i++)
buffer[i] = random() & 0xff;
if ((err = snd_pcm_open(&handle, AUDIO_DEV, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
cout << "open error " << snd_strerror(err) << endl;
return 0;
}
s_rate = AC_SAMPLE_RATE;
f_size = AC_FRAME_SIZE;
buffer_time = 2500;
cout << s_rate << " " << f_size << endl;
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle, params, AC_CHANNELS);
snd_pcm_hw_params_set_rate_near(handle, params, &s_rate, 0);
snd_pcm_hw_params_set_period_size_near(handle, params, &f_size, 0);
cout << s_rate << " " << f_size << endl;
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
cout << "open error " << snd_strerror(err) << endl;
return 0;
}
snd_pcm_sw_params_alloca(&sw);
snd_pcm_sw_params_current(handle, sw);
snd_pcm_sw_params_get_boundary(sw, &boundary);
snd_pcm_sw_params_set_stop_threshold(handle, sw, boundary);
rc = snd_pcm_sw_params(handle, sw);
if (rc < 0) {
cout << "open error " << snd_strerror(err) << endl;
return 0;
}
snd_pcm_sw_params_current(handle, sw);
snd_pcm_sw_params_get_stop_threshold(sw, &boundary);
cout << "VALUE " << boundary << endl;
for (i = 0; i < 1600; i++) {
usleep(100 * 1000);
frames = snd_pcm_writei(handle, buffer, f_size);
if (frames < 0)
frames = snd_pcm_recover(handle, frames, 0);
if (frames < 0) {
cout << "open error " << snd_strerror(frames) << endl;
break;
}
}
return 0;
}
【问题讨论】: