For example I have a simple play() function that plays arbitrary tone just fine. The problem is that as soon as I decide to stop playing tone ALSA produces click/pop sound. I've already tried using snd_pcm_drain(), stopping tone when it finishes period and in case of finite loop even tried to gradually silence tone. Is there a way to avoid this popping?
void play()
{
int err;
while (1) {
for (unsigned i = 0; i < buffer_size; i++)
{
buffer[i] = (AMP - 1) * gen_sine(time) + AMP;
time += time_step;
}
err = snd_pcm_writei(handle, buffer, buffer_size);
if (err == -EPIPE) {
fprintf(stderr, "underrun occurred\n");
snd_pcm_prepare(handle);
}
else if (err == -EBADFD) {
fprintf(stderr, "PCM is not in the right state\n");
}
else if (err < 0) {
fprintf(stderr, "error from writei: %s\n", snd_strerror(err));
}
}
}