diff options
| author | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-03-21 17:45:45 +0000 |
|---|---|---|
| committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-03-21 17:45:45 +0000 |
| commit | 590e6af88816d5b181370ccd45a9f25eb367da76 (patch) | |
| tree | bec05a3577e6aa4e9d60370013d7ae9bdd65ad6d | |
| parent | 834ac53c91fc55fdcbf5b04586fe3f64aaec0066 (diff) | |
| download | rockbox-590e6af88816d5b181370ccd45a9f25eb367da76.zip rockbox-590e6af88816d5b181370ccd45a9f25eb367da76.tar.gz rockbox-590e6af88816d5b181370ccd45a9f25eb367da76.tar.bz2 rockbox-590e6af88816d5b181370ccd45a9f25eb367da76.tar.xz | |
First try to get a better transition from a cancelled clip to a new one, by maintaining the frame sync. Doesn't seem to have much effect, though.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4425 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | apps/talk.c | 45 | ||||
| -rw-r--r-- | firmware/export/mp3_playback.h | 1 | ||||
| -rw-r--r-- | firmware/mp3_playback.c | 8 |
3 files changed, 51 insertions, 3 deletions
diff --git a/apps/talk.c b/apps/talk.c index bbc09a6..a543251 100644 --- a/apps/talk.c +++ b/apps/talk.c @@ -76,6 +76,12 @@ static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ static int queue_write; /* write index of queue, by application */ static int queue_read; /* read index of queue, by ISR context */ +/***************** Private prototypes *****************/ + +static int load_voicefont(void); +static void mp3_callback(unsigned char** start, int* size); +static int shutup(void); +static int queue_clip(unsigned char* buf, int size, bool enqueue); /***************** Private implementation *****************/ @@ -158,14 +164,47 @@ static void mp3_callback(unsigned char** start, int* size) /* stop the playback and the pending clips, but at frame boundary */ static int shutup(void) { + unsigned char* pos; + unsigned char* search; + unsigned char* end; + mp3_play_pause(false); /* pause */ - /* ToDo: search next frame boundary and continue up to there */ + if (!is_playing) /* has ended anyway */ + return 0; - queue_write = queue_read; + /* search next frame boundary and continue up to there */ + pos = search = mp3_get_pos(); + end = queue[queue_read].buf + queue[queue_read].len; + + while (search < end) /* search the remaining data */ + { + if (*search++ != 0xFF) /* search for frame sync byte */ + { + continue; + } + + /* look at the (bitswapped) 2nd byte of header candidate */ + if ((*search & 0x07) == 0x07 /* rest of frame sync */ + && (*search & 0x18) != 0x10 /* version != reserved */ + && (*search & 0x60) != 0x00) /* layer != reserved */ + { + break; /* From looking at the first 2 bytes, this is a header. */ + /* this is not a sufficient condition to find header, + may give "false alert" (end too early), but a start */ + } + } + + queue_write = queue_read; /* reset the queue */ is_playing = false; - mp3_play_stop(); + /* play old data until the frame end, to keep the MAS in sync */ + if (search-pos) + queue_clip(pos, search-pos, true); + + /* If the voice clips contain dependent frames (currently they don't), + it may be a good idea to insert an independent dummy frame here. */ + return 0; } diff --git a/firmware/export/mp3_playback.h b/firmware/export/mp3_playback.h index 15f5347..1eb5dc2 100644 --- a/firmware/export/mp3_playback.h +++ b/firmware/export/mp3_playback.h @@ -56,6 +56,7 @@ void mp3_play_stop(void); long mp3_get_playtime(void); void mp3_reset_playtime(void); bool mp3_is_playing(void); +unsigned char* mp3_get_pos(void); #define SOUND_VOLUME 0 diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c index a775ba4..070352c 100644 --- a/firmware/mp3_playback.c +++ b/firmware/mp3_playback.c @@ -1092,4 +1092,12 @@ bool mp3_is_playing(void) return playing; } + +/* returns the next byte position which would be transferred */ +unsigned char* mp3_get_pos(void) +{ + return (unsigned char*)SAR3; +} + + #endif /* #ifndef SIMULATOR */ |