summaryrefslogtreecommitdiff
path: root/firmware/pcm.c
diff options
context:
space:
mode:
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;