diff options
Diffstat (limited to 'apps/pcmbuf.c')
-rw-r--r-- | apps/pcmbuf.c | 156 |
1 files changed, 78 insertions, 78 deletions
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index e431ccd3e0..4a7608fcec 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c | |||
@@ -41,14 +41,6 @@ | |||
41 | #include "dsp.h" | 41 | #include "dsp.h" |
42 | #include "thread.h" | 42 | #include "thread.h" |
43 | 43 | ||
44 | /* Clip sample to signed 16 bit range */ | ||
45 | static inline int32_t clip_sample_16(int32_t sample) | ||
46 | { | ||
47 | if ((int16_t)sample != sample) | ||
48 | sample = 0x7fff ^ (sample >> 31); | ||
49 | return sample; | ||
50 | } | ||
51 | |||
52 | #define PCMBUF_TARGET_CHUNK 32768 /* This is the target fill size of chunks | 44 | #define PCMBUF_TARGET_CHUNK 32768 /* This is the target fill size of chunks |
53 | on the pcm buffer */ | 45 | on the pcm buffer */ |
54 | #define PCMBUF_MINAVG_CHUNK 24576 /* This is the minimum average size of | 46 | #define PCMBUF_MINAVG_CHUNK 24576 /* This is the minimum average size of |
@@ -142,7 +134,6 @@ extern unsigned int codec_thread_id; | |||
142 | #define LOW_DATA(quarter_secs) \ | 134 | #define LOW_DATA(quarter_secs) \ |
143 | (pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs) | 135 | (pcmbuf_unplayed_bytes < NATIVE_FREQUENCY * quarter_secs) |
144 | 136 | ||
145 | static bool pcmbuf_flush_fillpos(void); | ||
146 | static void pcmbuf_finish_track_change(void); | 137 | static void pcmbuf_finish_track_change(void); |
147 | #ifdef HAVE_CROSSFADE | 138 | #ifdef HAVE_CROSSFADE |
148 | static void crossfade_start(void); | 139 | static void crossfade_start(void); |
@@ -152,6 +143,7 @@ static bool pcmbuf_crossfade_init(bool manual_skip); | |||
152 | static void pcmbuf_finish_crossfade_enable(void); | 143 | static void pcmbuf_finish_crossfade_enable(void); |
153 | static bool pcmbuf_is_crossfade_enabled(void); | 144 | static bool pcmbuf_is_crossfade_enabled(void); |
154 | 145 | ||
146 | |||
155 | /**************************************/ | 147 | /**************************************/ |
156 | 148 | ||
157 | /* define this to show detailed pcmbufdesc usage information on the sim console */ | 149 | /* define this to show detailed pcmbufdesc usage information on the sim console */ |
@@ -253,6 +245,75 @@ static void pcmbuf_under_watermark(bool under) | |||
253 | } | 245 | } |
254 | } | 246 | } |
255 | 247 | ||
248 | /* This is really just part of pcmbuf_flush_fillpos, but is easier to keep | ||
249 | * in a separate function for the moment */ | ||
250 | static inline void pcmbuf_add_chunk(void) | ||
251 | { | ||
252 | register size_t size = audiobuffer_fillpos; | ||
253 | /* Grab the next description to write, and change the write pointer */ | ||
254 | register struct pcmbufdesc *pcmbuf_current = pcmbuf_write; | ||
255 | pcmbuf_write = pcmbuf_current->link; | ||
256 | /* Fill in the values in the new buffer chunk */ | ||
257 | pcmbuf_current->addr = &audiobuffer[audiobuffer_pos]; | ||
258 | pcmbuf_current->size = size; | ||
259 | pcmbuf_current->end_of_track = end_of_track; | ||
260 | pcmbuf_current->link = NULL; | ||
261 | end_of_track = false; /* This is single use only */ | ||
262 | if (pcmbuf_read != NULL) { | ||
263 | if (pcmbuf_flush) | ||
264 | { | ||
265 | pcmbuf_write_end->link = pcmbuf_read->link; | ||
266 | pcmbuf_read->link = pcmbuf_current; | ||
267 | while (pcmbuf_write_end->link) | ||
268 | { | ||
269 | pcmbuf_write_end = pcmbuf_write_end->link; | ||
270 | pcmbuf_unplayed_bytes -= pcmbuf_write_end->size; | ||
271 | } | ||
272 | pcmbuf_flush = false; | ||
273 | } | ||
274 | /* If there is already a read buffer setup, add to it */ | ||
275 | else | ||
276 | pcmbuf_read_end->link = pcmbuf_current; | ||
277 | } else { | ||
278 | /* Otherwise create the buffer */ | ||
279 | pcmbuf_read = pcmbuf_current; | ||
280 | } | ||
281 | /* This is now the last buffer to read */ | ||
282 | pcmbuf_read_end = pcmbuf_current; | ||
283 | |||
284 | /* Update bytes counters */ | ||
285 | pcmbuf_unplayed_bytes += size; | ||
286 | |||
287 | audiobuffer_pos += size; | ||
288 | if (audiobuffer_pos >= pcmbuf_size) | ||
289 | audiobuffer_pos -= pcmbuf_size; | ||
290 | |||
291 | audiobuffer_fillpos = 0; | ||
292 | DISPLAY_DESC("add_chunk"); | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * Commit samples waiting to the pcm buffer. | ||
297 | */ | ||
298 | static bool pcmbuf_flush_fillpos(void) | ||
299 | { | ||
300 | if (audiobuffer_fillpos) { | ||
301 | /* Never use the last buffer descriptor */ | ||
302 | while (pcmbuf_write == pcmbuf_write_end) { | ||
303 | /* If this happens, something is being stupid */ | ||
304 | if (!pcm_is_playing()) { | ||
305 | logf("pcmbuf_flush_fillpos error"); | ||
306 | pcmbuf_play_start(); | ||
307 | } | ||
308 | /* Let approximately one chunk of data playback */ | ||
309 | sleep(HZ*PCMBUF_TARGET_CHUNK/(NATIVE_FREQUENCY*4)); | ||
310 | } | ||
311 | pcmbuf_add_chunk(); | ||
312 | return true; | ||
313 | } | ||
314 | return false; | ||
315 | } | ||
316 | |||
256 | static bool prepare_insert(size_t length) | 317 | static bool prepare_insert(size_t length) |
257 | { | 318 | { |
258 | if (low_latency_mode) | 319 | if (low_latency_mode) |
@@ -344,75 +405,6 @@ void pcmbuf_write_complete(int count) | |||
344 | } | 405 | } |
345 | } | 406 | } |
346 | 407 | ||
347 | /* This is really just part of pcmbuf_flush_fillpos, but is easier to keep | ||
348 | * in a separate function for the moment */ | ||
349 | static inline void pcmbuf_add_chunk(void) | ||
350 | { | ||
351 | register size_t size = audiobuffer_fillpos; | ||
352 | /* Grab the next description to write, and change the write pointer */ | ||
353 | register struct pcmbufdesc *pcmbuf_current = pcmbuf_write; | ||
354 | pcmbuf_write = pcmbuf_current->link; | ||
355 | /* Fill in the values in the new buffer chunk */ | ||
356 | pcmbuf_current->addr = &audiobuffer[audiobuffer_pos]; | ||
357 | pcmbuf_current->size = size; | ||
358 | pcmbuf_current->end_of_track = end_of_track; | ||
359 | pcmbuf_current->link = NULL; | ||
360 | end_of_track = false; /* This is single use only */ | ||
361 | if (pcmbuf_read != NULL) { | ||
362 | if (pcmbuf_flush) | ||
363 | { | ||
364 | pcmbuf_write_end->link = pcmbuf_read->link; | ||
365 | pcmbuf_read->link = pcmbuf_current; | ||
366 | while (pcmbuf_write_end->link) | ||
367 | { | ||
368 | pcmbuf_write_end = pcmbuf_write_end->link; | ||
369 | pcmbuf_unplayed_bytes -= pcmbuf_write_end->size; | ||
370 | } | ||
371 | pcmbuf_flush = false; | ||
372 | } | ||
373 | /* If there is already a read buffer setup, add to it */ | ||
374 | else | ||
375 | pcmbuf_read_end->link = pcmbuf_current; | ||
376 | } else { | ||
377 | /* Otherwise create the buffer */ | ||
378 | pcmbuf_read = pcmbuf_current; | ||
379 | } | ||
380 | /* This is now the last buffer to read */ | ||
381 | pcmbuf_read_end = pcmbuf_current; | ||
382 | |||
383 | /* Update bytes counters */ | ||
384 | pcmbuf_unplayed_bytes += size; | ||
385 | |||
386 | audiobuffer_pos += size; | ||
387 | if (audiobuffer_pos >= pcmbuf_size) | ||
388 | audiobuffer_pos -= pcmbuf_size; | ||
389 | |||
390 | audiobuffer_fillpos = 0; | ||
391 | DISPLAY_DESC("add_chunk"); | ||
392 | } | ||
393 | |||
394 | /** | ||
395 | * Commit samples waiting to the pcm buffer. | ||
396 | */ | ||
397 | static bool pcmbuf_flush_fillpos(void) | ||
398 | { | ||
399 | if (audiobuffer_fillpos) { | ||
400 | /* Never use the last buffer descriptor */ | ||
401 | while (pcmbuf_write == pcmbuf_write_end) { | ||
402 | /* If this happens, something is being stupid */ | ||
403 | if (!pcm_is_playing()) { | ||
404 | logf("pcmbuf_flush_fillpos error"); | ||
405 | pcmbuf_play_start(); | ||
406 | } | ||
407 | /* Let approximately one chunk of data playback */ | ||
408 | sleep(HZ*PCMBUF_TARGET_CHUNK/(NATIVE_FREQUENCY*4)); | ||
409 | } | ||
410 | pcmbuf_add_chunk(); | ||
411 | return true; | ||
412 | } | ||
413 | return false; | ||
414 | } | ||
415 | |||
416 | 408 | ||
417 | /* Init */ | 409 | /* Init */ |
418 | 410 | ||
@@ -665,6 +657,14 @@ static void pcmbuf_finish_track_change(void) | |||
665 | 657 | ||
666 | /* Crossfade */ | 658 | /* Crossfade */ |
667 | 659 | ||
660 | /* Clip sample to signed 16 bit range */ | ||
661 | static inline int32_t clip_sample_16(int32_t sample) | ||
662 | { | ||
663 | if ((int16_t)sample != sample) | ||
664 | sample = 0x7fff ^ (sample >> 31); | ||
665 | return sample; | ||
666 | } | ||
667 | |||
668 | /** | 668 | /** |
669 | * Low memory targets don't have crossfade, so don't compile crossfade | 669 | * Low memory targets don't have crossfade, so don't compile crossfade |
670 | * specific code in order to save some memory. */ | 670 | * specific code in order to save some memory. */ |