summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/recorder/recording.c23
-rw-r--r--apps/settings.c6
-rw-r--r--apps/sound_menu.c20
-rw-r--r--firmware/export/audio.h2
-rw-r--r--firmware/export/config-h100.h3
-rw-r--r--firmware/export/config-h120.h3
-rw-r--r--firmware/pcm_record.c188
7 files changed, 214 insertions, 31 deletions
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index cf361eea76..854e979ade 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -577,6 +577,11 @@ bool recording_screen(void)
577#endif 577#endif
578 talk_buffer_steal(); /* will use the mp3 buffer */ 578 talk_buffer_steal(); /* will use the mp3 buffer */
579 579
580#ifdef HAVE_SPDIF_POWER
581 /* Tell recording whether we want S/PDIF power enabled at all times */
582 audio_set_spdif_power_setting(global_settings.spdif_enable);
583#endif
584
580 audio_set_recording_options(global_settings.rec_frequency, 585 audio_set_recording_options(global_settings.rec_frequency,
581 global_settings.rec_quality, 586 global_settings.rec_quality,
582 global_settings.rec_source, 587 global_settings.rec_source,
@@ -1011,6 +1016,7 @@ bool recording_screen(void)
1011 unsigned int dseconds, dhours, dminutes; 1016 unsigned int dseconds, dhours, dminutes;
1012 unsigned long num_recorded_bytes; 1017 unsigned long num_recorded_bytes;
1013 int pos = 0; 1018 int pos = 0;
1019 char spdif_sfreq[8];
1014 1020
1015 update_countdown = 5; 1021 update_countdown = 5;
1016 last_seconds = seconds; 1022 last_seconds = seconds;
@@ -1259,12 +1265,21 @@ bool recording_screen(void)
1259 2+PM_HEIGHT, true); 1265 2+PM_HEIGHT, true);
1260 } 1266 }
1261 } 1267 }
1262 1268/* Can't measure S/PDIF sample rate on Archos yet */
1269#if CONFIG_CODEC != MAS3587F && defined(HAVE_SPDIF_IN)
1270 if (global_settings.rec_source == SOURCE_SPDIF)
1271 snprintf(spdif_sfreq, 8, "%dHz", audio_get_spdif_sample_rate());
1272#else
1273 (void)spdif_sfreq;
1274#endif
1263 snprintf(buf, 32, "%s %s", 1275 snprintf(buf, 32, "%s %s",
1276#if CONFIG_CODEC != MAS3587F && defined(HAVE_SPDIF_IN)
1277 global_settings.rec_source == SOURCE_SPDIF ?
1278 spdif_sfreq :
1279#endif
1264 freq_str[global_settings.rec_frequency], 1280 freq_str[global_settings.rec_frequency],
1265 global_settings.rec_channels? 1281 global_settings.rec_channels ?
1266 str(LANG_CHANNEL_MONO):str(LANG_CHANNEL_STEREO)); 1282 str(LANG_CHANNEL_MONO) : str(LANG_CHANNEL_STEREO));
1267
1268 FOR_NB_SCREENS(i) 1283 FOR_NB_SCREENS(i)
1269 screens[i].puts(0, 5+PM_HEIGHT, buf); 1284 screens[i].puts(0, 5+PM_HEIGHT, buf);
1270 1285
diff --git a/apps/settings.c b/apps/settings.c
index ad1ec70c07..ccf0acd8f9 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -94,7 +94,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
94#include "dsp.h" 94#include "dsp.h"
95#endif 95#endif
96 96
97#define CONFIG_BLOCK_VERSION 41 97#define CONFIG_BLOCK_VERSION 42
98#define CONFIG_BLOCK_SIZE 512 98#define CONFIG_BLOCK_SIZE 512
99#define RTC_BLOCK_SIZE 44 99#define RTC_BLOCK_SIZE 44
100 100
@@ -504,7 +504,11 @@ static const struct bit_entry hd_bits[] =
504 "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00,04:00,06:00,08:00,10:00,12:00,18:00,24:00" }, 504 "off,00:05,00:10,00:15,00:30,01:00,01:14,01:20,02:00,04:00,06:00,08:00,10:00,12:00,18:00,24:00" },
505 {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" }, 505 {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" },
506 {4, S_O(rec_mic_gain), 4, "rec mic gain", NULL }, 506 {4, S_O(rec_mic_gain), 4, "rec mic gain", NULL },
507#ifdef HAVE_SPDIF_IN
508 {2, S_O(rec_source), 0 /* 0=mic */, "rec source", "mic,line,spdif" },
509#else
507 {1, S_O(rec_source), 0 /* 0=mic */, "rec source", "mic,line" }, 510 {1, S_O(rec_source), 0 /* 0=mic */, "rec source", "mic,line" },
511#endif
508 {3, S_O(rec_frequency), 0, /* 0=44.1kHz */ 512 {3, S_O(rec_frequency), 0, /* 0=44.1kHz */
509 "rec frequency", "44,48,32,22,24,16" }, 513 "rec frequency", "44,48,32,22,24,16" },
510 {4, S_O(rec_left_gain), 2, /* 0dB */ 514 {4, S_O(rec_left_gain), 2, /* 0dB */
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index 1d389f30de..d3377a3efa 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -302,6 +302,8 @@ static bool recsource(void)
302 sizeof(names)/sizeof(struct opt_items), NULL ); 302 sizeof(names)/sizeof(struct opt_items), NULL );
303} 303}
304 304
305/* To be removed when we add support for sample rates and channel settings */
306#ifndef HAVE_UDA1380
305static bool recfrequency(void) 307static bool recfrequency(void)
306{ 308{
307 static const struct opt_items names[] = { 309 static const struct opt_items names[] = {
@@ -327,12 +329,11 @@ static bool recchannels(void)
327 &global_settings.rec_channels, INT, 329 &global_settings.rec_channels, INT,
328 names, 2, NULL ); 330 names, 2, NULL );
329} 331}
332#endif
330 333
334#if CONFIG_CODEC == MAS3587F
331static bool recquality(void) 335static bool recquality(void)
332{ 336{
333#ifdef HAVE_UDA1380
334 (void)recquality();
335#endif
336 return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT, 337 return set_int(str(LANG_RECORDING_QUALITY), "", UNIT_INT,
337 &global_settings.rec_quality, 338 &global_settings.rec_quality,
338 NULL, 1, 0, 7, NULL ); 339 NULL, 1, 0, 7, NULL );
@@ -343,7 +344,7 @@ static bool receditable(void)
343 return set_bool(str(LANG_RECORDING_EDITABLE), 344 return set_bool(str(LANG_RECORDING_EDITABLE),
344 &global_settings.rec_editable); 345 &global_settings.rec_editable);
345} 346}
346 347#endif
347 348
348static bool rectimesplit(void) 349static bool rectimesplit(void)
349{ 350{
@@ -901,20 +902,29 @@ bool recording_menu(bool no_source)
901 struct menu_item items[13]; 902 struct menu_item items[13];
902 bool result; 903 bool result;
903 904
904#ifndef HAVE_UDA1380 905#if CONFIG_CODEC == MAS3587F
905 items[i].desc = ID2P(LANG_RECORDING_QUALITY); 906 items[i].desc = ID2P(LANG_RECORDING_QUALITY);
906 items[i++].function = recquality; 907 items[i++].function = recquality;
907#endif 908#endif
909/* We don't support frequency selection for UDA1380 yet. Let it just stay at
910 the default 44100 Hz. */
911#ifndef HAVE_UDA1380
908 items[i].desc = ID2P(LANG_RECORDING_FREQUENCY); 912 items[i].desc = ID2P(LANG_RECORDING_FREQUENCY);
909 items[i++].function = recfrequency; 913 items[i++].function = recfrequency;
914#endif
910 if(!no_source) { 915 if(!no_source) {
911 items[i].desc = ID2P(LANG_RECORDING_SOURCE); 916 items[i].desc = ID2P(LANG_RECORDING_SOURCE);
912 items[i++].function = recsource; 917 items[i++].function = recsource;
913 } 918 }
919/* We don't support other configurations than stereo yet either */
920#ifndef HAVE_UDA1380
914 items[i].desc = ID2P(LANG_RECORDING_CHANNELS); 921 items[i].desc = ID2P(LANG_RECORDING_CHANNELS);
915 items[i++].function = recchannels; 922 items[i++].function = recchannels;
923#endif
924#if CONFIG_CODEC == MAS3587F
916 items[i].desc = ID2P(LANG_RECORDING_EDITABLE); 925 items[i].desc = ID2P(LANG_RECORDING_EDITABLE);
917 items[i++].function = receditable; 926 items[i++].function = receditable;
927#endif
918 items[i].desc = ID2P(LANG_RECORD_TIMESPLIT); 928 items[i].desc = ID2P(LANG_RECORD_TIMESPLIT);
919 items[i++].function = rectimesplit; 929 items[i++].function = rectimesplit;
920 items[i].desc = ID2P(LANG_RECORD_PRERECORD_TIME); 930 items[i].desc = ID2P(LANG_RECORD_PRERECORD_TIME);
diff --git a/firmware/export/audio.h b/firmware/export/audio.h
index 6922dab1f6..b44bb91378 100644
--- a/firmware/export/audio.h
+++ b/firmware/export/audio.h
@@ -100,6 +100,8 @@ void audio_set_recording_options(int frequency, int quality,
100void audio_set_recording_gain(int left, int right, int type); 100void audio_set_recording_gain(int left, int right, int type);
101unsigned long audio_recorded_time(void); 101unsigned long audio_recorded_time(void);
102unsigned long audio_num_recorded_bytes(void); 102unsigned long audio_num_recorded_bytes(void);
103void audio_set_spdif_power_setting(bool on);
104unsigned long audio_get_spdif_sample_rate(void);
103 105
104 106
105 107
diff --git a/firmware/export/config-h100.h b/firmware/export/config-h100.h
index 942f18adf3..d53adcec14 100644
--- a/firmware/export/config-h100.h
+++ b/firmware/export/config-h100.h
@@ -125,6 +125,9 @@
125 125
126#endif 126#endif
127 127
128/* Define this for S/PDIF input available */
129#define HAVE_SPDIF_IN
130
128/* Define this for S/PDIF output available */ 131/* Define this for S/PDIF output available */
129#define HAVE_SPDIF_OUT 132#define HAVE_SPDIF_OUT
130 133
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h
index 186203c648..34f5059b69 100644
--- a/firmware/export/config-h120.h
+++ b/firmware/export/config-h120.h
@@ -120,6 +120,9 @@
120 120
121#endif 121#endif
122 122
123/* Define this for S/PDIF input available */
124#define HAVE_SPDIF_IN
125
123/* Define this for S/PDIF output available */ 126/* Define this for S/PDIF output available */
124#define HAVE_SPDIF_OUT 127#define HAVE_SPDIF_OUT
125 128
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index a7d8bc707c..f97995df72 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -30,6 +30,7 @@
30 30
31#include "cpu.h" 31#include "cpu.h"
32#include "i2c.h" 32#include "i2c.h"
33#include "power.h"
33#include "uda1380.h" 34#include "uda1380.h"
34#include "system.h" 35#include "system.h"
35#include "usb.h" 36#include "usb.h"
@@ -61,6 +62,8 @@ static volatile int error_count; /* Number of DMA errors */
61static long record_start_time; /* Value of current_tick when recording was started */ 62static long record_start_time; /* Value of current_tick when recording was started */
62static long pause_start_time; /* Value of current_tick when pause was started */ 63static long pause_start_time; /* Value of current_tick when pause was started */
63static volatile int buffered_chunks; /* number of valid chunks in buffer */ 64static volatile int buffered_chunks; /* number of valid chunks in buffer */
65static unsigned int sample_rate; /* Sample rate at time of recording start */
66static int rec_source; /* Current recording source */
64 67
65static int wav_file; 68static int wav_file;
66static char recording_filename[MAX_PATH]; 69static char recording_filename[MAX_PATH];
@@ -193,51 +196,144 @@ unsigned long audio_num_recorded_bytes(void)
193 return 0; 196 return 0;
194} 197}
195 198
199#ifdef HAVE_SPDIF_IN
200/* Only the last six of these are standard rates, but all sample rates are
201 * possible, so we support some other common ones as well.
202 */
203static unsigned long spdif_sample_rates[] = {
204 8000, 11025, 12000, 16000, 22050, 24000,
205 32000, 44100, 48000, 64000, 88200, 96000
206};
207
208/* Return SPDIF sample rate. Since we base our reading on the actual SPDIF
209 * sample rate (which might be a bit inaccurate), we round off to the closest
210 * sample rate that is supported by SPDIF.
211 */
212unsigned long audio_get_spdif_sample_rate(void)
213{
214 int i = 0;
215 unsigned long measured_rate;
216 const int upper_bound = sizeof(spdif_sample_rates)/sizeof(long) - 1;
217
218 /* The following formula is specified in MCF5249 user's manual section
219 * 17.6.1. The 3*(1 << 13) part will need changing if the setup of the
220 * PHASECONFIG register is ever changed. The 128 divide is because of the
221 * fact that the SPDIF clock is the sample rate times 128.
222 */
223 measured_rate = (unsigned long)((unsigned long long)FREQMEAS*CPU_FREQ/
224 ((1 << 15)*3*(1 << 13))/128);
225 /* Find which SPDIF sample rate we're closest to. */
226 while (spdif_sample_rates[i] < measured_rate && i < upper_bound) ++i;
227 if (i > 0 && i < upper_bound)
228 {
229 long diff1 = measured_rate - spdif_sample_rates[i - 1];
230 long diff2 = spdif_sample_rates[i] - measured_rate;
231
232 if (diff2 > diff1) --i;
233 }
234 return spdif_sample_rates[i];
235}
236#endif
237
238#ifdef HAVE_SPDIF_POWER
239static bool spdif_power_setting;
240
241void audio_set_spdif_power_setting(bool on)
242{
243 spdif_power_setting = on;
244}
245#endif
196 246
197/** 247/**
198 * Sets the audio source 248 * Sets the audio source
199 * 249 *
200 * This functions starts feeding the CPU with audio data over the I2S bus 250 * This functions starts feeding the CPU with audio data over the I2S bus
201 * 251 *
202 * @param source 0=mic, 1=line-in, (todo: 2=spdif) 252 * @param source 0=mic, 1=line-in, 2=spdif
203 */ 253 */
204void audio_set_recording_options(int frequency, int quality, 254void audio_set_recording_options(int frequency, int quality,
205 int source, int channel_mode, 255 int source, int channel_mode,
206 bool editable, int prerecord_time) 256 bool editable, int prerecord_time)
207{ 257{
208 /* TODO: */ 258 /* TODO: */
209 (void)frequency;
210 (void)quality; 259 (void)quality;
211 (void)channel_mode; 260 (void)channel_mode;
212 (void)editable; 261 (void)editable;
213 262
214 /* WARNING: calculation below uses fixed frequency! */ 263 /* NOTE: Coldfire UDA based recording does not yet support anything other
264 * than 44.1kHz sampling rate, so we limit it to that case here now. SPDIF
265 * based recording will overwrite this value with the proper sample rate in
266 * audio_record(), and will not be affected by this.
267 */
268 frequency = 44100;
215 pre_record_ticks = prerecord_time * HZ; 269 pre_record_ticks = prerecord_time * HZ;
216 pre_record_chunks = ((44100 * prerecord_time * 4)/CHUNK_SIZE)+1; 270 pre_record_chunks = ((frequency * prerecord_time * 4)/CHUNK_SIZE)+1;
217 if(pre_record_chunks >= (num_chunks-250)) 271 if(pre_record_chunks >= (num_chunks-250))
218 { 272 {
219 /* we can't prerecord more than our buffersize minus treshold to write to disk! */ 273 /* we can't prerecord more than our buffersize minus treshold to write to disk! */
220 pre_record_chunks = num_chunks-250; 274 pre_record_chunks = num_chunks-250;
221 /* don't forget to recalculate that time! */ 275 /* don't forget to recalculate that time! */
222 pre_record_ticks = ((pre_record_chunks * CHUNK_SIZE)/(4*44100)) * HZ; 276 pre_record_ticks = ((pre_record_chunks * CHUNK_SIZE)/(4*frequency)) * HZ;
223 } 277 }
224 278
225 //logf("pcmrec: src=%d", source); 279 //logf("pcmrec: src=%d", source);
226 280
281 rec_source = source;
282#ifdef HAVE_SPDIF_POWER
283 /* Check if S/PDIF output power should be switched off or on. NOTE: assumes
284 both optical in and out is controlled by the same power source, which is
285 the case on H1x0. */
286 spdif_power_enable((source == 2) || spdif_power_setting);
287#endif
227 switch (source) 288 switch (source)
228 { 289 {
229 /* mic */ 290 /* mic */
230 case 0: 291 case 0:
292 /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
293 DATAINCONTROL = 0xc020;
231 uda1380_enable_recording(true); 294 uda1380_enable_recording(true);
232 break; 295 break;
233 296
234 /* line-in */ 297 /* line-in */
235 case 1: 298 case 1:
299 /* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
300 DATAINCONTROL = 0xc020;
236 uda1380_enable_recording(false); 301 uda1380_enable_recording(false);
237 break; 302 break;
303#ifdef HAVE_SPDIF_IN
304 /* SPDIF */
305 case 2:
306 /* Int. when 6 samples in FIFO. PDIR2 source = ebu1RcvData */
307 DATAINCONTROL = 0xc038;
308 EBU1CONFIG = 0; /* Normal operation, source is EBU in 1 */
309 /* We can't use the EBU clock to drive the IIS interface, so we
310 * need to use the clock the UDA provides, which is 44.1kHz as of
311 * now. This is the reason S/PDIF monitoring distorts for all other
312 * sample rates. Enable record to enable clock gen.
313 */
314 uda1380_enable_recording(true);
315 break;
316#endif
238 } 317 }
239 318
319 sample_rate = frequency;
320
321#ifdef HAVE_SPDIF_IN
322 /* Turn on UDA based monitoring when UDA is used as input. */
323 if (source == 2) {
324 uda1380_set_monitor(false);
325 IIS2CONFIG = 0x800; /* Reset before reprogram */
326 /* SCLK follow IIS1 (UDA clock), TXSRC = EBU1rcv, 64 bclk/wclk */
327 IIS2CONFIG = (8 << 12) | (7 << 8) | (4 << 2);
328 }
329 else
330 {
331 uda1380_set_monitor(true);
332 IIS2CONFIG = 0x800; /* Stop the S/PDIF monitoring if it's active */
333 }
334#else
240 uda1380_set_monitor(true); 335 uda1380_set_monitor(true);
336#endif
241} 337}
242 338
243 339
@@ -271,6 +367,11 @@ void audio_record(const char *filename)
271 strncpy(recording_filename, filename, MAX_PATH - 1); 367 strncpy(recording_filename, filename, MAX_PATH - 1);
272 recording_filename[MAX_PATH - 1] = 0; 368 recording_filename[MAX_PATH - 1] = 0;
273 369
370#ifdef HAVE_SPDIF_IN
371 if (rec_source == 2)
372 sample_rate = audio_get_spdif_sample_rate();
373#endif
374
274 record_done = false; 375 record_done = false;
275 queue_post(&pcmrec_queue, PCMREC_START, 0); 376 queue_post(&pcmrec_queue, PCMREC_START, 0);
276 377
@@ -381,7 +482,7 @@ void pcm_rec_get_peaks(int *left, int *right)
381 * 482 *
382 */ 483 */
383 484
384static void pcmrec_callback(bool flush) __attribute__ ((section (".icode"))); 485static void pcmrec_callback(bool flush) ICODE_ATTR;
385static void pcmrec_callback(bool flush) 486static void pcmrec_callback(bool flush)
386{ 487{
387 int num_ready, num_free, num_new; 488 int num_ready, num_free, num_new;
@@ -493,6 +594,10 @@ static void pcmrec_dma_start(void)
493 /* Start the DMA transfer.. */ 594 /* Start the DMA transfer.. */
494 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START; 595 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
495 596
597#ifdef HAVE_SPDIF_IN
598 INTERRUPTCLEAR = 0x03c00000;
599#endif
600
496 /* pre-recording: buffer count */ 601 /* pre-recording: buffer count */
497 buffered_chunks = 0; 602 buffered_chunks = 0;
498 603
@@ -512,14 +617,36 @@ void DMA1(void)
512 { 617 {
513 DCR1 = 0; /* Stop DMA transfer */ 618 DCR1 = 0; /* Stop DMA transfer */
514 error_count++; 619 error_count++;
515 is_recording = false;
516 620
517 logf("dma1 err: 0x%x", res); 621 logf("dma1 err: 0x%x", res);
518
519 /* Flush recorded data to disk and stop recording */
520 queue_post(&pcmrec_queue, PCMREC_STOP, NULL);
521 622
522 } else 623 DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */
624 BCR1 = CHUNK_SIZE;
625 DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
626 }
627#ifdef HAVE_SPDIF_IN
628 else if ((rec_source == 2) && (INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */
629 {
630 INTERRUPTCLEAR = 0x03c00000;
631 error_count++;
632
633 logf("spdif err");
634
635 if (is_stopping)
636 {
637 DCR1 = 0; /* Stop DMA transfer */
638 is_stopping = false;
639
640 logf("dma1 stopping");
641 }
642 else
643 {
644 DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */
645 BCR1 = CHUNK_SIZE;
646 }
647 }
648#endif
649 else
523 { 650 {
524 write_index++; 651 write_index++;
525 if (write_index >= num_chunks) 652 if (write_index >= num_chunks)
@@ -535,15 +662,16 @@ void DMA1(void)
535 is_stopping = false; 662 is_stopping = false;
536 663
537 logf("dma1 stopping"); 664 logf("dma1 stopping");
538 665 }
539 } else if (write_index == read_index) 666 else if (write_index == read_index)
540 { 667 {
541 DCR1 = 0; /* Stop DMA transfer */ 668 DCR1 = 0; /* Stop DMA transfer */
542 is_recording = false; 669 is_recording = false;
543 670
544 logf("dma1 overrun"); 671 logf("dma1 overrun");
545 672
546 } else 673 }
674 else
547 { 675 {
548 DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */ 676 DAR1 = (unsigned long)GET_CHUNK(write_index); /* Destination address */
549 BCR1 = CHUNK_SIZE; 677 BCR1 = CHUNK_SIZE;
@@ -560,10 +688,11 @@ static int start_wave(void)
560 unsigned char header[44] = 688 unsigned char header[44] =
561 { 689 {
562 'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ', 690 'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',
563 0x10,0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0, 691 0x10,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,
564 4,0,0x10,0,'d','a','t','a',0,0,0,0 692 4,0,0x10,0,'d','a','t','a',0,0,0,0
565 }; 693 };
566 694 unsigned long avg_bytes_per_sec;
695
567 wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC); 696 wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC);
568 if (wav_file < 0) 697 if (wav_file < 0)
569 { 698 {
@@ -572,7 +701,18 @@ static int start_wave(void)
572 is_error = true; 701 is_error = true;
573 return -1; 702 return -1;
574 } 703 }
575 704 /* Now set the sample rate field of the WAV header to what it should be */
705 header[24] = (unsigned char)(sample_rate & 0xff);
706 header[25] = (unsigned char)(sample_rate >> 8);
707 header[26] = (unsigned char)(sample_rate >> 16);
708 header[27] = (unsigned char)(sample_rate >> 24);
709 /* And then the average bytes per second field */
710 avg_bytes_per_sec = sample_rate*4; /* Hard coded to 16 bit stereo */
711 header[28] = (unsigned char)(avg_bytes_per_sec & 0xff);
712 header[29] = (unsigned char)(avg_bytes_per_sec >> 8);
713 header[30] = (unsigned char)(avg_bytes_per_sec >> 16);
714 header[31] = (unsigned char)(avg_bytes_per_sec >> 24);
715
576 if (sizeof(header) != write(wav_file, header, sizeof(header))) 716 if (sizeof(header) != write(wav_file, header, sizeof(header)))
577 { 717 {
578 close(wav_file); 718 close(wav_file);
@@ -634,7 +774,7 @@ static void pcmrec_start(void)
634 { 774 {
635 /* not enough good chunks available - limit pre-record time */ 775 /* not enough good chunks available - limit pre-record time */
636 pre_chunks = buffered_chunks; 776 pre_chunks = buffered_chunks;
637 pre_ticks = ((buffered_chunks * CHUNK_SIZE)/(4*44100)) * HZ; 777 pre_ticks = ((buffered_chunks * CHUNK_SIZE)/(4*sample_rate)) * HZ;
638 } 778 }
639 record_start_time = current_tick - pre_ticks; 779 record_start_time = current_tick - pre_ticks;
640 780
@@ -792,7 +932,6 @@ static void pcmrec_resume(void)
792 logf("pcmrec_resume done"); 932 logf("pcmrec_resume done");
793} 933}
794 934
795
796/** 935/**
797 * audio_init_recording calls this function using PCMREC_INIT 936 * audio_init_recording calls this function using PCMREC_INIT
798 * 937 *
@@ -834,7 +973,6 @@ static void pcmrec_init(void)
834 IIS1CONFIG = 0x800; /* Stop any playback */ 973 IIS1CONFIG = 0x800; /* Stop any playback */
835 AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */ 974 AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */
836 DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */ 975 DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */
837 DATAINCONTROL |= 0x20; /* PDIR2 source = IIS1recv */
838 976
839 DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */ 977 DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */
840 DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */ 978 DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
@@ -842,6 +980,9 @@ static void pcmrec_init(void)
842 ICR7 = 0x1c; /* Enable interrupt at level 7, priority 0 */ 980 ICR7 = 0x1c; /* Enable interrupt at level 7, priority 0 */
843 IMR &= ~(1<<15); /* bit 15 is DMA1 */ 981 IMR &= ~(1<<15); /* bit 15 is DMA1 */
844 982
983#ifdef HAVE_SPDIF_IN
984 PHASECONFIG = 0x34; /* Gain = 3*2^13, source = EBUIN */
985#endif
845 pcmrec_dma_start(); 986 pcmrec_dma_start();
846 987
847 init_done = 1; 988 init_done = 1;
@@ -851,10 +992,15 @@ static void pcmrec_close(void)
851{ 992{
852 uda1380_disable_recording(); 993 uda1380_disable_recording();
853 994
995#ifdef HAVE_SPDIF_POWER
996 spdif_power_enable(spdif_power_setting);
997#endif
854 DMAROUTE = (DMAROUTE & 0xffff00ff); 998 DMAROUTE = (DMAROUTE & 0xffff00ff);
855 ICR7 = 0x00; /* Disable interrupt */ 999 ICR7 = 0x00; /* Disable interrupt */
856 IMR |= (1<<15); /* bit 15 is DMA1 */ 1000 IMR |= (1<<15); /* bit 15 is DMA1 */
857 1001
1002 /* Reset PDIR2 data flow */
1003 DATAINCONTROL = 0x200;
858 close_done = true; 1004 close_done = true;
859} 1005}
860 1006