admin管理员组文章数量:1122826
I am working on an embedded audio device, it is using kernel-5.10, and ALSA-LIB to play audio.
When I am trying to call snd_pcm_writei()
to play audio, I got a little confused on what is the right way to set its input parameters and handle its return value.
Here is my code.
/* Get periodsize from system */
snd_pcm_hw_params_get_period_size(hw_params, &periodsize, NULL);
left = frames;
sent = 0;
while (left > 0) {
sent = (left > periodsize) ? periodsize : left;
rc = snd_pcm_writei(pcm_handle, buf, sent);
if (rc < 0) {
if (rc == -EAGAIN) {
usleep(1000);
}
rc = snd_pcm_recover(pcm_handle, rc, 0);
if (rc < 0) {
snd_pcm_prepare(pcm_handle);
}
} else if (rc == 0) {
/* How to handle this case ?*/
} else {
/* Samples less than were sent to audio-card */
left -= rc;
buf += rc * frame_size;
}
}
In my testing, the frames is 820, and periodsize
is got from system, now it is 400. I am trying to sent data to audio-card upto the size of periodsize
, is it correct?
Should I send data with frames
of 820 directly to the audio card to play?
snd_pcm_writei(pcm_handle, buf, frames);
Updated with testing codes and testing results.
#ifdef TEST_APLAY
frame_size = chan * 2;
buf = databuf;
left = data_frames;
sent = 0;
while (left > 0) {
sent = (left > periodsize) ? periodsize : left;
rc = snd_pcm_writei(hah->pcm_handle, buf, sent);
if (rc == -EAGAIN || (rc >= 0 && (size_t)rc < sent)) {
snd_pcm_wait(hah->pcm_handle, 10);
} else if (rc == -EPIPE) {
snd_pcm_recover(hah->pcm_handle, rc, 0);
//// snd_pcm_prepare(hah->pcm_handle);
} else if (rc < 0) {
break;
}
if (rc > 0) {
left -= rc;
buf += rc * frame_size;
}
}
#endif
And I got the following results (start and stop playing 10 times).
Playing/stoping quickly for times, pid: 3168
Got end of media, breaking
Got end of media, breaking
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
Got end of media, breaking
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
Got end of media, breaking
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred
Got end of media, breaking
Above is tested in Ubuntu-20.04 X86_64 VM, with AC97 sound card.
本文标签: linuxWhat is the right way to play audio with ALSA LIBStack Overflow
版权声明:本文标题:linux - What is the right way to play audio with ALSA LIB? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736304956a1932419.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论