diff options
-rw-r--r-- | firmware/pcm_record.c | 62 |
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 */ | |||
58 | static volatile unsigned long num_file_bytes; /* Num bytes written to current file */ | 58 | static volatile unsigned long num_file_bytes; /* Num bytes written to current file */ |
59 | static volatile int error_count; /* Number of DMA errors */ | 59 | static volatile int error_count; /* Number of DMA errors */ |
60 | 60 | ||
61 | static unsigned long record_start_time; /* Value of current_tick when recording was started */ | 61 | static long record_start_time; /* Value of current_tick when recording was started */ |
62 | static unsigned long pause_start_time; /* Value of current_tick when pause was started */ | 62 | static long pause_start_time; /* Value of current_tick when pause was started */ |
63 | static volatile int buffered_chunks; /* number of valid chunks in buffer */ | ||
63 | 64 | ||
64 | static int wav_file; | 65 | static int wav_file; |
65 | static char recording_filename[MAX_PATH]; | 66 | static char recording_filename[MAX_PATH]; |
@@ -94,6 +95,8 @@ static int num_chunks; /* Number of chunks available in rec_buffer * | |||
94 | static volatile int write_index; /* Current chunk the DMA is writing to */ | 95 | static volatile int write_index; /* Current chunk the DMA is writing to */ |
95 | static volatile int read_index; /* Oldest chunk that is not written to disk */ | 96 | static volatile int read_index; /* Oldest chunk that is not written to disk */ |
96 | static volatile int read2_index; /* Latest chunk that has not been converted to little endian */ | 97 | static volatile int read2_index; /* Latest chunk that has not been converted to little endian */ |
98 | static long pre_record_ticks; /* pre-record time expressed in ticks */ | ||
99 | static 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 | ||
607 | static void pcmrec_start(void) | 628 | static 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; |