Move a few #defines to target specific config files
[kugel-rb.git] / firmware / mpeg.c
blob693e2df4805027da1d02732764fb4b4c24a7ac90
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) = NULL;
122 void (*track_unbuffer_callback)(struct mp3entry *id3) = NULL;
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))
480 track_buffer_callback = handler;
483 void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3))
485 track_unbuffer_callback = handler;
488 void audio_set_track_changed_event(void (*handler)(struct mp3entry *id3))
490 track_changed_callback = handler;
493 void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
495 cuesheet_callback = handler;
498 #ifndef SIMULATOR
499 /* Send callback events to notify about removing old tracks. */
500 static void generate_unbuffer_events(void)
502 int i;
503 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
504 int cur_idx = track_write_idx;
506 for (i = 0; i < numentries; i++)
508 /* Send an event to notify that track has finished. */
509 if (trackdata[cur_idx].event_sent)
511 if (track_unbuffer_callback)
512 track_unbuffer_callback(&trackdata[cur_idx].id3);
513 trackdata[cur_idx].event_sent = false;
515 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
519 /* Send callback events to notify about new tracks. */
520 static void generate_postbuffer_events(void)
522 int i;
523 int numentries = num_tracks_in_memory();
524 int cur_idx = track_read_idx;
526 for (i = 0; i < numentries; i++)
528 if (!trackdata[cur_idx].event_sent)
530 if (track_buffer_callback)
531 track_buffer_callback(&trackdata[cur_idx].id3);
532 trackdata[cur_idx].event_sent = true;
534 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
538 static void recalculate_watermark(int bitrate)
540 int bytes_per_sec;
541 int time = ata_spinup_time;
543 /* A bitrate of 0 probably means empty VBR header. We play safe
544 and set a high threshold */
545 if(bitrate == 0)
546 bitrate = 320;
548 bytes_per_sec = bitrate * 1000 / 8;
550 if(time)
552 /* No drive spins up faster than 3.5s */
553 if(time < 350)
554 time = 350;
556 time = time * 3;
557 low_watermark = ((low_watermark_margin * HZ + time) *
558 bytes_per_sec) / HZ;
560 else
562 low_watermark = MPEG_LOW_WATER;
566 #ifndef HAVE_FLASH_STORAGE
567 void audio_set_buffer_margin(int seconds)
569 low_watermark_margin = seconds;
571 #endif
573 void audio_get_debugdata(struct audio_debug *dbgdata)
575 dbgdata->audiobuflen = audiobuflen;
576 dbgdata->audiobuf_write = audiobuf_write;
577 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
578 dbgdata->audiobuf_read = audiobuf_read;
580 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
582 #if CONFIG_CPU == SH7034
583 dbgdata->dma_on = (SCR0 & 0x80) != 0;
584 #endif
585 dbgdata->playing = playing;
586 dbgdata->play_pending = play_pending;
587 dbgdata->is_playing = is_playing;
588 dbgdata->filling = filling;
589 dbgdata->dma_underrun = dma_underrun;
591 dbgdata->unplayed_space = get_unplayed_space();
592 dbgdata->playable_space = get_playable_space();
593 dbgdata->unswapped_space = get_unswapped_space();
595 dbgdata->low_watermark_level = low_watermark;
596 dbgdata->lowest_watermark_level = lowest_watermark_level;
599 #ifdef DEBUG
600 static void dbg_timer_start(void)
602 /* We are using timer 2 */
604 TSTR &= ~0x04; /* Stop the timer */
605 TSNC &= ~0x04; /* No synchronization */
606 TMDR &= ~0x44; /* Operate normally */
608 TCNT2 = 0; /* Start counting at 0 */
609 TCR2 = 0x03; /* Sysclock/8 */
611 TSTR |= 0x04; /* Start timer 2 */
614 static int dbg_cnt2us(unsigned int cnt)
616 return (cnt * 10000) / (FREQ/800);
618 #endif /* DEBUG */
620 static int get_unplayed_space(void)
622 int space = audiobuf_write - audiobuf_read;
623 if (space < 0)
624 space += audiobuflen;
625 return space;
628 static int get_playable_space(void)
630 int space = audiobuf_swapwrite - audiobuf_read;
631 if (space < 0)
632 space += audiobuflen;
633 return space;
636 static int get_unplayed_space_current_song(void)
638 int space;
640 if (num_tracks_in_memory() > 1)
642 space = get_trackdata(1)->mempos - audiobuf_read;
644 else
646 space = audiobuf_write - audiobuf_read;
649 if (space < 0)
650 space += audiobuflen;
652 return space;
655 static int get_unswapped_space(void)
657 int space = audiobuf_write - audiobuf_swapwrite;
658 if (space < 0)
659 space += audiobuflen;
660 return space;
663 #if CONFIG_CODEC == MAS3587F
664 static int get_unsaved_space(void)
666 int space = audiobuf_write - audiobuf_read;
667 if (space < 0)
668 space += audiobuflen;
669 return space;
672 static void drain_dma_buffer(void)
674 while (PBDRH & 0x40)
676 xor_b(0x08, &PADRH);
678 while (PBDRH & 0x80);
680 xor_b(0x08, &PADRH);
682 while (!(PBDRH & 0x80));
686 #ifdef DEBUG
687 static long timing_info_index = 0;
688 static long timing_info[1024];
689 #endif /* DEBUG */
691 void rec_tick (void) __attribute__ ((section (".icode")));
692 void rec_tick(void)
694 int i;
695 int delay;
696 char data;
698 if(is_recording && (PBDRH & 0x40))
700 #ifdef DEBUG
701 timing_info[timing_info_index++] = current_tick;
702 TCNT2 = 0;
703 #endif /* DEBUG */
704 /* Note: Although this loop is run in interrupt context, further
705 * optimisation will do no good. The MAS would then deliver bad
706 * frames occasionally, as observed in extended experiments. */
707 i = 0;
708 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
710 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
712 delay = 100;
713 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
715 if (--delay <= 0) /* Bail out if we have to wait too long */
716 { /* i.e. the MAS doesn't want to talk to us */
717 xor_b(0x08, &PADRH); /* Set PR inactive */
718 goto transfer_end; /* and get out of here */
722 data = *(unsigned char *)0x04000000; /* read data byte */
724 xor_b(0x08, &PADRH); /* Set PR inactive */
726 audiobuf[audiobuf_write++] = data;
728 if (audiobuf_write >= audiobuflen)
729 audiobuf_write = 0;
731 i++;
733 transfer_end:
735 #ifdef DEBUG
736 timing_info[timing_info_index++] = TCNT2 + (i << 16);
737 timing_info_index &= 0x3ff;
738 #endif /* DEBUG */
740 num_rec_bytes += i;
742 if(is_prerecording)
744 if(TIME_AFTER(current_tick, prerecord_timeout))
746 prerecord_timeout = current_tick + HZ;
747 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
750 else
752 /* Signal to save the data if we are running out of buffer
753 space */
754 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
755 && saving_status == NOT_SAVING)
757 saving_status = BUFFER_FULL;
758 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
763 #endif /* CONFIG_CODEC == MAS3587F */
765 void playback_tick(void)
767 struct trackdata *ptd = get_trackdata(0);
768 if(ptd)
770 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
771 last_dma_tick = current_tick;
772 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
773 (unsigned long)ptd->id3.elapsed);
777 static void reset_mp3_buffer(void)
779 audiobuf_read = 0;
780 audiobuf_write = 0;
781 audiobuf_swapwrite = 0;
782 lowest_watermark_level = audiobuflen;
785 /* DMA transfer end interrupt callback */
786 static void transfer_end(unsigned char** ppbuf, size_t* psize)
788 if(playing && !paused)
790 int unplayed_space_left;
791 int space_until_end_of_buffer;
792 int track_offset = 1;
793 struct trackdata *track;
795 audiobuf_read += last_dma_chunk_size;
796 if(audiobuf_read >= audiobuflen)
797 audiobuf_read = 0;
799 /* First, check if we are on a track boundary */
800 if (num_tracks_in_memory() > 1)
802 if (audiobuf_read == get_trackdata(track_offset)->mempos)
804 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
806 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
807 track_offset++;
812 unplayed_space_left = get_unplayed_space();
814 space_until_end_of_buffer = audiobuflen - audiobuf_read;
816 if(!filling && unplayed_space_left < low_watermark)
818 filling = true;
819 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
822 if(unplayed_space_left)
824 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
825 last_dma_chunk_size = MIN(last_dma_chunk_size,
826 space_until_end_of_buffer);
828 /* several tracks loaded? */
829 track = get_trackdata(track_offset);
830 if(track)
832 /* will we move across the track boundary? */
833 if (( audiobuf_read < track->mempos ) &&
834 ((audiobuf_read+last_dma_chunk_size) >
835 track->mempos ))
837 /* Make sure that we end exactly on the boundary */
838 last_dma_chunk_size = track->mempos - audiobuf_read;
842 *psize = last_dma_chunk_size & 0xffff;
843 *ppbuf = audiobuf + audiobuf_read;
844 track = get_trackdata(0);
845 if(track)
846 track->id3.offset += last_dma_chunk_size;
848 /* Update the watermark debug level */
849 if(unplayed_space_left < lowest_watermark_level)
850 lowest_watermark_level = unplayed_space_left;
852 else
854 /* Check if the end of data is because of a hard disk error.
855 If there is an open file handle, we are still playing music.
856 If not, the last file has been loaded, and the file handle is
857 closed. */
858 if(mpeg_file >= 0)
860 /* Update the watermark debug level */
861 if(unplayed_space_left < lowest_watermark_level)
862 lowest_watermark_level = unplayed_space_left;
864 DEBUGF("DMA underrun.\n");
865 dma_underrun = true;
867 else
869 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
871 DEBUGF("No more MP3 data. Stopping.\n");
872 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
873 playing = false;
876 *psize = 0; /* no more transfer */
881 static struct trackdata *add_track_to_tag_list(const char *filename)
883 struct trackdata *track;
885 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
887 DEBUGF("Tag memory is full\n");
888 return NULL;
891 track = &trackdata[track_write_idx];
893 /* grab id3 tag of new file and
894 remember where in memory it starts */
895 if(mp3info(&track->id3, filename))
897 DEBUGF("Bad mp3\n");
898 return NULL;
900 track->mempos = audiobuf_write;
901 track->id3.elapsed = 0;
902 #ifdef HAVE_LCD_BITMAP
903 if (track->id3.title)
904 lcd_getstringsize(track->id3.title, NULL, NULL);
905 if (track->id3.artist)
906 lcd_getstringsize(track->id3.artist, NULL, NULL);
907 if (track->id3.album)
908 lcd_getstringsize(track->id3.album, NULL, NULL);
909 #endif
910 if (cuesheet_callback)
911 if (cuesheet_callback(filename))
912 track->id3.cuesheet_type = 1;
914 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
915 debug_tags();
916 return track;
919 static int new_file(int steps)
921 int max_steps = playlist_amount();
922 int start = 0;
923 int i;
924 struct trackdata *track;
926 /* Find out how many steps to advance. The load_ahead_index field tells
927 us how many playlist entries it had to skip to get to a valid one.
928 We add those together to find out where to start. */
929 if(steps > 0 && num_tracks_in_memory() > 1)
931 /* Begin with the song after the currently playing one */
932 i = 1;
933 while((track = get_trackdata(i++)))
935 start += track->load_ahead_index;
939 do {
940 char *trackname;
942 trackname = playlist_peek( start + steps );
943 if ( !trackname )
944 return -1;
946 DEBUGF("Loading %s\n", trackname);
948 mpeg_file = open(trackname, O_RDONLY);
949 if(mpeg_file < 0) {
950 DEBUGF("Couldn't open file: %s\n",trackname);
951 if(steps < 0)
952 steps--;
953 else
954 steps++;
956 else
958 struct trackdata *track = add_track_to_tag_list(trackname);
960 if(!track)
962 /* Bad mp3 file */
963 if(steps < 0)
964 steps--;
965 else
966 steps++;
967 close(mpeg_file);
968 mpeg_file = -1;
970 else
972 /* skip past id3v2 tag */
973 lseek(mpeg_file,
974 track->id3.first_frame_offset,
975 SEEK_SET);
976 track->id3.index = steps;
977 track->load_ahead_index = steps;
978 track->id3.offset = 0;
980 if(track->id3.vbr)
981 /* Average bitrate * 1.5 */
982 recalculate_watermark(
983 (track->id3.bitrate * 3) / 2);
984 else
985 recalculate_watermark(
986 track->id3.bitrate);
991 /* Bail out if no file could be opened */
992 if(abs(steps) > max_steps)
993 return -1;
994 } while ( mpeg_file < 0 );
996 return 0;
999 static void stop_playing(void)
1001 struct trackdata *track;
1003 /* Stop the current stream */
1004 mp3_play_stop();
1005 playing = false;
1006 filling = false;
1008 track = get_trackdata(0);
1009 if (track != NULL)
1010 prev_track_elapsed = track->id3.elapsed;
1012 if(mpeg_file >= 0)
1013 close(mpeg_file);
1014 mpeg_file = -1;
1015 remove_all_tags();
1016 generate_unbuffer_events();
1017 reset_mp3_buffer();
1020 static void end_current_track(void) {
1021 struct trackdata *track;
1023 play_pending = false;
1024 playing = false;
1025 mp3_play_pause(false);
1027 track = get_trackdata(0);
1028 if (track != NULL)
1029 prev_track_elapsed = track->id3.elapsed;
1031 reset_mp3_buffer();
1032 remove_all_tags();
1033 generate_unbuffer_events();
1035 if(mpeg_file >= 0)
1036 close(mpeg_file);
1039 /* Is this a really the end of playback or is a new playlist starting */
1040 static void check_playlist_end(int direction)
1042 /* Use the largest possible step size to account for skipped tracks */
1043 int steps = playlist_amount();
1045 if (direction < 0)
1046 steps = -steps;
1048 if (playlist_next(steps) < 0)
1049 is_playing = false;
1052 static void update_playlist(void)
1054 if (num_tracks_in_memory() > 0)
1056 struct trackdata *track = get_trackdata(0);
1057 track->id3.index = playlist_next(track->id3.index);
1059 else
1061 /* End of playlist? */
1062 check_playlist_end(1);
1065 playlist_update_resume_info(audio_current_track());
1068 static void track_change(void)
1070 DEBUGF("Track change\n");
1072 struct trackdata *track = get_trackdata(0);
1073 prev_track_elapsed = track->id3.elapsed;
1075 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1076 /* Reset the AVC */
1077 sound_set_avc(-1);
1078 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1080 if (num_tracks_in_memory() > 0)
1082 remove_current_tag();
1083 if (track_changed_callback)
1084 track_changed_callback(audio_current_track());
1085 update_playlist();
1088 current_track_counter++;
1091 unsigned long audio_prev_elapsed(void)
1093 return prev_track_elapsed;
1096 #ifdef DEBUG
1097 void hexdump(const unsigned char *buf, int len)
1099 int i;
1101 for(i = 0;i < len;i++)
1103 if(i && (i & 15) == 0)
1105 DEBUGF("\n");
1107 DEBUGF("%02x ", buf[i]);
1109 DEBUGF("\n");
1111 #endif /* DEBUG */
1113 static void start_playback_if_ready(void)
1115 int playable_space;
1117 playable_space = audiobuf_swapwrite - audiobuf_read;
1118 if(playable_space < 0)
1119 playable_space += audiobuflen;
1121 /* See if we have started playing yet. If not, do it. */
1122 if(play_pending || dma_underrun)
1124 /* If the filling has stopped, and we still haven't reached
1125 the watermark, the file must be smaller than the
1126 watermark. We must still play it. */
1127 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1128 !filling || dma_underrun)
1130 DEBUGF("P\n");
1131 if (play_pending) /* don't do this when recovering from DMA underrun */
1133 generate_postbuffer_events(); /* signal first track as buffered */
1134 if (play_pending_track_change)
1136 play_pending_track_change = false;
1137 if(track_changed_callback)
1138 track_changed_callback(audio_current_track());
1140 play_pending = false;
1142 playing = true;
1144 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1145 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1146 dma_underrun = false;
1148 if (!paused)
1150 last_dma_tick = current_tick;
1151 mp3_play_pause(true);
1154 /* Tell ourselves that we need more data */
1155 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1160 static bool swap_one_chunk(void)
1162 int free_space_left;
1163 int amount_to_swap;
1165 free_space_left = get_unswapped_space();
1167 if(free_space_left == 0 && !play_pending)
1168 return false;
1170 /* Swap in larger chunks when the user is waiting for the playback
1171 to start, or when there is dangerously little playable data left */
1172 if(play_pending)
1173 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1174 else
1176 if(get_playable_space() < low_watermark)
1177 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1178 free_space_left);
1179 else
1180 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1183 if(audiobuf_write < audiobuf_swapwrite)
1184 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1185 amount_to_swap);
1186 else
1187 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1188 amount_to_swap);
1190 bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap);
1192 audiobuf_swapwrite += amount_to_swap;
1193 if(audiobuf_swapwrite >= audiobuflen)
1195 audiobuf_swapwrite = 0;
1198 return true;
1201 static void mpeg_thread(void)
1203 static int pause_tick = 0;
1204 static unsigned int pause_track = 0;
1205 struct queue_event ev;
1206 int len;
1207 int free_space_left;
1208 int unplayed_space_left;
1209 int amount_to_read;
1210 int t1, t2;
1211 int start_offset;
1212 #if CONFIG_CODEC == MAS3587F
1213 int amount_to_save;
1214 int save_endpos = 0;
1215 int rc;
1216 int level;
1217 long offset;
1218 #endif /* CONFIG_CODEC == MAS3587F */
1220 is_playing = false;
1221 play_pending = false;
1222 playing = false;
1223 mpeg_file = -1;
1225 while(1)
1227 #if CONFIG_CODEC == MAS3587F
1228 if(mpeg_mode == MPEG_DECODER)
1230 #endif /* CONFIG_CODEC == MAS3587F */
1231 yield();
1233 /* Swap if necessary, and don't block on the queue_wait() */
1234 if(swap_one_chunk())
1236 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1238 else if (playing)
1240 /* periodically update resume info */
1241 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1243 else
1245 DEBUGF("S R:%x W:%x SW:%x\n",
1246 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1247 queue_wait(&mpeg_queue, &ev);
1250 start_playback_if_ready();
1252 switch(ev.id)
1254 case MPEG_PLAY:
1255 DEBUGF("MPEG_PLAY\n");
1257 #if CONFIG_TUNER
1258 /* Silence the A/D input, it may be on because the radio
1259 may be playing */
1260 mas_codec_writereg(6, 0x0000);
1261 #endif /* CONFIG_TUNER */
1263 /* Stop the current stream */
1264 paused = false;
1265 end_current_track();
1267 if ( new_file(0) == -1 )
1269 is_playing = false;
1270 track_change();
1271 break;
1274 start_offset = (int)ev.data;
1276 /* mid-song resume? */
1277 if (start_offset) {
1278 struct mp3entry* id3 = &get_trackdata(0)->id3;
1279 lseek(mpeg_file, start_offset, SEEK_SET);
1280 id3->offset = start_offset;
1281 set_elapsed(id3);
1283 else {
1284 /* skip past id3v2 tag */
1285 lseek(mpeg_file,
1286 get_trackdata(0)->id3.first_frame_offset,
1287 SEEK_SET);
1291 /* Make it read more data */
1292 filling = true;
1293 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1295 /* Tell the file loading code that we want to start playing
1296 as soon as we have some data */
1297 play_pending = true;
1298 play_pending_track_change = true;
1300 update_playlist();
1301 current_track_counter++;
1302 break;
1304 case MPEG_STOP:
1305 DEBUGF("MPEG_STOP\n");
1306 is_playing = false;
1307 paused = false;
1309 if (playing)
1310 playlist_update_resume_info(audio_current_track());
1312 stop_playing();
1313 mpeg_stop_done = true;
1314 break;
1316 case MPEG_PAUSE:
1317 DEBUGF("MPEG_PAUSE\n");
1318 /* Stop the current stream */
1319 if (playing)
1320 playlist_update_resume_info(audio_current_track());
1321 paused = true;
1322 playing = false;
1323 pause_tick = current_tick;
1324 pause_track = current_track_counter;
1325 mp3_play_pause(false);
1326 break;
1328 case MPEG_RESUME:
1329 DEBUGF("MPEG_RESUME\n");
1330 /* Continue the current stream */
1331 paused = false;
1332 if (!play_pending)
1334 playing = true;
1335 if ( current_track_counter == pause_track )
1336 last_dma_tick += current_tick - pause_tick;
1337 else
1338 last_dma_tick = current_tick;
1339 pause_tick = 0;
1340 mp3_play_pause(true);
1342 break;
1344 case MPEG_NEXT:
1345 DEBUGF("MPEG_NEXT\n");
1346 /* is next track in ram? */
1347 if ( num_tracks_in_memory() > 1 ) {
1348 int unplayed_space_left, unswapped_space_left;
1350 /* stop the current stream */
1351 play_pending = false;
1352 playing = false;
1353 mp3_play_pause(false);
1355 track_change();
1356 audiobuf_read = get_trackdata(0)->mempos;
1357 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1358 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1359 dma_underrun = false;
1360 last_dma_tick = current_tick;
1362 unplayed_space_left = get_unplayed_space();
1363 unswapped_space_left = get_unswapped_space();
1365 /* should we start reading more data? */
1366 if(!filling && (unplayed_space_left < low_watermark)) {
1367 filling = true;
1368 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1369 play_pending = true;
1370 } else if(unswapped_space_left &&
1371 unswapped_space_left > unplayed_space_left) {
1372 /* Stop swapping the data from the previous file */
1373 audiobuf_swapwrite = audiobuf_read;
1374 play_pending = true;
1375 } else {
1376 playing = true;
1377 if (!paused)
1378 mp3_play_pause(true);
1381 else {
1382 if (!playlist_check(1))
1383 break;
1385 /* stop the current stream */
1386 end_current_track();
1388 if (new_file(1) < 0) {
1389 DEBUGF("No more files to play\n");
1390 filling = false;
1392 check_playlist_end(1);
1393 current_track_counter++;
1394 } else {
1395 /* Make it read more data */
1396 filling = true;
1397 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1399 /* Tell the file loading code that we want
1400 to start playing as soon as we have some data */
1401 play_pending = true;
1402 play_pending_track_change = true;
1404 update_playlist();
1405 current_track_counter++;
1408 break;
1410 case MPEG_PREV: {
1411 DEBUGF("MPEG_PREV\n");
1413 if (!playlist_check(-1))
1414 break;
1416 /* stop the current stream */
1417 end_current_track();
1419 /* Open the next file */
1420 if (new_file(-1) < 0) {
1421 DEBUGF("No more files to play\n");
1422 filling = false;
1424 check_playlist_end(-1);
1425 current_track_counter++;
1426 } else {
1427 /* Make it read more data */
1428 filling = true;
1429 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1431 /* Tell the file loading code that we want to
1432 start playing as soon as we have some data */
1433 play_pending = true;
1434 play_pending_track_change = true;
1436 update_playlist();
1437 current_track_counter++;
1439 break;
1442 case MPEG_FF_REWIND: {
1443 struct mp3entry *id3 = audio_current_track();
1444 unsigned int oldtime = id3->elapsed;
1445 unsigned int newtime = (unsigned int)ev.data;
1446 int curpos, newpos, diffpos;
1447 DEBUGF("MPEG_FF_REWIND\n");
1449 id3->elapsed = newtime;
1451 newpos = audio_get_file_pos();
1452 if(newpos < 0)
1454 id3->elapsed = oldtime;
1455 break;
1458 if (mpeg_file >= 0)
1459 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1460 else
1461 curpos = id3->filesize;
1463 if (num_tracks_in_memory() > 1)
1465 /* We have started loading other tracks that need to be
1466 accounted for */
1467 struct trackdata *track;
1468 int i = 0;
1470 while((track = get_trackdata(i++)))
1472 curpos += track->id3.filesize;
1476 diffpos = curpos - newpos;
1478 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1480 int unplayed_space_left, unswapped_space_left;
1482 /* We are changing to a position that's already in
1483 memory, so we just move the DMA read pointer. */
1484 audiobuf_read = audiobuf_write - diffpos;
1485 if (audiobuf_read < 0)
1487 audiobuf_read += audiobuflen;
1490 unplayed_space_left = get_unplayed_space();
1491 unswapped_space_left = get_unswapped_space();
1493 /* If unswapped_space_left is larger than
1494 unplayed_space_left, it means that the swapwrite pointer
1495 hasn't yet advanced up to the new location of the read
1496 pointer. We just move it, there is no need to swap
1497 data that won't be played anyway. */
1499 if (unswapped_space_left > unplayed_space_left)
1501 DEBUGF("Moved swapwrite\n");
1502 audiobuf_swapwrite = audiobuf_read;
1503 play_pending = true;
1506 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1508 /* We need to load more data before starting */
1509 filling = true;
1510 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1511 play_pending = true;
1513 else
1515 /* resume will start at new position */
1516 last_dma_chunk_size =
1517 MIN(0x2000, get_unplayed_space_current_song());
1518 mp3_play_data(audiobuf + audiobuf_read,
1519 last_dma_chunk_size, transfer_end);
1520 dma_underrun = false;
1523 else
1525 /* Move to the new position in the file and start
1526 loading data */
1527 reset_mp3_buffer();
1529 if (num_tracks_in_memory() > 1)
1531 /* We have to reload the current track */
1532 close(mpeg_file);
1533 remove_all_non_current_tags();
1534 generate_unbuffer_events();
1535 mpeg_file = -1;
1538 if (mpeg_file < 0)
1540 mpeg_file = open(id3->path, O_RDONLY);
1541 if (mpeg_file < 0)
1543 id3->elapsed = oldtime;
1544 break;
1548 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1550 id3->elapsed = oldtime;
1551 break;
1554 filling = true;
1555 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1557 /* Tell the file loading code that we want to start playing
1558 as soon as we have some data */
1559 play_pending = true;
1562 id3->offset = newpos;
1564 break;
1567 case MPEG_FLUSH_RELOAD: {
1568 int numtracks = num_tracks_in_memory();
1569 bool reload_track = false;
1571 if (numtracks > 1)
1573 /* Reset the buffer */
1574 audiobuf_write = get_trackdata(1)->mempos;
1576 /* Reset swapwrite unless we're still swapping current
1577 track */
1578 if (get_unplayed_space() <= get_playable_space())
1579 audiobuf_swapwrite = audiobuf_write;
1581 close(mpeg_file);
1582 remove_all_non_current_tags();
1583 generate_unbuffer_events();
1584 mpeg_file = -1;
1585 reload_track = true;
1587 else if (numtracks == 1 && mpeg_file < 0)
1589 reload_track = true;
1592 if(reload_track && new_file(1) >= 0)
1594 /* Tell ourselves that we want more data */
1595 filling = true;
1596 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1599 break;
1602 case MPEG_NEED_DATA:
1603 free_space_left = audiobuf_read - audiobuf_write;
1605 /* We interpret 0 as "empty buffer" */
1606 if(free_space_left <= 0)
1607 free_space_left += audiobuflen;
1609 unplayed_space_left = audiobuflen - free_space_left;
1611 /* Make sure that we don't fill the entire buffer */
1612 free_space_left -= MPEG_HIGH_WATER;
1614 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1615 generate_unbuffer_events();
1617 /* do we have any more buffer space to fill? */
1618 if(free_space_left <= 0)
1620 DEBUGF("0\n");
1621 filling = false;
1622 generate_postbuffer_events();
1623 ata_sleep();
1624 break;
1627 /* Read small chunks while we are below the low water mark */
1628 if(unplayed_space_left < low_watermark)
1629 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1630 free_space_left);
1631 else
1632 amount_to_read = free_space_left;
1634 /* Don't read more than until the end of the buffer */
1635 amount_to_read = MIN(audiobuflen - audiobuf_write,
1636 amount_to_read);
1637 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1638 amount_to_read = MIN(0x40000, amount_to_read);
1639 #elif MEM == 8
1640 amount_to_read = MIN(0x100000, amount_to_read);
1641 #endif
1643 /* Read as much mpeg data as we can fit in the buffer */
1644 if(mpeg_file >= 0)
1646 DEBUGF("R\n");
1647 t1 = current_tick;
1648 len = read(mpeg_file, audiobuf + audiobuf_write,
1649 amount_to_read);
1650 if(len > 0)
1652 t2 = current_tick;
1653 DEBUGF("time: %d\n", t2 - t1);
1654 DEBUGF("R: %x\n", len);
1656 /* Now make sure that we don't feed the MAS with ID3V1
1657 data */
1658 if (len < amount_to_read)
1660 int i;
1661 static const unsigned char tag[] = "TAG";
1662 int taglen = 128;
1663 int tagptr = audiobuf_write + len - 128;
1665 /* Really rare case: entire potential tag wasn't
1666 read in this call AND audiobuf_write < 128 */
1667 if (tagptr < 0)
1668 tagptr += audiobuflen;
1670 for(i = 0;i < 3;i++)
1672 if(tagptr >= audiobuflen)
1673 tagptr -= audiobuflen;
1675 if(audiobuf[tagptr] != tag[i])
1677 taglen = 0;
1678 break;
1681 tagptr++;
1684 if(taglen)
1686 /* Skip id3v1 tag */
1687 DEBUGF("Skipping ID3v1 tag\n");
1688 len -= taglen;
1690 /* In the very rare case when the entire tag
1691 wasn't read in this read() len will be < 0.
1692 Take care of this when changing the write
1693 pointer. */
1697 audiobuf_write += len;
1699 if (audiobuf_write < 0)
1700 audiobuf_write += audiobuflen;
1702 if(audiobuf_write >= audiobuflen)
1704 audiobuf_write = 0;
1705 DEBUGF("W\n");
1708 /* Tell ourselves that we want more data */
1709 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1711 else
1713 if(len < 0)
1715 DEBUGF("MPEG read error\n");
1718 close(mpeg_file);
1719 mpeg_file = -1;
1721 if(new_file(1) < 0)
1723 /* No more data to play */
1724 DEBUGF("No more files to play\n");
1725 filling = false;
1727 else
1729 /* Tell ourselves that we want more data */
1730 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1734 break;
1736 case MPEG_TRACK_CHANGE:
1737 track_change();
1738 break;
1740 #ifndef USB_NONE
1741 case SYS_USB_CONNECTED:
1742 is_playing = false;
1743 paused = false;
1744 stop_playing();
1746 /* Tell the USB thread that we are safe */
1747 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1748 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1750 /* Wait until the USB cable is extracted again */
1751 usb_wait_for_disconnect(&mpeg_queue);
1752 break;
1753 #endif /* !USB_NONE */
1755 #if CONFIG_CODEC == MAS3587F
1756 case MPEG_INIT_RECORDING:
1757 init_recording();
1758 init_recording_done = true;
1759 break;
1760 #endif /* CONFIG_CODEC == MAS3587F */
1762 case SYS_TIMEOUT:
1763 if (playing)
1764 playlist_update_resume_info(audio_current_track());
1765 break;
1767 #if CONFIG_CODEC == MAS3587F
1769 else
1771 queue_wait(&mpeg_queue, &ev);
1772 switch(ev.id)
1774 case MPEG_RECORD:
1775 if (is_prerecording)
1777 int startpos;
1779 /* Go back prerecord_count seconds in the buffer */
1780 startpos = prerecord_index - prerecord_count;
1781 if(startpos < 0)
1782 startpos += prerecording_max_seconds;
1784 /* Read the position data from the prerecord buffer */
1785 frame_count_start = prerecord_buffer[startpos].framecount;
1786 startpos = prerecord_buffer[startpos].mempos;
1788 DEBUGF("Start looking at address %x (%x)\n",
1789 audiobuf+startpos, startpos);
1791 saved_header = mpeg_get_last_header();
1793 mem_find_next_frame(startpos, &offset, 1800,
1794 saved_header);
1796 audiobuf_read = startpos + offset;
1797 if(audiobuf_read >= audiobuflen)
1798 audiobuf_read -= audiobuflen;
1800 DEBUGF("New audiobuf_read address: %x (%x)\n",
1801 audiobuf+audiobuf_read, audiobuf_read);
1803 level = set_irq_level(HIGHEST_IRQ_LEVEL);
1804 num_rec_bytes = get_unsaved_space();
1805 set_irq_level(level);
1807 else
1809 frame_count_start = 0;
1810 num_rec_bytes = 0;
1811 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1812 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1815 prepend_header();
1816 DEBUGF("Recording...\n");
1817 start_recording();
1819 /* Wait until at least one frame is encoded and get the
1820 frame header, for later use by the Xing header
1821 generation */
1822 sleep(HZ/5);
1823 saved_header = mpeg_get_last_header();
1825 /* delayed until buffer is saved, don't open yet */
1826 strcpy(delayed_filename, recording_filename);
1827 mpeg_file = -1;
1829 break;
1831 case MPEG_STOP:
1832 DEBUGF("MPEG_STOP\n");
1834 stop_recording();
1836 /* Save the remaining data in the buffer */
1837 save_endpos = audiobuf_write;
1838 saving_status = STOP_RECORDING;
1839 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1840 break;
1842 case MPEG_STOP_DONE:
1843 DEBUGF("MPEG_STOP_DONE\n");
1845 if (mpeg_file >= 0)
1846 close(mpeg_file);
1847 mpeg_file = -1;
1849 update_header();
1850 #ifdef DEBUG1
1852 int i;
1853 for(i = 0;i < 512;i++)
1855 DEBUGF("%d - %d us (%d bytes)\n",
1856 timing_info[i*2],
1857 (timing_info[i*2+1] & 0xffff) *
1858 10000 / 13824,
1859 timing_info[i*2+1] >> 16);
1862 #endif /* DEBUG1 */
1864 if (prerecording)
1866 start_prerecording();
1868 mpeg_stop_done = true;
1869 break;
1871 case MPEG_NEW_FILE:
1872 /* Bail out when a more important save is happening */
1873 if (saving_status > NEW_FILE)
1874 break;
1876 /* Make sure we have at least one complete frame
1877 in the buffer. If we haven't recorded a single
1878 frame within 200ms, the MAS is probably not recording
1879 anything, and we bail out. */
1880 amount_to_save = get_unsaved_space();
1881 if (amount_to_save < 1800)
1883 sleep(HZ/5);
1884 amount_to_save = get_unsaved_space();
1887 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1888 &frame_count_end, 1);
1890 last_rec_time = current_tick - record_start_time;
1891 record_start_time = current_tick;
1892 if (paused)
1893 pause_start_time = record_start_time;
1895 /* capture all values at one point */
1896 level = set_irq_level(HIGHEST_IRQ_LEVEL);
1897 save_endpos = audiobuf_write;
1898 last_rec_bytes = num_rec_bytes;
1899 num_rec_bytes = 0;
1900 set_irq_level(level);
1902 if (amount_to_save >= 1800)
1904 /* Now find a frame boundary to split at */
1905 save_endpos -= 1800;
1906 if (save_endpos < 0)
1907 save_endpos += audiobuflen;
1909 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1910 saved_header);
1911 if (!rc) /* No header found, save whole buffer */
1912 offset = 1800;
1914 save_endpos += offset;
1915 if (save_endpos >= audiobuflen)
1916 save_endpos -= audiobuflen;
1918 last_rec_bytes += offset - 1800;
1919 level = set_irq_level(HIGHEST_IRQ_LEVEL);
1920 num_rec_bytes += 1800 - offset;
1921 set_irq_level(level);
1924 saving_status = NEW_FILE;
1925 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1926 break;
1928 case MPEG_SAVE_DATA:
1929 if (saving_status == BUFFER_FULL)
1930 save_endpos = audiobuf_write;
1932 if (mpeg_file < 0) /* delayed file open */
1934 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT);
1936 if (mpeg_file < 0)
1937 panicf("recfile: %d", mpeg_file);
1940 amount_to_save = save_endpos - audiobuf_read;
1941 if (amount_to_save < 0)
1942 amount_to_save += audiobuflen;
1944 amount_to_save = MIN(amount_to_save,
1945 audiobuflen - audiobuf_read);
1946 #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */
1947 amount_to_save = MIN(0x40000, amount_to_save);
1948 #elif MEM == 8
1949 amount_to_save = MIN(0x100000, amount_to_save);
1950 #endif
1951 rc = write(mpeg_file, audiobuf + audiobuf_read,
1952 amount_to_save);
1953 if (rc < 0)
1955 if (errno == ENOSPC)
1957 mpeg_errno = AUDIOERR_DISK_FULL;
1958 stop_recording();
1959 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1960 /* will close the file */
1961 break;
1963 else
1964 panicf("rec wrt: %d", rc);
1967 audiobuf_read += amount_to_save;
1968 if (audiobuf_read >= audiobuflen)
1969 audiobuf_read = 0;
1971 if (audiobuf_read == save_endpos) /* all saved */
1973 switch (saving_status)
1975 case BUFFER_FULL:
1976 rc = fsync(mpeg_file);
1977 if (rc < 0)
1978 panicf("rec fls: %d", rc);
1979 ata_sleep();
1980 break;
1982 case NEW_FILE:
1983 /* Close the current file */
1984 rc = close(mpeg_file);
1985 if (rc < 0)
1986 panicf("rec cls: %d", rc);
1987 mpeg_file = -1;
1988 update_header();
1989 ata_sleep();
1991 /* copy new filename */
1992 strcpy(delayed_filename, recording_filename);
1993 prepend_header();
1994 frame_count_start = frame_count_end;
1995 break;
1997 case STOP_RECORDING:
1998 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1999 /* will close the file */
2000 break;
2002 default:
2003 break;
2005 saving_status = NOT_SAVING;
2007 else /* tell ourselves to save the next chunk */
2008 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2010 break;
2012 case MPEG_PRERECORDING_TICK:
2013 if(!is_prerecording)
2014 break;
2016 /* Store the write pointer every second */
2017 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2018 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2019 &prerecord_buffer[prerecord_index].framecount, 1);
2021 /* Wrap if necessary */
2022 if(++prerecord_index == prerecording_max_seconds)
2023 prerecord_index = 0;
2025 /* Update the number of seconds recorded */
2026 if(prerecord_count < prerecording_max_seconds)
2027 prerecord_count++;
2028 break;
2030 case MPEG_INIT_PLAYBACK:
2031 /* Stop the prerecording */
2032 stop_recording();
2033 reset_mp3_buffer();
2034 mp3_play_init();
2035 init_playback_done = true;
2036 break;
2038 case MPEG_PAUSE_RECORDING:
2039 pause_recording();
2040 break;
2042 case MPEG_RESUME_RECORDING:
2043 resume_recording();
2044 break;
2046 case SYS_USB_CONNECTED:
2047 /* We can safely go to USB mode if no recording
2048 is taking place */
2049 if((!is_recording || is_prerecording) && mpeg_stop_done)
2051 /* Even if we aren't recording, we still call this
2052 function, to put the MAS in monitoring mode,
2053 to save power. */
2054 stop_recording();
2056 /* Tell the USB thread that we are safe */
2057 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2058 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2060 /* Wait until the USB cable is extracted again */
2061 usb_wait_for_disconnect(&mpeg_queue);
2063 break;
2066 #endif /* CONFIG_CODEC == MAS3587F */
2069 #endif /* !SIMULATOR */
2071 struct mp3entry* audio_current_track()
2073 #ifdef SIMULATOR
2074 return &taginfo;
2075 #else /* !SIMULATOR */
2076 if(num_tracks_in_memory())
2077 return &get_trackdata(0)->id3;
2078 else
2079 return NULL;
2080 #endif /* !SIMULATOR */
2083 struct mp3entry* audio_next_track()
2085 #ifdef SIMULATOR
2086 return &taginfo;
2087 #else /* !SIMULATOR */
2088 if(num_tracks_in_memory() > 1)
2089 return &get_trackdata(1)->id3;
2090 else
2091 return NULL;
2092 #endif /* !SIMULATOR */
2095 bool audio_has_changed_track(void)
2097 if(last_track_counter != current_track_counter)
2099 last_track_counter = current_track_counter;
2100 return true;
2102 return false;
2105 #if CONFIG_CODEC == MAS3587F
2106 #ifndef SIMULATOR
2107 void audio_init_playback(void)
2109 init_playback_done = false;
2110 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2112 while(!init_playback_done)
2113 sleep_thread(1);
2117 /****************************************************************************
2118 * Recording functions
2119 ***************************************************************************/
2120 void audio_init_recording(unsigned int buffer_offset)
2122 buffer_offset = buffer_offset;
2123 init_recording_done = false;
2124 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2126 while(!init_recording_done)
2127 sleep_thread(1);
2130 static void init_recording(void)
2132 unsigned long val;
2133 int rc;
2135 /* Disable IRQ6 */
2136 IPRB &= 0xff0f;
2138 stop_playing();
2139 is_playing = false;
2140 paused = false;
2142 /* Init the recording variables */
2143 is_recording = false;
2144 is_prerecording = false;
2146 mpeg_stop_done = true;
2148 mas_reset();
2150 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2151 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2152 if(rc < 0)
2153 panicf("mas_ctrl_w: %d", rc);
2155 /* Stop the current application */
2156 val = 0;
2157 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2160 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2161 } while(val);
2163 /* Perform black magic as described by the data sheet */
2164 if((mas_version_code & 0x0fff) == 0x0102)
2166 DEBUGF("Performing MAS black magic for B2 version\n");
2167 mas_writereg(0xa3, 0x98);
2168 mas_writereg(0x94, 0xfffff);
2169 val = 0;
2170 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2171 mas_writereg(0xa3, 0x90);
2174 /* Enable A/D Converters */
2175 shadow_codec_reg0 = 0xcccd;
2176 mas_codec_writereg(0x0, shadow_codec_reg0);
2178 /* Copy left channel to right (mono mode) */
2179 mas_codec_writereg(8, 0x8000);
2181 /* ADC scale 0%, DSP scale 100%
2182 We use the DSP output for monitoring, because it works with all
2183 sources including S/PDIF */
2184 mas_codec_writereg(6, 0x0000);
2185 mas_codec_writereg(7, 0x4000);
2187 /* No mute */
2188 shadow_soft_mute = 0;
2189 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2191 #ifdef HAVE_SPDIF_OUT
2192 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2193 #else
2194 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2195 #endif
2196 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2198 /* Set Demand mode, monitoring OFF and validate all settings */
2199 shadow_io_control_main = 0x125;
2200 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2202 /* Start the encoder application */
2203 val = 0x40;
2204 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2207 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2208 } while(!(val & 0x40));
2210 /* We have started the recording application with monitoring OFF.
2211 This is because we want to record at least one frame to fill the DMA
2212 buffer, because the silly MAS will not negate EOD until at least one
2213 DMA transfer has taken place.
2214 Now let's wait for some data to be encoded. */
2215 sleep(HZ/5);
2217 /* Now set it to Monitoring mode as default, saves power */
2218 shadow_io_control_main = 0x525;
2219 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2221 /* Wait until the DSP has accepted the settings */
2224 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2225 } while(val & 1);
2227 drain_dma_buffer();
2228 mpeg_mode = MPEG_ENCODER;
2230 DEBUGF("MAS Recording application started\n");
2232 /* At this point, all settings are the reset MAS defaults, next thing is to
2233 call mpeg_set_recording_options(). */
2236 void audio_record(const char *filename)
2238 mpeg_errno = 0;
2240 strncpy(recording_filename, filename, MAX_PATH - 1);
2241 recording_filename[MAX_PATH - 1] = 0;
2243 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2246 void audio_pause_recording(void)
2248 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2251 void audio_resume_recording(void)
2253 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2256 static void prepend_header(void)
2258 int startpos;
2259 unsigned i;
2261 /* Make room for header */
2262 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2263 if(audiobuf_read < 0)
2265 /* Clear the bottom half */
2266 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2268 /* And the top half */
2269 audiobuf_read += audiobuflen;
2270 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2272 else
2274 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2276 /* Copy the empty ID3 header */
2277 startpos = audiobuf_read;
2278 for(i = 0; i < sizeof(empty_id3_header); i++)
2280 audiobuf[startpos++] = empty_id3_header[i];
2281 if(startpos == audiobuflen)
2282 startpos = 0;
2286 static void update_header(void)
2288 int fd, framelen;
2289 unsigned long frames;
2291 if (last_rec_bytes > 0)
2293 /* Create the Xing header */
2294 fd = open(delayed_filename, O_RDWR);
2295 if (fd < 0)
2296 panicf("rec upd: %d (%s)", fd, recording_filename);
2298 frames = frame_count_end - frame_count_start;
2299 /* If the number of recorded frames has reached 0x7ffff,
2300 we can no longer trust it */
2301 if (frame_count_end == 0x7ffff)
2302 frames = 0;
2304 /* saved_header is saved right before stopping the MAS */
2305 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2306 frames, last_rec_time * (1000/HZ),
2307 saved_header, NULL, false);
2309 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2310 write(fd, xing_buffer, framelen);
2311 close(fd);
2315 static void start_prerecording(void)
2317 unsigned long val;
2319 DEBUGF("Starting prerecording\n");
2321 prerecord_index = 0;
2322 prerecord_count = 0;
2323 prerecord_timeout = current_tick + HZ;
2324 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2325 reset_mp3_buffer();
2327 is_prerecording = true;
2329 /* Stop monitoring and start the encoder */
2330 shadow_io_control_main &= ~(1 << 10);
2331 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2332 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2334 /* Wait until the DSP has accepted the settings */
2337 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2338 } while(val & 1);
2340 is_recording = true;
2341 saving_status = NOT_SAVING;
2343 demand_irq_enable(true);
2346 static void start_recording(void)
2348 unsigned long val;
2350 if(is_prerecording)
2352 /* This will make the IRQ handler start recording
2353 for real, i.e send MPEG_SAVE_DATA messages when
2354 the buffer is full */
2355 is_prerecording = false;
2357 else
2359 /* If prerecording is off, we need to stop the monitoring
2360 and start the encoder */
2361 shadow_io_control_main &= ~(1 << 10);
2362 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2363 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2365 /* Wait until the DSP has accepted the settings */
2368 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2369 } while(val & 1);
2372 is_recording = true;
2373 saving_status = NOT_SAVING;
2374 paused = false;
2376 /* Store the current time */
2377 if(prerecording)
2378 record_start_time = current_tick - prerecord_count * HZ;
2379 else
2380 record_start_time = current_tick;
2382 pause_start_time = 0;
2384 demand_irq_enable(true);
2387 static void pause_recording(void)
2389 pause_start_time = current_tick;
2391 /* Set the pause bit */
2392 shadow_soft_mute |= 2;
2393 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2395 paused = true;
2398 static void resume_recording(void)
2400 paused = false;
2402 /* Clear the pause bit */
2403 shadow_soft_mute &= ~2;
2404 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2406 /* Compensate for the time we have been paused */
2407 if(pause_start_time)
2409 record_start_time =
2410 current_tick - (pause_start_time - record_start_time);
2411 pause_start_time = 0;
2415 static void stop_recording(void)
2417 unsigned long val;
2419 /* Let it finish the last frame */
2420 if(!paused)
2421 pause_recording();
2422 sleep(HZ/5);
2424 demand_irq_enable(false);
2426 is_recording = false;
2427 is_prerecording = false;
2429 last_rec_bytes = num_rec_bytes;
2430 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2431 last_rec_time = current_tick - record_start_time;
2433 /* Start monitoring */
2434 shadow_io_control_main |= (1 << 10);
2435 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2436 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2438 /* Wait until the DSP has accepted the settings */
2441 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2442 } while(val & 1);
2444 resume_recording();
2447 void audio_set_recording_options(struct audio_recording_options *options)
2449 bool is_mpeg1;
2451 is_mpeg1 = (options->rec_frequency < 3)?true:false;
2453 rec_version_index = is_mpeg1?3:2;
2454 rec_frequency_index = options->rec_frequency % 3;
2456 shadow_encoder_control = (options->rec_quality << 17) |
2457 (rec_frequency_index << 10) |
2458 ((is_mpeg1?1:0) << 9) |
2459 (((options->rec_channels * 2 + 1) & 3) << 6) |
2460 (1 << 5) /* MS-stereo */ |
2461 (1 << 2) /* Is an original */;
2462 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2464 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2466 shadow_soft_mute = options->rec_editable?4:0;
2467 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2469 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2471 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2472 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2473 (1 << 5) | /* SDO strobe invert */
2474 ((is_mpeg1?0:1) << 3) |
2475 (1 << 2) | /* Inverted SIBC clock signal */
2476 1; /* Validate */
2477 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2479 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2481 if(options->rec_source == AUDIO_SRC_MIC)
2483 /* Copy left channel to right (mono mode) */
2484 mas_codec_writereg(8, 0x8000);
2486 else
2488 /* Stereo input mode */
2489 mas_codec_writereg(8, 0);
2492 prerecording_max_seconds = options->rec_prerecord_time;
2493 if(prerecording_max_seconds)
2495 prerecording = true;
2496 start_prerecording();
2498 else
2500 prerecording = false;
2501 is_prerecording = false;
2502 is_recording = false;
2506 /* If use_mic is true, the left gain is used */
2507 void audio_set_recording_gain(int left, int right, int type)
2509 /* Enable both left and right A/D */
2510 shadow_codec_reg0 = (left << 12) |
2511 (right << 8) |
2512 (left << 4) |
2513 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2514 0x0007;
2515 mas_codec_writereg(0x0, shadow_codec_reg0);
2518 #if CONFIG_TUNER & S1A0903X01
2519 /* Get the (unpitched) MAS PLL frequency, for avoiding FM interference with the
2520 * Samsung tuner. Zero means unknown. Currently handles recording from analog
2521 * input only. */
2522 int mpeg_get_mas_pllfreq(void)
2524 if (mpeg_mode != MPEG_ENCODER)
2525 return 0;
2527 if (rec_frequency_index == 0) /* 44.1 kHz / 22.05 kHz */
2528 return 22579000;
2529 else
2530 return 24576000;
2532 #endif /* CONFIG_TUNER & S1A0903X01 */
2534 /* try to make some kind of beep, also in recording mode */
2535 void audio_beep(int duration)
2537 long starttick = current_tick;
2539 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2540 * While this is still audible even without an external signal,
2541 * it doesn't affect the (pre-)recording. */
2542 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2543 mas_codec_writereg(0, shadow_codec_reg0);
2544 yield();
2546 while (current_tick - starttick < duration);
2549 void audio_new_file(const char *filename)
2551 mpeg_errno = 0;
2553 strncpy(recording_filename, filename, MAX_PATH - 1);
2554 recording_filename[MAX_PATH - 1] = 0;
2556 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2559 unsigned long audio_recorded_time(void)
2561 if(is_prerecording)
2562 return prerecord_count * HZ;
2564 if(is_recording)
2566 if(paused)
2567 return pause_start_time - record_start_time;
2568 else
2569 return current_tick - record_start_time;
2572 return 0;
2575 unsigned long audio_num_recorded_bytes(void)
2577 int num_bytes;
2578 int index;
2580 if(is_recording)
2582 if(is_prerecording)
2584 index = prerecord_index - prerecord_count;
2585 if(index < 0)
2586 index += prerecording_max_seconds;
2588 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2589 if(num_bytes < 0)
2590 num_bytes += audiobuflen;
2592 return num_bytes;;
2594 else
2595 return num_rec_bytes;
2597 else
2598 return 0;
2601 #else /* SIMULATOR */
2603 /* dummies coming up */
2605 void audio_init_playback(void)
2607 /* a dummy */
2609 unsigned long audio_recorded_time(void)
2611 /* a dummy */
2612 return 0;
2614 void audio_beep(int duration)
2616 /* a dummy */
2617 (void)duration;
2619 void audio_pause_recording(void)
2621 /* a dummy */
2623 void audio_resume_recording(void)
2625 /* a dummy */
2627 unsigned long audio_num_recorded_bytes(void)
2629 /* a dummy */
2630 return 0;
2632 void audio_record(const char *filename)
2634 /* a dummy */
2635 (void)filename;
2637 void audio_new_file(const char *filename)
2639 /* a dummy */
2640 (void)filename;
2643 void audio_set_recording_gain(int left, int right, int type)
2645 /* a dummy */
2646 (void)left;
2647 (void)right;
2648 (void)type;
2650 void audio_init_recording(unsigned int buffer_offset)
2652 /* a dummy */
2653 (void)buffer_offset;
2655 void audio_set_recording_options(struct audio_recording_options *options)
2657 /* a dummy */
2658 (void)options;
2660 #endif /* SIMULATOR */
2661 #endif /* CONFIG_CODEC == MAS3587F */
2663 void audio_play(long offset)
2665 #ifdef SIMULATOR
2666 char* trackname;
2667 int steps=0;
2669 is_playing = true;
2671 do {
2672 trackname = playlist_peek( steps );
2673 if (!trackname)
2674 break;
2675 if(mp3info(&taginfo, trackname)) {
2676 /* bad mp3, move on */
2677 if(++steps > playlist_amount())
2678 break;
2679 continue;
2681 #ifdef HAVE_MPEG_PLAY
2682 real_mpeg_play(trackname);
2683 #endif
2684 playlist_next(steps);
2685 taginfo.offset = offset;
2686 set_elapsed(&taginfo);
2687 is_playing = true;
2688 playing = true;
2689 break;
2690 } while(1);
2691 #else /* !SIMULATOR */
2692 is_playing = true;
2694 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2695 #endif /* !SIMULATOR */
2697 mpeg_errno = 0;
2700 void audio_stop(void)
2702 #ifndef SIMULATOR
2703 if (playing)
2705 struct trackdata *track = get_trackdata(0);
2706 prev_track_elapsed = track->id3.elapsed;
2708 mpeg_stop_done = false;
2709 queue_post(&mpeg_queue, MPEG_STOP, 0);
2710 while(!mpeg_stop_done)
2711 yield();
2712 #else /* SIMULATOR */
2713 paused = false;
2714 is_playing = false;
2715 playing = false;
2716 #endif /* SIMULATOR */
2719 /* dummy */
2720 void audio_stop_recording(void)
2722 audio_stop();
2725 void audio_pause(void)
2727 #ifndef SIMULATOR
2728 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2729 #else /* SIMULATOR */
2730 is_playing = true;
2731 playing = false;
2732 paused = true;
2733 #endif /* SIMULATOR */
2736 void audio_resume(void)
2738 #ifndef SIMULATOR
2739 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2740 #else /* SIMULATOR */
2741 is_playing = true;
2742 playing = true;
2743 paused = false;
2744 #endif /* SIMULATOR */
2747 void audio_next(void)
2749 #ifndef SIMULATOR
2750 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2751 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2752 #else /* SIMULATOR */
2753 char* file;
2754 int steps = 1;
2755 int index;
2757 do {
2758 file = playlist_peek(steps);
2759 if(!file)
2760 break;
2761 if(mp3info(&taginfo, file)) {
2762 if(++steps > playlist_amount())
2763 break;
2764 continue;
2766 index = playlist_next(steps);
2767 taginfo.index = index;
2768 current_track_counter++;
2769 is_playing = true;
2770 playing = true;
2771 break;
2772 } while(1);
2773 #endif /* SIMULATOR */
2776 void audio_prev(void)
2778 #ifndef SIMULATOR
2779 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2780 queue_post(&mpeg_queue, MPEG_PREV, 0);
2781 #else /* SIMULATOR */
2782 char* file;
2783 int steps = -1;
2784 int index;
2786 do {
2787 file = playlist_peek(steps);
2788 if(!file)
2789 break;
2790 if(mp3info(&taginfo, file)) {
2791 steps--;
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_ff_rewind(long newtime)
2806 #ifndef SIMULATOR
2807 queue_post(&mpeg_queue, MPEG_FF_REWIND, newtime);
2808 #else /* SIMULATOR */
2809 (void)newtime;
2810 #endif /* SIMULATOR */
2813 void audio_flush_and_reload_tracks(void)
2815 #ifndef SIMULATOR
2816 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2817 #endif /* !SIMULATOR*/
2820 int audio_status(void)
2822 int ret = 0;
2824 if(is_playing)
2825 ret |= AUDIO_STATUS_PLAY;
2827 if(paused)
2828 ret |= AUDIO_STATUS_PAUSE;
2830 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2831 if(is_recording && !is_prerecording)
2832 ret |= AUDIO_STATUS_RECORD;
2834 if(is_prerecording)
2835 ret |= AUDIO_STATUS_PRERECORD;
2836 #endif /* CONFIG_CODEC == MAS3587F */
2838 if(mpeg_errno)
2839 ret |= AUDIO_STATUS_ERROR;
2841 return ret;
2844 unsigned int audio_error(void)
2846 return mpeg_errno;
2849 void audio_error_clear(void)
2851 mpeg_errno = 0;
2854 #ifdef SIMULATOR
2855 static void mpeg_thread(void)
2857 struct mp3entry* id3;
2858 while ( 1 ) {
2859 if (is_playing) {
2860 id3 = audio_current_track();
2861 if (!paused)
2863 id3->elapsed+=1000;
2864 id3->offset+=1000;
2866 if (id3->elapsed>=id3->length)
2867 audio_next();
2869 sleep(HZ);
2872 #endif /* SIMULATOR */
2874 void audio_init(void)
2876 mpeg_errno = 0;
2878 #ifndef SIMULATOR
2879 audiobuflen = audiobufend - audiobuf;
2880 queue_init(&mpeg_queue, true);
2881 #endif /* !SIMULATOR */
2882 create_thread(mpeg_thread, mpeg_stack,
2883 sizeof(mpeg_stack), 0, mpeg_thread_name
2884 IF_PRIO(, PRIORITY_SYSTEM)
2885 IF_COP(, CPU));
2887 memset(trackdata, sizeof(trackdata), 0);
2889 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2890 if (HW_MASK & PR_ACTIVE_HIGH)
2891 and_b(~0x08, &PADRH);
2892 else
2893 or_b(0x08, &PADRH);
2894 #endif /* CONFIG_CODEC == MAS3587F */
2896 #ifdef DEBUG
2897 dbg_timer_start();
2898 dbg_cnt2us(0);
2899 #endif /* DEBUG */
2902 #endif /* CONFIG_CODEC != SWCODEC */