summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2005-06-09 07:19:16 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2005-06-09 07:19:16 +0000
commitb4bc106efbf0e7e51a5602fec8ac75dbab9bc969 (patch)
tree288feec87d016f575fbb6d4aa9285b9293732272 /firmware
parentb24549616ba0ee65d91350e45d3ee695d1e572bf (diff)
downloadrockbox-b4bc106efbf0e7e51a5602fec8ac75dbab9bc969.tar.gz
rockbox-b4bc106efbf0e7e51a5602fec8ac75dbab9bc969.zip
Fixed forward next track bugs (still some pause issues though). Added
experimental cross-fader. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6632 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/pcm_playback.h1
-rw-r--r--firmware/pcm_playback.c76
2 files changed, 68 insertions, 9 deletions
diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h
index 3c29018394..d101c823ba 100644
--- a/firmware/export/pcm_playback.h
+++ b/firmware/export/pcm_playback.h
@@ -42,6 +42,7 @@ void pcm_play_set_watermark(int numbytes, void (*callback)(int bytes_left));
42 42
43void pcm_set_boost_mode(bool state); 43void pcm_set_boost_mode(bool state);
44bool pcm_is_lowdata(void); 44bool pcm_is_lowdata(void);
45void pcm_crossfade_start(void);
45unsigned int audiobuffer_get_latency(void); 46unsigned int audiobuffer_get_latency(void);
46bool audiobuffer_insert(char *buf, size_t length); 47bool audiobuffer_insert(char *buf, size_t length);
47 48
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index 99a71c2f41..ab4f0c0375 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -56,6 +56,11 @@ static volatile size_t audiobuffer_free;
56static size_t audiobuffer_fillpos; 56static size_t audiobuffer_fillpos;
57static bool boost_mode; 57static bool boost_mode;
58 58
59static bool crossfade_active;
60static int crossfade_pos;
61static int crossfade_amount;
62static int crossfade_rem;
63
59static unsigned char *next_start; 64static unsigned char *next_start;
60static long next_size; 65static long next_size;
61 66
@@ -106,6 +111,9 @@ void pcm_boost(bool state)
106{ 111{
107 static bool boost_state = false; 112 static bool boost_state = false;
108 113
114 if (crossfade_active)
115 return ;
116
109 if (state != boost_state) { 117 if (state != boost_state) {
110 cpu_boost(state); 118 cpu_boost(state);
111 boost_state = state; 119 boost_state = state;
@@ -334,6 +342,7 @@ void pcm_watermark_callback(int bytes_left)
334 342
335 /* Fill audio buffer by boosting cpu */ 343 /* Fill audio buffer by boosting cpu */
336 pcm_boost(true); 344 pcm_boost(true);
345 crossfade_active = false;
337} 346}
338 347
339void pcm_set_boost_mode(bool state) 348void pcm_set_boost_mode(bool state)
@@ -373,11 +382,43 @@ bool pcm_is_lowdata(void)
373 return false; 382 return false;
374} 383}
375 384
385void pcm_crossfade_start(void)
386{
387 if (audiobuffer_free > CHUNK_SIZE * 4) {
388 return ;
389 }
390 pcm_boost(true);
391 crossfade_active = true;
392 crossfade_pos = audiobuffer_pos;
393 crossfade_amount = (PCMBUF_SIZE - audiobuffer_free - CHUNK_SIZE * 22)/2;
394 crossfade_rem = crossfade_amount;
395 audiobuffer_fillpos = 0;
396
397 crossfade_pos -= crossfade_amount*2;
398 if (crossfade_pos < 0)
399 crossfade_pos = PCMBUF_SIZE + crossfade_pos;
400}
401
402static __inline
403void crossfade(short *buf, const short *buf2, int length)
404{
405 while (length--) {
406 *buf = (int)((*buf * ((crossfade_rem)*1000/crossfade_amount))/1000);
407 *buf += (int)((*buf2 * ((crossfade_amount-crossfade_rem)*1000/crossfade_amount))/1000);
408 buf++;
409 buf2++;
410 if (--crossfade_rem <= 0) {
411 crossfade_active = false;
412 break ;
413 }
414 }
415}
416
376bool audiobuffer_insert(char *buf, size_t length) 417bool audiobuffer_insert(char *buf, size_t length)
377{ 418{
378 size_t copy_n = 0; 419 size_t copy_n = 0;
379 420
380 if (audiobuffer_free < length + CHUNK_SIZE) { 421 if (audiobuffer_free < length + CHUNK_SIZE && !crossfade_active) {
381 if (!boost_mode) 422 if (!boost_mode)
382 pcm_boost(false); 423 pcm_boost(false);
383 return false; 424 return false;
@@ -385,19 +426,35 @@ bool audiobuffer_insert(char *buf, size_t length)
385 426
386 if (!pcm_is_playing() && !pcm_paused) { 427 if (!pcm_is_playing() && !pcm_paused) {
387 pcm_boost(true); 428 pcm_boost(true);
429 crossfade_active = false;
388 if (audiobuffer_free < PCMBUF_SIZE - CHUNK_SIZE*2) 430 if (audiobuffer_free < PCMBUF_SIZE - CHUNK_SIZE*2)
389 pcm_play_start(); 431 pcm_play_start();
390 } 432 }
391 433
392 while (length > 0) { 434 while (length > 0) {
393 copy_n = MIN(length, PCMBUF_SIZE - audiobuffer_pos - 435 if (!crossfade_active) {
394 audiobuffer_fillpos); 436 copy_n = MIN(length, PCMBUF_SIZE - audiobuffer_pos -
395 copy_n = MIN(CHUNK_SIZE, copy_n); 437 audiobuffer_fillpos);
396 memcpy(&audiobuffer[audiobuffer_pos+audiobuffer_fillpos], 438 copy_n = MIN(CHUNK_SIZE, copy_n);
397 buf, copy_n); 439
398 buf += copy_n; 440 memcpy(&audiobuffer[audiobuffer_pos+audiobuffer_fillpos],
399 audiobuffer_free -= copy_n; 441 buf, copy_n);
400 length -= copy_n; 442 buf += copy_n;
443 audiobuffer_free -= copy_n;
444 length -= copy_n;
445
446 } else {
447 copy_n = MIN(length, PCMBUF_SIZE - (unsigned int)crossfade_pos);
448
449 crossfade((short *)&audiobuffer[crossfade_pos],
450 (const short *)buf, copy_n/2);
451 buf += copy_n;
452 length -= copy_n;
453 crossfade_pos += copy_n;
454 if (crossfade_pos >= PCMBUF_SIZE)
455 crossfade_pos -= PCMBUF_SIZE;
456 continue ;
457 }
401 458
402 /* Pre-buffer to meet CHUNK_SIZE requirement */ 459 /* Pre-buffer to meet CHUNK_SIZE requirement */
403 if (copy_n + audiobuffer_fillpos < CHUNK_SIZE && length == 0) { 460 if (copy_n + audiobuffer_fillpos < CHUNK_SIZE && length == 0) {
@@ -452,6 +509,7 @@ void pcm_play_start(void)
452 int size; 509 int size;
453 char *start; 510 char *start;
454 511
512 crossfade_active = false;
455 if(!pcm_is_playing()) 513 if(!pcm_is_playing())
456 { 514 {
457 size = MIN(desc->size, 32768); 515 size = MIN(desc->size, 32768);