add the correct input file to makeindex call
[Rockbox.git] / firmware / pcm_record.c
blob2785d4b1b198885457a33215db9845bee4bb930d
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "config.h"
21 #include "debug.h"
22 #include "panic.h"
23 #include "thread.h"
25 #include <kernel.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <string.h>
31 #include "cpu.h"
32 #include "i2c.h"
33 #include "power.h"
34 #ifdef HAVE_UDA1380
35 #include "uda1380.h"
36 #endif
37 #ifdef HAVE_TLV320
38 #include "tlv320.h"
39 #endif
40 #include "system.h"
41 #include "usb.h"
43 #include "buffer.h"
44 #include "audio.h"
45 #include "button.h"
46 #include "file.h"
47 #include "sprintf.h"
48 #include "logf.h"
49 #include "button.h"
50 #include "lcd.h"
51 #include "lcd-remote.h"
52 #include "pcm_playback.h"
53 #include "sound.h"
54 #include "id3.h"
55 #include "pcm_record.h"
57 extern int boost_counter; /* used for boost check */
59 /***************************************************************************/
61 static bool is_recording; /* We are recording */
62 static bool is_paused; /* We have paused */
63 static bool is_error; /* An error has occured */
65 static unsigned long num_rec_bytes; /* Num bytes recorded */
66 static unsigned long num_file_bytes; /* Num bytes written to current file */
67 static int error_count; /* Number of DMA errors */
68 static unsigned long num_pcm_samples; /* Num pcm samples written to current file */
70 static long record_start_time; /* current_tick when recording was started */
71 static long pause_start_time; /* current_tick when pause was started */
72 static unsigned int sample_rate; /* Sample rate at time of recording start */
73 static int rec_source; /* Current recording source */
75 static int wav_file;
76 static char recording_filename[MAX_PATH];
78 static volatile bool init_done, close_done, record_done;
79 static volatile bool stop_done, pause_done, resume_done, new_file_done;
81 static int peak_left, peak_right;
83 #ifdef IAUDIO_X5
84 #define SET_IIS_PLAY(x) IIS1CONFIG = (x);
85 #define SET_IIS_REC(x) IIS1CONFIG = (x);
86 #else
87 #define SET_IIS_PLAY(x) IIS2CONFIG = (x);
88 #define SET_IIS_REC(x) IIS1CONFIG = (x);
89 #endif
91 /****************************************************************************
92 use 2 circular buffers of same size:
93 rec_buffer=DMA output buffer: chunks (8192 Bytes) of raw pcm audio data
94 enc_buffer=encoded audio buffer: storage for encoder output data
96 Flow:
97 1. when entering recording_screen DMA feeds the ringbuffer rec_buffer
98 2. if enough pcm data are available the encoder codec does encoding of pcm
99 chunks (4-8192 Bytes) into ringbuffer enc_buffer in codec_thread
100 3. pcmrec_callback detects enc_buffer 'near full' and writes data to disk
102 Functions calls:
103 1.main: codec_load_encoder(); start the encoder
104 2.encoder: enc_get_inputs(); get encoder buffsize, mono/stereo, quality
105 3.encoder: enc_set_parameters(); set the encoder parameters (max.chunksize)
106 4.encoder: enc_get_wav_data(); get n bytes of unprocessed pcm data
107 5.encoder: enc_wavbuf_near_empty();if true: reduce cpu_boost
108 6.encoder: enc_alloc_chunk(); get a ptr to next enc chunk
109 7.encoder: <process enc chunk> compress and store data to enc chunk
110 8.encoder: enc_free_chunk(); inform main about chunk process finished
111 9.encoder: repeat 4. to 8.
112 A.main: enc_set_header_callback(); create the current format header (file)
113 ****************************************************************************/
114 #define NUM_CHUNKS 256 /* Power of 2 */
115 #define CHUNK_SIZE 8192 /* Power of 2 */
116 #define MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */
117 #define CHUNK_MASK (NUM_CHUNKS * CHUNK_SIZE - 1)
118 #define WRITE_THRESHOLD (44100 * 5 / enc_samp_per_chunk) /* 5sec */
119 #define GET_CHUNK(x) (long*)(&rec_buffer[x])
120 #define GET_ENC_CHUNK(x) (long*)(&enc_buffer[enc_chunk_size*(x)])
122 static int audio_enc_id; /* current encoder id */
123 static unsigned char *rec_buffer; /* Circular recording buffer */
124 static unsigned char *enc_buffer; /* Circular encoding buffer */
125 static unsigned char *enc_head_buffer; /* encoder header buffer */
126 static int enc_head_size; /* used size in header buffer */
127 static int write_pos; /* Current chunk pos for DMA writing */
128 static int read_pos; /* Current chunk pos for encoding */
129 static long pre_record_ticks;/* pre-record time expressed in ticks */
130 static int enc_wr_index; /* Current encoding chunk write index */
131 static int enc_rd_index; /* Current encoding chunk read index */
132 static int enc_chunk_size; /* maximum encoder chunk size */
133 static int enc_num_chunks; /* number of chunks in ringbuffer */
134 static int enc_buffer_size; /* encode buffer size */
135 static int enc_channels; /* 1=mono 2=stereo */
136 static int enc_quality; /* mp3: 64,96,128,160,192,320 kBit */
137 static int enc_samp_per_chunk;/* pcm samples per encoder chunk */
138 static bool wav_queue_empty; /* all wav chunks processed? */
139 static unsigned long avrg_bit_rate; /* average bit rates from chunks */
140 static unsigned long curr_bit_rate; /* cumulated bit rates from chunks */
141 static unsigned long curr_chunk_cnt; /* number of processed chunks */
143 void (*enc_set_header_callback)(void *head_buffer, int head_size,
144 int num_pcm_samples, bool is_file_header);
146 /***************************************************************************/
148 static struct event_queue pcmrec_queue;
149 static long pcmrec_stack[2*DEFAULT_STACK_SIZE/sizeof(long)];
150 static const char pcmrec_thread_name[] = "pcmrec";
152 static void pcmrec_thread(void);
153 static void pcmrec_dma_start(void);
154 static void pcmrec_dma_stop(void);
155 static void close_wave(void);
157 /* Event IDs */
158 #define PCMREC_INIT 1 /* Enable recording */
159 #define PCMREC_CLOSE 2
161 #define PCMREC_START 3 /* Start a new recording */
162 #define PCMREC_STOP 4 /* Stop the current recording */
163 #define PCMREC_PAUSE 10
164 #define PCMREC_RESUME 11
165 #define PCMREC_NEW_FILE 12
166 #define PCMREC_SET_GAIN 13
168 /*******************************************************************/
169 /* Functions that are not executing in the pcmrec_thread first */
170 /*******************************************************************/
172 /* Creates pcmrec_thread */
173 void pcm_rec_init(void)
175 queue_init(&pcmrec_queue, true);
176 create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack),
177 pcmrec_thread_name IF_PRIO(, PRIORITY_RECORDING));
181 int audio_get_encoder_id(void)
183 return audio_enc_id;
186 /* Initializes recording:
187 * - Set up the UDA1380/TLV320 for recording
188 * - Prepare for DMA transfers
191 void audio_init_recording(unsigned int buffer_offset)
193 (void)buffer_offset;
195 init_done = false;
196 queue_post(&pcmrec_queue, PCMREC_INIT, 0);
198 while(!init_done)
199 sleep_thread(1);
202 void audio_close_recording(void)
204 close_done = false;
205 queue_post(&pcmrec_queue, PCMREC_CLOSE, 0);
207 while(!close_done)
208 sleep_thread(1);
210 audio_remove_encoder();
213 unsigned long pcm_rec_status(void)
215 unsigned long ret = 0;
217 if (is_recording)
218 ret |= AUDIO_STATUS_RECORD;
219 if (is_paused)
220 ret |= AUDIO_STATUS_PAUSE;
221 if (is_error)
222 ret |= AUDIO_STATUS_ERROR;
223 if (!is_recording && pre_record_ticks && init_done && !close_done)
224 ret |= AUDIO_STATUS_PRERECORD;
226 return ret;
229 int pcm_rec_current_bitrate(void)
231 return avrg_bit_rate;
234 unsigned long audio_recorded_time(void)
236 if (is_recording)
238 if (is_paused)
239 return pause_start_time - record_start_time;
240 else
241 return current_tick - record_start_time;
244 return 0;
247 unsigned long audio_num_recorded_bytes(void)
249 if (is_recording)
250 return num_rec_bytes;
252 return 0;
255 #ifdef HAVE_SPDIF_IN
256 /* Only the last six of these are standard rates, but all sample rates are
257 * possible, so we support some other common ones as well.
259 static unsigned long spdif_sample_rates[] = {
260 8000, 11025, 12000, 16000, 22050, 24000,
261 32000, 44100, 48000, 64000, 88200, 96000
264 /* Return SPDIF sample rate. Since we base our reading on the actual SPDIF
265 * sample rate (which might be a bit inaccurate), we round off to the closest
266 * sample rate that is supported by SPDIF.
268 unsigned long audio_get_spdif_sample_rate(void)
270 int i = 0;
271 unsigned long measured_rate;
272 const int upper_bound = sizeof(spdif_sample_rates)/sizeof(long) - 1;
274 /* The following formula is specified in MCF5249 user's manual section
275 * 17.6.1. The 3*(1 << 13) part will need changing if the setup of the
276 * PHASECONFIG register is ever changed. The 128 divide is because of the
277 * fact that the SPDIF clock is the sample rate times 128.
279 measured_rate = (unsigned long)((unsigned long long)FREQMEAS*CPU_FREQ/
280 ((1 << 15)*3*(1 << 13))/128);
281 /* Find which SPDIF sample rate we're closest to. */
282 while (spdif_sample_rates[i] < measured_rate && i < upper_bound) ++i;
283 if (i > 0 && i < upper_bound)
285 long diff1 = measured_rate - spdif_sample_rates[i - 1];
286 long diff2 = spdif_sample_rates[i] - measured_rate;
288 if (diff2 > diff1) --i;
290 return i;
292 #endif
294 #if 0
295 /* not needed atm */
296 #ifdef HAVE_SPDIF_POWER
297 static bool spdif_power_setting;
299 void audio_set_spdif_power_setting(bool on)
301 spdif_power_setting = on;
303 #endif
304 #endif
307 * Sets recording parameters
309 * This functions starts feeding the CPU with audio data over the I2S bus
311 void audio_set_recording_options(int frequency, int quality,
312 int source, int channel_mode,
313 bool editable, int prerecord_time)
315 /* TODO: */
316 (void)editable;
318 /* NOTE: Coldfire UDA based recording does not yet support anything other
319 * than 44.1kHz sampling rate, so we limit it to that case here now. SPDIF
320 * based recording will overwrite this value with the proper sample rate in
321 * audio_record(), and will not be affected by this.
323 frequency = 44100;
324 enc_quality = quality;
325 rec_source = source;
326 enc_channels = channel_mode == CHN_MODE_MONO ? 1 : 2;
327 pre_record_ticks = prerecord_time * HZ;
329 switch (source)
331 case AUDIO_SRC_MIC:
332 case AUDIO_SRC_LINEIN:
333 #ifdef HAVE_FMRADIO_IN
334 case AUDIO_SRC_FMRADIO:
335 #endif
336 /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
337 DATAINCONTROL = 0xc020;
338 break;
340 #ifdef HAVE_SPDIF_IN
341 case AUDIO_SRC_SPDIF:
342 /* Int. when 6 samples in FIFO. PDIR2 source = ebu1RcvData */
343 DATAINCONTROL = 0xc038;
344 break;
345 #endif /* HAVE_SPDIF_IN */
348 sample_rate = frequency;
350 /* Monitoring: route the signals through the coldfire audio interface. */
352 SET_IIS_PLAY(0x800); /* Reset before reprogram */
354 #ifdef HAVE_SPDIF_IN
355 if (source == AUDIO_SRC_SPDIF)
357 /* SCLK2 = Audioclk/4 (can't use EBUin clock), TXSRC = EBU1rcv, 64 bclk/wclk */
358 IIS2CONFIG = (6 << 12) | (7 << 8) | (4 << 2);
359 /* S/PDIF feed-through already configured */
361 else
363 /* SCLK2 follow IIS1 (UDA clock), TXSRC = IIS1rcv, 64 bclk/wclk */
364 IIS2CONFIG = (8 << 12) | (4 << 8) | (4 << 2);
366 EBU1CONFIG = 0x800; /* Reset before reprogram */
367 /* SCLK2, TXSRC = IIS1recv, validity, normal operation */
368 EBU1CONFIG = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2);
370 #else
371 /* SCLK2 follow IIS1 (UDA clock), TXSRC = IIS1rcv, 64 bclk/wclk */
372 SET_IIS_PLAY( (8 << 12) | (4 << 8) | (4 << 2) );
373 #endif
375 audio_load_encoder(rec_quality_info_afmt[quality]);
380 * Note that microphone is mono, only left value is used
381 * See {uda1380,tlv320}_set_recvol() for exact ranges.
383 * @param type 0=line-in (radio), 1=mic
386 void audio_set_recording_gain(int left, int right, int type)
388 //logf("rcmrec: t=%d l=%d r=%d", type, left, right);
389 #if defined(HAVE_UDA1380)
390 uda1380_set_recvol(left, right, type);
391 #elif defined (HAVE_TLV320)
392 tlv320_set_recvol(left, right, type);
393 #endif
398 * Start recording
400 * Use audio_set_recording_options first to select recording options
402 void audio_record(const char *filename)
404 if (is_recording)
406 logf("record while recording");
407 return;
410 strncpy(recording_filename, filename, MAX_PATH - 1);
411 recording_filename[MAX_PATH - 1] = 0;
413 #ifdef HAVE_SPDIF_IN
414 if (rec_source == AUDIO_SRC_SPDIF)
415 sample_rate = audio_get_spdif_sample_rate();
416 #endif
418 record_done = false;
419 queue_post(&pcmrec_queue, PCMREC_START, 0);
421 while(!record_done)
422 sleep_thread(1);
426 void audio_new_file(const char *filename)
428 logf("pcm_new_file");
430 new_file_done = false;
432 strncpy(recording_filename, filename, MAX_PATH - 1);
433 recording_filename[MAX_PATH - 1] = 0;
435 queue_post(&pcmrec_queue, PCMREC_NEW_FILE, 0);
437 while(!new_file_done)
438 sleep_thread(1);
440 logf("pcm_new_file done");
446 void audio_stop_recording(void)
448 if (!is_recording)
449 return;
451 logf("pcm_stop");
453 is_paused = true; /* fix pcm write ptr at current position */
454 stop_done = false;
455 queue_post(&pcmrec_queue, PCMREC_STOP, 0);
457 while(!stop_done)
458 sleep_thread(1);
460 logf("pcm_stop done");
463 void audio_pause_recording(void)
465 if (!is_recording)
467 logf("pause when not recording");
468 return;
470 if (is_paused)
472 logf("pause when paused");
473 return;
476 pause_done = false;
477 queue_post(&pcmrec_queue, PCMREC_PAUSE, 0);
479 while(!pause_done)
480 sleep_thread(1);
483 void audio_resume_recording(void)
485 if (!is_paused)
487 logf("resume when not paused");
488 return;
491 resume_done = false;
492 queue_post(&pcmrec_queue, PCMREC_RESUME, 0);
494 while(!resume_done)
495 sleep_thread(1);
498 /* return peaks as int, so convert from short first
499 note that peak values are always positive */
500 void pcm_rec_get_peaks(int *left, int *right)
502 if (left)
503 *left = peak_left;
504 if (right)
505 *right = peak_right;
506 peak_left = 0;
507 peak_right = 0;
510 /***************************************************************************/
511 /* Functions that executes in the context of pcmrec_thread */
512 /***************************************************************************/
515 * Process the chunks
517 * This function is called when queue_get_w_tmo times out.
519 * Other functions can also call this function with flush = true when
520 * they want to save everything in the buffers to disk.
523 static void pcmrec_callback(bool flush)
525 int i, num_ready, size_yield;
526 long *enc_chunk, chunk_size;
528 if (!is_recording && !flush)
529 return;
531 num_ready = enc_wr_index - enc_rd_index;
532 if (num_ready < 0)
533 num_ready += enc_num_chunks;
535 /* calculate an estimate of recorded bytes */
536 num_rec_bytes = num_file_bytes + num_ready * /* enc_chunk_size */
537 ((avrg_bit_rate * 1000 / 8 * enc_samp_per_chunk + 22050) / 44100);
539 /* near full state reached: less than 5sec remaining space */
540 if (enc_num_chunks - num_ready < WRITE_THRESHOLD || flush)
542 logf("writing: %d (%d)", num_ready, flush);
544 cpu_boost_id(true, CPUBOOSTID_PCMRECORD);
546 size_yield = 0;
547 for (i=0; i<num_ready; i++)
549 enc_chunk = GET_ENC_CHUNK(enc_rd_index);
550 chunk_size = *enc_chunk++;
552 /* safety net: if size entry got corrupted => limit */
553 if (chunk_size > (long)(enc_chunk_size - sizeof(long)))
554 chunk_size = enc_chunk_size - sizeof(long);
556 if (enc_set_header_callback != NULL)
557 enc_set_header_callback(enc_chunk, enc_chunk_size,
558 num_pcm_samples, false);
560 if (write(wav_file, enc_chunk, chunk_size) != chunk_size)
562 close_wave();
563 logf("pcmrec: write err");
564 is_error = true;
565 break;
568 num_file_bytes += chunk_size;
569 num_pcm_samples += enc_samp_per_chunk;
570 size_yield += chunk_size;
572 if (size_yield >= 32768)
573 { /* yield when 32kB written */
574 size_yield = 0;
575 yield();
578 enc_rd_index = (enc_rd_index + 1) % enc_num_chunks;
581 /* sync file */
582 fsync(wav_file);
584 cpu_boost_id(false, CPUBOOSTID_PCMRECORD);
586 logf("done");
590 /* Abort dma transfer */
591 static void pcmrec_dma_stop(void)
593 DCR1 = 0;
595 error_count++;
597 DSR1 = 1; /* Clear interrupt */
598 IPR |= (1<<15); /* Clear pending interrupt request */
600 logf("dma1 stopped");
603 static void pcmrec_dma_start(void)
605 DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
606 SAR1 = (unsigned long)&PDIR2; /* Source address */
607 BCR1 = CHUNK_SIZE; /* Bytes to transfer */
609 /* Start the DMA transfer.. */
610 #ifdef HAVE_SPDIF_IN
611 INTERRUPTCLEAR = 0x03c00000;
612 #endif
614 /* 16Byte transfers prevents from sporadic errors during cpu_boost() */
615 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_DSIZE(3) | DMA_START;
617 logf("dma1 started");
620 /* DMA1 Interrupt is called when the DMA has finished transfering a chunk */
621 void DMA1(void) __attribute__ ((interrupt_handler, section(".icode")));
622 void DMA1(void)
624 int res = DSR1;
626 DSR1 = 1; /* Clear interrupt */
628 if (res & 0x70)
630 DCR1 = 0; /* Stop DMA transfer */
631 error_count++;
633 logf("dma1 err: 0x%x", res);
635 DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
636 BCR1 = CHUNK_SIZE;
637 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
639 /* Flush recorded data to disk and stop recording */
640 queue_post(&pcmrec_queue, PCMREC_STOP, NULL);
642 #ifdef HAVE_SPDIF_IN
643 else if ((rec_source == AUDIO_SRC_SPDIF) &&
644 (INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */
646 INTERRUPTCLEAR = 0x03c00000;
647 error_count++;
649 logf("spdif err");
651 DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
652 BCR1 = CHUNK_SIZE;
654 #endif
655 else
657 long peak_l, peak_r;
658 long *ptr, j;
660 ptr = GET_CHUNK(write_pos);
662 if (!is_paused) /* advance write position */
663 write_pos = (write_pos + CHUNK_SIZE) & CHUNK_MASK;
665 DAR1 = (unsigned long)GET_CHUNK(write_pos); /* Destination address */
666 BCR1 = CHUNK_SIZE;
668 peak_l = peak_r = 0;
670 /* only peak every 4th sample */
671 for (j=0; j<CHUNK_SIZE/4; j+=4)
673 long value = ptr[j];
674 #ifdef ROCKBOX_BIG_ENDIAN
675 if (value > peak_l) peak_l = value;
676 else if (-value > peak_l) peak_l = -value;
678 value <<= 16;
679 if (value > peak_r) peak_r = value;
680 else if (-value > peak_r) peak_r = -value;
681 #else
682 if (value > peak_r) peak_r = value;
683 else if (-value > peak_r) peak_r = -value;
685 value <<= 16;
686 if (value > peak_l) peak_l = value;
687 else if (-value > peak_l) peak_l = -value;
688 #endif
691 peak_left = (int)(peak_l >> 16);
692 peak_right = (int)(peak_r >> 16);
695 IPR |= (1<<15); /* Clear pending interrupt request */
698 /* Create WAVE file and write header */
699 /* Sets returns 0 if success, -1 on failure */
700 static int start_wave(void)
702 wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC);
704 if (wav_file < 0)
706 wav_file = -1;
707 logf("rec: create failed: %d", wav_file);
708 is_error = true;
709 return -1;
712 /* add main file header (enc_head_size=0 for encoders without) */
713 if (enc_head_size != write(wav_file, enc_head_buffer, enc_head_size))
715 close(wav_file);
716 wav_file = -1;
717 logf("rec: write failed");
718 is_error = true;
719 return -1;
722 return 0;
725 /* Update header and set correct length values */
726 static void close_wave(void)
728 unsigned char head[100]; /* assume maximum 100 bytes for file header */
729 int size_read;
731 if (wav_file != -1)
733 /* update header before closing the file (wav+wv encoder will do) */
734 if (enc_set_header_callback != NULL)
736 lseek(wav_file, 0, SEEK_SET);
737 /* try to read the head size (but we'll accept less) */
738 size_read = read(wav_file, head, sizeof(head));
740 enc_set_header_callback(head, size_read, num_pcm_samples, true);
741 lseek(wav_file, 0, SEEK_SET);
742 write(wav_file, head, size_read);
744 close(wav_file);
745 wav_file = -1;
749 static void pcmrec_start(void)
751 long max_pre_chunks, pre_ticks, max_pre_ticks;
753 logf("pcmrec_start");
755 if (is_recording)
757 logf("already recording");
758 record_done = true;
759 return;
762 if (wav_file != -1)
763 close_wave();
765 if (start_wave() != 0)
767 /* failed to create the file */
768 record_done = true;
769 return;
772 /* calculate maximum available chunks & resulting ticks */
773 max_pre_chunks = (enc_wr_index - enc_rd_index +
774 enc_num_chunks) % enc_num_chunks;
775 if (max_pre_chunks > enc_num_chunks - WRITE_THRESHOLD)
776 max_pre_chunks = enc_num_chunks - WRITE_THRESHOLD;
777 max_pre_ticks = max_pre_chunks * HZ * enc_samp_per_chunk / 44100;
779 /* limit prerecord if not enough data available */
780 pre_ticks = pre_record_ticks > max_pre_ticks ?
781 max_pre_ticks : pre_record_ticks;
782 max_pre_chunks = 44100 * pre_ticks / HZ / enc_samp_per_chunk;
783 enc_rd_index = (enc_wr_index - max_pre_chunks +
784 enc_num_chunks) % enc_num_chunks;
786 record_start_time = current_tick - pre_ticks;
788 num_rec_bytes = enc_num_chunks * CHUNK_SIZE;
789 num_file_bytes = 0;
790 num_pcm_samples = 0;
791 pause_start_time = 0;
793 is_paused = false;
794 is_recording = true;
795 record_done = true;
798 static void pcmrec_stop(void)
800 logf("pcmrec_stop");
802 if (is_recording)
804 /* wait for encoding finish */
805 is_paused = true;
806 while(!wav_queue_empty)
807 sleep_thread(1);
809 is_recording = false;
811 /* Flush buffers to file */
812 pcmrec_callback(true);
813 close_wave();
816 is_paused = false;
817 stop_done = true;
819 logf("pcmrec_stop done");
822 static void pcmrec_new_file(void)
824 logf("pcmrec_new_file");
826 if (!is_recording)
828 logf("not recording");
829 new_file_done = true;
830 return;
833 /* Since pcmrec_callback() blocks until the data has been written,
834 here is a good approximation when recording to the new file starts
836 record_start_time = current_tick;
838 if (is_paused)
839 pause_start_time = record_start_time;
841 /* Flush what we got in buffers to file */
842 pcmrec_callback(true);
844 close_wave();
846 num_rec_bytes = 0;
847 num_file_bytes = 0;
848 num_pcm_samples = 0;
850 /* start the new file */
851 if (start_wave() != 0)
853 logf("new_file failed");
854 pcmrec_stop();
857 new_file_done = true;
858 logf("pcmrec_new_file done");
861 static void pcmrec_pause(void)
863 logf("pcmrec_pause");
865 if (!is_recording)
867 logf("pause: not recording");
868 pause_done = true;
869 return;
872 pause_start_time = current_tick;
873 is_paused = true;
874 pause_done = true;
876 logf("pcmrec_pause done");
880 static void pcmrec_resume(void)
882 logf("pcmrec_resume");
884 if (!is_paused)
886 logf("resume: not paused");
887 resume_done = true;
888 return;
891 is_paused = false;
892 is_recording = true;
894 /* Compensate for the time we have been paused */
895 if (pause_start_time)
897 record_start_time += current_tick - pause_start_time;
898 pause_start_time = 0;
901 resume_done = true;
902 logf("pcmrec_resume done");
906 * audio_init_recording calls this function using PCMREC_INIT
909 static void pcmrec_init(void)
911 wav_file = -1;
912 read_pos = 0;
913 write_pos = 0;
914 enc_wr_index = 0;
915 enc_rd_index = 0;
917 avrg_bit_rate = 0;
918 curr_bit_rate = 0;
919 curr_chunk_cnt = 0;
921 peak_left = 0;
922 peak_right = 0;
924 num_rec_bytes = 0;
925 num_file_bytes = 0;
926 num_pcm_samples = 0;
927 record_start_time = 0;
928 pause_start_time = 0;
930 close_done = false;
931 is_recording = false;
932 is_paused = false;
933 is_error = false;
935 rec_buffer = (unsigned char*)(((long)audiobuf + 15) & ~15);
936 enc_buffer = rec_buffer + NUM_CHUNKS * CHUNK_SIZE + MAX_FEED_SIZE;
937 /* 8000Bytes at audiobufend */
938 enc_buffer_size = audiobufend - enc_buffer - 8000;
940 SET_IIS_PLAY(0x800); /* Stop any playback */
941 AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */
942 DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */
944 DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */
945 DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
946 DMAROUTE = (DMAROUTE & 0xffff00ff) | DMA1_REQ_AUDIO_2;
947 ICR7 = 0x1c; /* Enable interrupt at level 7, priority 0 */
948 IMR &= ~(1<<15); /* bit 15 is DMA1 */
950 #ifdef HAVE_SPDIF_IN
951 PHASECONFIG = 0x34; /* Gain = 3*2^13, source = EBUIN */
952 #endif
953 pcmrec_dma_start();
955 init_done = 1;
958 static void pcmrec_close(void)
960 DMAROUTE = (DMAROUTE & 0xffff00ff);
961 ICR7 = 0x00; /* Disable interrupt */
962 IMR |= (1<<15); /* bit 15 is DMA1 */
964 pcmrec_dma_stop();
966 /* Reset PDIR2 data flow */
967 DATAINCONTROL = 0x200;
968 close_done = true;
969 init_done = false;
972 static void pcmrec_thread(void)
974 struct event ev;
976 logf("thread pcmrec start");
978 error_count = 0;
980 while(1)
982 queue_wait_w_tmo(&pcmrec_queue, &ev, HZ / 4);
984 switch (ev.id)
986 case PCMREC_INIT:
987 pcmrec_init();
988 break;
990 case PCMREC_CLOSE:
991 pcmrec_close();
992 break;
994 case PCMREC_START:
995 pcmrec_start();
996 break;
998 case PCMREC_STOP:
999 pcmrec_stop();
1000 break;
1002 case PCMREC_PAUSE:
1003 pcmrec_pause();
1004 break;
1006 case PCMREC_RESUME:
1007 pcmrec_resume();
1008 break;
1010 case PCMREC_NEW_FILE:
1011 pcmrec_new_file();
1012 break;
1014 case SYS_TIMEOUT:
1015 pcmrec_callback(false);
1016 break;
1018 case SYS_USB_CONNECTED:
1019 if (!is_recording)
1021 pcmrec_close();
1022 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1023 usb_wait_for_disconnect(&pcmrec_queue);
1025 break;
1029 logf("thread pcmrec done");
1032 /* Select VINL & VINR source: 0=Line-in, 1=FM Radio */
1033 void pcm_rec_mux(int source)
1035 #ifdef IRIVER_H300_SERIES
1036 if(source == 0)
1037 and_l(~0x40000000, &GPIO_OUT); /* Line In */
1038 else
1039 or_l(0x40000000, &GPIO_OUT); /* FM radio */
1041 or_l(0x40000000, &GPIO_ENABLE);
1042 or_l(0x40000000, &GPIO_FUNCTION);
1043 #elif defined(IRIVER_H100_SERIES)
1044 if(source == 0)
1045 and_l(~0x00800000, &GPIO_OUT); /* Line In */
1046 else
1047 or_l(0x00800000, &GPIO_OUT); /* FM radio */
1049 or_l(0x00800000, &GPIO_ENABLE);
1050 or_l(0x00800000, &GPIO_FUNCTION);
1052 #elif defined(IAUDIO_X5)
1053 if(source == 0)
1054 or_l((1<<29), &GPIO_OUT); /* Line In */
1055 else
1056 and_l(~(1<<29), &GPIO_OUT); /* FM radio */
1058 or_l((1<<29), &GPIO_ENABLE);
1059 or_l((1<<29), &GPIO_FUNCTION);
1061 /* iAudio x5 */
1062 #endif
1066 /****************************************************************************/
1067 /* */
1068 /* following functions will be called by the encoder codec */
1069 /* */
1070 /****************************************************************************/
1072 /* pass the encoder buffer pointer/size, mono/stereo, quality to the encoder */
1073 void enc_get_inputs(int *buffer_size, int *channels, int *quality)
1075 *buffer_size = enc_buffer_size;
1076 *channels = enc_channels;
1077 *quality = enc_quality;
1080 /* set the encoder dimensions (called by encoder codec at initialization) */
1081 void enc_set_parameters(int chunk_size, int num_chunks, int samp_per_chunk,
1082 char *head_ptr, int head_size, int enc_id)
1084 /* set read_pos just in front of current write_pos */
1085 read_pos = (write_pos - CHUNK_SIZE) & CHUNK_MASK;
1087 enc_rd_index = 0; /* reset */
1088 enc_wr_index = 0; /* reset */
1089 enc_chunk_size = chunk_size; /* max chunk size */
1090 enc_num_chunks = num_chunks; /* total number of chunks */
1091 enc_samp_per_chunk = samp_per_chunk; /* pcm samples / encoderchunk */
1092 enc_head_buffer = head_ptr; /* optional file header data (wav) */
1093 enc_head_size = head_size; /* optional file header data (wav) */
1094 audio_enc_id = enc_id; /* AFMT_* id */
1097 /* allocate encoder chunk */
1098 unsigned int *enc_alloc_chunk(void)
1100 return (unsigned int*)(enc_buffer + enc_wr_index * enc_chunk_size);
1103 /* free previously allocated encoder chunk */
1104 void enc_free_chunk(void)
1106 unsigned long *enc_chunk;
1108 enc_chunk = GET_ENC_CHUNK(enc_wr_index);
1109 curr_chunk_cnt++;
1110 /* curr_bit_rate += *enc_chunk * 44100 * 8 / (enc_samp_per_chunk * 1000); */
1111 curr_bit_rate += *enc_chunk * 441 * 8 / (enc_samp_per_chunk * 10 );
1112 avrg_bit_rate = (curr_bit_rate + curr_chunk_cnt / 2) / curr_chunk_cnt;
1114 /* advance enc_wr_index to the next chunk */
1115 enc_wr_index = (enc_wr_index + 1) % enc_num_chunks;
1117 /* buffer full: advance enc_rd_index (for prerecording purpose) */
1118 if (enc_rd_index == enc_wr_index)
1120 enc_rd_index = (enc_rd_index + 1) % enc_num_chunks;
1124 /* checks near empty state on wav input buffer */
1125 int enc_wavbuf_near_empty(void)
1127 /* less than 1sec raw data? => unboost encoder */
1128 if (((write_pos - read_pos) & CHUNK_MASK) < 44100*4)
1129 return 1;
1130 else
1131 return 0;
1134 /* passes a pointer to next chunk of unprocessed wav data */
1135 char *enc_get_wav_data(int size)
1137 char *ptr;
1138 int avail;
1140 /* limit the requested pcm data size */
1141 if(size > MAX_FEED_SIZE)
1142 size = MAX_FEED_SIZE;
1144 avail = (write_pos - read_pos) & CHUNK_MASK;
1146 if (avail >= size)
1148 ptr = rec_buffer + read_pos;
1149 read_pos = (read_pos + size) & CHUNK_MASK;
1151 /* ptr must point to continous data at wraparound position */
1152 if (read_pos < size)
1153 memcpy(rec_buffer + NUM_CHUNKS * CHUNK_SIZE,
1154 rec_buffer, read_pos);
1156 wav_queue_empty = false;
1157 return ptr;
1160 wav_queue_empty = true;
1161 return NULL;