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.