From 013fe35992c2e735f6f93e51ca26fb6d61dd8c33 Mon Sep 17 00:00:00 2001 From: Jeffrey Goode Date: Thu, 5 Nov 2009 17:32:32 +0000 Subject: [PATCH] pcmbuf: better latency calculation, added debug code git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23537 a1c6a512-1295-4272-9138-f99709370657 --- apps/codec_thread.c | 8 ++-- apps/codecs.h | 2 +- apps/pcmbuf.c | 86 ++++++++++++++++++++++++++++----------- apps/pcmbuf.h | 2 +- apps/plugins/test_codec.c | 2 +- 5 files changed, 70 insertions(+), 30 deletions(-) diff --git a/apps/codec_thread.c b/apps/codec_thread.c index affb560183..fbcb23179d 100644 --- a/apps/codec_thread.c +++ b/apps/codec_thread.c @@ -215,7 +215,7 @@ static bool codec_pcmbuf_insert_callback( return true; } /* codec_pcmbuf_insert_callback */ -static void codec_set_elapsed_callback(unsigned int value) +static void codec_set_elapsed_callback(unsigned long value) { if (ci.seek_time) return; @@ -224,12 +224,12 @@ static void codec_set_elapsed_callback(unsigned int value) ab_position_report(value); #endif - unsigned int latency = pcmbuf_get_latency(); + unsigned long latency = pcmbuf_get_latency(); if (value < latency) thistrack_id3->elapsed = 0; else { - unsigned int elapsed = value - latency; + unsigned long elapsed = value - latency; if (elapsed > thistrack_id3->elapsed || elapsed < thistrack_id3->elapsed - 2) { @@ -243,7 +243,7 @@ static void codec_set_offset_callback(size_t value) if (ci.seek_time) return; - unsigned int latency = pcmbuf_get_latency() * thistrack_id3->bitrate / 8; + unsigned long latency = pcmbuf_get_latency() * thistrack_id3->bitrate / 8; if (value < latency) thistrack_id3->offset = 0; else diff --git a/apps/codecs.h b/apps/codecs.h index b61c3c0c94..39a8457666 100644 --- a/apps/codecs.h +++ b/apps/codecs.h @@ -123,7 +123,7 @@ struct codec_api { automatically. */ bool (*pcmbuf_insert)(const void *ch1, const void *ch2, int count); /* Set song position in WPS (value in ms). */ - void (*set_elapsed)(unsigned int value); + void (*set_elapsed)(unsigned long value); /* Read next amount bytes from file buffer to . Will return number of bytes read or 0 if end of file. */ diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index 3b461ecdc1..c8f89d9af9 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c @@ -136,6 +136,45 @@ static void pcmbuf_under_watermark(bool under); static bool pcmbuf_flush_fillpos(void); +/**************************************/ + +/* define this to show detailed pcmbufdesc usage information on the sim console */ +/*#define DESC_DEBUG*/ + +#ifndef SIMULATOR +#undef DESC_DEBUG +#endif +#ifdef DESC_DEBUG +static struct pcmbufdesc *first_desc; +static bool show_desc_in_use = false; +#define DISPLAY_DESC(caller) while(!show_desc(caller)) +#define DESC_IDX(desc) (desc ? desc - first_desc : -1) +#define DESCL_IDX(desc) (desc && desc->link ? desc->link - first_desc : -1) +#define SHOW_1ST(desc) if(DESC_IDX (desc)==-1) DEBUGF(" -- "); \ + else DEBUGF(" %02d ", DESC_IDX(desc)) +#define SHOW_2ND(desc) if(DESCL_IDX(desc)==-1) DEBUGF("l -- "); \ + else DEBUGF("l %02d ", DESCL_IDX(desc)) +#define DESC_SHOW(tag, desc) DEBUGF(tag);SHOW_1ST(desc); \ + DEBUGF(tag);SHOW_2ND(desc) + +static bool show_desc(char *caller) +{ + if (show_desc_in_use) return false; + show_desc_in_use = true; + DEBUGF("%-14s\t", caller); + DESC_SHOW("r", pcmbuf_read); + DESC_SHOW("re", pcmbuf_read_end); + DEBUGF(" "); + DESC_SHOW("w", pcmbuf_write); + DESC_SHOW("we", pcmbuf_write_end); + DEBUGF("\n"); + show_desc_in_use = false; + return true; +} +#else +#define DISPLAY_DESC(caller) do{}while(0) +#endif + /* Track change functions */ /* The codec is moving on to the next track, but the current track is @@ -232,6 +271,7 @@ static void pcmbuf_pcm_callback(unsigned char** start, size_t* size) pcmbuf_finish_track_change(); } } + DISPLAY_DESC("callback"); } static void pcmbuf_set_watermark_bytes(void) @@ -287,6 +327,7 @@ static inline void pcmbuf_add_chunk(void) audiobuffer_pos -= pcmbuf_size; audiobuffer_fillpos = 0; + DISPLAY_DESC("add_chunk"); } #ifdef HAVE_PRIORITY_SCHEDULING @@ -348,11 +389,11 @@ static void pcmbuf_under_watermark(bool under) } } -unsigned int pcmbuf_get_latency(void) +unsigned long pcmbuf_get_latency(void) { /* Be careful how this calculation is rearranged, it's easy to overflow */ size_t bytes = pcmbuf_unplayed_bytes + pcm_get_bytes_waiting(); - return bytes / 4 / (NATIVE_FREQUENCY/1000); + return bytes / 4 * 1000 / NATIVE_FREQUENCY; } void pcmbuf_set_low_latency(bool state) @@ -437,6 +478,7 @@ void pcmbuf_play_stop(void) crossfade_init = false; crossfade_active = false; pcmbuf_flush = false; + DISPLAY_DESC("play_stop"); #ifdef HAVE_PRIORITY_SCHEDULING /* Can unboost the codec thread here no matter who's calling */ @@ -462,6 +504,9 @@ int pcmbuf_descs(void) static void pcmbuf_init_pcmbuffers(void) { +#ifdef DESC_DEBUG + first_desc = pcmbuf_write; +#endif struct pcmbufdesc *next = pcmbuf_write; next++; pcmbuf_write_end = pcmbuf_write; @@ -470,6 +515,7 @@ static void pcmbuf_init_pcmbuffers(void) pcmbuf_write_end=next; next++; } + DISPLAY_DESC("init"); } static size_t pcmbuf_get_next_required_pcmbuf_size(void) @@ -755,24 +801,6 @@ static size_t crossfade_mix(int factor, const char *buf, size_t length) return 0; } -static void pcmbuf_flush_buffer(const char *buf, size_t length) -{ - size_t copy_n; - while (length > 0) { - size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; - if (NEED_FLUSH(audiobuffer_index)) - { - pcmbuf_flush_fillpos(); - audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; - } - copy_n = MIN(length, pcmbuf_size - audiobuffer_index); - memcpy(&audiobuffer[audiobuffer_index], buf, copy_n); - buf += copy_n; - audiobuffer_fillpos += copy_n; - length -= copy_n; - } -} - static void flush_crossfade(char *buf, size_t length) { if (length) @@ -826,11 +854,23 @@ static void flush_crossfade(char *buf, size_t length) /* Flush samples to the buffer */ while (!prepare_insert(length)) sleep(1); - pcmbuf_flush_buffer(buf, length); + while (length > 0) + { + size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; + if (NEED_FLUSH(audiobuffer_index)) + { + pcmbuf_flush_fillpos(); + audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; + } + size_t copy_n = MIN(length, pcmbuf_size - audiobuffer_index); + memcpy(&audiobuffer[audiobuffer_index], buf, copy_n); + buf += copy_n; + audiobuffer_fillpos += copy_n; + length -= copy_n; + } } - } -#endif +#endif /* HAVE_CROSSFADE */ static bool prepare_insert(size_t length) { diff --git a/apps/pcmbuf.h b/apps/pcmbuf.h index b6f0c767f2..1d893f9c62 100644 --- a/apps/pcmbuf.h +++ b/apps/pcmbuf.h @@ -59,7 +59,7 @@ void pcmbuf_play_start(void); bool pcmbuf_crossfade_init(bool manual_skip); void pcmbuf_start_track_change(void); size_t pcmbuf_free(void); -unsigned int pcmbuf_get_latency(void); +unsigned long pcmbuf_get_latency(void); void pcmbuf_set_low_latency(bool state); void * pcmbuf_request_buffer(int *count); void pcmbuf_write_complete(int count); diff --git a/apps/plugins/test_codec.c b/apps/plugins/test_codec.c index b41f053571..465030d7fc 100644 --- a/apps/plugins/test_codec.c +++ b/apps/plugins/test_codec.c @@ -363,7 +363,7 @@ static bool pcmbuf_insert_wav(const void *ch1, const void *ch2, int count) } /* Set song position in WPS (value in ms). */ -static void set_elapsed(unsigned int value) +static void set_elapsed(unsigned long value) { elapsed = value; }