summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/pcmbuf.c43
1 files changed, 19 insertions, 24 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 32e1157132..aa30c64912 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -58,6 +58,9 @@
58 on commit */ 58 on commit */
59#define CROSSFADE_BUFSIZE 8192u 59#define CROSSFADE_BUFSIZE 8192u
60 60
61/* Return data level in 1/4-second increments */
62#define DATA_LEVEL(quarter_secs) (NATIVE_FREQUENCY * (quarter_secs))
63
61/* Number of bytes played per second: 64/* Number of bytes played per second:
62 (sample rate * 2 channels * 2 bytes/sample) */ 65 (sample rate * 2 channels * 2 bytes/sample) */
63#define BYTERATE (NATIVE_FREQUENCY * 4) 66#define BYTERATE (NATIVE_FREQUENCY * 4)
@@ -66,9 +69,13 @@
66/* Keep watermark high for large memory target - at least (2s) */ 69/* Keep watermark high for large memory target - at least (2s) */
67#define PCMBUF_WATERMARK (BYTERATE * 2) 70#define PCMBUF_WATERMARK (BYTERATE * 2)
68#define MIN_BUFFER_SIZE (BYTERATE * 3) 71#define MIN_BUFFER_SIZE (BYTERATE * 3)
72/* 1 seconds of buffer is low data */
73#define LOW_DATA DATA_LEVEL(4)
69#else 74#else
70#define PCMBUF_WATERMARK (BYTERATE / 4) /* 0.25 seconds */ 75#define PCMBUF_WATERMARK (BYTERATE / 4) /* 0.25 seconds */
71#define MIN_BUFFER_SIZE (BYTERATE * 1) 76#define MIN_BUFFER_SIZE (BYTERATE * 1)
77/* under watermark is low data */
78#define LOW_DATA pcmbuf_watermark
72#endif 79#endif
73 80
74/* Describes each audio packet - keep it small since there are many of them */ 81/* Describes each audio packet - keep it small since there are many of them */
@@ -95,10 +102,11 @@ static size_t chunk_ridx;
95static size_t chunk_widx; 102static size_t chunk_widx;
96 103
97static size_t pcmbuf_bytes_waiting; 104static size_t pcmbuf_bytes_waiting;
98
99static size_t pcmbuf_watermark;
100static struct chunkdesc *current_desc; 105static struct chunkdesc *current_desc;
101 106
107/* Only written if HAVE_CROSSFADE */
108static size_t pcmbuf_watermark = PCMBUF_WATERMARK;
109
102static bool low_latency_mode = false; 110static bool low_latency_mode = false;
103 111
104static bool pcmbuf_sync_position = false; 112static bool pcmbuf_sync_position = false;
@@ -160,10 +168,6 @@ static void pcmbuf_finish_crossfade_enable(void);
160static int codec_thread_priority = PRIORITY_PLAYBACK; 168static int codec_thread_priority = PRIORITY_PLAYBACK;
161#endif 169#endif
162 170
163/* Helpful macros for use in conditionals this assumes some of the above
164 * static variable names */
165#define DATA_LEVEL(quarter_secs) (NATIVE_FREQUENCY * (quarter_secs))
166
167/* Callbacks into playback.c */ 171/* Callbacks into playback.c */
168extern void audio_pcmbuf_position_callback(unsigned long elapsed, 172extern void audio_pcmbuf_position_callback(unsigned long elapsed,
169 off_t offset, unsigned int key); 173 off_t offset, unsigned int key);
@@ -187,6 +191,12 @@ static size_t pcmbuf_unplayed_bytes(void)
187 return widx - ridx; 191 return widx - ridx;
188} 192}
189 193
194/* Returns TRUE if amount of data is under the target fill size */
195static bool pcmbuf_data_critical(void)
196{
197 return pcmbuf_unplayed_bytes() < LOW_DATA;
198}
199
190/* Return the next PCM chunk in the PCM buffer given a byte index into it */ 200/* Return the next PCM chunk in the PCM buffer given a byte index into it */
191static size_t index_next(size_t index) 201static size_t index_next(size_t index)
192{ 202{
@@ -418,15 +428,8 @@ void * pcmbuf_request_buffer(int *count)
418 trigger_cpu_boost(); 428 trigger_cpu_boost();
419 429
420 /* If pre-buffered to the watermark, start playback */ 430 /* If pre-buffered to the watermark, start playback */
421#if MEMORYSIZE > 2 431 if (!pcmbuf_data_critical() && audio_pcmbuf_may_play())
422 if (remaining > DATA_LEVEL(4)) 432 pcmbuf_play_start();
423#else
424 if (remaining > pcmbuf_watermark)
425#endif
426 {
427 if (audio_pcmbuf_may_play())
428 pcmbuf_play_start();
429 }
430 } 433 }
431 434
432 void *buf = 435 void *buf =
@@ -520,8 +523,6 @@ size_t pcmbuf_init(unsigned char *bufend)
520 } 523 }
521 524
522 pcmbuf_finish_crossfade_enable(); 525 pcmbuf_finish_crossfade_enable();
523#else /* !HAVE_CROSSFADE */
524 pcmbuf_watermark = PCMBUF_WATERMARK;
525#endif /* HAVE_CROSSFADE */ 526#endif /* HAVE_CROSSFADE */
526 527
527 init_buffer_state(); 528 init_buffer_state();
@@ -1283,13 +1284,7 @@ bool pcmbuf_is_lowdata(void)
1283 if (status != CHANNEL_PLAYING || pcmbuf_is_crossfade_active()) 1284 if (status != CHANNEL_PLAYING || pcmbuf_is_crossfade_active())
1284 return false; 1285 return false;
1285 1286
1286#if MEMORYSIZE > 2 1287 return pcmbuf_data_critical();
1287 /* 1 seconds of buffer is low data */
1288 return pcmbuf_unplayed_bytes() < DATA_LEVEL(4);
1289#else
1290 /* under watermark is low data */
1291 return pcmbuf_unplayed_bytes() < pcmbuf_watermark;
1292#endif
1293} 1288}
1294 1289
1295void pcmbuf_set_low_latency(bool state) 1290void pcmbuf_set_low_latency(bool state)