Alsa snd_pcm_avail 总是返回 0
Alsa snd_pcm_avail always returning a 0
我正在尝试从我的编解码器中读取数据。由于我项目中的原因,我想做非阻塞,但每次我读取编解码器上可用的字节数时,它都显示为零。
算法非常简单:等待 1ms,然后检查编解码器中是否有 160+ 个样本可供读取,然后读取样本。但每次我读它时,它都说样本计数为零。
谁能帮我理解为什么 "rc = snd_pcm_avail(inputCodecHandle);" 总是返回零?
这是包含代码的线程。
void CRadioStack::rcvThread() {
ChannelBuffer_t *buffer_p = NULL;
int8_t *inputBuf_p;
int rc;
int16_t *inputBuf16_p;
int samplesToRead;
const int rxFrameSize = 160;
snd_pcm_sframes_t delay;
snd_pcm_nonblock(inputCodecHandle, 1);
snd_pcm_prepare(inputCodecHandle);
while (true) {
TWTime::msleep(1);
// get the number of samples available
snd_pcm_delay(inputCodecHandle, &delay);
rc = snd_pcm_avail(inputCodecHandle);
if (rc < 0) {
myLog->warn("Error in getting sample count: %s", snd_strerror(rc));
snd_pcm_prepare(outputCodecHandle);
continue;
}
samplesToRead = rc;
// if number of samples > 160 then get 160 samples
if (samplesToRead <= rxFrameSize) {
continue;
}
// read the from the codec into the Channel Buffer.
rc = snd_pcm_readi(inputCodecHandle, inputBuf_p, rxFrameSize);
if (rc < 0) {
myLog->warn("Error reading Codec: %s", snd_strerror(rc));
continue;
} else if (rc != rxFrameSize) { // nothing to get
myLog->warn("Input samples on codec not 160");
}
pushToInputQueue(inputBuf_p);
}
}
这是打开编解码器的代码。
bool CRadioStack::openInputCodec()
{
unsigned int val;
int dir;
const int NUM_OF_CHAN = 1;
codecRunning = false;
snd_pcm_uframes_t frames;
int rc;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
inputCodecHandle = nullptr;
// Open pcm device for output
rc = snd_pcm_open(&handle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0) {
myLog->error("Unable to open input codec: %s", snd_strerror(rc));
return false;
}
// allocate a hardware parameters object
snd_pcm_hw_params_alloca(¶ms);
// fill with default values
snd_pcm_hw_params_any(handle, params);
// now setup the hardware paramters
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); // interleaved
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); // 16bin linear little-endian
snd_pcm_hw_params_set_channels(handle, params, NUM_OF_CHAN); // one channel
val = 0;
snd_pcm_hw_params_set_channels_near(handle, params, &val); // one channel
val = 8000;
dir = 0;
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); // 8k sample rate.
frames = 160;
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); // period size = 160 frames
// save the hardware parameters
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
myLog->error("Unable to save hardware parameters to output codec.");
return false;
}
// ready to write to output codec.
// so save the handle so that it can be used elsewhere.
inputCodecHandle = handle;
return true;
}
谢谢!
设备从未启动。
这将在第一次 snd_pcm_read*()
调用时自动发生,但也可以通过 snd_pcm_start()
.
显式完成
我正在尝试从我的编解码器中读取数据。由于我项目中的原因,我想做非阻塞,但每次我读取编解码器上可用的字节数时,它都显示为零。
算法非常简单:等待 1ms,然后检查编解码器中是否有 160+ 个样本可供读取,然后读取样本。但每次我读它时,它都说样本计数为零。
谁能帮我理解为什么 "rc = snd_pcm_avail(inputCodecHandle);" 总是返回零?
这是包含代码的线程。
void CRadioStack::rcvThread() {
ChannelBuffer_t *buffer_p = NULL;
int8_t *inputBuf_p;
int rc;
int16_t *inputBuf16_p;
int samplesToRead;
const int rxFrameSize = 160;
snd_pcm_sframes_t delay;
snd_pcm_nonblock(inputCodecHandle, 1);
snd_pcm_prepare(inputCodecHandle);
while (true) {
TWTime::msleep(1);
// get the number of samples available
snd_pcm_delay(inputCodecHandle, &delay);
rc = snd_pcm_avail(inputCodecHandle);
if (rc < 0) {
myLog->warn("Error in getting sample count: %s", snd_strerror(rc));
snd_pcm_prepare(outputCodecHandle);
continue;
}
samplesToRead = rc;
// if number of samples > 160 then get 160 samples
if (samplesToRead <= rxFrameSize) {
continue;
}
// read the from the codec into the Channel Buffer.
rc = snd_pcm_readi(inputCodecHandle, inputBuf_p, rxFrameSize);
if (rc < 0) {
myLog->warn("Error reading Codec: %s", snd_strerror(rc));
continue;
} else if (rc != rxFrameSize) { // nothing to get
myLog->warn("Input samples on codec not 160");
}
pushToInputQueue(inputBuf_p);
}
}
这是打开编解码器的代码。
bool CRadioStack::openInputCodec()
{
unsigned int val;
int dir;
const int NUM_OF_CHAN = 1;
codecRunning = false;
snd_pcm_uframes_t frames;
int rc;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
inputCodecHandle = nullptr;
// Open pcm device for output
rc = snd_pcm_open(&handle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0) {
myLog->error("Unable to open input codec: %s", snd_strerror(rc));
return false;
}
// allocate a hardware parameters object
snd_pcm_hw_params_alloca(¶ms);
// fill with default values
snd_pcm_hw_params_any(handle, params);
// now setup the hardware paramters
snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); // interleaved
snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); // 16bin linear little-endian
snd_pcm_hw_params_set_channels(handle, params, NUM_OF_CHAN); // one channel
val = 0;
snd_pcm_hw_params_set_channels_near(handle, params, &val); // one channel
val = 8000;
dir = 0;
snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); // 8k sample rate.
frames = 160;
snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); // period size = 160 frames
// save the hardware parameters
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
myLog->error("Unable to save hardware parameters to output codec.");
return false;
}
// ready to write to output codec.
// so save the handle so that it can be used elsewhere.
inputCodecHandle = handle;
return true;
}
谢谢!
设备从未启动。
这将在第一次 snd_pcm_read*()
调用时自动发生,但也可以通过 snd_pcm_start()
.