diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-02-07 19:17:51 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-02-07 19:17:51 +0000 |
commit | 4408b6b70c29ae119a468fc5cf9d83a125d6e368 (patch) | |
tree | 2a512ebc6c9f65fc0e0c52d3fe5b98e740eae9a0 /apps | |
parent | 69519a97f2340fdc81911165f9a95d9f4c436243 (diff) | |
download | rockbox-4408b6b70c29ae119a468fc5cf9d83a125d6e368.tar.gz rockbox-4408b6b70c29ae119a468fc5cf9d83a125d6e368.zip |
Reduce latency when configuring the EQ.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8609 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/pcmbuf.c | 34 | ||||
-rw-r--r-- | apps/pcmbuf.h | 1 | ||||
-rw-r--r-- | apps/sound_menu.c | 9 |
3 files changed, 35 insertions, 9 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index f184672bd1..22e725507b 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c | |||
@@ -36,11 +36,12 @@ | |||
36 | #include "audio.h" | 36 | #include "audio.h" |
37 | #include "dsp.h" | 37 | #include "dsp.h" |
38 | 38 | ||
39 | #define CHUNK_SIZE PCMBUF_GUARD | 39 | #define CHUNK_SIZE 32768 |
40 | /* Must be a power of 2 */ | 40 | /* Must be a power of 2 */ |
41 | #define NUM_PCM_BUFFERS 128 | 41 | #define NUM_PCM_BUFFERS 128 |
42 | #define NUM_PCM_BUFFERS_MASK (NUM_PCM_BUFFERS - 1) | 42 | #define NUM_PCM_BUFFERS_MASK (NUM_PCM_BUFFERS - 1) |
43 | #define PCMBUF_WATERMARK (CHUNK_SIZE * 6) | 43 | /* Watermark level at 1s. */ |
44 | #define PCMBUF_WATERMARK (NATIVE_FREQUENCY * 4 * 1) | ||
44 | 45 | ||
45 | /* Audio buffer related settings. */ | 46 | /* Audio buffer related settings. */ |
46 | static long pcmbuf_size = 0; /* Size of the PCM buffer. */ | 47 | static long pcmbuf_size = 0; /* Size of the PCM buffer. */ |
@@ -83,7 +84,7 @@ struct pcmbufdesc | |||
83 | int size; | 84 | int size; |
84 | /* Call this when the buffer has been played */ | 85 | /* Call this when the buffer has been played */ |
85 | void (*callback)(void); | 86 | void (*callback)(void); |
86 | } pcmbuffers[NUM_PCM_BUFFERS] IDATA_ATTR; | 87 | } pcmbuffers[NUM_PCM_BUFFERS] IDATA_ATTR; /* Do we really need IRAM for this? */ |
87 | 88 | ||
88 | static int pcmbuf_read_index; | 89 | static int pcmbuf_read_index; |
89 | static int pcmbuf_write_index; | 90 | static int pcmbuf_write_index; |
@@ -95,6 +96,7 @@ static int pcmbuf_num_used_buffers(void); | |||
95 | static void (*position_callback)(int size); | 96 | static void (*position_callback)(int size); |
96 | static int last_chunksize; | 97 | static int last_chunksize; |
97 | static long mixpos = 0; | 98 | static long mixpos = 0; |
99 | static bool low_latency_mode = false; | ||
98 | 100 | ||
99 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 101 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
100 | static bool boost_mode; | 102 | static bool boost_mode; |
@@ -222,12 +224,17 @@ unsigned int pcmbuf_get_latency(void) | |||
222 | return latency<0?0:latency; | 224 | return latency<0?0:latency; |
223 | } | 225 | } |
224 | 226 | ||
227 | void pcmbuf_set_low_latency(bool state) | ||
228 | { | ||
229 | low_latency_mode = state; | ||
230 | } | ||
231 | |||
225 | bool pcmbuf_is_lowdata(void) | 232 | bool pcmbuf_is_lowdata(void) |
226 | { | 233 | { |
227 | if (!pcm_is_playing() || pcm_is_paused() || crossfade_init || crossfade_active) | 234 | if (!pcm_is_playing() || pcm_is_paused() || crossfade_init || crossfade_active) |
228 | return false; | 235 | return false; |
229 | 236 | ||
230 | if (pcmbuf_unplayed_bytes < CHUNK_SIZE * 4) | 237 | if (pcmbuf_unplayed_bytes < pcmbuf_watermark - CHUNK_SIZE) |
231 | return true; | 238 | return true; |
232 | 239 | ||
233 | return false; | 240 | return false; |
@@ -237,7 +244,7 @@ bool pcmbuf_crossfade_init(bool manual_skip) | |||
237 | { | 244 | { |
238 | if (pcmbuf_size - audiobuffer_free < CHUNK_SIZE * 8 | 245 | if (pcmbuf_size - audiobuffer_free < CHUNK_SIZE * 8 |
239 | || !pcmbuf_is_crossfade_enabled() | 246 | || !pcmbuf_is_crossfade_enabled() |
240 | || crossfade_active || crossfade_init) { | 247 | || crossfade_active || crossfade_init || low_latency_mode) { |
241 | pcmbuf_flush_audio(); | 248 | pcmbuf_flush_audio(); |
242 | return false; | 249 | return false; |
243 | } | 250 | } |
@@ -422,7 +429,7 @@ static void crossfade_start(void) | |||
422 | int fade_in_delay = 0; | 429 | int fade_in_delay = 0; |
423 | 430 | ||
424 | crossfade_init = 0; | 431 | crossfade_init = 0; |
425 | if (bytesleft < CHUNK_SIZE * 4) { | 432 | if (bytesleft < NATIVE_FREQUENCY * 4 / 2) { |
426 | logf("crossfade rejected"); | 433 | logf("crossfade rejected"); |
427 | pcmbuf_play_stop(); | 434 | pcmbuf_play_stop(); |
428 | return ; | 435 | return ; |
@@ -439,7 +446,7 @@ static void crossfade_start(void) | |||
439 | case CFM_MIX: | 446 | case CFM_MIX: |
440 | case CFM_CROSSFADE: | 447 | case CFM_CROSSFADE: |
441 | /* Initialize the crossfade buffer size. */ | 448 | /* Initialize the crossfade buffer size. */ |
442 | crossfade_rem = (bytesleft - (CHUNK_SIZE * 2))/2; | 449 | crossfade_rem = (bytesleft - (NATIVE_FREQUENCY / 4))/2; |
443 | 450 | ||
444 | /* Get fade out delay from settings. */ | 451 | /* Get fade out delay from settings. */ |
445 | fade_out_delay = NATIVE_FREQUENCY | 452 | fade_out_delay = NATIVE_FREQUENCY |
@@ -593,6 +600,14 @@ static bool prepare_insert(long length) | |||
593 | { | 600 | { |
594 | if (crossfade_init) | 601 | if (crossfade_init) |
595 | crossfade_start(); | 602 | crossfade_start(); |
603 | |||
604 | if (low_latency_mode) | ||
605 | { | ||
606 | /* 1/4s latency. */ | ||
607 | if (pcmbuf_unplayed_bytes > NATIVE_FREQUENCY * 4 / 4 | ||
608 | && pcm_is_playing()) | ||
609 | return false; | ||
610 | } | ||
596 | 611 | ||
597 | if (audiobuffer_free < length + audiobuffer_fillpos | 612 | if (audiobuffer_free < length + audiobuffer_fillpos |
598 | + CHUNK_SIZE && !crossfade_active) { | 613 | + CHUNK_SIZE && !crossfade_active) { |
@@ -603,7 +618,8 @@ static bool prepare_insert(long length) | |||
603 | if (!pcm_is_playing()) { | 618 | if (!pcm_is_playing()) { |
604 | pcmbuf_boost(true); | 619 | pcmbuf_boost(true); |
605 | crossfade_active = false; | 620 | crossfade_active = false; |
606 | if (audiobuffer_free < pcmbuf_size - CHUNK_SIZE*4) { | 621 | /* Pre-buffer 1s. */ |
622 | if (audiobuffer_free < pcmbuf_size - NATIVE_FREQUENCY*4) { | ||
607 | logf("pcm starting"); | 623 | logf("pcm starting"); |
608 | pcmbuf_play_start(); | 624 | pcmbuf_play_start(); |
609 | } | 625 | } |
@@ -840,7 +856,7 @@ void pcmbuf_crossfade_enable(bool on_off) | |||
840 | crossfade_enabled = on_off; | 856 | crossfade_enabled = on_off; |
841 | 857 | ||
842 | if (crossfade_enabled) { | 858 | if (crossfade_enabled) { |
843 | pcmbuf_set_watermark_bytes(pcmbuf_size - (CHUNK_SIZE*6)); | 859 | pcmbuf_set_watermark_bytes(pcmbuf_size - (NATIVE_FREQUENCY*4/2)); |
844 | } else { | 860 | } else { |
845 | pcmbuf_set_watermark_bytes(PCMBUF_WATERMARK); | 861 | pcmbuf_set_watermark_bytes(PCMBUF_WATERMARK); |
846 | } | 862 | } |
diff --git a/apps/pcmbuf.h b/apps/pcmbuf.h index afc62021aa..2476857f88 100644 --- a/apps/pcmbuf.h +++ b/apps/pcmbuf.h | |||
@@ -45,6 +45,7 @@ bool pcmbuf_crossfade_init(bool manual_skip); | |||
45 | void pcmbuf_add_event(void (*event_handler)(void)); | 45 | void pcmbuf_add_event(void (*event_handler)(void)); |
46 | void pcmbuf_set_position_callback(void (*callback)(int size)); | 46 | void pcmbuf_set_position_callback(void (*callback)(int size)); |
47 | unsigned int pcmbuf_get_latency(void); | 47 | unsigned int pcmbuf_get_latency(void); |
48 | void pcmbuf_set_low_latency(bool state); | ||
48 | bool pcmbuf_insert_buffer(char *buf, long length); | 49 | bool pcmbuf_insert_buffer(char *buf, long length); |
49 | void pcmbuf_flush_buffer(long length); | 50 | void pcmbuf_flush_buffer(long length); |
50 | void* pcmbuf_request_buffer(long length, long *realsize); | 51 | void* pcmbuf_request_buffer(long length, long *realsize); |
diff --git a/apps/sound_menu.c b/apps/sound_menu.c index 2bd0ff6e59..9c8d398029 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #if CONFIG_CODEC == SWCODEC | 46 | #if CONFIG_CODEC == SWCODEC |
47 | #include "dsp.h" | 47 | #include "dsp.h" |
48 | #include "eq_menu.h" | 48 | #include "eq_menu.h" |
49 | #include "pcmbuf.h" | ||
49 | #endif | 50 | #endif |
50 | 51 | ||
51 | int selected_setting; /* Used by the callback */ | 52 | int selected_setting; /* Used by the callback */ |
@@ -394,11 +395,19 @@ bool sound_menu(void) | |||
394 | #endif | 395 | #endif |
395 | }; | 396 | }; |
396 | 397 | ||
398 | #if CONFIG_CODEC == SWCODEC | ||
399 | pcmbuf_set_low_latency(true); | ||
400 | #endif | ||
401 | |||
397 | m=menu_init( items, sizeof(items) / sizeof(*items), NULL, | 402 | m=menu_init( items, sizeof(items) / sizeof(*items), NULL, |
398 | NULL, NULL, NULL); | 403 | NULL, NULL, NULL); |
399 | result = menu_run(m); | 404 | result = menu_run(m); |
400 | menu_exit(m); | 405 | menu_exit(m); |
401 | 406 | ||
407 | #if CONFIG_CODEC == SWCODEC | ||
408 | pcmbuf_set_low_latency(false); | ||
409 | #endif | ||
410 | |||
402 | return result; | 411 | return result; |
403 | } | 412 | } |
404 | 413 | ||