summaryrefslogtreecommitdiff
path: root/firmware/pcm.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-05-12 14:05:36 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-05-12 14:05:36 +0000
commit4d04132c76700b30708bf99fc0ef664e8bb0b58d (patch)
tree4a32974c7d75d93477413fa3fe8cd152709e3d8c /firmware/pcm.c
parentf2df42ee91ee61f793dac4844255cb4ec9049621 (diff)
downloadrockbox-4d04132c76700b30708bf99fc0ef664e8bb0b58d.tar.gz
rockbox-4d04132c76700b30708bf99fc0ef664e8bb0b58d.zip
PCM bottom layer simplification. pcm_rec_peak_addr variable no longer has to be handled there. Driver can just return current pointer for recording peaks. A new define, HAVE_PCM_REC_DMA_ADDRESS, specifies that physical addresses are being used for recording and translation is needed before starting a new block. The drivers need not worry about aligning start and size nor should care if either will be zero. All this will be checked in the logical layer first.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25970 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/pcm.c')
-rw-r--r--firmware/pcm.c62
1 files changed, 53 insertions, 9 deletions
diff --git a/firmware/pcm.c b/firmware/pcm.c
index edd4113677..8d2ec2bf60 100644
--- a/firmware/pcm.c
+++ b/firmware/pcm.c
@@ -40,7 +40,6 @@
40 * pcm_play_unlock 40 * pcm_play_unlock
41 * Semi-private - 41 * Semi-private -
42 * pcm_play_dma_init 42 * pcm_play_dma_init
43 * pcm_play_dma_init
44 * pcm_play_dma_start 43 * pcm_play_dma_start
45 * pcm_play_dma_stop 44 * pcm_play_dma_stop
46 * pcm_play_dma_pause 45 * pcm_play_dma_pause
@@ -66,10 +65,10 @@
66 * pcm_rec_dma_init 65 * pcm_rec_dma_init
67 * pcm_rec_dma_close 66 * pcm_rec_dma_close
68 * pcm_rec_dma_start 67 * pcm_rec_dma_start
68 * pcm_rec_dma_record_more
69 * pcm_rec_dma_stop 69 * pcm_rec_dma_stop
70 * pcm_rec_dma_get_peak_buffer 70 * pcm_rec_dma_get_peak_buffer
71 * Data Read/Written within TSP - 71 * Data Read/Written within TSP -
72 * pcm_rec_peak_addr (R/W)
73 * pcm_callback_more_ready (R) 72 * pcm_callback_more_ready (R)
74 * pcm_recording (R) 73 * pcm_recording (R)
75 * 74 *
@@ -210,6 +209,9 @@ void pcm_init(void)
210/* Common code to pcm_play_data and pcm_play_pause */ 209/* Common code to pcm_play_data and pcm_play_pause */
211static void pcm_play_data_start(unsigned char *start, size_t size) 210static void pcm_play_data_start(unsigned char *start, size_t size)
212{ 211{
212 start = (unsigned char *)(((uintptr_t)start + 3) & ~3);
213 size &= ~3;
214
213 if (!(start && size)) 215 if (!(start && size))
214 { 216 {
215 pcm_more_callback_type get_more = pcm_callback_for_more; 217 pcm_more_callback_type get_more = pcm_callback_for_more;
@@ -218,6 +220,9 @@ static void pcm_play_data_start(unsigned char *start, size_t size)
218 { 220 {
219 logf(" get_more"); 221 logf(" get_more");
220 get_more(&start, &size); 222 get_more(&start, &size);
223
224 start = (unsigned char *)(((uintptr_t)start + 3) & ~3);
225 size &= ~3;
221 } 226 }
222 } 227 }
223 228
@@ -359,7 +364,7 @@ bool pcm_is_paused(void)
359/** Low level pcm recording apis **/ 364/** Low level pcm recording apis **/
360 365
361/* Next start for recording peaks */ 366/* Next start for recording peaks */
362const volatile void *pcm_rec_peak_addr SHAREDBSS_ATTR = NULL; 367static const void * volatile pcm_rec_peak_addr SHAREDBSS_ATTR = NULL;
363/* the registered callback function for when more data is available */ 368/* the registered callback function for when more data is available */
364volatile pcm_more_callback_type2 369volatile pcm_more_callback_type2
365 pcm_callback_more_ready SHAREDBSS_ATTR = NULL; 370 pcm_callback_more_ready SHAREDBSS_ATTR = NULL;
@@ -373,17 +378,23 @@ volatile bool pcm_recording SHAREDBSS_ATTR = false;
373void pcm_calculate_rec_peaks(int *left, int *right) 378void pcm_calculate_rec_peaks(int *left, int *right)
374{ 379{
375 static int peaks[2]; 380 static int peaks[2];
376 int count;
377 const void *addr = pcm_rec_dma_get_peak_buffer(&count);
378 381
379 if (pcm_recording) 382 if (pcm_recording)
380 { 383 {
381 if (count > 0) 384 const void *peak_addr = pcm_rec_peak_addr;
385 const void *addr = pcm_rec_dma_get_peak_buffer();
386
387 if (addr != NULL)
382 { 388 {
383 pcm_peak_peeker(addr, count, peaks); 389 int count = (int)(((intptr_t)addr - (intptr_t)peak_addr) >> 2);
384 390
385 if (addr == pcm_rec_peak_addr) 391 if (count > 0)
386 pcm_rec_peak_addr = (int32_t *)addr + count; 392 {
393 pcm_peak_peeker(peak_addr, count, peaks);
394
395 if (peak_addr == pcm_rec_peak_addr)
396 pcm_rec_peak_addr = addr;
397 }
387 } 398 }
388 /* else keep previous peak values */ 399 /* else keep previous peak values */
389 } 400 }
@@ -443,6 +454,10 @@ void pcm_record_data(pcm_more_callback_type2 more_ready,
443{ 454{
444 logf("pcm_record_data"); 455 logf("pcm_record_data");
445 456
457 /* 32-bit aligned and sized data only */
458 start = (void *)(((uintptr_t)start + 3) & ~3);
459 size &= ~3;
460
446 if (!(start && size)) 461 if (!(start && size))
447 { 462 {
448 logf(" no buffer"); 463 logf(" no buffer");
@@ -453,6 +468,13 @@ void pcm_record_data(pcm_more_callback_type2 more_ready,
453 468
454 pcm_callback_more_ready = more_ready; 469 pcm_callback_more_ready = more_ready;
455 470
471#ifdef HAVE_PCM_REC_DMA_ADDRESS
472 /* Need a physical DMA address translation, if not already physical. */
473 pcm_rec_peak_addr = pcm_dma_addr(start);
474#else
475 pcm_rec_peak_addr = start;
476#endif
477
456 logf(" pcm_rec_dma_start"); 478 logf(" pcm_rec_dma_start");
457 pcm_apply_settings(); 479 pcm_apply_settings();
458 pcm_rec_dma_start(start, size); 480 pcm_rec_dma_start(start, size);
@@ -477,6 +499,28 @@ void pcm_stop_recording(void)
477 pcm_rec_unlock(); 499 pcm_rec_unlock();
478} /* pcm_stop_recording */ 500} /* pcm_stop_recording */
479 501
502void pcm_record_more(void *start, size_t size)
503{
504 start = (void *)(((uintptr_t)start + 3) & ~3);
505 size = size & ~3;
506
507 if (!size)
508 {
509 pcm_rec_dma_stop();
510 pcm_rec_dma_stopped_callback();
511 return;
512 }
513
514#ifdef HAVE_PCM_REC_DMA_ADDRESS
515 /* Need a physical DMA address translation, if not already physical. */
516 pcm_rec_peak_addr = pcm_dma_addr(start);
517#else
518 pcm_rec_peak_addr = start;
519#endif
520
521 pcm_rec_dma_record_more(start, size);
522}
523
480bool pcm_is_recording(void) 524bool pcm_is_recording(void)
481{ 525{
482 return pcm_recording; 526 return pcm_recording;