summaryrefslogtreecommitdiff
path: root/apps/pcmbuf.c
diff options
context:
space:
mode:
authorJeffrey Goode <jeffg7@gmail.com>2009-11-05 17:32:32 +0000
committerJeffrey Goode <jeffg7@gmail.com>2009-11-05 17:32:32 +0000
commit013fe35992c2e735f6f93e51ca26fb6d61dd8c33 (patch)
tree38da6463deb82c7bd7b15c0fbe226c20dd74d809 /apps/pcmbuf.c
parent070d515049fab343786b237bc92881f9a28ea688 (diff)
downloadrockbox-013fe35992c2e735f6f93e51ca26fb6d61dd8c33.tar.gz
rockbox-013fe35992c2e735f6f93e51ca26fb6d61dd8c33.zip
pcmbuf: better latency calculation, added debug code
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23537 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r--apps/pcmbuf.c86
1 files changed, 63 insertions, 23 deletions
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);
136static bool pcmbuf_flush_fillpos(void); 136static bool pcmbuf_flush_fillpos(void);
137 137
138 138
139/**************************************/
140
141/* define this to show detailed pcmbufdesc usage information on the sim console */
142/*#define DESC_DEBUG*/
143
144#ifndef SIMULATOR
145#undef DESC_DEBUG
146#endif
147#ifdef DESC_DEBUG
148static struct pcmbufdesc *first_desc;
149static bool show_desc_in_use = false;
150#define DISPLAY_DESC(caller) while(!show_desc(caller))
151#define DESC_IDX(desc) (desc ? desc - first_desc : -1)
152#define DESCL_IDX(desc) (desc && desc->link ? desc->link - first_desc : -1)
153#define SHOW_1ST(desc) if(DESC_IDX (desc)==-1) DEBUGF(" -- "); \
154 else DEBUGF(" %02d ", DESC_IDX(desc))
155#define SHOW_2ND(desc) if(DESCL_IDX(desc)==-1) DEBUGF("l -- "); \
156 else DEBUGF("l %02d ", DESCL_IDX(desc))
157#define DESC_SHOW(tag, desc) DEBUGF(tag);SHOW_1ST(desc); \
158 DEBUGF(tag);SHOW_2ND(desc)
159
160static bool show_desc(char *caller)
161{
162 if (show_desc_in_use) return false;
163 show_desc_in_use = true;
164 DEBUGF("%-14s\t", caller);
165 DESC_SHOW("r", pcmbuf_read);
166 DESC_SHOW("re", pcmbuf_read_end);
167 DEBUGF(" ");
168 DESC_SHOW("w", pcmbuf_write);
169 DESC_SHOW("we", pcmbuf_write_end);
170 DEBUGF("\n");
171 show_desc_in_use = false;
172 return true;
173}
174#else
175#define DISPLAY_DESC(caller) do{}while(0)
176#endif
177
139/* Track change functions */ 178/* Track change functions */
140 179
141/* The codec is moving on to the next track, but the current track is 180/* 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)
232 pcmbuf_finish_track_change(); 271 pcmbuf_finish_track_change();
233 } 272 }
234 } 273 }
274 DISPLAY_DESC("callback");
235} 275}
236 276
237static void pcmbuf_set_watermark_bytes(void) 277static void pcmbuf_set_watermark_bytes(void)
@@ -287,6 +327,7 @@ static inline void pcmbuf_add_chunk(void)
287 audiobuffer_pos -= pcmbuf_size; 327 audiobuffer_pos -= pcmbuf_size;
288 328
289 audiobuffer_fillpos = 0; 329 audiobuffer_fillpos = 0;
330 DISPLAY_DESC("add_chunk");
290} 331}
291 332
292#ifdef HAVE_PRIORITY_SCHEDULING 333#ifdef HAVE_PRIORITY_SCHEDULING
@@ -348,11 +389,11 @@ static void pcmbuf_under_watermark(bool under)
348 } 389 }
349} 390}
350 391
351unsigned int pcmbuf_get_latency(void) 392unsigned long pcmbuf_get_latency(void)
352{ 393{
353 /* Be careful how this calculation is rearranged, it's easy to overflow */ 394 /* Be careful how this calculation is rearranged, it's easy to overflow */
354 size_t bytes = pcmbuf_unplayed_bytes + pcm_get_bytes_waiting(); 395 size_t bytes = pcmbuf_unplayed_bytes + pcm_get_bytes_waiting();
355 return bytes / 4 / (NATIVE_FREQUENCY/1000); 396 return bytes / 4 * 1000 / NATIVE_FREQUENCY;
356} 397}
357 398
358void pcmbuf_set_low_latency(bool state) 399void pcmbuf_set_low_latency(bool state)
@@ -437,6 +478,7 @@ void pcmbuf_play_stop(void)
437 crossfade_init = false; 478 crossfade_init = false;
438 crossfade_active = false; 479 crossfade_active = false;
439 pcmbuf_flush = false; 480 pcmbuf_flush = false;
481 DISPLAY_DESC("play_stop");
440 482
441#ifdef HAVE_PRIORITY_SCHEDULING 483#ifdef HAVE_PRIORITY_SCHEDULING
442 /* Can unboost the codec thread here no matter who's calling */ 484 /* Can unboost the codec thread here no matter who's calling */
@@ -462,6 +504,9 @@ int pcmbuf_descs(void)
462 504
463static void pcmbuf_init_pcmbuffers(void) 505static void pcmbuf_init_pcmbuffers(void)
464{ 506{
507#ifdef DESC_DEBUG
508 first_desc = pcmbuf_write;
509#endif
465 struct pcmbufdesc *next = pcmbuf_write; 510 struct pcmbufdesc *next = pcmbuf_write;
466 next++; 511 next++;
467 pcmbuf_write_end = pcmbuf_write; 512 pcmbuf_write_end = pcmbuf_write;
@@ -470,6 +515,7 @@ static void pcmbuf_init_pcmbuffers(void)
470 pcmbuf_write_end=next; 515 pcmbuf_write_end=next;
471 next++; 516 next++;
472 } 517 }
518 DISPLAY_DESC("init");
473} 519}
474 520
475static size_t pcmbuf_get_next_required_pcmbuf_size(void) 521static 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)
755 return 0; 801 return 0;
756} 802}
757 803
758static void pcmbuf_flush_buffer(const char *buf, size_t length)
759{
760 size_t copy_n;
761 while (length > 0) {
762 size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
763 if (NEED_FLUSH(audiobuffer_index))
764 {
765 pcmbuf_flush_fillpos();
766 audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
767 }
768 copy_n = MIN(length, pcmbuf_size - audiobuffer_index);
769 memcpy(&audiobuffer[audiobuffer_index], buf, copy_n);
770 buf += copy_n;
771 audiobuffer_fillpos += copy_n;
772 length -= copy_n;
773 }
774}
775
776static void flush_crossfade(char *buf, size_t length) 804static void flush_crossfade(char *buf, size_t length)
777{ 805{
778 if (length) 806 if (length)
@@ -826,11 +854,23 @@ static void flush_crossfade(char *buf, size_t length)
826 /* Flush samples to the buffer */ 854 /* Flush samples to the buffer */
827 while (!prepare_insert(length)) 855 while (!prepare_insert(length))
828 sleep(1); 856 sleep(1);
829 pcmbuf_flush_buffer(buf, length); 857 while (length > 0)
858 {
859 size_t audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
860 if (NEED_FLUSH(audiobuffer_index))
861 {
862 pcmbuf_flush_fillpos();
863 audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
864 }
865 size_t copy_n = MIN(length, pcmbuf_size - audiobuffer_index);
866 memcpy(&audiobuffer[audiobuffer_index], buf, copy_n);
867 buf += copy_n;
868 audiobuffer_fillpos += copy_n;
869 length -= copy_n;
870 }
830 } 871 }
831
832} 872}
833#endif 873#endif /* HAVE_CROSSFADE */
834 874
835static bool prepare_insert(size_t length) 875static bool prepare_insert(size_t length)
836{ 876{