Corrected timescreen buttons
[kugel-rb.git] / firmware / mpeg.c
blob65fb024db30de6146efd80e3fada07f803b2ab73
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 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 ****************************************************************************/
19 #include <stdbool.h>
20 #include <stdlib.h>
21 #include "config.h"
23 #if CONFIG_CODEC != SWCODEC
25 #include "debug.h"
26 #include "panic.h"
27 #include "id3.h"
28 #include "mpeg.h"
29 #include "audio.h"
30 #include "ata.h"
31 #include "string.h"
32 #include <kernel.h>
33 #include "thread.h"
34 #include "errno.h"
35 #include "mp3data.h"
36 #include "buffer.h"
37 #include "mp3_playback.h"
38 #include "sound.h"
39 #include "bitswap.h"
40 #ifndef SIMULATOR
41 #include "i2c.h"
42 #include "mas.h"
43 #include "dac.h"
44 #include "system.h"
45 #include "usb.h"
46 #include "file.h"
47 #include "hwcompat.h"
48 #endif /* !SIMULATOR */
49 #ifdef HAVE_LCD_BITMAP
50 #include "lcd.h"
51 #endif
53 #ifndef SIMULATOR
54 extern unsigned long mas_version_code;
55 #endif
57 #if CONFIG_CODEC == MAS3587F
58 extern enum /* from mp3_playback.c */
60 MPEG_DECODER,
61 MPEG_ENCODER
62 } mpeg_mode;
63 #endif /* CONFIG_CODEC == MAS3587F */
65 extern char* playlist_peek(int steps);
66 extern bool playlist_check(int steps);
67 extern int playlist_next(int steps);
68 extern int playlist_amount(void);
69 extern int playlist_update_resume_info(const struct mp3entry* id3);
71 #define MPEG_PLAY 1
72 #define MPEG_STOP 2
73 #define MPEG_PAUSE 3
74 #define MPEG_RESUME 4
75 #define MPEG_NEXT 5
76 #define MPEG_PREV 6
77 #define MPEG_FF_REWIND 7
78 #define MPEG_FLUSH_RELOAD 8
79 #define MPEG_RECORD 9
80 #define MPEG_INIT_RECORDING 10
81 #define MPEG_INIT_PLAYBACK 11
82 #define MPEG_NEW_FILE 12
83 #define MPEG_PAUSE_RECORDING 13
84 #define MPEG_RESUME_RECORDING 14
85 #define MPEG_NEED_DATA 100
86 #define MPEG_TRACK_CHANGE 101
87 #define MPEG_SAVE_DATA 102
88 #define MPEG_STOP_DONE 103
89 #define MPEG_PRERECORDING_TICK 104
91 /* indicator for MPEG_NEED_DATA */
92 #define GENERATE_UNBUFFER_EVENTS 1
94 /* list of tracks in memory */
95 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
96 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
98 struct trackdata
100 struct mp3entry id3;
101 int mempos;
102 int load_ahead_index;
103 bool event_sent;
106 static struct trackdata trackdata[MAX_TRACK_ENTRIES];
108 static unsigned int current_track_counter = 0;
109 static unsigned int last_track_counter = 0;
111 /* Play time of the previous track */
112 unsigned long prev_track_elapsed;
114 #ifndef SIMULATOR
115 static int track_read_idx = 0;
116 static int track_write_idx = 0;
117 #endif /* !SIMULATOR */
119 /* Callback function to call when current track has really changed. */
120 void (*track_changed_callback)(struct mp3entry *id3) = NULL;
121 void (*track_buffer_callback)(struct mp3entry *id3, bool last_track);
122 void (*track_unbuffer_callback)(struct mp3entry *id3, bool last_track);
124 /* Cuesheet callback */
125 static bool (*cuesheet_callback)(const char *filename) = NULL;
127 static const char mpeg_thread_name[] = "mpeg";
128 static unsigned int mpeg_errno;
130 static bool playing = false; /* We are playing an MP3 stream */
131 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
132 static bool paused; /* playback is paused */
134 #ifdef SIMULATOR
135 static char mpeg_stack[DEFAULT_STACK_SIZE];
136 static struct mp3entry taginfo;
138 #else /* !SIMULATOR */
139 static struct event_queue mpeg_queue;
140 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
142 static int audiobuflen;
143 static int audiobuf_write;
144 static int audiobuf_swapwrite;
145 static int audiobuf_read;
147 static int mpeg_file;
149 static bool play_pending; /* We are about to start playing */
150 static bool play_pending_track_change; /* When starting play we're starting a new file */
151 static bool filling; /* We are filling the buffer with data from disk */
152 static bool dma_underrun; /* True when the DMA has stopped because of
153 slow disk reading (read error, shaking) */
154 static bool mpeg_stop_done;
156 static int last_dma_tick = 0;
157 static int last_dma_chunk_size;
159 static long low_watermark; /* Dynamic low watermark level */
160 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
161 static long lowest_watermark_level; /* Debug value to observe the buffer
162 usage */
163 #if CONFIG_CODEC == MAS3587F
164 static char recording_filename[MAX_PATH]; /* argument to thread */
165 static char delayed_filename[MAX_PATH]; /* internal copy of above */
167 static char xing_buffer[MAX_XING_HEADER_SIZE];
169 static bool init_recording_done;
170 static bool init_playback_done;
171 static bool prerecording; /* True if prerecording is enabled */
172 static bool is_prerecording; /* True if we are prerecording */
173 static bool is_recording; /* We are recording */
175 static enum {
176 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
177 BUFFER_FULL,
178 NEW_FILE,
179 STOP_RECORDING
180 } saving_status;
182 static int rec_frequency_index; /* For create_xing_header() calls */
183 static int rec_version_index; /* For create_xing_header() calls */
185 struct prerecord_info {
186 int mempos;
187 unsigned long framecount;
190 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
191 static int prerecord_index; /* Current index in the prerecord buffer */
192 static int prerecording_max_seconds; /* Max number of seconds to store */
193 static int prerecord_count; /* Number of seconds in the prerecord buffer */
194 static int prerecord_timeout; /* The tick count of the next prerecord data
195 store */
197 unsigned long record_start_time; /* Value of current_tick when recording
198 was started */
199 unsigned long pause_start_time; /* Value of current_tick when pause was
200 started */
201 static unsigned long last_rec_time;
202 static unsigned long num_rec_bytes;
203 static unsigned long last_rec_bytes;
204 static unsigned long frame_count_start;
205 static unsigned long frame_count_end;
206 static unsigned long saved_header = 0;
208 /* Shadow MAS registers */
209 unsigned long shadow_encoder_control = 0;
210 #endif /* CONFIG_CODEC == MAS3587F */
212 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
213 unsigned long shadow_io_control_main = 0;
214 unsigned long shadow_soft_mute = 0;
215 unsigned shadow_codec_reg0;
216 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
218 #ifdef HAVE_RECORDING
219 const unsigned char empty_id3_header[] =
221 'I', 'D', '3', 0x03, 0x00, 0x00,
222 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
224 #endif /* HAVE_RECORDING */
227 static int get_unplayed_space(void);
228 static int get_playable_space(void);
229 static int get_unswapped_space(void);
230 #endif /* !SIMULATOR */
232 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
233 static void init_recording(void);
234 static void prepend_header(void);
235 static void update_header(void);
236 static void start_prerecording(void);
237 static void start_recording(void);
238 static void stop_recording(void);
239 static int get_unsaved_space(void);
240 static void pause_recording(void);
241 static void resume_recording(void);
242 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
245 #ifndef SIMULATOR
246 static int num_tracks_in_memory(void)
248 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
251 #ifdef DEBUG_TAGS
252 static void debug_tags(void)
254 int i;
256 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
258 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
260 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
261 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
263 #else /* !DEBUG_TAGS */
264 #define debug_tags()
265 #endif /* !DEBUG_TAGS */
267 static void remove_current_tag(void)
269 if(num_tracks_in_memory() > 0)
271 /* First move the index, so nobody tries to access the tag */
272 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
273 debug_tags();
275 else
277 DEBUGF("remove_current_tag: no tracks to remove\n");
281 static void remove_all_non_current_tags(void)
283 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
284 debug_tags();
287 static void remove_all_tags(void)
289 track_write_idx = track_read_idx;
291 debug_tags();
294 static struct trackdata *get_trackdata(int offset)
296 if(offset >= num_tracks_in_memory())
297 return NULL;
298 else
299 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
301 #endif /* !SIMULATOR */
303 /***********************************************************************/
304 /* audio event handling */
306 #define MAX_EVENT_HANDLERS 10
307 struct event_handlers_table
309 AUDIO_EVENT_HANDLER handler;
310 unsigned short mask;
312 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
313 static int event_handlers_count = 0;
315 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
317 if (event_handlers_count < MAX_EVENT_HANDLERS)
319 event_handlers[event_handlers_count].handler = handler;
320 event_handlers[event_handlers_count].mask = mask;
321 event_handlers_count++;
325 /* dispatch calls each handler in the order registered and returns after some
326 handler actually handles the event (the event is assumed to no longer be valid
327 after this, due to the handler changing some condition); returns true if someone
328 handled the event, which is expected to cause the caller to skip its own handling
329 of the event */
330 #ifndef SIMULATOR
331 static bool audio_dispatch_event(unsigned short event, unsigned long data)
333 int i = 0;
334 for(i=0; i < event_handlers_count; i++)
336 if ( event_handlers[i].mask & event )
338 int rc = event_handlers[i].handler(event, data);
339 if ( rc == AUDIO_EVENT_RC_HANDLED )
340 return true;
343 return false;
345 #endif
347 /***********************************************************************/
349 static void set_elapsed(struct mp3entry* id3)
351 if ( id3->vbr ) {
352 if ( id3->has_toc ) {
353 /* calculate elapsed time using TOC */
354 int i;
355 unsigned int remainder, plen, relpos, nextpos;
357 /* find wich percent we're at */
358 for (i=0; i<100; i++ )
360 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
362 break;
366 i--;
367 if (i < 0)
368 i = 0;
370 relpos = id3->toc[i];
372 if (i < 99)
374 nextpos = id3->toc[i+1];
376 else
378 nextpos = 256;
381 remainder = id3->offset - (relpos * (id3->filesize / 256));
383 /* set time for this percent (divide before multiply to prevent
384 overflow on long files. loss of precision is negligible on
385 short files) */
386 id3->elapsed = i * (id3->length / 100);
388 /* calculate remainder time */
389 plen = (nextpos - relpos) * (id3->filesize / 256);
390 id3->elapsed += (((remainder * 100) / plen) *
391 (id3->length / 10000));
393 else {
394 /* no TOC exists. set a rough estimate using average bitrate */
395 int tpk = id3->length / (id3->filesize / 1024);
396 id3->elapsed = id3->offset / 1024 * tpk;
399 else
400 /* constant bitrate, use exact calculation */
401 id3->elapsed = id3->offset / (id3->bitrate / 8);
404 int audio_get_file_pos(void)
406 int pos = -1;
407 struct mp3entry *id3 = audio_current_track();
409 if (id3->vbr)
411 if (id3->has_toc)
413 /* Use the TOC to find the new position */
414 unsigned int percent, remainder;
415 int curtoc, nexttoc, plen;
417 percent = (id3->elapsed*100)/id3->length;
418 if (percent > 99)
419 percent = 99;
421 curtoc = id3->toc[percent];
423 if (percent < 99)
424 nexttoc = id3->toc[percent+1];
425 else
426 nexttoc = 256;
428 pos = (id3->filesize/256)*curtoc;
430 /* Use the remainder to get a more accurate position */
431 remainder = (id3->elapsed*100)%id3->length;
432 remainder = (remainder*100)/id3->length;
433 plen = (nexttoc - curtoc)*(id3->filesize/256);
434 pos += (plen/100)*remainder;
436 else
438 /* No TOC exists, estimate the new position */
439 pos = (id3->filesize / (id3->length / 1000)) *
440 (id3->elapsed / 1000);
443 else if (id3->bitrate)
444 pos = id3->elapsed * (id3->bitrate / 8);
445 else
447 return -1;
450 if (pos >= (int)(id3->filesize - id3->id3v1len))
452 /* Don't seek right to the end of the file so that we can
453 transition properly to the next song */
454 pos = id3->filesize - id3->id3v1len - 1;
456 else if (pos < (int)id3->first_frame_offset)
458 /* skip past id3v2 tag and other leading garbage */
459 pos = id3->first_frame_offset;
461 return pos;
464 unsigned long mpeg_get_last_header(void)
466 #ifdef SIMULATOR
467 return 0;
468 #else /* !SIMULATOR */
469 unsigned long tmp[2];
471 /* Read the frame data from the MAS and reconstruct it with the
472 frame sync and all */
473 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
474 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
475 #endif /* !SIMULATOR */
478 void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3,
479 bool last_track))
481 track_buffer_callback = handler;
484 void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
485 bool last_track))
487 track_unbuffer_callback = handler;
490 void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3))
492 track_changed_callback = handler;
495 void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
497 cuesheet_callback = handler;
500 #ifndef SIMULATOR
501 /* Send callback events to notify about removing old tracks. */
502 static void generate_unbuffer_events(void)
504 int i;
505 int event_count = 0;
506 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
507 int cur_idx = track_write_idx;
509 for (i = 0; i < numentries; i++)
511 if (trackdata[cur_idx].event_sent)
512 event_count++;
514 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
517 cur_idx = track_write_idx;
519 for (i = 0; i < numentries; i++)
521 /* Send an event to notify that track has finished. */
522 if (trackdata[cur_idx].event_sent)
524 event_count--;
525 if (track_unbuffer_callback)
526 track_unbuffer_callback(&trackdata[cur_idx].id3,
527 event_count == 0);
528 trackdata[cur_idx].event_sent = false;
530 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
534 /* Send callback events to notify about new tracks. */
535 static void generate_postbuffer_events(void)
537 int i;
538 int event_count = 0;
539 int numentries = num_tracks_in_memory();
540 int cur_idx = track_read_idx;
542 for (i = 0; i < numentries; i++)
544 if (!trackdata[cur_idx].event_sent)
545 event_count++;
547 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
550 cur_idx = track_read_idx;
552 for (i = 0; i < numentries; i++)
554 if (!trackdata[cur_idx].event_sent)
556 event_count--;
557 if (track_buffer_callback)
558 track_buffer_callback(&trackdata[cur_idx].id3,
559 event_count == 0);
560 trackdata[cur_idx].event_sent = true;
562 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
566 static void recalculate_watermark(int bitrate)
568 int bytes_per_sec;
569 int time = ata_spinup_time;
571 /* A bitrate of 0 probably means empty VBR header. We play safe
572 and set a high threshold */
573 if(bitrate == 0)
574 bitrate = 320;
576 bytes_per_sec = bitrate * 1000 / 8;
578 if(time)
580 /* No drive spins up faster than 3.5s */
581 if(time < 350)
582 time = 350;
584 time = time * 3;
585 low_watermark = ((low_watermark_margin * HZ + time) *
586 bytes_per_sec) / HZ;
588 else
590 low_watermark = MPEG_LOW_WATER;
594 #ifndef HAVE_FLASH_STORAGE
595 void audio_set_buffer_margin(int seconds)
597 low_watermark_margin = seconds;
599 #endif
601 void audio_get_debugdata(struct audio_debug *dbgdata)
603 dbgdata->audiobuflen = audiobuflen;
604 dbgdata->audiobuf_write = audiobuf_write;
605 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
606 dbgdata->audiobuf_read = audiobuf_read;
608 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
610 #if CONFIG_CPU == SH7034
611 dbgdata->dma_on = (SCR0 & 0x80) != 0;
612 #endif
613 dbgdata->playing = playing;
614 dbgdata->play_pending = play_pending;
615 dbgdata->is_playing = is_playing;
616 dbgdata->filling = filling;
617 dbgdata->dma_underrun = dma_underrun;
619 dbgdata->unplayed_space = get_unplayed_space();
620 dbgdata->playable_space = get_playable_space();
621 dbgdata->unswapped_space = get_unswapped_space();
623 dbgdata->low_watermark_level = low_watermark;
624 dbgdata->lowest_watermark_level = lowest_watermark_level;
627 #ifdef DEBUG
628 static void dbg_timer_start(void)
630 /* We are using timer 2 */
632 TSTR &= ~0x04; /* Stop the timer */
633 TSNC &= ~0x04; /* No synchronization */
634 TMDR &= ~0x44; /* Operate normally */
636 TCNT2 = 0; /* Start counting at 0 */
637 TCR2 = 0x03; /* Sysclock/8 */
639 TSTR |= 0x04; /* Start timer 2 */
642 static int dbg_cnt2us(unsigned int cnt)
644 return (cnt * 10000) / (FREQ/800);
646 #endif /* DEBUG */
648 static int get_unplayed_space(void)
650 int space = audiobuf_write - audiobuf_read;
651 if (space < 0)
652 space += audiobuflen;
653 return space;
656 static int get_playable_space(void)
658 int space = audiobuf_swapwrite - audiobuf_read;
659 if (space < 0)
660 space += audiobuflen;
661 return space;
664 static int get_unplayed_space_current_song(void)
666 int space;
668 if (num_tracks_in_memory() > 1)
670 space = get_trackdata(1)->mempos - audiobuf_read;
672 else
674 space = audiobuf_write - audiobuf_read;
677 if (space < 0)
678 space += audiobuflen;
680 return space;
683 static int get_unswapped_space(void)
685 int space = audiobuf_write - audiobuf_swapwrite;
686 if (space < 0)
687 space += audiobuflen;
688 return space;
691 #if CONFIG_CODEC == MAS3587F
692 static int get_unsaved_space(void)
694 int space = audiobuf_write - audiobuf_read;
695 if (space < 0)
696 space += audiobuflen;
697 return space;
700 static void drain_dma_buffer(void)
702 while (PBDRH & 0x40)
704 xor_b(0x08, &PADRH);
706 while (PBDRH & 0x80);
708 xor_b(0x08, &PADRH);
710 while (!(PBDRH & 0x80));
714 #ifdef DEBUG
715 static long timing_info_index = 0;
716 static long timing_info[1024];
717 #endif /* DEBUG */
719 void rec_tick (void) __attribute__ ((section (".icode")));
720 void rec_tick(void)
722 int i;
723 int delay;
724 char data;
726 if(is_recording && (PBDRH & 0x40))
728 #ifdef DEBUG
729 timing_info[timing_info_index++] = current_tick;
730 TCNT2 = 0;
731 #endif /* DEBUG */
732 /* Note: Although this loop is run in interrupt context, further
733 * optimisation will do no good. The MAS would then deliver bad
734 * frames occasionally, as observed in extended experiments. */
735 i = 0;
736 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
738 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
740 delay = 100;
741 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
743 if (--delay <= 0) /* Bail out if we have to wait too long */
744 { /* i.e. the MAS doesn't want to talk to us */
745 xor_b(0x08, &PADRH); /* Set PR inactive */
746 goto transfer_end; /* and get out of here */
750 data = *(unsigned char *)0x04000000; /* read data byte */
752 xor_b(0x08, &PADRH); /* Set PR inactive */
754 audiobuf[audiobuf_write++] = data;
756 if (audiobuf_write >= audiobuflen)
757 audiobuf_write = 0;
759 i++;
761 transfer_end:
763 #ifdef DEBUG
764 timing_info[timing_info_index++] = TCNT2 + (i << 16);
765 timing_info_index &= 0x3ff;
766 #endif /* DEBUG */
768 num_rec_bytes += i;
770 if(is_prerecording)
772 if(TIME_AFTER(current_tick, prerecord_timeout))
774 prerecord_timeout = current_tick + HZ;
775 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
778 else
780 /* Signal to save the data if we are running out of buffer
781 space */
782 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
783 && saving_status == NOT_SAVING)
785 saving_status = BUFFER_FULL;
786 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
791 #endif /* CONFIG_CODEC == MAS3587F */
793 void playback_tick(void)
795 struct trackdata *ptd = get_trackdata(0);
796 if(ptd)
798 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
799 last_dma_tick = current_tick;
800 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
801 (unsigned long)ptd->id3.elapsed);
805 static void reset_mp3_buffer(void)
807 audiobuf_read = 0;
808 audiobuf_write = 0;
809 audiobuf_swapwrite = 0;
810 lowest_watermark_level = audiobuflen;
813 /* DMA transfer end interrupt callback */
814 static void transfer_end(unsigned char** ppbuf, size_t* psize)
816 if(playing && !paused)
818 int unplayed_space_left;
819 int space_until_end_of_buffer;
820 int track_offset = 1;
821 struct trackdata *track;
823 audiobuf_read += last_dma_chunk_size;
824 if(audiobuf_read >= audiobuflen)
825 audiobuf_read = 0;
827 /* First, check if we are on a track boundary */
828 if (num_tracks_in_memory() > 1)
830 if (audiobuf_read == get_trackdata(track_offset)->mempos)
832 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
834 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
835 track_offset++;
840 unplayed_space_left = get_unplayed_space();
842 space_until_end_of_buffer = audiobuflen - audiobuf_read;
844 if(!filling && unplayed_space_left < low_watermark)
846 filling = true;
847 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
850 if(unplayed_space_left)
852 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
853 last_dma_chunk_size = MIN(last_dma_chunk_size,
854 space_until_end_of_buffer);
856 /* several tracks loaded? */
857 track = get_trackdata(track_offset);
858 if(track)
860 /* will we move across the track boundary? */
861 if (( audiobuf_read < track->mempos ) &&
862 ((audiobuf_read+last_dma_chunk_size) >
863 track->mempos ))
865 /* Make sure that we end exactly on the boundary */
866 last_dma_chunk_size = track->mempos - audiobuf_read;
870 *psize = last_dma_chunk_size & 0xffff;
871 *ppbuf = audiobuf + audiobuf_read;
872 track = get_trackdata(0);
873 if(track)
874 track->id3.offset += last_dma_chunk_size;
876 /* Update the watermark debug level */
877 if(unplayed_space_left < lowest_watermark_level)
878 lowest_watermark_level = unplayed_space_left;
880 else
882 /* Check if the end of data is because of a hard disk error.
883 If there is an open file handle, we are still playing music.
884 If not, the last file has been loaded, and the file handle is
885 closed. */
886 if(mpeg_file >= 0)
888 /* Update the watermark debug level */
889 if(unplayed_space_left < lowest_watermark_level)
890 lowest_watermark_level = unplayed_space_left;
892 DEBUGF("DMA underrun.\n");
893 dma_underrun = true;
895 else
897 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
899 DEBUGF("No more MP3 data. Stopping.\n");
900 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
901 playing = false;
904 *psize = 0; /* no more transfer */
909 static struct trackdata *add_track_to_tag_list(const char *filename)
911 struct trackdata *track;
913 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
915 DEBUGF("Tag memory is full\n");
916 return NULL;
919 track = &trackdata[track_write_idx];
921 /* grab id3 tag of new file and
922 remember where in memory it starts */
923 if(mp3info(&track->id3, filename))
925 DEBUGF("Bad mp3\n");
926 return NULL;
928 track->mempos = audiobuf_write;
929 track->id3.elapsed = 0;
930 #ifdef HAVE_LCD_BITMAP
931 if (track->id3.title)
932 lcd_getstringsize(track->id3.title, NULL, NULL);
933 if (track->id3.artist)
934 lcd_getstringsize(track->id3.artist, NULL, NULL);
935 if (track->id3.album)
936 lcd_getstringsize(track->id3.album, NULL, NULL);
937 #endif
938 if (cuesheet_callback)
939 if (cuesheet_callback(filename))
940 track->id3.cuesheet_type = 1;
942 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
943 debug_tags();
944 return track;
947 static int new_file(int steps)
949 int max_steps = playlist_amount();
950 int start = 0;
951 int i;
952 struct trackdata *track;
954 /* Find out how many steps to advance. The load_ahead_index field tells
955 us how many playlist entries it had to skip to get to a valid one.
956 We add those together to find out where to start. */
957 if(steps > 0 && num_tracks_in_memory() > 1)
959 /* Begin with the song after the currently playing one */
960 i = 1;
961 while((track = get_trackdata(i++)))
963 start += track->load_ahead_index;
967 do {
968 char *trackname;
970 trackname = playlist_peek( start + steps );
971 if ( !trackname )
972 return -1;
974 DEBUGF("Loading %s\n", trackname);
976 mpeg_file = open(trackname, O_RDONLY);
977 if(mpeg_file < 0) {
978 DEBUGF("Couldn't open file: %s\n",trackname);
979 if(steps < 0)
980 steps--;
981 else
982 steps++;
984 else
986 struct trackdata *track = add_track_to_tag_list(trackname);
988 if(!track)
990 /* Bad mp3 file */
991 if(steps < 0)
992 steps--;
993 else
994 steps++;
995 close(mpeg_file);
996 mpeg_file = -1;
998 else
1000 /* skip past id3v2 tag */
1001 lseek(mpeg_file,
1002 track->id3.first_frame_offset,
1003 SEEK_SET);
1004 track->id3.index = steps;
1005 track->load_ahead_index = steps;
1006 track->id3.offset = 0;
1008 if(track->id3.vbr)
1009 /* Average bitrate * 1.5 */
1010 recalculate_watermark(
1011 (track->id3.bitrate * 3) / 2);
1012 else
1013 recalculate_watermark(
1014 track->id3.bitrate);
1019 /* Bail out if no file could be opened */
1020 if(abs(steps) > max_steps)
1021 return -1;
1022 } while ( mpeg_file < 0 );
1024 return 0;
1027 static void stop_playing(void)
1029 struct trackdata *track;
1031 /* Stop the current stream */
1032 mp3_play_stop();
1033 playing = false;
1034 filling = false;
1036 track = get_trackdata(0);
1037 if (track != NULL)
1038 prev_track_elapsed = track->id3.elapsed;
1040 if(mpeg_file >= 0)
1041 close(mpeg_file);
1042 mpeg_file = -1;
1043 remove_all_tags();
1044 generate_unbuffer_events();
1045 reset_mp3_buffer();
1048 static void end_current_track(void) {
1049 struct trackdata *track;
1051 play_pending = false;
1052 playing = false;
1053 mp3_play_pause(false);
1055 track = get_trackdata(0);
1056 if (track != NULL)
1057 prev_track_elapsed = track->id3.elapsed;
1059 reset_mp3_buffer();
1060 remove_all_tags();
1061 generate_unbuffer_events();
1063 if(mpeg_file >= 0)
1064 close(mpeg_file);
1067 /* Is this a really the end of playback or is a new playlist starting */
1068 static void check_playlist_end(int direction)
1070 /* Use the largest possible step size to account for skipped tracks */
1071 int steps = playlist_amount();
1073 if (direction < 0)
1074 steps = -steps;
1076 if (playlist_next(steps) < 0)
1077 is_playing = false;
1080 static void update_playlist(void)
1082 if (num_tracks_in_memory() > 0)
1084 struct trackdata *track = get_trackdata(0);
1085 track->id3.index = playlist_next(track->id3.index);
1087 else
1089 /* End of playlist? */
1090 check_playlist_end(1);
1093 playlist_update_resume_info(audio_current_track());
1096 static void track_change(void)
1098 DEBUGF("Track change\n");
1100 struct trackdata *track = get_trackdata(0);
1101 prev_track_elapsed = track->id3.elapsed;
1103 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1104 /* Reset the AVC */
1105 sound_set_avc(-1);
1106 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1108 if (num_tracks_in_memory() > 0)
1110 remove_current_tag();
1111 if (track_changed_callback)
1112 track_changed_callback(audio_current_track());
1113 update_playlist();
1116 current_track_counter++;
1119 unsigned long audio_prev_elapsed(void)
1121 return prev_track_elapsed;
1124 #ifdef DEBUG
1125 void hexdump(const unsigned char *buf, int len)
1127 int i;
1129 for(i = 0;i < len;i++)
1131 if(i && (i & 15) == 0)
1133 DEBUGF("\n");
1135 DEBUGF("%02x ", buf[i]);
1137 DEBUGF("\n");
1139 #endif /* DEBUG */
1141 static void start_playback_if_ready(void)
1143 int playable_space;
1145 playable_space = audiobuf_swapwrite - audiobuf_read;
1146 if(playable_space < 0)
1147 playable_space += audiobuflen;
1149 /* See if we have started playing yet. If not, do it. */
1150 if(play_pending || dma_underrun)
1152 /* If the filling has stopped, and we still haven't reached
1153 the watermark, the file must be smaller than the
1154 watermark. We must still play it. */
1155 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1156 !filling || dma_underrun)
1158 DEBUGF("P\n");
1159 if (play_pending) /* don't do this when recovering from DMA underrun */
1161 generate_postbuffer_events(); /* signal first track as buffered */
1162 if (play_pending_track_change)
1164 play_pending_track_change = false;
1165 if(track_changed_callback)
1166 track_changed_callback(audio_current_track());
1168 play_pending = false;
1170 playing = true;
1172 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1173 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1174 dma_underrun = false;
1176 if (!paused)
1178 last_dma_tick = current_tick;
1179 mp3_play_pause(true);
1182 /* Tell ourselves that we need more data */
1183 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1188 static bool swap_one_chunk(void)
1190 int free_space_left;
1191 int amount_to_swap;
1193 free_space_left = get_unswapped_space();
1195 if(free_space_left == 0 && !play_pending)
1196 return false;
1198 /* Swap in larger chunks when the user is waiting for the playback
1199 to start, or when there is dangerously little playable data left */
1200 if(play_pending)
1201 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1202 else
1204 if(get_playable_space() < low_watermark)
1205 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1206 free_space_left);
1207 else
1208 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1211 if(audiobuf_write < audiobuf_swapwrite)
1212 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1213 amount_to_swap);
1214 else
1215 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1216 amount_to_swap);
1218 bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap);
1220 audiobuf_swapwrite += amount_to_swap;
1221 if(audiobuf_swapwrite >= audiobuflen)
1223 audiobuf_swapwrite = 0;
1226 return true;
1229 static void mpeg_thread(void)
1231 static int pause_tick = 0;
1232 static unsigned int pause_track = 0;
1233 struct event ev;
1234 int len;
1235 int free_space_left;
1236 int unplayed_space_left;
1237 int amount_to_read;
1238 int t1, t2;
1239 int start_offset;
1240 #if CONFIG_CODEC == MAS3587F
1241 int amount_to_save;
1242 int save_endpos = 0;
1243 int rc;
1244 int level;
1245 long offset;
1246 #endif /* CONFIG_CODEC == MAS3587F */
1248 is_playing = false;
1249 play_pending = false;
1250 playing = false;
1251 mpeg_file = -1;
1253 while(1)
1255 #if CONFIG_CODEC == MAS3587F
1256 if(mpeg_mode == MPEG_DECODER)
1258 #endif /* CONFIG_CODEC == MAS3587F */
1259 yield();
1261 /* Swap if necessary, and don't block on the queue_wait() */
1262 if(swap_one_chunk())
1264 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1266 else if (playing)
1268 /* periodically update resume info */
1269 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1271 else
1273 DEBUGF("S R:%x W:%x SW:%x\n",
1274 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1275 queue_wait(&mpeg_queue, &ev);
1278 start_playback_if_ready();
1280 switch(ev.id)
1282 case MPEG_PLAY:
1283 DEBUGF("MPEG_PLAY\n");
1285 #if CONFIG_TUNER
1286 /* Silence the A/D input, it may be on because the radio
1287 may be playing */
1288 mas_codec_writereg(6, 0x0000);
1289 #endif /* CONFIG_TUNER */
1291 /* Stop the current stream */
1292 paused = false;
1293 end_current_track();
1295 if ( new_file(0) == -1 )
1297 is_playing = false;
1298 track_change();
1299 break;
1302 start_offset = (int)ev.data;
1304 /* mid-song resume? */
1305 if (start_offset) {
1306 struct mp3entry* id3 = &get_trackdata(0)->id3;
1307 lseek(mpeg_file, start_offset, SEEK_SET);
1308 id3->offset = start_offset;
1309 set_elapsed(id3);
1311 else {
1312 /* skip past id3v2 tag */
1313 lseek(mpeg_file,
1314 get_trackdata(0)->id3.first_frame_offset,
1315 SEEK_SET);
1319 /* Make it read more data */
1320 filling = true;
1321 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1323 /* Tell the file loading code that we want to start playing
1324 as soon as we have some data */
1325 play_pending = true;
1326 play_pending_track_change = true;
1328 update_playlist();
1329 current_track_counter++;
1330 break;
1332 case MPEG_STOP:
1333 DEBUGF("MPEG_STOP\n");
1334 is_playing = false;
1335 paused = false;
1337 if (playing)
1338 playlist_update_resume_info(audio_current_track());
1340 stop_playing();
1341 mpeg_stop_done = true;
1342 break;
1344 case MPEG_PAUSE:
1345 DEBUGF("MPEG_PAUSE\n");
1346 /* Stop the current stream */
1347 if (playing)
1348 playlist_update_resume_info(audio_current_track());
1349 paused = true;
1350 playing = false;
1351 pause_tick = current_tick;
1352 pause_track = current_track_counter;
1353 mp3_play_pause(false);
1354 break;
1356 case MPEG_RESUME:
1357 DEBUGF("MPEG_RESUME\n");
1358 /* Continue the current stream */
1359 paused = false;
1360 if (!play_pending)
1362 playing = true;
1363 if ( current_track_counter == pause_track )
1364 last_dma_tick += current_tick - pause_tick;
1365 else
1366 last_dma_tick = current_tick;
1367 pause_tick = 0;
1368 mp3_play_pause(true);
1370 break;
1372 case MPEG_NEXT:
1373 DEBUGF("MPEG_NEXT\n");
1374 /* is next track in ram? */
1375 if ( num_tracks_in_memory() > 1 ) {
1376 int unplayed_space_left, unswapped_space_left;
1378 /* stop the current stream */
1379 play_pending = false;
1380 playing = false;
1381 mp3_play_pause(false);
1383 track_change();
1384 audiobuf_read = get_trackdata(0)->mempos;
1385 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1386 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1387 dma_underrun = false;
1388 last_dma_tick = current_tick;
1390 unplayed_space_left = get_unplayed_space();
1391 unswapped_space_left = get_unswapped_space();
1393 /* should we start reading more data? */
1394 if(!filling && (unplayed_space_left < low_watermark)) {
1395 filling = true;
1396 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1397 play_pending = true;
1398 } else if(unswapped_space_left &&
1399 unswapped_space_left > unplayed_space_left) {
1400 /* Stop swapping the data from the previous file */
1401 audiobuf_swapwrite = audiobuf_read;
1402 play_pending = true;
1403 } else {
1404 playing = true;
1405 if (!paused)
1406 mp3_play_pause(true);
1409 else {
1410 if (!playlist_check(1))
1411 break;
1413 /* stop the current stream */
1414 end_current_track();
1416 if (new_file(1) < 0) {
1417 DEBUGF("No more files to play\n");
1418 filling = false;
1420 check_playlist_end(1);
1421 current_track_counter++;
1422 } else {
1423 /* Make it read more data */
1424 filling = true;
1425 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1427 /* Tell the file loading code that we want
1428 to start playing as soon as we have some data */
1429 play_pending = true;
1430 play_pending_track_change = true;
1432 update_playlist();
1433 current_track_counter++;
1436 break;
1438 case MPEG_PREV: {
1439 DEBUGF("MPEG_PREV\n");
1441 if (!playlist_check(-1))
1442 break;
1444 /* stop the current stream */
1445 end_current_track();
1447 /* Open the next file */
1448 if (new_file(-1) < 0) {
1449 DEBUGF("No more files to play\n");
1450 filling = false;
1452 check_playlist_end(-1);
1453 current_track_counter++;
1454 } else {
1455 /* Make it read more data */
1456 filling = true;
1457 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1459 /* Tell the file loading code that we want to
1460 start playing as soon as we have some data */
1461 play_pending = true;
1462 play_pending_track_change = true;
1464 update_playlist();
1465 current_track_counter++;
1467 break;
1470 case MPEG_FF_REWIND: {
1471 struct mp3entry *id3 = audio_current_track();
1472 unsigned int oldtime = id3->elapsed;
1473 unsigned int newtime = (unsigned int)ev.data;
1474 int curpos, newpos, diffpos;
1475 DEBUGF("MPEG_FF_REWIND\n");
1477 id3->elapsed = newtime;
1479 newpos = audio_get_file_pos();
1480 if(newpos < 0)
1482 id3->elapsed = oldtime;
1483 break;
1486 if (mpeg_file >= 0)
1487 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1488 else
1489 curpos = id3->filesize;
1491 if (num_tracks_in_memory() > 1)
1493 /* We have started loading other tracks that need to be
1494 accounted for */
1495 struct trackdata *track;
1496 int i = 0;
1498 while((track = get_trackdata(i++)))
1500 curpos += track->id3.filesize;
1504 diffpos = curpos - newpos;
1506 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1508 int unplayed_space_left, unswapped_space_left;
1510 /* We are changing to a position that's already in
1511 memory, so we just move the DMA read pointer. */
1512 audiobuf_read = audiobuf_write - diffpos;
1513 if (audiobuf_read < 0)
1515 audiobuf_read += audiobuflen;
1518 unplayed_space_left = get_unplayed_space();
1519 unswapped_space_left = get_unswapped_space();
1521 /* If unswapped_space_left is larger than
1522 unplayed_space_left, it means that the swapwrite pointer
1523 hasn't yet advanced up to the new location of the read
1524 pointer. We just move it, there is no need to swap
1525 data that won't be played anyway. */
1527 if (unswapped_space_left > unplayed_space_left)
1529 DEBUGF("Moved swapwrite\n");
1530 audiobuf_swapwrite = audiobuf_read;
1531 play_pending = true;
1534 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1536 /* We need to load more data before starting */
1537 filling = true;
1538 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1539 play_pending = true;
1541 else
1543 /* resume will start at new position */
1544 last_dma_chunk_size =
1545 MIN(0x2000, get_unplayed_space_current_song());
1546 mp3_play_data(audiobuf + audiobuf_read,
1547 last_dma_chunk_size, transfer_end);
1548 dma_underrun = false;
1551 else
1553 /* Move to the new position in the file and start
1554 loading data */
1555 reset_mp3_buffer();
1557 if (num_tracks_in_memory() > 1)
1559 /* We have to reload the current track */
1560 close(mpeg_file);
1561 remove_all_non_current_tags();
1562 generate_unbuffer_events();
1563 mpeg_file = -1;
1566 if (mpeg_file < 0)
1568 mpeg_file = open(id3->path, O_RDONLY);
1569 if (mpeg_file < 0)
1571 id3->elapsed = oldtime;
1572 break;
1576 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1578 id3->elapsed = oldtime;
1579 break;
1582 filling = true;
1583 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1585 /* Tell the file loading code that we want to start playing
1586 as soon as we have some data */
1587 play_pending = true;
1590 id3->offset = newpos;
1592 break;
1595 case MPEG_FLUSH_RELOAD: {
1596 int numtracks = num_tracks_in_memory();
1597 bool reload_track = false;
1599 if (numtracks > 1)
1601 /* Reset the buffer */
1602 audiobuf_write = get_trackdata(1)->mempos;
1604 /* Reset swapwrite unless we're still swapping current
1605 track */
1606 if (get_unplayed_space() <= get_playable_space())
1607 audiobuf_swapwrite = audiobuf_write;
1609 close(mpeg_file);
1610 remove_all_non_current_tags();
1611 generate_unbuffer_events();
1612 mpeg_file = -1;
1613 reload_track = true;
1615 else if (numtracks == 1 && mpeg_file < 0)
1617 reload_track = true;
1620 if(reload_track && new_file(1) >= 0)
1622 /* Tell ourselves that we want more data */
1623 filling = true;
1624 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1627 break;
1630 case MPEG_NEED_DATA:
1631 free_space_left = audiobuf_read - audiobuf_write;
1633 /* We interpret 0 as "empty buffer" */
1634 if(free_space_left <= 0)
1635 free_space_left += audiobuflen;
1637 unplayed_space_left = audiobuflen - free_space_left;
1639 /* Make sure that we don't fill the entire buffer */
1640 free_space_left -= MPEG_HIGH_WATER;
1642 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1643 generate_unbuffer_events();
1645 /* do we have any more buffer space to fill? */
1646 if(free_space_left <= 0)
1648 DEBUGF("0\n");
1649 filling = false;
1650 generate_postbuffer_events();
1651 ata_sleep();
1652 break;
1655 /* Read small chunks while we are below the low water mark */
1656 if(unplayed_space_left < low_watermark)
1657 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1658 free_space_left);
1659 else
1660 amount_to_read = free_space_left;
1662 /* Don't read more than until the end of the buffer */
1663 amount_to_read = MIN(audiobuflen - audiobuf_write,
1664 amount_to_read);
1665 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1666 amount_to_read = MIN(0x40000, amount_to_read);
1667 #elif MEM == 8
1668 amount_to_read = MIN(0x100000, amount_to_read);
1669 #endif
1671 /* Read as much mpeg data as we can fit in the buffer */
1672 if(mpeg_file >= 0)
1674 DEBUGF("R\n");
1675 t1 = current_tick;
1676 len = read(mpeg_file, audiobuf + audiobuf_write,
1677 amount_to_read);
1678 if(len > 0)
1680 t2 = current_tick;
1681 DEBUGF("time: %d\n", t2 - t1);
1682 DEBUGF("R: %x\n", len);
1684 /* Now make sure that we don't feed the MAS with ID3V1
1685 data */
1686 if (len < amount_to_read)
1688 int i;
1689 static const unsigned char tag[] = "TAG";
1690 int taglen = 128;
1691 int tagptr = audiobuf_write + len - 128;
1693 /* Really rare case: entire potential tag wasn't
1694 read in this call AND audiobuf_write < 128 */
1695 if (tagptr < 0)
1696 tagptr += audiobuflen;
1698 for(i = 0;i < 3;i++)
1700 if(tagptr >= audiobuflen)
1701 tagptr -= audiobuflen;
1703 if(audiobuf[tagptr] != tag[i])
1705 taglen = 0;
1706 break;
1709 tagptr++;
1712 if(taglen)
1714 /* Skip id3v1 tag */
1715 DEBUGF("Skipping ID3v1 tag\n");
1716 len -= taglen;
1718 /* In the very rare case when the entire tag
1719 wasn't read in this read() len will be < 0.
1720 Take care of this when changing the write
1721 pointer. */
1725 audiobuf_write += len;
1727 if (audiobuf_write < 0)
1728 audiobuf_write += audiobuflen;
1730 if(audiobuf_write >= audiobuflen)
1732 audiobuf_write = 0;
1733 DEBUGF("W\n");
1736 /* Tell ourselves that we want more data */
1737 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1739 else
1741 if(len < 0)
1743 DEBUGF("MPEG read error\n");
1746 close(mpeg_file);
1747 mpeg_file = -1;
1749 if(new_file(1) < 0)
1751 /* No more data to play */
1752 DEBUGF("No more files to play\n");
1753 filling = false;
1755 else
1757 /* Tell ourselves that we want more data */
1758 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1762 break;
1764 case MPEG_TRACK_CHANGE:
1765 track_change();
1766 break;
1768 #ifndef USB_NONE
1769 case SYS_USB_CONNECTED:
1770 is_playing = false;
1771 paused = false;
1772 stop_playing();
1774 /* Tell the USB thread that we are safe */
1775 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1776 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1778 /* Wait until the USB cable is extracted again */
1779 usb_wait_for_disconnect(&mpeg_queue);
1780 break;
1781 #endif /* !USB_NONE */
1783 #if CONFIG_CODEC == MAS3587F
1784 case MPEG_INIT_RECORDING:
1785 init_recording();
1786 init_recording_done = true;
1787 break;
1788 #endif /* CONFIG_CODEC == MAS3587F */
1790 case SYS_TIMEOUT:
1791 if (playing)
1792 playlist_update_resume_info(audio_current_track());
1793 break;
1795 #if CONFIG_CODEC == MAS3587F
1797 else
1799 queue_wait(&mpeg_queue, &ev);
1800 switch(ev.id)
1802 case MPEG_RECORD:
1803 if (is_prerecording)
1805 int startpos;
1807 /* Go back prerecord_count seconds in the buffer */
1808 startpos = prerecord_index - prerecord_count;
1809 if(startpos < 0)
1810 startpos += prerecording_max_seconds;
1812 /* Read the position data from the prerecord buffer */
1813 frame_count_start = prerecord_buffer[startpos].framecount;
1814 startpos = prerecord_buffer[startpos].mempos;
1816 DEBUGF("Start looking at address %x (%x)\n",
1817 audiobuf+startpos, startpos);
1819 saved_header = mpeg_get_last_header();
1821 mem_find_next_frame(startpos, &offset, 1800,
1822 saved_header);
1824 audiobuf_read = startpos + offset;
1825 if(audiobuf_read >= audiobuflen)
1826 audiobuf_read -= audiobuflen;
1828 DEBUGF("New audiobuf_read address: %x (%x)\n",
1829 audiobuf+audiobuf_read, audiobuf_read);
1831 level = set_irq_level(HIGHEST_IRQ_LEVEL);
1832 num_rec_bytes = get_unsaved_space();
1833 set_irq_level(level);
1835 else
1837 frame_count_start = 0;
1838 num_rec_bytes = 0;
1839 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1840 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1843 prepend_header();
1844 DEBUGF("Recording...\n");
1845 start_recording();
1847 /* Wait until at least one frame is encoded and get the
1848 frame header, for later use by the Xing header
1849 generation */
1850 sleep(HZ/5);
1851 saved_header = mpeg_get_last_header();
1853 /* delayed until buffer is saved, don't open yet */
1854 strcpy(delayed_filename, recording_filename);
1855 mpeg_file = -1;
1857 break;
1859 case MPEG_STOP:
1860 DEBUGF("MPEG_STOP\n");
1862 stop_recording();
1864 /* Save the remaining data in the buffer */
1865 save_endpos = audiobuf_write;
1866 saving_status = STOP_RECORDING;
1867 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1868 break;
1870 case MPEG_STOP_DONE:
1871 DEBUGF("MPEG_STOP_DONE\n");
1873 if (mpeg_file >= 0)
1874 close(mpeg_file);
1875 mpeg_file = -1;
1877 update_header();
1878 #ifdef DEBUG1
1880 int i;
1881 for(i = 0;i < 512;i++)
1883 DEBUGF("%d - %d us (%d bytes)\n",
1884 timing_info[i*2],
1885 (timing_info[i*2+1] & 0xffff) *
1886 10000 / 13824,
1887 timing_info[i*2+1] >> 16);
1890 #endif /* DEBUG1 */
1892 if (prerecording)
1894 start_prerecording();
1896 mpeg_stop_done = true;
1897 break;
1899 case MPEG_NEW_FILE:
1900 /* Bail out when a more important save is happening */
1901 if (saving_status > NEW_FILE)
1902 break;
1904 /* Make sure we have at least one complete frame
1905 in the buffer. If we haven't recorded a single
1906 frame within 200ms, the MAS is probably not recording
1907 anything, and we bail out. */
1908 amount_to_save = get_unsaved_space();
1909 if (amount_to_save < 1800)
1911 sleep(HZ/5);
1912 amount_to_save = get_unsaved_space();
1915 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1916 &frame_count_end, 1);
1918 last_rec_time = current_tick - record_start_time;
1919 record_start_time = current_tick;
1920 if (paused)
1921 pause_start_time = record_start_time;
1923 /* capture all values at one point */
1924 level = set_irq_level(HIGHEST_IRQ_LEVEL);
1925 save_endpos = audiobuf_write;
1926 last_rec_bytes = num_rec_bytes;
1927 num_rec_bytes = 0;
1928 set_irq_level(level);
1930 if (amount_to_save >= 1800)
1932 /* Now find a frame boundary to split at */
1933 save_endpos -= 1800;
1934 if (save_endpos < 0)
1935 save_endpos += audiobuflen;
1937 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1938 saved_header);
1939 if (!rc) /* No header found, save whole buffer */
1940 offset = 1800;
1942 save_endpos += offset;
1943 if (save_endpos >= audiobuflen)
1944 save_endpos -= audiobuflen;
1946 last_rec_bytes += offset - 1800;
1947 level = set_irq_level(HIGHEST_IRQ_LEVEL);
1948 num_rec_bytes += 1800 - offset;
1949 set_irq_level(level);
1952 saving_status = NEW_FILE;
1953 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1954 break;
1956 case MPEG_SAVE_DATA:
1957 if (saving_status == BUFFER_FULL)
1958 save_endpos = audiobuf_write;
1960 if (mpeg_file < 0) /* delayed file open */
1962 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT);
1964 if (mpeg_file < 0)
1965 panicf("recfile: %d", mpeg_file);
1968 amount_to_save = save_endpos - audiobuf_read;
1969 if (amount_to_save < 0)
1970 amount_to_save += audiobuflen;
1972 amount_to_save = MIN(amount_to_save,
1973 audiobuflen - audiobuf_read);
1974 #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */
1975 amount_to_save = MIN(0x40000, amount_to_save);
1976 #elif MEM == 8
1977 amount_to_save = MIN(0x100000, amount_to_save);
1978 #endif
1979 rc = write(mpeg_file, audiobuf + audiobuf_read,
1980 amount_to_save);
1981 if (rc < 0)
1983 if (errno == ENOSPC)
1985 mpeg_errno = AUDIOERR_DISK_FULL;
1986 stop_recording();
1987 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1988 /* will close the file */
1989 break;
1991 else
1992 panicf("rec wrt: %d", rc);
1995 audiobuf_read += amount_to_save;
1996 if (audiobuf_read >= audiobuflen)
1997 audiobuf_read = 0;
1999 if (audiobuf_read == save_endpos) /* all saved */
2001 switch (saving_status)
2003 case BUFFER_FULL:
2004 rc = fsync(mpeg_file);
2005 if (rc < 0)
2006 panicf("rec fls: %d", rc);
2007 ata_sleep();
2008 break;
2010 case NEW_FILE:
2011 /* Close the current file */
2012 rc = close(mpeg_file);
2013 if (rc < 0)
2014 panicf("rec cls: %d", rc);
2015 mpeg_file = -1;
2016 update_header();
2017 ata_sleep();
2019 /* copy new filename */
2020 strcpy(delayed_filename, recording_filename);
2021 prepend_header();
2022 frame_count_start = frame_count_end;
2023 break;
2025 case STOP_RECORDING:
2026 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2027 /* will close the file */
2028 break;
2030 default:
2031 break;
2033 saving_status = NOT_SAVING;
2035 else /* tell ourselves to save the next chunk */
2036 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2038 break;
2040 case MPEG_PRERECORDING_TICK:
2041 if(!is_prerecording)
2042 break;
2044 /* Store the write pointer every second */
2045 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2046 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2047 &prerecord_buffer[prerecord_index].framecount, 1);
2049 /* Wrap if necessary */
2050 if(++prerecord_index == prerecording_max_seconds)
2051 prerecord_index = 0;
2053 /* Update the number of seconds recorded */
2054 if(prerecord_count < prerecording_max_seconds)
2055 prerecord_count++;
2056 break;
2058 case MPEG_INIT_PLAYBACK:
2059 /* Stop the prerecording */
2060 stop_recording();
2061 reset_mp3_buffer();
2062 mp3_play_init();
2063 init_playback_done = true;
2064 break;
2066 case MPEG_PAUSE_RECORDING:
2067 pause_recording();
2068 break;
2070 case MPEG_RESUME_RECORDING:
2071 resume_recording();
2072 break;
2074 case SYS_USB_CONNECTED:
2075 /* We can safely go to USB mode if no recording
2076 is taking place */
2077 if((!is_recording || is_prerecording) && mpeg_stop_done)
2079 /* Even if we aren't recording, we still call this
2080 function, to put the MAS in monitoring mode,
2081 to save power. */
2082 stop_recording();
2084 /* Tell the USB thread that we are safe */
2085 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2086 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2088 /* Wait until the USB cable is extracted again */
2089 usb_wait_for_disconnect(&mpeg_queue);
2091 break;
2094 #endif /* CONFIG_CODEC == MAS3587F */
2097 #endif /* !SIMULATOR */
2099 struct mp3entry* audio_current_track()
2101 #ifdef SIMULATOR
2102 return &taginfo;
2103 #else /* !SIMULATOR */
2104 if(num_tracks_in_memory())
2105 return &get_trackdata(0)->id3;
2106 else
2107 return NULL;
2108 #endif /* !SIMULATOR */
2111 struct mp3entry* audio_next_track()
2113 #ifdef SIMULATOR
2114 return &taginfo;
2115 #else /* !SIMULATOR */
2116 if(num_tracks_in_memory() > 1)
2117 return &get_trackdata(1)->id3;
2118 else
2119 return NULL;
2120 #endif /* !SIMULATOR */
2123 bool audio_has_changed_track(void)
2125 if(last_track_counter != current_track_counter)
2127 last_track_counter = current_track_counter;
2128 return true;
2130 return false;
2133 #if CONFIG_CODEC == MAS3587F
2134 #ifndef SIMULATOR
2135 void audio_init_playback(void)
2137 init_playback_done = false;
2138 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2140 while(!init_playback_done)
2141 sleep_thread(1);
2145 /****************************************************************************
2146 * Recording functions
2147 ***************************************************************************/
2148 void audio_init_recording(unsigned int buffer_offset)
2150 buffer_offset = buffer_offset;
2151 init_recording_done = false;
2152 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2154 while(!init_recording_done)
2155 sleep_thread(1);
2158 static void init_recording(void)
2160 unsigned long val;
2161 int rc;
2163 /* Disable IRQ6 */
2164 IPRB &= 0xff0f;
2166 stop_playing();
2167 is_playing = false;
2168 paused = false;
2170 /* Init the recording variables */
2171 is_recording = false;
2172 is_prerecording = false;
2174 mpeg_stop_done = true;
2176 mas_reset();
2178 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2179 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2180 if(rc < 0)
2181 panicf("mas_ctrl_w: %d", rc);
2183 /* Stop the current application */
2184 val = 0;
2185 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2188 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2189 } while(val);
2191 /* Perform black magic as described by the data sheet */
2192 if((mas_version_code & 0x0fff) == 0x0102)
2194 DEBUGF("Performing MAS black magic for B2 version\n");
2195 mas_writereg(0xa3, 0x98);
2196 mas_writereg(0x94, 0xfffff);
2197 val = 0;
2198 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2199 mas_writereg(0xa3, 0x90);
2202 /* Enable A/D Converters */
2203 shadow_codec_reg0 = 0xcccd;
2204 mas_codec_writereg(0x0, shadow_codec_reg0);
2206 /* Copy left channel to right (mono mode) */
2207 mas_codec_writereg(8, 0x8000);
2209 /* ADC scale 0%, DSP scale 100%
2210 We use the DSP output for monitoring, because it works with all
2211 sources including S/PDIF */
2212 mas_codec_writereg(6, 0x0000);
2213 mas_codec_writereg(7, 0x4000);
2215 /* No mute */
2216 shadow_soft_mute = 0;
2217 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2219 #ifdef HAVE_SPDIF_OUT
2220 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2221 #else
2222 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2223 #endif
2224 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2226 /* Set Demand mode, monitoring OFF and validate all settings */
2227 shadow_io_control_main = 0x125;
2228 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2230 /* Start the encoder application */
2231 val = 0x40;
2232 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2235 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2236 } while(!(val & 0x40));
2238 /* We have started the recording application with monitoring OFF.
2239 This is because we want to record at least one frame to fill the DMA
2240 buffer, because the silly MAS will not negate EOD until at least one
2241 DMA transfer has taken place.
2242 Now let's wait for some data to be encoded. */
2243 sleep(HZ/5);
2245 /* Now set it to Monitoring mode as default, saves power */
2246 shadow_io_control_main = 0x525;
2247 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2249 /* Wait until the DSP has accepted the settings */
2252 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2253 } while(val & 1);
2255 drain_dma_buffer();
2256 mpeg_mode = MPEG_ENCODER;
2258 DEBUGF("MAS Recording application started\n");
2260 /* At this point, all settings are the reset MAS defaults, next thing is to
2261 call mpeg_set_recording_options(). */
2264 void audio_record(const char *filename)
2266 mpeg_errno = 0;
2268 strncpy(recording_filename, filename, MAX_PATH - 1);
2269 recording_filename[MAX_PATH - 1] = 0;
2271 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2274 void audio_pause_recording(void)
2276 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2279 void audio_resume_recording(void)
2281 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2284 static void prepend_header(void)
2286 int startpos;
2287 unsigned i;
2289 /* Make room for header */
2290 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2291 if(audiobuf_read < 0)
2293 /* Clear the bottom half */
2294 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2296 /* And the top half */
2297 audiobuf_read += audiobuflen;
2298 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2300 else
2302 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2304 /* Copy the empty ID3 header */
2305 startpos = audiobuf_read;
2306 for(i = 0; i < sizeof(empty_id3_header); i++)
2308 audiobuf[startpos++] = empty_id3_header[i];
2309 if(startpos == audiobuflen)
2310 startpos = 0;
2314 static void update_header(void)
2316 int fd, framelen;
2317 unsigned long frames;
2319 if (last_rec_bytes > 0)
2321 /* Create the Xing header */
2322 fd = open(delayed_filename, O_RDWR);
2323 if (fd < 0)
2324 panicf("rec upd: %d (%s)", fd, recording_filename);
2326 frames = frame_count_end - frame_count_start;
2327 /* If the number of recorded frames has reached 0x7ffff,
2328 we can no longer trust it */
2329 if (frame_count_end == 0x7ffff)
2330 frames = 0;
2332 /* saved_header is saved right before stopping the MAS */
2333 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2334 frames, last_rec_time * (1000/HZ),
2335 saved_header, NULL, false);
2337 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2338 write(fd, xing_buffer, framelen);
2339 close(fd);
2343 static void start_prerecording(void)
2345 unsigned long val;
2347 DEBUGF("Starting prerecording\n");
2349 prerecord_index = 0;
2350 prerecord_count = 0;
2351 prerecord_timeout = current_tick + HZ;
2352 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2353 reset_mp3_buffer();
2355 is_prerecording = true;
2357 /* Stop monitoring and start the encoder */
2358 shadow_io_control_main &= ~(1 << 10);
2359 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2360 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2362 /* Wait until the DSP has accepted the settings */
2365 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2366 } while(val & 1);
2368 is_recording = true;
2369 saving_status = NOT_SAVING;
2371 demand_irq_enable(true);
2374 static void start_recording(void)
2376 unsigned long val;
2378 if(is_prerecording)
2380 /* This will make the IRQ handler start recording
2381 for real, i.e send MPEG_SAVE_DATA messages when
2382 the buffer is full */
2383 is_prerecording = false;
2385 else
2387 /* If prerecording is off, we need to stop the monitoring
2388 and start the encoder */
2389 shadow_io_control_main &= ~(1 << 10);
2390 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2391 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2393 /* Wait until the DSP has accepted the settings */
2396 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2397 } while(val & 1);
2400 is_recording = true;
2401 saving_status = NOT_SAVING;
2402 paused = false;
2404 /* Store the current time */
2405 if(prerecording)
2406 record_start_time = current_tick - prerecord_count * HZ;
2407 else
2408 record_start_time = current_tick;
2410 pause_start_time = 0;
2412 demand_irq_enable(true);
2415 static void pause_recording(void)
2417 pause_start_time = current_tick;
2419 /* Set the pause bit */
2420 shadow_soft_mute |= 2;
2421 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2423 paused = true;
2426 static void resume_recording(void)
2428 paused = false;
2430 /* Clear the pause bit */
2431 shadow_soft_mute &= ~2;
2432 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2434 /* Compensate for the time we have been paused */
2435 if(pause_start_time)
2437 record_start_time =
2438 current_tick - (pause_start_time - record_start_time);
2439 pause_start_time = 0;
2443 static void stop_recording(void)
2445 unsigned long val;
2447 /* Let it finish the last frame */
2448 if(!paused)
2449 pause_recording();
2450 sleep(HZ/5);
2452 demand_irq_enable(false);
2454 is_recording = false;
2455 is_prerecording = false;
2457 last_rec_bytes = num_rec_bytes;
2458 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2459 last_rec_time = current_tick - record_start_time;
2461 /* Start monitoring */
2462 shadow_io_control_main |= (1 << 10);
2463 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2464 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2466 /* Wait until the DSP has accepted the settings */
2469 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2470 } while(val & 1);
2472 resume_recording();
2475 void audio_set_recording_options(struct audio_recording_options *options)
2477 bool is_mpeg1;
2479 is_mpeg1 = (options->rec_frequency < 3)?true:false;
2481 rec_version_index = is_mpeg1?3:2;
2482 rec_frequency_index = options->rec_frequency % 3;
2484 shadow_encoder_control = (options->rec_quality << 17) |
2485 (rec_frequency_index << 10) |
2486 ((is_mpeg1?1:0) << 9) |
2487 (((options->rec_channels * 2 + 1) & 3) << 6) |
2488 (1 << 5) /* MS-stereo */ |
2489 (1 << 2) /* Is an original */;
2490 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2492 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2494 shadow_soft_mute = options->rec_editable?4:0;
2495 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2497 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2499 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2500 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2501 (1 << 5) | /* SDO strobe invert */
2502 ((is_mpeg1?0:1) << 3) |
2503 (1 << 2) | /* Inverted SIBC clock signal */
2504 1; /* Validate */
2505 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2507 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2509 if(options->rec_source == AUDIO_SRC_MIC)
2511 /* Copy left channel to right (mono mode) */
2512 mas_codec_writereg(8, 0x8000);
2514 else
2516 /* Stereo input mode */
2517 mas_codec_writereg(8, 0);
2520 prerecording_max_seconds = options->rec_prerecord_time;
2521 if(prerecording_max_seconds)
2523 prerecording = true;
2524 start_prerecording();
2526 else
2528 prerecording = false;
2529 is_prerecording = false;
2530 is_recording = false;
2534 /* If use_mic is true, the left gain is used */
2535 void audio_set_recording_gain(int left, int right, int type)
2537 /* Enable both left and right A/D */
2538 shadow_codec_reg0 = (left << 12) |
2539 (right << 8) |
2540 (left << 4) |
2541 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2542 0x0007;
2543 mas_codec_writereg(0x0, shadow_codec_reg0);
2546 #if CONFIG_TUNER & S1A0903X01
2547 /* Get the (unpitched) MAS PLL frequency, for avoiding FM interference with the
2548 * Samsung tuner. Zero means unknown. Currently handles recording from analog
2549 * input only. */
2550 int mpeg_get_mas_pllfreq(void)
2552 if (mpeg_mode != MPEG_ENCODER)
2553 return 0;
2555 if (rec_frequency_index == 0) /* 44.1 kHz / 22.05 kHz */
2556 return 22579000;
2557 else
2558 return 24576000;
2560 #endif /* CONFIG_TUNER & S1A0903X01 */
2562 /* try to make some kind of beep, also in recording mode */
2563 void audio_beep(int duration)
2565 long starttick = current_tick;
2567 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2568 * While this is still audible even without an external signal,
2569 * it doesn't affect the (pre-)recording. */
2570 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2571 mas_codec_writereg(0, shadow_codec_reg0);
2572 yield();
2574 while (current_tick - starttick < duration);
2577 void audio_new_file(const char *filename)
2579 mpeg_errno = 0;
2581 strncpy(recording_filename, filename, MAX_PATH - 1);
2582 recording_filename[MAX_PATH - 1] = 0;
2584 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2587 unsigned long audio_recorded_time(void)
2589 if(is_prerecording)
2590 return prerecord_count * HZ;
2592 if(is_recording)
2594 if(paused)
2595 return pause_start_time - record_start_time;
2596 else
2597 return current_tick - record_start_time;
2600 return 0;
2603 unsigned long audio_num_recorded_bytes(void)
2605 int num_bytes;
2606 int index;
2608 if(is_recording)
2610 if(is_prerecording)
2612 index = prerecord_index - prerecord_count;
2613 if(index < 0)
2614 index += prerecording_max_seconds;
2616 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2617 if(num_bytes < 0)
2618 num_bytes += audiobuflen;
2620 return num_bytes;;
2622 else
2623 return num_rec_bytes;
2625 else
2626 return 0;
2629 #else /* SIMULATOR */
2631 /* dummies coming up */
2633 void audio_init_playback(void)
2635 /* a dummy */
2637 unsigned long audio_recorded_time(void)
2639 /* a dummy */
2640 return 0;
2642 void audio_beep(int duration)
2644 /* a dummy */
2645 (void)duration;
2647 void audio_pause_recording(void)
2649 /* a dummy */
2651 void audio_resume_recording(void)
2653 /* a dummy */
2655 unsigned long audio_num_recorded_bytes(void)
2657 /* a dummy */
2658 return 0;
2660 void audio_record(const char *filename)
2662 /* a dummy */
2663 (void)filename;
2665 void audio_new_file(const char *filename)
2667 /* a dummy */
2668 (void)filename;
2671 void audio_set_recording_gain(int left, int right, int type)
2673 /* a dummy */
2674 (void)left;
2675 (void)right;
2676 (void)type;
2678 void audio_init_recording(unsigned int buffer_offset)
2680 /* a dummy */
2681 (void)buffer_offset;
2683 void audio_set_recording_options(struct audio_recording_options *options)
2685 /* a dummy */
2686 (void)options;
2688 #endif /* SIMULATOR */
2689 #endif /* CONFIG_CODEC == MAS3587F */
2691 void audio_play(long offset)
2693 #ifdef SIMULATOR
2694 char* trackname;
2695 int steps=0;
2697 is_playing = true;
2699 do {
2700 trackname = playlist_peek( steps );
2701 if (!trackname)
2702 break;
2703 if(mp3info(&taginfo, trackname)) {
2704 /* bad mp3, move on */
2705 if(++steps > playlist_amount())
2706 break;
2707 continue;
2709 #ifdef HAVE_MPEG_PLAY
2710 real_mpeg_play(trackname);
2711 #endif
2712 playlist_next(steps);
2713 taginfo.offset = offset;
2714 set_elapsed(&taginfo);
2715 is_playing = true;
2716 playing = true;
2717 break;
2718 } while(1);
2719 #else /* !SIMULATOR */
2720 is_playing = true;
2722 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2723 #endif /* !SIMULATOR */
2725 mpeg_errno = 0;
2728 void audio_stop(void)
2730 #ifndef SIMULATOR
2731 if (playing)
2733 struct trackdata *track = get_trackdata(0);
2734 prev_track_elapsed = track->id3.elapsed;
2736 mpeg_stop_done = false;
2737 queue_post(&mpeg_queue, MPEG_STOP, 0);
2738 while(!mpeg_stop_done)
2739 yield();
2740 #else /* SIMULATOR */
2741 paused = false;
2742 is_playing = false;
2743 playing = false;
2744 #endif /* SIMULATOR */
2747 /* dummy */
2748 void audio_stop_recording(void)
2750 audio_stop();
2753 void audio_pause(void)
2755 #ifndef SIMULATOR
2756 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2757 #else /* SIMULATOR */
2758 is_playing = true;
2759 playing = false;
2760 paused = true;
2761 #endif /* SIMULATOR */
2764 void audio_resume(void)
2766 #ifndef SIMULATOR
2767 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2768 #else /* SIMULATOR */
2769 is_playing = true;
2770 playing = true;
2771 paused = false;
2772 #endif /* SIMULATOR */
2775 void audio_next(void)
2777 #ifndef SIMULATOR
2778 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2779 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2780 #else /* SIMULATOR */
2781 char* file;
2782 int steps = 1;
2783 int index;
2785 do {
2786 file = playlist_peek(steps);
2787 if(!file)
2788 break;
2789 if(mp3info(&taginfo, file)) {
2790 if(++steps > playlist_amount())
2791 break;
2792 continue;
2794 index = playlist_next(steps);
2795 taginfo.index = index;
2796 current_track_counter++;
2797 is_playing = true;
2798 playing = true;
2799 break;
2800 } while(1);
2801 #endif /* SIMULATOR */
2804 void audio_prev(void)
2806 #ifndef SIMULATOR
2807 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2808 queue_post(&mpeg_queue, MPEG_PREV, 0);
2809 #else /* SIMULATOR */
2810 char* file;
2811 int steps = -1;
2812 int index;
2814 do {
2815 file = playlist_peek(steps);
2816 if(!file)
2817 break;
2818 if(mp3info(&taginfo, file)) {
2819 steps--;
2820 continue;
2822 index = playlist_next(steps);
2823 taginfo.index = index;
2824 current_track_counter++;
2825 is_playing = true;
2826 playing = true;
2827 break;
2828 } while(1);
2829 #endif /* SIMULATOR */
2832 void audio_ff_rewind(long newtime)
2834 #ifndef SIMULATOR
2835 queue_post(&mpeg_queue, MPEG_FF_REWIND, newtime);
2836 #else /* SIMULATOR */
2837 (void)newtime;
2838 #endif /* SIMULATOR */
2841 void audio_flush_and_reload_tracks(void)
2843 #ifndef SIMULATOR
2844 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2845 #endif /* !SIMULATOR*/
2848 int audio_status(void)
2850 int ret = 0;
2852 if(is_playing)
2853 ret |= AUDIO_STATUS_PLAY;
2855 if(paused)
2856 ret |= AUDIO_STATUS_PAUSE;
2858 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2859 if(is_recording && !is_prerecording)
2860 ret |= AUDIO_STATUS_RECORD;
2862 if(is_prerecording)
2863 ret |= AUDIO_STATUS_PRERECORD;
2864 #endif /* CONFIG_CODEC == MAS3587F */
2866 if(mpeg_errno)
2867 ret |= AUDIO_STATUS_ERROR;
2869 return ret;
2872 unsigned int audio_error(void)
2874 return mpeg_errno;
2877 void audio_error_clear(void)
2879 mpeg_errno = 0;
2882 #ifdef SIMULATOR
2883 static void mpeg_thread(void)
2885 struct mp3entry* id3;
2886 while ( 1 ) {
2887 if (is_playing) {
2888 id3 = audio_current_track();
2889 if (!paused)
2891 id3->elapsed+=1000;
2892 id3->offset+=1000;
2894 if (id3->elapsed>=id3->length)
2895 audio_next();
2897 sleep(HZ);
2900 #endif /* SIMULATOR */
2902 void audio_init(void)
2904 mpeg_errno = 0;
2905 track_buffer_callback = NULL;
2906 track_unbuffer_callback = NULL;
2908 #ifndef SIMULATOR
2909 audiobuflen = audiobufend - audiobuf;
2910 queue_init(&mpeg_queue, true);
2911 #endif /* !SIMULATOR */
2912 create_thread(mpeg_thread, mpeg_stack,
2913 sizeof(mpeg_stack), mpeg_thread_name IF_PRIO(, PRIORITY_SYSTEM)
2914 IF_COP(, CPU, false));
2916 memset(trackdata, sizeof(trackdata), 0);
2918 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2919 if (HW_MASK & PR_ACTIVE_HIGH)
2920 and_b(~0x08, &PADRH);
2921 else
2922 or_b(0x08, &PADRH);
2923 #endif /* CONFIG_CODEC == MAS3587F */
2925 #ifdef DEBUG
2926 dbg_timer_start();
2927 dbg_cnt2us(0);
2928 #endif /* DEBUG */
2931 #endif /* CONFIG_CODEC != SWCODEC */