static int alsa_play (const char *buff, const size_t size) { int to_write = size; int buf_pos = 0; assert (chunk_size > 0); debug ("Got %d bytes to play", (int)size); while (to_write) { int to_copy = MIN((size_t)to_write, sizeof(alsa_buf) - (size_t)alsa_buf_fill); memcpy (alsa_buf + alsa_buf_fill, buff + buf_pos, to_copy); to_write -= to_copy; buf_pos += to_copy; alsa_buf_fill += to_copy; debug ("Copied %d bytes to alsa_buf (now is filled with %d " "bytes)", to_copy, alsa_buf_fill); if (play_buf_chunks() < 0) return -1; } debug ("Played everything"); return size; }
static void alsa_close () { snd_pcm_sframes_t delay; assert (handle != NULL); /* play what remained in the buffer */ if (alsa_buf_fill) { assert (alsa_buf_fill < chunk_size); snd_pcm_format_set_silence (params.format, alsa_buf + alsa_buf_fill, (chunk_size - alsa_buf_fill) / bytes_per_frame * params.channels); alsa_buf_fill = chunk_size; play_buf_chunks (); } /* Wait for ALSA buffers to empty. * Do not be tempted to use snd_pcm_nonblock() and snd_pcm_drain() * here; there are two bugs in ALSA which make it a bad idea (see * the SVN commit log for r2550). Instead we sleep for the duration * of the still unplayed samples. */ if (snd_pcm_delay (handle, &delay) == 0) usleep ((uint64_t) delay * 1000000 / params.rate); snd_pcm_close (handle); logit ("ALSA device closed"); params.format = 0; params.rate = 0; params.channels = 0; handle = NULL; }
static void alsa_close () { assert (handle != NULL); /* play what remained in the buffer */ if (alsa_buf_fill) { assert (alsa_buf_fill < chunk_size); /* FIXME: why the last argument is multiplied by number of * channels? */ snd_pcm_format_set_silence (params.format, alsa_buf + alsa_buf_fill, (chunk_size - alsa_buf_fill) / bytes_per_frame * params.channels); play_buf_chunks (); } params.format = 0; params.rate = 0; params.channels = 0; snd_pcm_close (handle); logit ("ALSA device closed"); handle = NULL; }
static void alsa_close () { assert (handle != NULL); /* play what remained in the buffer */ if (alsa_buf_fill) { assert (alsa_buf_fill < chunk_size); snd_pcm_format_set_silence (params.format, alsa_buf + alsa_buf_fill, (chunk_size - alsa_buf_fill) / bytes_per_frame * params.channels); alsa_buf_fill = chunk_size; play_buf_chunks (); } params.format = 0; params.rate = 0; params.channels = 0; snd_pcm_close (handle); logit ("ALSA device closed"); handle = NULL; }