From 88091e0359fd4854a0ae638040093d19a270821e Mon Sep 17 00:00:00 2001 From: Jan Hoffmann Date: Sun, 9 Apr 2017 10:56:05 +0200 Subject: Add gapless repeat for tone playback (#231) * Add gapless repeat for tone playback This allows to play progress tones with defined intervals continuously, without redundancy in the audio file. * Fix incorrect pointer arithmetic In order to move the output buffer pointer byte-wise it has to be cast first. --- src/play.c | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/play.c b/src/play.c index f35cce5..bd5d3de 100644 --- a/src/play.c +++ b/src/play.c @@ -11,7 +11,7 @@ #include "core.h" -enum {SILENCE_DUR = 2000, PTIME = 40}; +enum {PTIME = 40}; /** Audio file player */ struct play { @@ -49,21 +49,6 @@ static void tmr_stop(void *arg) } -static void tmr_repeat(void *arg) -{ - struct play *play = arg; - - lock_write_get(play->lock); - - play->mb->pos = 0; - play->eof = false; - - tmr_start(&play->tmr, 1000, tmr_polling, arg); - - lock_rel(play->lock); -} - - static void tmr_polling(void *arg) { struct play *play = arg; @@ -73,13 +58,8 @@ static void tmr_polling(void *arg) tmr_start(&play->tmr, 1000, tmr_polling, arg); if (play->eof) { - if (play->repeat > 0) - play->repeat--; - if (play->repeat == 0) tmr_start(&play->tmr, 1, tmr_stop, arg); - else - tmr_start(&play->tmr, SILENCE_DUR, tmr_repeat, arg); } lock_rel(play->lock); @@ -93,27 +73,39 @@ static void write_handler(int16_t *sampv, size_t sampc, void *arg) { struct play *play = arg; size_t sz = sampc * 2; + size_t pos = 0; + size_t left; + size_t count; lock_write_get(play->lock); if (play->eof) goto silence; - if (mbuf_get_left(play->mb) < sz) { + while (pos < sz) { + left = mbuf_get_left(play->mb); + count = (left > sz - pos) ? sz - pos : left; - memset(sampv, 0, sz); - (void)mbuf_read_mem(play->mb, (void *)sampv, - mbuf_get_left(play->mb)); + (void)mbuf_read_mem(play->mb, (uint8_t *)sampv + pos, count); - play->eof = true; - } - else { - (void)mbuf_read_mem(play->mb, (void *)sampv, sz); + pos += count; + + if (pos < sz) { + if (play->repeat > 0) + play->repeat--; + + if (play->repeat == 0) { + play->eof = true; + goto silence; + } + + play->mb->pos = 0; + } } silence: if (play->eof) - memset(sampv, 0, sz); + memset((uint8_t *)sampv + pos, 0, sz - pos); lock_rel(play->lock); } -- cgit v1.2.3