summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/pcm_record.c62
1 files changed, 49 insertions, 13 deletions
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index af58df36d0..c4ba7bad9a 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -58,8 +58,9 @@ static volatile unsigned long num_rec_bytes; /* Num bytes recorded */
58static volatile unsigned long num_file_bytes; /* Num bytes written to current file */ 58static volatile unsigned long num_file_bytes; /* Num bytes written to current file */
59static volatile int error_count; /* Number of DMA errors */ 59static volatile int error_count; /* Number of DMA errors */
60 60
61static unsigned long record_start_time; /* Value of current_tick when recording was started */ 61static long record_start_time; /* Value of current_tick when recording was started */
62static unsigned long pause_start_time; /* Value of current_tick when pause was started */ 62static long pause_start_time; /* Value of current_tick when pause was started */
63static volatile int buffered_chunks; /* number of valid chunks in buffer */
63 64
64static int wav_file; 65static int wav_file;
65static char recording_filename[MAX_PATH]; 66static char recording_filename[MAX_PATH];
@@ -94,6 +95,8 @@ static int num_chunks; /* Number of chunks available in rec_buffer *
94static volatile int write_index; /* Current chunk the DMA is writing to */ 95static volatile int write_index; /* Current chunk the DMA is writing to */
95static volatile int read_index; /* Oldest chunk that is not written to disk */ 96static volatile int read_index; /* Oldest chunk that is not written to disk */
96static volatile int read2_index; /* Latest chunk that has not been converted to little endian */ 97static volatile int read2_index; /* Latest chunk that has not been converted to little endian */
98static long pre_record_ticks; /* pre-record time expressed in ticks */
99static int pre_record_chunks; /* pre-record time expressed in chunks */
97 100
98/***************************************************************************/ 101/***************************************************************************/
99 102
@@ -205,7 +208,17 @@ void audio_set_recording_options(int frequency, int quality,
205 (void)quality; 208 (void)quality;
206 (void)channel_mode; 209 (void)channel_mode;
207 (void)editable; 210 (void)editable;
208 (void)prerecord_time; 211
212 /* WARNING: calculation below uses fixed frequency! */
213 pre_record_ticks = prerecord_time * HZ;
214 pre_record_chunks = ((44100 * prerecord_time * 4)/CHUNK_SIZE)+1;
215 if(pre_record_chunks >= (num_chunks-250))
216 {
217 /* we can't prerecord more than our buffersize minus treshold to write to disk! */
218 pre_record_chunks = num_chunks-250;
219 /* don't forget to recalculate that time! */
220 pre_record_ticks = ((pre_record_chunks * CHUNK_SIZE)/(4*44100)) * HZ;
221 }
209 222
210 //logf("pcmrec: src=%d", source); 223 //logf("pcmrec: src=%d", source);
211 224
@@ -423,6 +436,7 @@ static void pcmrec_callback(bool flush)
423 436
424 if ((!is_recording || is_paused) && !flush) 437 if ((!is_recording || is_paused) && !flush)
425 { 438 {
439 /* not recording = no saving to disk, fake buffer clearing */
426 read_index = write_index; 440 read_index = write_index;
427 return; 441 return;
428 } 442 }
@@ -499,6 +513,9 @@ static void pcmrec_dma_start(void)
499 /* Start the DMA transfer.. */ 513 /* Start the DMA transfer.. */
500 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START; 514 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
501 515
516 /* pre-recording: buffer count */
517 buffered_chunks = 0;
518
502 logf("dma1 started"); 519 logf("dma1 started");
503} 520}
504 521
@@ -528,6 +545,10 @@ void DMA1(void)
528 if (write_index >= num_chunks) 545 if (write_index >= num_chunks)
529 write_index = 0; 546 write_index = 0;
530 547
548 /* update number of valid chunks for pre-recording */
549 if(buffered_chunks < num_chunks)
550 buffered_chunks++;
551
531 if (is_stopping) 552 if (is_stopping)
532 { 553 {
533 DCR1 = 0; /* Stop DMA transfer */ 554 DCR1 = 0; /* Stop DMA transfer */
@@ -606,6 +627,9 @@ static void close_wave(void)
606 627
607static void pcmrec_start(void) 628static void pcmrec_start(void)
608{ 629{
630 int pre_chunks = pre_record_chunks; /* recalculate every time! */
631 long pre_ticks = pre_record_ticks; /* recalculate every time! */
632
609 logf("pcmrec_start"); 633 logf("pcmrec_start");
610 634
611 if (is_recording) 635 if (is_recording)
@@ -614,7 +638,7 @@ static void pcmrec_start(void)
614 record_done = true; 638 record_done = true;
615 return; 639 return;
616 } 640 }
617 641
618 if (wav_file != -1) 642 if (wav_file != -1)
619 close(wav_file); 643 close(wav_file);
620 644
@@ -624,19 +648,30 @@ static void pcmrec_start(void)
624 record_done = true; 648 record_done = true;
625 return; 649 return;
626 } 650 }
627 651
652 /* pre-recording calculation */
653 if(buffered_chunks < pre_chunks)
654 {
655 /* not enough good chunks available - limit pre-record time */
656 pre_chunks = buffered_chunks;
657 pre_ticks = ((buffered_chunks * CHUNK_SIZE)/(4*44100)) * HZ;
658 }
659 record_start_time = current_tick - pre_ticks;
660
661 read_index = write_index - pre_chunks;
662 if(read_index < 0)
663 {
664 read_index += num_chunks;
665 }
666 read2_index = read_index;
667
628 peak_left = 0; 668 peak_left = 0;
629 peak_right = 0; 669 peak_right = 0;
630 670
631 num_rec_bytes = 0; 671 num_rec_bytes = 0;
632 num_file_bytes = 0; 672 num_file_bytes = 0;
633 record_start_time = current_tick;
634 pause_start_time = 0; 673 pause_start_time = 0;
635 674
636 write_index = 0;
637 read_index = 0;
638 read2_index = 0;
639
640 is_stopping = false; 675 is_stopping = false;
641 is_paused = false; 676 is_paused = false;
642 is_recording = true; 677 is_recording = true;
@@ -791,7 +826,9 @@ static void pcmrec_init(void)
791 read_index = 0; 826 read_index = 0;
792 read2_index = 0; 827 read2_index = 0;
793 write_index = 0; 828 write_index = 0;
794 829 pre_record_chunks = 0;
830 pre_record_ticks = 0;
831
795 peak_left = 0; 832 peak_left = 0;
796 peak_right = 0; 833 peak_right = 0;
797 834
@@ -799,6 +836,7 @@ static void pcmrec_init(void)
799 num_file_bytes = 0; 836 num_file_bytes = 0;
800 record_start_time = 0; 837 record_start_time = 0;
801 pause_start_time = 0; 838 pause_start_time = 0;
839 buffered_chunks = 0;
802 840
803 is_recording = false; 841 is_recording = false;
804 is_stopping = false; 842 is_stopping = false;
@@ -808,8 +846,6 @@ static void pcmrec_init(void)
808 rec_buffer = (unsigned char*)(((unsigned long)audiobuf) & ~3); 846 rec_buffer = (unsigned char*)(((unsigned long)audiobuf) & ~3);
809 buffer_size = (long)audiobufend - (long)audiobuf - 16; 847 buffer_size = (long)audiobufend - (long)audiobuf - 16;
810 848
811 //buffer_size = 1024*1024*5;
812
813 logf("buf size: %d kb", buffer_size/1024); 849 logf("buf size: %d kb", buffer_size/1024);
814 850
815 num_chunks = buffer_size / CHUNK_SIZE; 851 num_chunks = buffer_size / CHUNK_SIZE;