1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
51 #include "lcd-remote.h"
52 #include "pcm_playback.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 */
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
;
84 #define SET_IIS_PLAY(x) IIS1CONFIG = (x);
85 #define SET_IIS_REC(x) IIS1CONFIG = (x);
87 #define SET_IIS_PLAY(x) IIS2CONFIG = (x);
88 #define SET_IIS_REC(x) IIS1CONFIG = (x);
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
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
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);
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)
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
)
196 queue_post(&pcmrec_queue
, PCMREC_INIT
, 0);
202 void audio_close_recording(void)
205 queue_post(&pcmrec_queue
, PCMREC_CLOSE
, 0);
210 audio_remove_encoder();
213 unsigned long pcm_rec_status(void)
215 unsigned long ret
= 0;
218 ret
|= AUDIO_STATUS_RECORD
;
220 ret
|= AUDIO_STATUS_PAUSE
;
222 ret
|= AUDIO_STATUS_ERROR
;
223 if (!is_recording
&& pre_record_ticks
&& init_done
&& !close_done
)
224 ret
|= AUDIO_STATUS_PRERECORD
;
229 int pcm_rec_current_bitrate(void)
231 return avrg_bit_rate
;
234 unsigned long audio_recorded_time(void)
239 return pause_start_time
- record_start_time
;
241 return current_tick
- record_start_time
;
247 unsigned long audio_num_recorded_bytes(void)
250 return num_rec_bytes
;
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)
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
;
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
;
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
)
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.
324 enc_quality
= quality
;
326 enc_channels
= channel_mode
== CHN_MODE_MONO
? 1 : 2;
327 pre_record_ticks
= prerecord_time
* HZ
;
332 case AUDIO_SRC_LINEIN
:
333 #ifdef HAVE_FMRADIO_IN
334 case AUDIO_SRC_FMRADIO
:
336 /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
337 DATAINCONTROL
= 0xc020;
341 case AUDIO_SRC_SPDIF
:
342 /* Int. when 6 samples in FIFO. PDIR2 source = ebu1RcvData */
343 DATAINCONTROL
= 0xc038;
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 */
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 */
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);
371 /* SCLK2 follow IIS1 (UDA clock), TXSRC = IIS1rcv, 64 bclk/wclk */
372 SET_IIS_PLAY( (8 << 12) | (4 << 8) | (4 << 2) );
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
);
400 * Use audio_set_recording_options first to select recording options
402 void audio_record(const char *filename
)
406 logf("record while recording");
410 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
411 recording_filename
[MAX_PATH
- 1] = 0;
414 if (rec_source
== AUDIO_SRC_SPDIF
)
415 sample_rate
= audio_get_spdif_sample_rate();
419 queue_post(&pcmrec_queue
, PCMREC_START
, 0);
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
)
440 logf("pcm_new_file done");
446 void audio_stop_recording(void)
453 is_paused
= true; /* fix pcm write ptr at current position */
455 queue_post(&pcmrec_queue
, PCMREC_STOP
, 0);
460 logf("pcm_stop done");
463 void audio_pause_recording(void)
467 logf("pause when not recording");
472 logf("pause when paused");
477 queue_post(&pcmrec_queue
, PCMREC_PAUSE
, 0);
483 void audio_resume_recording(void)
487 logf("resume when not paused");
492 queue_post(&pcmrec_queue
, PCMREC_RESUME
, 0);
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
)
510 /***************************************************************************/
511 /* Functions that executes in the context of pcmrec_thread */
512 /***************************************************************************/
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
)
531 num_ready
= enc_wr_index
- enc_rd_index
;
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
);
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
)
563 logf("pcmrec: write err");
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 */
578 enc_rd_index
= (enc_rd_index
+ 1) % enc_num_chunks
;
584 cpu_boost_id(false, CPUBOOSTID_PCMRECORD
);
590 /* Abort dma transfer */
591 static void pcmrec_dma_stop(void)
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.. */
611 INTERRUPTCLEAR
= 0x03c00000;
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")));
626 DSR1
= 1; /* Clear interrupt */
630 DCR1
= 0; /* Stop DMA transfer */
633 logf("dma1 err: 0x%x", res
);
635 DAR1
= (unsigned long)GET_CHUNK(write_pos
); /* Destination address */
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
);
643 else if ((rec_source
== AUDIO_SRC_SPDIF
) &&
644 (INTERRUPTSTAT
& 0x01c00000)) /* valnogood, symbolerr, parityerr */
646 INTERRUPTCLEAR
= 0x03c00000;
651 DAR1
= (unsigned long)GET_CHUNK(write_pos
); /* Destination address */
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 */
670 /* only peak every 4th sample */
671 for (j
=0; j
<CHUNK_SIZE
/4; j
+=4)
674 #ifdef ROCKBOX_BIG_ENDIAN
675 if (value
> peak_l
) peak_l
= value
;
676 else if (-value
> peak_l
) peak_l
= -value
;
679 if (value
> peak_r
) peak_r
= value
;
680 else if (-value
> peak_r
) peak_r
= -value
;
682 if (value
> peak_r
) peak_r
= value
;
683 else if (-value
> peak_r
) peak_r
= -value
;
686 if (value
> peak_l
) peak_l
= value
;
687 else if (-value
> peak_l
) peak_l
= -value
;
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
);
707 logf("rec: create failed: %d", wav_file
);
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
))
717 logf("rec: write failed");
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 */
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
);
749 static void pcmrec_start(void)
751 long max_pre_chunks
, pre_ticks
, max_pre_ticks
;
753 logf("pcmrec_start");
757 logf("already recording");
765 if (start_wave() != 0)
767 /* failed to create the file */
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
;
791 pause_start_time
= 0;
798 static void pcmrec_stop(void)
804 /* wait for encoding finish */
806 while(!wav_queue_empty
)
809 is_recording
= false;
811 /* Flush buffers to file */
812 pcmrec_callback(true);
819 logf("pcmrec_stop done");
822 static void pcmrec_new_file(void)
824 logf("pcmrec_new_file");
828 logf("not recording");
829 new_file_done
= true;
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
;
839 pause_start_time
= record_start_time
;
841 /* Flush what we got in buffers to file */
842 pcmrec_callback(true);
850 /* start the new file */
851 if (start_wave() != 0)
853 logf("new_file failed");
857 new_file_done
= true;
858 logf("pcmrec_new_file done");
861 static void pcmrec_pause(void)
863 logf("pcmrec_pause");
867 logf("pause: not recording");
872 pause_start_time
= current_tick
;
876 logf("pcmrec_pause done");
880 static void pcmrec_resume(void)
882 logf("pcmrec_resume");
886 logf("resume: not paused");
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;
902 logf("pcmrec_resume done");
906 * audio_init_recording calls this function using PCMREC_INIT
909 static void pcmrec_init(void)
927 record_start_time
= 0;
928 pause_start_time
= 0;
931 is_recording
= 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 */
951 PHASECONFIG
= 0x34; /* Gain = 3*2^13, source = EBUIN */
958 static void pcmrec_close(void)
960 DMAROUTE
= (DMAROUTE
& 0xffff00ff);
961 ICR7
= 0x00; /* Disable interrupt */
962 IMR
|= (1<<15); /* bit 15 is DMA1 */
966 /* Reset PDIR2 data flow */
967 DATAINCONTROL
= 0x200;
972 static void pcmrec_thread(void)
976 logf("thread pcmrec start");
982 queue_wait_w_tmo(&pcmrec_queue
, &ev
, HZ
/ 4);
1010 case PCMREC_NEW_FILE
:
1015 pcmrec_callback(false);
1018 case SYS_USB_CONNECTED
:
1022 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1023 usb_wait_for_disconnect(&pcmrec_queue
);
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
1037 and_l(~0x40000000, &GPIO_OUT
); /* Line In */
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)
1045 and_l(~0x00800000, &GPIO_OUT
); /* Line In */
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)
1054 or_l((1<<29), &GPIO_OUT
); /* Line In */
1056 and_l(~(1<<29), &GPIO_OUT
); /* FM radio */
1058 or_l((1<<29), &GPIO_ENABLE
);
1059 or_l((1<<29), &GPIO_FUNCTION
);
1066 /****************************************************************************/
1068 /* following functions will be called by the encoder codec */
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
);
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)
1134 /* passes a pointer to next chunk of unprocessed wav data */
1135 char *enc_get_wav_data(int size
)
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
;
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;
1160 wav_queue_empty
= true;