Revert hotkey bitmaps
[kugel-rb.git] / apps / mpeg.c
blob7917015a9beaafe0fab0ac99c4cf9d21319cedc6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include "config.h"
25 #if CONFIG_CODEC != SWCODEC
27 #include "debug.h"
28 #include "panic.h"
29 #include "metadata.h"
30 #include "mpeg.h"
31 #include "audio.h"
32 #include "storage.h"
33 #include "string.h"
34 #include <kernel.h>
35 #include "thread.h"
36 #include "errno.h"
37 #include "mp3data.h"
38 #include "buffer.h"
39 #include "mp3_playback.h"
40 #include "sound.h"
41 #include "bitswap.h"
42 #include "appevents.h"
43 #include "cuesheet.h"
44 #include "settings.h"
45 #ifndef SIMULATOR
46 #include "i2c.h"
47 #include "mas.h"
48 #include "system.h"
49 #include "usb.h"
50 #include "file.h"
51 #include "hwcompat.h"
52 #endif /* !SIMULATOR */
53 #ifdef HAVE_LCD_BITMAP
54 #include "lcd.h"
55 #endif
57 #define MPEG_SWAP_CHUNKSIZE 0x2000
58 #define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
59 wouldn't be able to see the difference between
60 an empty buffer and a full one. */
61 #define MPEG_LOW_WATER 0x60000
62 #define MPEG_RECORDING_LOW_WATER 0x80000
63 #define MPEG_LOW_WATER_CHUNKSIZE 0x40000
64 #define MPEG_LOW_WATER_SWAP_CHUNKSIZE 0x10000
65 #if (CONFIG_STORAGE & STORAGE_MMC)
66 #define MPEG_PLAY_PENDING_THRESHOLD 0x20000
67 #define MPEG_PLAY_PENDING_SWAPSIZE 0x20000
68 #else
69 #define MPEG_PLAY_PENDING_THRESHOLD 0x10000
70 #define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
71 #endif
73 #define MPEG_MAX_PRERECORD_SECONDS 30
75 /* For ID3 info and VBR header */
76 #define MPEG_RESERVED_HEADER_SPACE (4096 + 576)
78 #ifndef SIMULATOR
79 extern unsigned long mas_version_code;
80 #endif
82 #if CONFIG_CODEC == MAS3587F
83 extern enum /* from mp3_playback.c */
85 MPEG_DECODER,
86 MPEG_ENCODER
87 } mpeg_mode;
88 #endif /* CONFIG_CODEC == MAS3587F */
90 extern char* playlist_peek(int steps);
91 extern bool playlist_check(int steps);
92 extern int playlist_next(int steps);
93 extern int playlist_amount(void);
94 extern int playlist_update_resume_info(const struct mp3entry* id3);
96 #define MPEG_PLAY 1
97 #define MPEG_STOP 2
98 #define MPEG_PAUSE 3
99 #define MPEG_RESUME 4
100 #define MPEG_NEXT 5
101 #define MPEG_PREV 6
102 #define MPEG_FF_REWIND 7
103 #define MPEG_FLUSH_RELOAD 8
104 #define MPEG_RECORD 9
105 #define MPEG_INIT_RECORDING 10
106 #define MPEG_INIT_PLAYBACK 11
107 #define MPEG_NEW_FILE 12
108 #define MPEG_PAUSE_RECORDING 13
109 #define MPEG_RESUME_RECORDING 14
110 #define MPEG_NEED_DATA 100
111 #define MPEG_TRACK_CHANGE 101
112 #define MPEG_SAVE_DATA 102
113 #define MPEG_STOP_DONE 103
114 #define MPEG_PRERECORDING_TICK 104
116 /* indicator for MPEG_NEED_DATA */
117 #define GENERATE_UNBUFFER_EVENTS 1
119 /* list of tracks in memory */
120 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
121 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
123 struct trackdata
125 struct mp3entry id3;
126 int mempos;
127 int load_ahead_index;
130 static struct trackdata trackdata[MAX_TRACK_ENTRIES];
132 static unsigned int current_track_counter = 0;
134 #ifndef SIMULATOR
135 /* Play time of the previous track */
136 static unsigned long prev_track_elapsed;
138 static int track_read_idx = 0;
139 static int track_write_idx = 0;
140 #endif /* !SIMULATOR */
142 /* Cuesheet support */
143 static struct cuesheet *curr_cuesheet = NULL;
144 static bool checked_for_cuesheet = false;
146 static const char mpeg_thread_name[] = "mpeg";
147 static unsigned int mpeg_errno;
149 static bool playing = false; /* We are playing an MP3 stream */
150 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
151 static bool paused; /* playback is paused */
153 #ifdef SIMULATOR
154 static char mpeg_stack[DEFAULT_STACK_SIZE];
155 static struct mp3entry taginfo;
157 #else /* !SIMULATOR */
158 static struct event_queue mpeg_queue;
159 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
161 static int audiobuflen;
162 static int audiobuf_write;
163 static int audiobuf_swapwrite;
164 static int audiobuf_read;
166 static int mpeg_file;
168 static bool play_pending; /* We are about to start playing */
169 static bool play_pending_track_change; /* When starting play we're starting a new file */
170 static bool filling; /* We are filling the buffer with data from disk */
171 static bool dma_underrun; /* True when the DMA has stopped because of
172 slow disk reading (read error, shaking) */
173 static bool mpeg_stop_done;
175 static int last_dma_tick = 0;
176 static int last_dma_chunk_size;
178 static long low_watermark; /* Dynamic low watermark level */
179 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
180 static long lowest_watermark_level; /* Debug value to observe the buffer
181 usage */
182 #if CONFIG_CODEC == MAS3587F
183 static char recording_filename[MAX_PATH]; /* argument to thread */
184 static char delayed_filename[MAX_PATH]; /* internal copy of above */
186 static char xing_buffer[MAX_XING_HEADER_SIZE];
188 static bool init_recording_done;
189 static bool init_playback_done;
190 static bool prerecording; /* True if prerecording is enabled */
191 static bool is_prerecording; /* True if we are prerecording */
192 static bool is_recording; /* We are recording */
194 static enum {
195 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
196 BUFFER_FULL,
197 NEW_FILE,
198 STOP_RECORDING
199 } saving_status;
201 static int rec_frequency_index; /* For create_xing_header() calls */
202 static int rec_version_index; /* For create_xing_header() calls */
204 struct prerecord_info {
205 int mempos;
206 unsigned long framecount;
209 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
210 static int prerecord_index; /* Current index in the prerecord buffer */
211 static int prerecording_max_seconds; /* Max number of seconds to store */
212 static int prerecord_count; /* Number of seconds in the prerecord buffer */
213 static int prerecord_timeout; /* The tick count of the next prerecord data
214 store */
216 static unsigned long record_start_time; /* Value of current_tick when recording
217 was started */
218 static unsigned long pause_start_time; /* Value of current_tick when pause was
219 started */
220 static unsigned long last_rec_time;
221 static unsigned long num_rec_bytes;
222 static unsigned long last_rec_bytes;
223 static unsigned long frame_count_start;
224 static unsigned long frame_count_end;
225 static unsigned long saved_header = 0;
227 /* Shadow MAS registers */
228 unsigned long shadow_encoder_control = 0;
229 #endif /* CONFIG_CODEC == MAS3587F */
231 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
232 unsigned long shadow_io_control_main = 0;
233 unsigned long shadow_soft_mute = 0;
234 unsigned shadow_codec_reg0;
235 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
237 #ifdef HAVE_RECORDING
238 static const unsigned char empty_id3_header[] =
240 'I', 'D', '3', 0x03, 0x00, 0x00,
241 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
243 #endif /* HAVE_RECORDING */
246 static int get_unplayed_space(void);
247 static int get_playable_space(void);
248 static int get_unswapped_space(void);
249 #endif /* !SIMULATOR */
251 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
252 static void init_recording(void);
253 static void prepend_header(void);
254 static void update_header(void);
255 static void start_prerecording(void);
256 static void start_recording(void);
257 static void stop_recording(void);
258 static int get_unsaved_space(void);
259 static void pause_recording(void);
260 static void resume_recording(void);
261 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
264 #ifndef SIMULATOR
265 static int num_tracks_in_memory(void)
267 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
270 #ifdef DEBUG_TAGS
271 static void debug_tags(void)
273 int i;
275 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
277 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
279 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
280 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
282 #else /* !DEBUG_TAGS */
283 #define debug_tags()
284 #endif /* !DEBUG_TAGS */
286 static void remove_current_tag(void)
288 if(num_tracks_in_memory() > 0)
290 /* First move the index, so nobody tries to access the tag */
291 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
292 checked_for_cuesheet = false;
293 debug_tags();
295 else
297 DEBUGF("remove_current_tag: no tracks to remove\n");
301 static void remove_all_non_current_tags(void)
303 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
304 debug_tags();
307 static void remove_all_tags(void)
309 track_write_idx = track_read_idx;
311 debug_tags();
314 static struct trackdata *get_trackdata(int offset)
316 if(offset >= num_tracks_in_memory())
317 return NULL;
318 else
319 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
321 #endif /* !SIMULATOR */
323 /***********************************************************************/
324 /* audio event handling */
326 #define MAX_EVENT_HANDLERS 10
327 struct event_handlers_table
329 AUDIO_EVENT_HANDLER handler;
330 unsigned short mask;
332 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
333 static int event_handlers_count = 0;
335 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
337 if (event_handlers_count < MAX_EVENT_HANDLERS)
339 event_handlers[event_handlers_count].handler = handler;
340 event_handlers[event_handlers_count].mask = mask;
341 event_handlers_count++;
345 /* dispatch calls each handler in the order registered and returns after some
346 handler actually handles the event (the event is assumed to no longer be valid
347 after this, due to the handler changing some condition); returns true if someone
348 handled the event, which is expected to cause the caller to skip its own handling
349 of the event */
350 #ifndef SIMULATOR
351 static bool audio_dispatch_event(unsigned short event, unsigned long data)
353 int i = 0;
354 for(i=0; i < event_handlers_count; i++)
356 if ( event_handlers[i].mask & event )
358 int rc = event_handlers[i].handler(event, data);
359 if ( rc == AUDIO_EVENT_RC_HANDLED )
360 return true;
363 return false;
365 #endif
367 /***********************************************************************/
369 static void set_elapsed(struct mp3entry* id3)
371 if ( id3->vbr ) {
372 if ( id3->has_toc ) {
373 /* calculate elapsed time using TOC */
374 int i;
375 unsigned int remainder, plen, relpos, nextpos;
377 /* find wich percent we're at */
378 for (i=0; i<100; i++ )
380 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
382 break;
386 i--;
387 if (i < 0)
388 i = 0;
390 relpos = id3->toc[i];
392 if (i < 99)
394 nextpos = id3->toc[i+1];
396 else
398 nextpos = 256;
401 remainder = id3->offset - (relpos * (id3->filesize / 256));
403 /* set time for this percent (divide before multiply to prevent
404 overflow on long files. loss of precision is negligible on
405 short files) */
406 id3->elapsed = i * (id3->length / 100);
408 /* calculate remainder time */
409 plen = (nextpos - relpos) * (id3->filesize / 256);
410 id3->elapsed += (((remainder * 100) / plen) *
411 (id3->length / 10000));
413 else {
414 /* no TOC exists. set a rough estimate using average bitrate */
415 int tpk = id3->length / (id3->filesize / 1024);
416 id3->elapsed = id3->offset / 1024 * tpk;
419 else
420 /* constant bitrate, use exact calculation */
421 id3->elapsed = id3->offset / (id3->bitrate / 8);
424 int audio_get_file_pos(void)
426 int pos = -1;
427 struct mp3entry *id3 = audio_current_track();
429 if (id3->vbr)
431 if (id3->has_toc)
433 /* Use the TOC to find the new position */
434 unsigned int percent, remainder;
435 int curtoc, nexttoc, plen;
437 percent = (id3->elapsed*100)/id3->length;
438 if (percent > 99)
439 percent = 99;
441 curtoc = id3->toc[percent];
443 if (percent < 99)
444 nexttoc = id3->toc[percent+1];
445 else
446 nexttoc = 256;
448 pos = (id3->filesize/256)*curtoc;
450 /* Use the remainder to get a more accurate position */
451 remainder = (id3->elapsed*100)%id3->length;
452 remainder = (remainder*100)/id3->length;
453 plen = (nexttoc - curtoc)*(id3->filesize/256);
454 pos += (plen/100)*remainder;
456 else
458 /* No TOC exists, estimate the new position */
459 pos = (id3->filesize / (id3->length / 1000)) *
460 (id3->elapsed / 1000);
463 else if (id3->bitrate)
464 pos = id3->elapsed * (id3->bitrate / 8);
465 else
467 return -1;
470 if (pos >= (int)(id3->filesize - id3->id3v1len))
472 /* Don't seek right to the end of the file so that we can
473 transition properly to the next song */
474 pos = id3->filesize - id3->id3v1len - 1;
476 else if (pos < (int)id3->first_frame_offset)
478 /* skip past id3v2 tag and other leading garbage */
479 pos = id3->first_frame_offset;
481 return pos;
484 unsigned long mpeg_get_last_header(void)
486 #ifdef SIMULATOR
487 return 0;
488 #else /* !SIMULATOR */
489 unsigned long tmp[2];
491 /* Read the frame data from the MAS and reconstruct it with the
492 frame sync and all */
493 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
494 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
495 #endif /* !SIMULATOR */
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 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
510 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
514 /* Send callback events to notify about new tracks. */
515 static void generate_postbuffer_events(void)
517 int i;
518 int numentries = num_tracks_in_memory();
519 int cur_idx = track_read_idx;
521 for (i = 0; i < numentries; i++)
523 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
524 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
528 static void recalculate_watermark(int bitrate)
530 int bytes_per_sec;
531 int time = storage_spinup_time();
533 /* A bitrate of 0 probably means empty VBR header. We play safe
534 and set a high threshold */
535 if(bitrate == 0)
536 bitrate = 320;
538 bytes_per_sec = bitrate * 1000 / 8;
540 if(time)
542 /* No drive spins up faster than 3.5s */
543 if(time < 350)
544 time = 350;
546 time = time * 3;
547 low_watermark = ((low_watermark_margin * HZ + time) *
548 bytes_per_sec) / HZ;
550 else
552 low_watermark = MPEG_LOW_WATER;
556 #ifdef HAVE_DISK_STORAGE
557 void audio_set_buffer_margin(int setting)
559 low_watermark_margin = setting; /* in seconds */
561 #endif
563 void audio_get_debugdata(struct audio_debug *dbgdata)
565 dbgdata->audiobuflen = audiobuflen;
566 dbgdata->audiobuf_write = audiobuf_write;
567 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
568 dbgdata->audiobuf_read = audiobuf_read;
570 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
572 #if CONFIG_CPU == SH7034
573 dbgdata->dma_on = (SCR0 & 0x80) != 0;
574 #endif
575 dbgdata->playing = playing;
576 dbgdata->play_pending = play_pending;
577 dbgdata->is_playing = is_playing;
578 dbgdata->filling = filling;
579 dbgdata->dma_underrun = dma_underrun;
581 dbgdata->unplayed_space = get_unplayed_space();
582 dbgdata->playable_space = get_playable_space();
583 dbgdata->unswapped_space = get_unswapped_space();
585 dbgdata->low_watermark_level = low_watermark;
586 dbgdata->lowest_watermark_level = lowest_watermark_level;
589 #ifdef DEBUG
590 static void dbg_timer_start(void)
592 /* We are using timer 2 */
594 TSTR &= ~0x04; /* Stop the timer */
595 TSNC &= ~0x04; /* No synchronization */
596 TMDR &= ~0x44; /* Operate normally */
598 TCNT2 = 0; /* Start counting at 0 */
599 TCR2 = 0x03; /* Sysclock/8 */
601 TSTR |= 0x04; /* Start timer 2 */
604 static int dbg_cnt2us(unsigned int cnt)
606 return (cnt * 10000) / (FREQ/800);
608 #endif /* DEBUG */
610 static int get_unplayed_space(void)
612 int space = audiobuf_write - audiobuf_read;
613 if (space < 0)
614 space += audiobuflen;
615 return space;
618 static int get_playable_space(void)
620 int space = audiobuf_swapwrite - audiobuf_read;
621 if (space < 0)
622 space += audiobuflen;
623 return space;
626 static int get_unplayed_space_current_song(void)
628 int space;
630 if (num_tracks_in_memory() > 1)
632 space = get_trackdata(1)->mempos - audiobuf_read;
634 else
636 space = audiobuf_write - audiobuf_read;
639 if (space < 0)
640 space += audiobuflen;
642 return space;
645 static int get_unswapped_space(void)
647 int space = audiobuf_write - audiobuf_swapwrite;
648 if (space < 0)
649 space += audiobuflen;
650 return space;
653 #if CONFIG_CODEC == MAS3587F
654 static int get_unsaved_space(void)
656 int space = audiobuf_write - audiobuf_read;
657 if (space < 0)
658 space += audiobuflen;
659 return space;
662 static void drain_dma_buffer(void)
664 while (PBDRH & 0x40)
666 xor_b(0x08, &PADRH);
668 while (PBDRH & 0x80);
670 xor_b(0x08, &PADRH);
672 while (!(PBDRH & 0x80));
676 #ifdef DEBUG
677 static long timing_info_index = 0;
678 static long timing_info[1024];
679 #endif /* DEBUG */
681 void rec_tick (void) __attribute__ ((section (".icode")));
682 void rec_tick(void)
684 int i;
685 int delay;
686 char data;
688 if(is_recording && (PBDRH & 0x40))
690 #ifdef DEBUG
691 timing_info[timing_info_index++] = current_tick;
692 TCNT2 = 0;
693 #endif /* DEBUG */
694 /* Note: Although this loop is run in interrupt context, further
695 * optimisation will do no good. The MAS would then deliver bad
696 * frames occasionally, as observed in extended experiments. */
697 i = 0;
698 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
700 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
702 delay = 100;
703 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
705 if (--delay <= 0) /* Bail out if we have to wait too long */
706 { /* i.e. the MAS doesn't want to talk to us */
707 xor_b(0x08, &PADRH); /* Set PR inactive */
708 goto transfer_end; /* and get out of here */
712 data = *(unsigned char *)0x04000000; /* read data byte */
714 xor_b(0x08, &PADRH); /* Set PR inactive */
716 audiobuf[audiobuf_write++] = data;
718 if (audiobuf_write >= audiobuflen)
719 audiobuf_write = 0;
721 i++;
723 transfer_end:
725 #ifdef DEBUG
726 timing_info[timing_info_index++] = TCNT2 + (i << 16);
727 timing_info_index &= 0x3ff;
728 #endif /* DEBUG */
730 num_rec_bytes += i;
732 if(is_prerecording)
734 if(TIME_AFTER(current_tick, prerecord_timeout))
736 prerecord_timeout = current_tick + HZ;
737 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
740 else
742 /* Signal to save the data if we are running out of buffer
743 space */
744 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
745 && saving_status == NOT_SAVING)
747 saving_status = BUFFER_FULL;
748 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
753 #endif /* CONFIG_CODEC == MAS3587F */
755 void playback_tick(void)
757 struct trackdata *ptd = get_trackdata(0);
758 if(ptd)
760 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
761 last_dma_tick = current_tick;
762 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
763 (unsigned long)ptd->id3.elapsed);
767 static void reset_mp3_buffer(void)
769 audiobuf_read = 0;
770 audiobuf_write = 0;
771 audiobuf_swapwrite = 0;
772 lowest_watermark_level = audiobuflen;
775 /* DMA transfer end interrupt callback */
776 static void transfer_end(unsigned char** ppbuf, size_t* psize)
778 if(playing && !paused)
780 int unplayed_space_left;
781 int space_until_end_of_buffer;
782 int track_offset = 1;
783 struct trackdata *track;
785 audiobuf_read += last_dma_chunk_size;
786 if(audiobuf_read >= audiobuflen)
787 audiobuf_read = 0;
789 /* First, check if we are on a track boundary */
790 if (num_tracks_in_memory() > 1)
792 if (audiobuf_read == get_trackdata(track_offset)->mempos)
794 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
796 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
797 track_offset++;
802 unplayed_space_left = get_unplayed_space();
804 space_until_end_of_buffer = audiobuflen - audiobuf_read;
806 if(!filling && unplayed_space_left < low_watermark)
808 filling = true;
809 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
812 if(unplayed_space_left)
814 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
815 last_dma_chunk_size = MIN(last_dma_chunk_size,
816 space_until_end_of_buffer);
818 /* several tracks loaded? */
819 track = get_trackdata(track_offset);
820 if(track)
822 /* will we move across the track boundary? */
823 if (( audiobuf_read < track->mempos ) &&
824 ((audiobuf_read+last_dma_chunk_size) >
825 track->mempos ))
827 /* Make sure that we end exactly on the boundary */
828 last_dma_chunk_size = track->mempos - audiobuf_read;
832 *psize = last_dma_chunk_size & 0xffff;
833 *ppbuf = audiobuf + audiobuf_read;
834 track = get_trackdata(0);
835 if(track)
836 track->id3.offset += last_dma_chunk_size;
838 /* Update the watermark debug level */
839 if(unplayed_space_left < lowest_watermark_level)
840 lowest_watermark_level = unplayed_space_left;
842 else
844 /* Check if the end of data is because of a hard disk error.
845 If there is an open file handle, we are still playing music.
846 If not, the last file has been loaded, and the file handle is
847 closed. */
848 if(mpeg_file >= 0)
850 /* Update the watermark debug level */
851 if(unplayed_space_left < lowest_watermark_level)
852 lowest_watermark_level = unplayed_space_left;
854 DEBUGF("DMA underrun.\n");
855 dma_underrun = true;
857 else
859 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
861 DEBUGF("No more MP3 data. Stopping.\n");
862 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
863 playing = false;
866 *psize = 0; /* no more transfer */
871 static struct trackdata *add_track_to_tag_list(const char *filename)
873 struct trackdata *track;
874 bool send_nid3_event;
876 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
878 DEBUGF("Tag memory is full\n");
879 return NULL;
882 track = &trackdata[track_write_idx];
884 /* grab id3 tag of new file and
885 remember where in memory it starts */
886 if(mp3info(&track->id3, filename))
888 DEBUGF("Bad mp3\n");
889 return NULL;
891 track->mempos = audiobuf_write;
892 track->id3.elapsed = 0;
893 #ifdef HAVE_LCD_BITMAP
894 if (track->id3.title)
895 lcd_getstringsize(track->id3.title, NULL, NULL);
896 if (track->id3.artist)
897 lcd_getstringsize(track->id3.artist, NULL, NULL);
898 if (track->id3.album)
899 lcd_getstringsize(track->id3.album, NULL, NULL);
900 #endif
902 /* if this track is the next track then let the UI know it can get it */
903 send_nid3_event = (track_write_idx == track_read_idx + 1);
904 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
905 if (send_nid3_event)
906 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
907 debug_tags();
908 return track;
911 static int new_file(int steps)
913 int max_steps = playlist_amount();
914 int start = 0;
915 int i;
916 struct trackdata *track;
918 /* Find out how many steps to advance. The load_ahead_index field tells
919 us how many playlist entries it had to skip to get to a valid one.
920 We add those together to find out where to start. */
921 if(steps > 0 && num_tracks_in_memory() > 1)
923 /* Begin with the song after the currently playing one */
924 i = 1;
925 while((track = get_trackdata(i++)))
927 start += track->load_ahead_index;
931 do {
932 char *trackname;
934 trackname = playlist_peek( start + steps );
935 if ( !trackname )
936 return -1;
938 DEBUGF("Loading %s\n", trackname);
940 mpeg_file = open(trackname, O_RDONLY);
941 if(mpeg_file < 0) {
942 DEBUGF("Couldn't open file: %s\n",trackname);
943 if(steps < 0)
944 steps--;
945 else
946 steps++;
948 else
950 struct trackdata *track = add_track_to_tag_list(trackname);
952 if(!track)
954 /* Bad mp3 file */
955 if(steps < 0)
956 steps--;
957 else
958 steps++;
959 close(mpeg_file);
960 mpeg_file = -1;
962 else
964 /* skip past id3v2 tag */
965 lseek(mpeg_file,
966 track->id3.first_frame_offset,
967 SEEK_SET);
968 track->id3.index = steps;
969 track->load_ahead_index = steps;
970 track->id3.offset = 0;
972 if(track->id3.vbr)
973 /* Average bitrate * 1.5 */
974 recalculate_watermark(
975 (track->id3.bitrate * 3) / 2);
976 else
977 recalculate_watermark(
978 track->id3.bitrate);
983 /* Bail out if no file could be opened */
984 if(abs(steps) > max_steps)
985 return -1;
986 } while ( mpeg_file < 0 );
988 return 0;
991 static void stop_playing(void)
993 struct trackdata *track;
995 /* Stop the current stream */
996 mp3_play_stop();
997 playing = false;
998 filling = false;
1000 track = get_trackdata(0);
1001 if (track != NULL)
1002 prev_track_elapsed = track->id3.elapsed;
1004 if(mpeg_file >= 0)
1005 close(mpeg_file);
1006 mpeg_file = -1;
1007 remove_all_tags();
1008 generate_unbuffer_events();
1009 reset_mp3_buffer();
1012 static void end_current_track(void) {
1013 struct trackdata *track;
1015 play_pending = false;
1016 playing = false;
1017 mp3_play_pause(false);
1019 track = get_trackdata(0);
1020 if (track != NULL)
1021 prev_track_elapsed = track->id3.elapsed;
1023 reset_mp3_buffer();
1024 remove_all_tags();
1025 generate_unbuffer_events();
1027 if(mpeg_file >= 0)
1028 close(mpeg_file);
1031 /* Is this a really the end of playback or is a new playlist starting */
1032 static void check_playlist_end(int direction)
1034 /* Use the largest possible step size to account for skipped tracks */
1035 int steps = playlist_amount();
1037 if (direction < 0)
1038 steps = -steps;
1040 if (playlist_next(steps) < 0)
1041 is_playing = false;
1044 static void update_playlist(void)
1046 if (num_tracks_in_memory() > 0)
1048 struct trackdata *track = get_trackdata(0);
1049 track->id3.index = playlist_next(track->id3.index);
1051 else
1053 /* End of playlist? */
1054 check_playlist_end(1);
1057 playlist_update_resume_info(audio_current_track());
1060 static void track_change(void)
1062 DEBUGF("Track change\n");
1064 struct trackdata *track = get_trackdata(0);
1065 prev_track_elapsed = track->id3.elapsed;
1067 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1068 /* Reset the AVC */
1069 sound_set_avc(-1);
1070 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1072 if (num_tracks_in_memory() > 0)
1074 remove_current_tag();
1075 update_playlist();
1076 if (is_playing)
1077 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1080 current_track_counter++;
1083 unsigned long audio_prev_elapsed(void)
1085 return prev_track_elapsed;
1088 #ifdef DEBUG
1089 void hexdump(const unsigned char *buf, int len)
1091 int i;
1093 for(i = 0;i < len;i++)
1095 if(i && (i & 15) == 0)
1097 DEBUGF("\n");
1099 DEBUGF("%02x ", buf[i]);
1101 DEBUGF("\n");
1103 #endif /* DEBUG */
1105 static void start_playback_if_ready(void)
1107 int playable_space;
1109 playable_space = audiobuf_swapwrite - audiobuf_read;
1110 if(playable_space < 0)
1111 playable_space += audiobuflen;
1113 /* See if we have started playing yet. If not, do it. */
1114 if(play_pending || dma_underrun)
1116 /* If the filling has stopped, and we still haven't reached
1117 the watermark, the file must be smaller than the
1118 watermark. We must still play it. */
1119 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1120 !filling || dma_underrun)
1122 DEBUGF("P\n");
1123 if (play_pending) /* don't do this when recovering from DMA underrun */
1125 generate_postbuffer_events(); /* signal first track as buffered */
1126 if (play_pending_track_change)
1128 play_pending_track_change = false;
1129 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1131 play_pending = false;
1133 playing = true;
1135 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1136 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1137 dma_underrun = false;
1139 if (!paused)
1141 last_dma_tick = current_tick;
1142 mp3_play_pause(true);
1145 /* Tell ourselves that we need more data */
1146 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1151 static bool swap_one_chunk(void)
1153 int free_space_left;
1154 int amount_to_swap;
1156 free_space_left = get_unswapped_space();
1158 if(free_space_left == 0 && !play_pending)
1159 return false;
1161 /* Swap in larger chunks when the user is waiting for the playback
1162 to start, or when there is dangerously little playable data left */
1163 if(play_pending)
1164 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1165 else
1167 if(get_playable_space() < low_watermark)
1168 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1169 free_space_left);
1170 else
1171 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1174 if(audiobuf_write < audiobuf_swapwrite)
1175 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1176 amount_to_swap);
1177 else
1178 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1179 amount_to_swap);
1181 bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap);
1183 audiobuf_swapwrite += amount_to_swap;
1184 if(audiobuf_swapwrite >= audiobuflen)
1186 audiobuf_swapwrite = 0;
1189 return true;
1192 static void mpeg_thread(void)
1194 static int pause_tick = 0;
1195 static unsigned int pause_track = 0;
1196 struct queue_event ev;
1197 int len;
1198 int free_space_left;
1199 int unplayed_space_left;
1200 int amount_to_read;
1201 int t1, t2;
1202 int start_offset;
1203 #if CONFIG_CODEC == MAS3587F
1204 int amount_to_save;
1205 int save_endpos = 0;
1206 int rc;
1207 int level;
1208 long offset;
1209 #endif /* CONFIG_CODEC == MAS3587F */
1211 is_playing = false;
1212 play_pending = false;
1213 playing = false;
1214 mpeg_file = -1;
1216 while(1)
1218 #if CONFIG_CODEC == MAS3587F
1219 if(mpeg_mode == MPEG_DECODER)
1221 #endif /* CONFIG_CODEC == MAS3587F */
1222 yield();
1224 /* Swap if necessary, and don't block on the queue_wait() */
1225 if(swap_one_chunk())
1227 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1229 else if (playing)
1231 /* periodically update resume info */
1232 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1234 else
1236 DEBUGF("S R:%x W:%x SW:%x\n",
1237 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1238 queue_wait(&mpeg_queue, &ev);
1241 start_playback_if_ready();
1243 switch(ev.id)
1245 case MPEG_PLAY:
1246 DEBUGF("MPEG_PLAY\n");
1248 #if CONFIG_TUNER
1249 /* Silence the A/D input, it may be on because the radio
1250 may be playing */
1251 mas_codec_writereg(6, 0x0000);
1252 #endif /* CONFIG_TUNER */
1254 /* Stop the current stream */
1255 paused = false;
1256 end_current_track();
1258 if ( new_file(0) == -1 )
1260 is_playing = false;
1261 track_change();
1262 break;
1265 start_offset = (int)ev.data;
1267 /* mid-song resume? */
1268 if (start_offset) {
1269 struct mp3entry* id3 = &get_trackdata(0)->id3;
1270 lseek(mpeg_file, start_offset, SEEK_SET);
1271 id3->offset = start_offset;
1272 set_elapsed(id3);
1274 else {
1275 /* skip past id3v2 tag */
1276 lseek(mpeg_file,
1277 get_trackdata(0)->id3.first_frame_offset,
1278 SEEK_SET);
1282 /* Make it read more data */
1283 filling = true;
1284 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1286 /* Tell the file loading code that we want to start playing
1287 as soon as we have some data */
1288 play_pending = true;
1289 play_pending_track_change = true;
1291 update_playlist();
1292 current_track_counter++;
1293 break;
1295 case MPEG_STOP:
1296 DEBUGF("MPEG_STOP\n");
1297 is_playing = false;
1298 paused = false;
1300 if (playing)
1301 playlist_update_resume_info(audio_current_track());
1303 stop_playing();
1304 mpeg_stop_done = true;
1305 break;
1307 case MPEG_PAUSE:
1308 DEBUGF("MPEG_PAUSE\n");
1309 /* Stop the current stream */
1310 if (playing)
1311 playlist_update_resume_info(audio_current_track());
1312 paused = true;
1313 playing = false;
1314 pause_tick = current_tick;
1315 pause_track = current_track_counter;
1316 mp3_play_pause(false);
1317 break;
1319 case MPEG_RESUME:
1320 DEBUGF("MPEG_RESUME\n");
1321 /* Continue the current stream */
1322 paused = false;
1323 if (!play_pending)
1325 playing = true;
1326 if ( current_track_counter == pause_track )
1327 last_dma_tick += current_tick - pause_tick;
1328 else
1329 last_dma_tick = current_tick;
1330 pause_tick = 0;
1331 mp3_play_pause(true);
1333 break;
1335 case MPEG_NEXT:
1336 DEBUGF("MPEG_NEXT\n");
1337 /* is next track in ram? */
1338 if ( num_tracks_in_memory() > 1 ) {
1339 int unplayed_space_left, unswapped_space_left;
1341 /* stop the current stream */
1342 play_pending = false;
1343 playing = false;
1344 mp3_play_pause(false);
1346 track_change();
1347 audiobuf_read = get_trackdata(0)->mempos;
1348 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1349 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1350 dma_underrun = false;
1351 last_dma_tick = current_tick;
1353 unplayed_space_left = get_unplayed_space();
1354 unswapped_space_left = get_unswapped_space();
1356 /* should we start reading more data? */
1357 if(!filling && (unplayed_space_left < low_watermark)) {
1358 filling = true;
1359 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1360 play_pending = true;
1361 } else if(unswapped_space_left &&
1362 unswapped_space_left > unplayed_space_left) {
1363 /* Stop swapping the data from the previous file */
1364 audiobuf_swapwrite = audiobuf_read;
1365 play_pending = true;
1366 } else {
1367 playing = true;
1368 if (!paused)
1369 mp3_play_pause(true);
1372 else {
1373 if (!playlist_check(1))
1374 break;
1376 /* stop the current stream */
1377 end_current_track();
1379 if (new_file(1) < 0) {
1380 DEBUGF("No more files to play\n");
1381 filling = false;
1383 check_playlist_end(1);
1384 current_track_counter++;
1385 } else {
1386 /* Make it read more data */
1387 filling = true;
1388 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1390 /* Tell the file loading code that we want
1391 to start playing as soon as we have some data */
1392 play_pending = true;
1393 play_pending_track_change = true;
1395 update_playlist();
1396 current_track_counter++;
1399 break;
1401 case MPEG_PREV: {
1402 DEBUGF("MPEG_PREV\n");
1404 if (!playlist_check(-1))
1405 break;
1407 /* stop the current stream */
1408 end_current_track();
1410 /* Open the next file */
1411 if (new_file(-1) < 0) {
1412 DEBUGF("No more files to play\n");
1413 filling = false;
1415 check_playlist_end(-1);
1416 current_track_counter++;
1417 } else {
1418 /* Make it read more data */
1419 filling = true;
1420 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1422 /* Tell the file loading code that we want to
1423 start playing as soon as we have some data */
1424 play_pending = true;
1425 play_pending_track_change = true;
1427 update_playlist();
1428 current_track_counter++;
1430 break;
1433 case MPEG_FF_REWIND: {
1434 struct mp3entry *id3 = audio_current_track();
1435 unsigned int oldtime = id3->elapsed;
1436 unsigned int newtime = (unsigned int)ev.data;
1437 int curpos, newpos, diffpos;
1438 DEBUGF("MPEG_FF_REWIND\n");
1440 id3->elapsed = newtime;
1442 newpos = audio_get_file_pos();
1443 if(newpos < 0)
1445 id3->elapsed = oldtime;
1446 break;
1449 if (mpeg_file >= 0)
1450 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1451 else
1452 curpos = id3->filesize;
1454 if (num_tracks_in_memory() > 1)
1456 /* We have started loading other tracks that need to be
1457 accounted for */
1458 struct trackdata *track;
1459 int i = 0;
1461 while((track = get_trackdata(i++)))
1463 curpos += track->id3.filesize;
1467 diffpos = curpos - newpos;
1469 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1471 int unplayed_space_left, unswapped_space_left;
1473 /* We are changing to a position that's already in
1474 memory, so we just move the DMA read pointer. */
1475 audiobuf_read = audiobuf_write - diffpos;
1476 if (audiobuf_read < 0)
1478 audiobuf_read += audiobuflen;
1481 unplayed_space_left = get_unplayed_space();
1482 unswapped_space_left = get_unswapped_space();
1484 /* If unswapped_space_left is larger than
1485 unplayed_space_left, it means that the swapwrite pointer
1486 hasn't yet advanced up to the new location of the read
1487 pointer. We just move it, there is no need to swap
1488 data that won't be played anyway. */
1490 if (unswapped_space_left > unplayed_space_left)
1492 DEBUGF("Moved swapwrite\n");
1493 audiobuf_swapwrite = audiobuf_read;
1494 play_pending = true;
1497 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1499 /* We need to load more data before starting */
1500 filling = true;
1501 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1502 play_pending = true;
1504 else
1506 /* resume will start at new position */
1507 last_dma_chunk_size =
1508 MIN(0x2000, get_unplayed_space_current_song());
1509 mp3_play_data(audiobuf + audiobuf_read,
1510 last_dma_chunk_size, transfer_end);
1511 dma_underrun = false;
1514 else
1516 /* Move to the new position in the file and start
1517 loading data */
1518 reset_mp3_buffer();
1520 if (num_tracks_in_memory() > 1)
1522 /* We have to reload the current track */
1523 close(mpeg_file);
1524 remove_all_non_current_tags();
1525 generate_unbuffer_events();
1526 mpeg_file = -1;
1529 if (mpeg_file < 0)
1531 mpeg_file = open(id3->path, O_RDONLY);
1532 if (mpeg_file < 0)
1534 id3->elapsed = oldtime;
1535 break;
1539 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1541 id3->elapsed = oldtime;
1542 break;
1545 filling = true;
1546 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1548 /* Tell the file loading code that we want to start playing
1549 as soon as we have some data */
1550 play_pending = true;
1553 id3->offset = newpos;
1555 break;
1558 case MPEG_FLUSH_RELOAD: {
1559 int numtracks = num_tracks_in_memory();
1560 bool reload_track = false;
1562 if (numtracks > 1)
1564 /* Reset the buffer */
1565 audiobuf_write = get_trackdata(1)->mempos;
1567 /* Reset swapwrite unless we're still swapping current
1568 track */
1569 if (get_unplayed_space() <= get_playable_space())
1570 audiobuf_swapwrite = audiobuf_write;
1572 close(mpeg_file);
1573 remove_all_non_current_tags();
1574 generate_unbuffer_events();
1575 mpeg_file = -1;
1576 reload_track = true;
1578 else if (numtracks == 1 && mpeg_file < 0)
1580 reload_track = true;
1583 if(reload_track && new_file(1) >= 0)
1585 /* Tell ourselves that we want more data */
1586 filling = true;
1587 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1590 break;
1593 case MPEG_NEED_DATA:
1594 free_space_left = audiobuf_read - audiobuf_write;
1596 /* We interpret 0 as "empty buffer" */
1597 if(free_space_left <= 0)
1598 free_space_left += audiobuflen;
1600 unplayed_space_left = audiobuflen - free_space_left;
1602 /* Make sure that we don't fill the entire buffer */
1603 free_space_left -= MPEG_HIGH_WATER;
1605 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1606 generate_unbuffer_events();
1608 /* do we have any more buffer space to fill? */
1609 if(free_space_left <= 0)
1611 DEBUGF("0\n");
1612 filling = false;
1613 generate_postbuffer_events();
1614 storage_sleep();
1615 break;
1618 /* Read small chunks while we are below the low water mark */
1619 if(unplayed_space_left < low_watermark)
1620 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1621 free_space_left);
1622 else
1623 amount_to_read = free_space_left;
1625 /* Don't read more than until the end of the buffer */
1626 amount_to_read = MIN(audiobuflen - audiobuf_write,
1627 amount_to_read);
1628 #if (CONFIG_STORAGE & STORAGE_MMC)
1629 /* MMC is slow, so don't read too large chunks */
1630 amount_to_read = MIN(0x40000, amount_to_read);
1631 #elif MEM == 8
1632 amount_to_read = MIN(0x100000, amount_to_read);
1633 #endif
1635 /* Read as much mpeg data as we can fit in the buffer */
1636 if(mpeg_file >= 0)
1638 DEBUGF("R\n");
1639 t1 = current_tick;
1640 len = read(mpeg_file, audiobuf + audiobuf_write,
1641 amount_to_read);
1642 if(len > 0)
1644 t2 = current_tick;
1645 DEBUGF("time: %d\n", t2 - t1);
1646 DEBUGF("R: %x\n", len);
1648 /* Now make sure that we don't feed the MAS with ID3V1
1649 data */
1650 if (len < amount_to_read)
1652 int i;
1653 static const unsigned char tag[] = "TAG";
1654 int taglen = 128;
1655 int tagptr = audiobuf_write + len - 128;
1657 /* Really rare case: entire potential tag wasn't
1658 read in this call AND audiobuf_write < 128 */
1659 if (tagptr < 0)
1660 tagptr += audiobuflen;
1662 for(i = 0;i < 3;i++)
1664 if(tagptr >= audiobuflen)
1665 tagptr -= audiobuflen;
1667 if(audiobuf[tagptr] != tag[i])
1669 taglen = 0;
1670 break;
1673 tagptr++;
1676 if(taglen)
1678 /* Skip id3v1 tag */
1679 DEBUGF("Skipping ID3v1 tag\n");
1680 len -= taglen;
1682 /* In the very rare case when the entire tag
1683 wasn't read in this read() len will be < 0.
1684 Take care of this when changing the write
1685 pointer. */
1689 audiobuf_write += len;
1691 if (audiobuf_write < 0)
1692 audiobuf_write += audiobuflen;
1694 if(audiobuf_write >= audiobuflen)
1696 audiobuf_write = 0;
1697 DEBUGF("W\n");
1700 /* Tell ourselves that we want more data */
1701 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1703 else
1705 if(len < 0)
1707 DEBUGF("MPEG read error\n");
1710 close(mpeg_file);
1711 mpeg_file = -1;
1713 if(new_file(1) < 0)
1715 /* No more data to play */
1716 DEBUGF("No more files to play\n");
1717 filling = false;
1719 else
1721 /* Tell ourselves that we want more data */
1722 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1726 break;
1728 case MPEG_TRACK_CHANGE:
1729 track_change();
1730 break;
1732 #ifndef USB_NONE
1733 case SYS_USB_CONNECTED:
1734 is_playing = false;
1735 paused = false;
1736 stop_playing();
1738 /* Tell the USB thread that we are safe */
1739 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1740 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1742 /* Wait until the USB cable is extracted again */
1743 usb_wait_for_disconnect(&mpeg_queue);
1744 break;
1745 #endif /* !USB_NONE */
1747 #if CONFIG_CODEC == MAS3587F
1748 case MPEG_INIT_RECORDING:
1749 init_recording();
1750 init_recording_done = true;
1751 break;
1752 #endif /* CONFIG_CODEC == MAS3587F */
1754 case SYS_TIMEOUT:
1755 if (playing)
1756 playlist_update_resume_info(audio_current_track());
1757 break;
1759 #if CONFIG_CODEC == MAS3587F
1761 else
1763 queue_wait(&mpeg_queue, &ev);
1764 switch(ev.id)
1766 case MPEG_RECORD:
1767 if (is_prerecording)
1769 int startpos;
1771 /* Go back prerecord_count seconds in the buffer */
1772 startpos = prerecord_index - prerecord_count;
1773 if(startpos < 0)
1774 startpos += prerecording_max_seconds;
1776 /* Read the position data from the prerecord buffer */
1777 frame_count_start = prerecord_buffer[startpos].framecount;
1778 startpos = prerecord_buffer[startpos].mempos;
1780 DEBUGF("Start looking at address %x (%x)\n",
1781 audiobuf+startpos, startpos);
1783 saved_header = mpeg_get_last_header();
1785 mem_find_next_frame(startpos, &offset, 1800,
1786 saved_header);
1788 audiobuf_read = startpos + offset;
1789 if(audiobuf_read >= audiobuflen)
1790 audiobuf_read -= audiobuflen;
1792 DEBUGF("New audiobuf_read address: %x (%x)\n",
1793 audiobuf+audiobuf_read, audiobuf_read);
1795 level = disable_irq_save();
1796 num_rec_bytes = get_unsaved_space();
1797 restore_irq(level);
1799 else
1801 frame_count_start = 0;
1802 num_rec_bytes = 0;
1803 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1804 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1807 prepend_header();
1808 DEBUGF("Recording...\n");
1809 start_recording();
1811 /* Wait until at least one frame is encoded and get the
1812 frame header, for later use by the Xing header
1813 generation */
1814 sleep(HZ/5);
1815 saved_header = mpeg_get_last_header();
1817 /* delayed until buffer is saved, don't open yet */
1818 strcpy(delayed_filename, recording_filename);
1819 mpeg_file = -1;
1821 break;
1823 case MPEG_STOP:
1824 DEBUGF("MPEG_STOP\n");
1826 stop_recording();
1828 /* Save the remaining data in the buffer */
1829 save_endpos = audiobuf_write;
1830 saving_status = STOP_RECORDING;
1831 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1832 break;
1834 case MPEG_STOP_DONE:
1835 DEBUGF("MPEG_STOP_DONE\n");
1837 if (mpeg_file >= 0)
1838 close(mpeg_file);
1839 mpeg_file = -1;
1841 update_header();
1842 #ifdef DEBUG1
1844 int i;
1845 for(i = 0;i < 512;i++)
1847 DEBUGF("%d - %d us (%d bytes)\n",
1848 timing_info[i*2],
1849 (timing_info[i*2+1] & 0xffff) *
1850 10000 / 13824,
1851 timing_info[i*2+1] >> 16);
1854 #endif /* DEBUG1 */
1856 if (prerecording)
1858 start_prerecording();
1860 mpeg_stop_done = true;
1861 break;
1863 case MPEG_NEW_FILE:
1864 /* Bail out when a more important save is happening */
1865 if (saving_status > NEW_FILE)
1866 break;
1868 /* Make sure we have at least one complete frame
1869 in the buffer. If we haven't recorded a single
1870 frame within 200ms, the MAS is probably not recording
1871 anything, and we bail out. */
1872 amount_to_save = get_unsaved_space();
1873 if (amount_to_save < 1800)
1875 sleep(HZ/5);
1876 amount_to_save = get_unsaved_space();
1879 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1880 &frame_count_end, 1);
1882 last_rec_time = current_tick - record_start_time;
1883 record_start_time = current_tick;
1884 if (paused)
1885 pause_start_time = record_start_time;
1887 /* capture all values at one point */
1888 level = disable_irq_save();
1889 save_endpos = audiobuf_write;
1890 last_rec_bytes = num_rec_bytes;
1891 num_rec_bytes = 0;
1892 restore_irq(level);
1894 if (amount_to_save >= 1800)
1896 /* Now find a frame boundary to split at */
1897 save_endpos -= 1800;
1898 if (save_endpos < 0)
1899 save_endpos += audiobuflen;
1901 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1902 saved_header);
1903 if (!rc) /* No header found, save whole buffer */
1904 offset = 1800;
1906 save_endpos += offset;
1907 if (save_endpos >= audiobuflen)
1908 save_endpos -= audiobuflen;
1910 last_rec_bytes += offset - 1800;
1911 level = disable_irq_save();
1912 num_rec_bytes += 1800 - offset;
1913 restore_irq(level);
1916 saving_status = NEW_FILE;
1917 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1918 break;
1920 case MPEG_SAVE_DATA:
1921 if (saving_status == BUFFER_FULL)
1922 save_endpos = audiobuf_write;
1924 if (mpeg_file < 0) /* delayed file open */
1926 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
1928 if (mpeg_file < 0)
1929 panicf("recfile: %d", mpeg_file);
1932 amount_to_save = save_endpos - audiobuf_read;
1933 if (amount_to_save < 0)
1934 amount_to_save += audiobuflen;
1936 amount_to_save = MIN(amount_to_save,
1937 audiobuflen - audiobuf_read);
1938 #if (CONFIG_STORAGE & STORAGE_MMC)
1939 /* MMC is slow, so don't save too large chunks at once */
1940 amount_to_save = MIN(0x40000, amount_to_save);
1941 #elif MEM == 8
1942 amount_to_save = MIN(0x100000, amount_to_save);
1943 #endif
1944 rc = write(mpeg_file, audiobuf + audiobuf_read,
1945 amount_to_save);
1946 if (rc < 0)
1948 if (errno == ENOSPC)
1950 mpeg_errno = AUDIOERR_DISK_FULL;
1951 stop_recording();
1952 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1953 /* will close the file */
1954 break;
1956 else
1957 panicf("rec wrt: %d", rc);
1960 audiobuf_read += amount_to_save;
1961 if (audiobuf_read >= audiobuflen)
1962 audiobuf_read = 0;
1964 if (audiobuf_read == save_endpos) /* all saved */
1966 switch (saving_status)
1968 case BUFFER_FULL:
1969 rc = fsync(mpeg_file);
1970 if (rc < 0)
1971 panicf("rec fls: %d", rc);
1972 storage_sleep();
1973 break;
1975 case NEW_FILE:
1976 /* Close the current file */
1977 rc = close(mpeg_file);
1978 if (rc < 0)
1979 panicf("rec cls: %d", rc);
1980 mpeg_file = -1;
1981 update_header();
1982 storage_sleep();
1984 /* copy new filename */
1985 strcpy(delayed_filename, recording_filename);
1986 prepend_header();
1987 frame_count_start = frame_count_end;
1988 break;
1990 case STOP_RECORDING:
1991 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1992 /* will close the file */
1993 break;
1995 default:
1996 break;
1998 saving_status = NOT_SAVING;
2000 else /* tell ourselves to save the next chunk */
2001 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2003 break;
2005 case MPEG_PRERECORDING_TICK:
2006 if(!is_prerecording)
2007 break;
2009 /* Store the write pointer every second */
2010 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2011 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2012 &prerecord_buffer[prerecord_index].framecount, 1);
2014 /* Wrap if necessary */
2015 if(++prerecord_index == prerecording_max_seconds)
2016 prerecord_index = 0;
2018 /* Update the number of seconds recorded */
2019 if(prerecord_count < prerecording_max_seconds)
2020 prerecord_count++;
2021 break;
2023 case MPEG_INIT_PLAYBACK:
2024 /* Stop the prerecording */
2025 stop_recording();
2026 reset_mp3_buffer();
2027 mp3_play_init();
2028 init_playback_done = true;
2029 break;
2031 case MPEG_PAUSE_RECORDING:
2032 pause_recording();
2033 break;
2035 case MPEG_RESUME_RECORDING:
2036 resume_recording();
2037 break;
2039 case SYS_USB_CONNECTED:
2040 /* We can safely go to USB mode if no recording
2041 is taking place */
2042 if((!is_recording || is_prerecording) && mpeg_stop_done)
2044 /* Even if we aren't recording, we still call this
2045 function, to put the MAS in monitoring mode,
2046 to save power. */
2047 stop_recording();
2049 /* Tell the USB thread that we are safe */
2050 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2051 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2053 /* Wait until the USB cable is extracted again */
2054 usb_wait_for_disconnect(&mpeg_queue);
2056 break;
2059 #endif /* CONFIG_CODEC == MAS3587F */
2062 #endif /* !SIMULATOR */
2064 struct mp3entry* audio_current_track(void)
2066 #ifdef SIMULATOR
2067 struct mp3entry *id3 = &taginfo;
2068 #else /* !SIMULATOR */
2069 if(num_tracks_in_memory())
2071 struct mp3entry *id3 = &get_trackdata(0)->id3;
2072 #endif
2073 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2075 checked_for_cuesheet = true; /* only check once per track */
2076 char cuepath[MAX_PATH];
2078 if (look_for_cuesheet_file(id3->path, cuepath) &&
2079 parse_cuesheet(cuepath, curr_cuesheet))
2081 id3->cuesheet = curr_cuesheet;
2082 cue_spoof_id3(curr_cuesheet, id3);
2085 return id3;
2086 #ifndef SIMULATOR
2088 else
2089 return NULL;
2090 #endif /* !SIMULATOR */
2093 struct mp3entry* audio_next_track(void)
2095 #ifdef SIMULATOR
2096 return &taginfo;
2097 #else /* !SIMULATOR */
2098 if(num_tracks_in_memory() > 1)
2099 return &get_trackdata(1)->id3;
2100 else
2101 return NULL;
2102 #endif /* !SIMULATOR */
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(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(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 strlcpy(recording_filename, filename, MAX_PATH);
2242 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2245 void audio_pause_recording(void)
2247 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2250 void audio_resume_recording(void)
2252 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2255 static void prepend_header(void)
2257 int startpos;
2258 unsigned i;
2260 /* Make room for header */
2261 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2262 if(audiobuf_read < 0)
2264 /* Clear the bottom half */
2265 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2267 /* And the top half */
2268 audiobuf_read += audiobuflen;
2269 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2271 else
2273 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2275 /* Copy the empty ID3 header */
2276 startpos = audiobuf_read;
2277 for(i = 0; i < sizeof(empty_id3_header); i++)
2279 audiobuf[startpos++] = empty_id3_header[i];
2280 if(startpos == audiobuflen)
2281 startpos = 0;
2285 static void update_header(void)
2287 int fd, framelen;
2288 unsigned long frames;
2290 if (last_rec_bytes > 0)
2292 /* Create the Xing header */
2293 fd = open(delayed_filename, O_RDWR);
2294 if (fd < 0)
2295 panicf("rec upd: %d (%s)", fd, recording_filename);
2297 frames = frame_count_end - frame_count_start;
2298 /* If the number of recorded frames has reached 0x7ffff,
2299 we can no longer trust it */
2300 if (frame_count_end == 0x7ffff)
2301 frames = 0;
2303 /* saved_header is saved right before stopping the MAS */
2304 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2305 frames, last_rec_time * (1000/HZ),
2306 saved_header, NULL, false);
2308 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2309 write(fd, xing_buffer, framelen);
2310 close(fd);
2314 static void start_prerecording(void)
2316 unsigned long val;
2318 DEBUGF("Starting prerecording\n");
2320 prerecord_index = 0;
2321 prerecord_count = 0;
2322 prerecord_timeout = current_tick + HZ;
2323 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2324 reset_mp3_buffer();
2326 is_prerecording = true;
2328 /* Stop monitoring and start the encoder */
2329 shadow_io_control_main &= ~(1 << 10);
2330 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2331 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2333 /* Wait until the DSP has accepted the settings */
2336 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2337 } while(val & 1);
2339 is_recording = true;
2340 saving_status = NOT_SAVING;
2342 demand_irq_enable(true);
2345 static void start_recording(void)
2347 unsigned long val;
2349 if(is_prerecording)
2351 /* This will make the IRQ handler start recording
2352 for real, i.e send MPEG_SAVE_DATA messages when
2353 the buffer is full */
2354 is_prerecording = false;
2356 else
2358 /* If prerecording is off, we need to stop the monitoring
2359 and start the encoder */
2360 shadow_io_control_main &= ~(1 << 10);
2361 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2362 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2364 /* Wait until the DSP has accepted the settings */
2367 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2368 } while(val & 1);
2371 is_recording = true;
2372 saving_status = NOT_SAVING;
2373 paused = false;
2375 /* Store the current time */
2376 if(prerecording)
2377 record_start_time = current_tick - prerecord_count * HZ;
2378 else
2379 record_start_time = current_tick;
2381 pause_start_time = 0;
2383 demand_irq_enable(true);
2386 static void pause_recording(void)
2388 pause_start_time = current_tick;
2390 /* Set the pause bit */
2391 shadow_soft_mute |= 2;
2392 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2394 paused = true;
2397 static void resume_recording(void)
2399 paused = false;
2401 /* Clear the pause bit */
2402 shadow_soft_mute &= ~2;
2403 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2405 /* Compensate for the time we have been paused */
2406 if(pause_start_time)
2408 record_start_time =
2409 current_tick - (pause_start_time - record_start_time);
2410 pause_start_time = 0;
2414 static void stop_recording(void)
2416 unsigned long val;
2418 /* Let it finish the last frame */
2419 if(!paused)
2420 pause_recording();
2421 sleep(HZ/5);
2423 demand_irq_enable(false);
2425 is_recording = false;
2426 is_prerecording = false;
2428 last_rec_bytes = num_rec_bytes;
2429 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2430 last_rec_time = current_tick - record_start_time;
2432 /* Start monitoring */
2433 shadow_io_control_main |= (1 << 10);
2434 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2435 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2437 /* Wait until the DSP has accepted the settings */
2440 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2441 } while(val & 1);
2443 resume_recording();
2446 void audio_set_recording_options(struct audio_recording_options *options)
2448 bool is_mpeg1;
2450 is_mpeg1 = (options->rec_frequency < 3);
2452 rec_version_index = is_mpeg1?3:2;
2453 rec_frequency_index = options->rec_frequency % 3;
2455 shadow_encoder_control = (options->rec_quality << 17) |
2456 (rec_frequency_index << 10) |
2457 ((is_mpeg1?1:0) << 9) |
2458 (((options->rec_channels * 2 + 1) & 3) << 6) |
2459 (1 << 5) /* MS-stereo */ |
2460 (1 << 2) /* Is an original */;
2461 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2463 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2465 #if CONFIG_TUNER & S1A0903X01
2466 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2467 interference with the Samsung tuner. */
2468 if (rec_frequency_index)
2469 mas_store_pllfreq(24576000);
2470 else
2471 mas_store_pllfreq(22579000);
2472 #endif
2474 shadow_soft_mute = options->rec_editable?4:0;
2475 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2477 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2479 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2480 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2481 (1 << 5) | /* SDO strobe invert */
2482 ((is_mpeg1?0:1) << 3) |
2483 (1 << 2) | /* Inverted SIBC clock signal */
2484 1; /* Validate */
2485 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2487 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2489 if(options->rec_source == AUDIO_SRC_MIC)
2491 /* Copy left channel to right (mono mode) */
2492 mas_codec_writereg(8, 0x8000);
2494 else
2496 /* Stereo input mode */
2497 mas_codec_writereg(8, 0);
2500 prerecording_max_seconds = options->rec_prerecord_time;
2501 if(prerecording_max_seconds)
2503 prerecording = true;
2504 start_prerecording();
2506 else
2508 prerecording = false;
2509 is_prerecording = false;
2510 is_recording = false;
2514 /* If use_mic is true, the left gain is used */
2515 void audio_set_recording_gain(int left, int right, int type)
2517 /* Enable both left and right A/D */
2518 shadow_codec_reg0 = (left << 12) |
2519 (right << 8) |
2520 (left << 4) |
2521 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2522 0x0007;
2523 mas_codec_writereg(0x0, shadow_codec_reg0);
2526 /* try to make some kind of beep, also in recording mode */
2527 void audio_beep(int duration)
2529 long starttick = current_tick;
2531 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2532 * While this is still audible even without an external signal,
2533 * it doesn't affect the (pre-)recording. */
2534 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2535 mas_codec_writereg(0, shadow_codec_reg0);
2536 yield();
2538 while (current_tick - starttick < duration);
2541 void audio_new_file(const char *filename)
2543 mpeg_errno = 0;
2545 strlcpy(recording_filename, filename, MAX_PATH);
2547 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2550 unsigned long audio_recorded_time(void)
2552 if(is_prerecording)
2553 return prerecord_count * HZ;
2555 if(is_recording)
2557 if(paused)
2558 return pause_start_time - record_start_time;
2559 else
2560 return current_tick - record_start_time;
2563 return 0;
2566 unsigned long audio_num_recorded_bytes(void)
2568 int num_bytes;
2569 int index;
2571 if(is_recording)
2573 if(is_prerecording)
2575 index = prerecord_index - prerecord_count;
2576 if(index < 0)
2577 index += prerecording_max_seconds;
2579 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2580 if(num_bytes < 0)
2581 num_bytes += audiobuflen;
2583 return num_bytes;
2585 else
2586 return num_rec_bytes;
2588 else
2589 return 0;
2592 #else /* SIMULATOR */
2594 /* dummies coming up */
2596 void audio_init_playback(void)
2598 /* a dummy */
2600 unsigned long audio_recorded_time(void)
2602 /* a dummy */
2603 return 0;
2605 void audio_beep(int duration)
2607 /* a dummy */
2608 (void)duration;
2610 void audio_pause_recording(void)
2612 /* a dummy */
2614 void audio_resume_recording(void)
2616 /* a dummy */
2618 unsigned long audio_num_recorded_bytes(void)
2620 /* a dummy */
2621 return 0;
2623 void audio_record(const char *filename)
2625 /* a dummy */
2626 (void)filename;
2628 void audio_new_file(const char *filename)
2630 /* a dummy */
2631 (void)filename;
2634 void audio_set_recording_gain(int left, int right, int type)
2636 /* a dummy */
2637 (void)left;
2638 (void)right;
2639 (void)type;
2641 void audio_init_recording(unsigned int buffer_offset)
2643 /* a dummy */
2644 (void)buffer_offset;
2646 void audio_set_recording_options(struct audio_recording_options *options)
2648 /* a dummy */
2649 (void)options;
2651 #endif /* SIMULATOR */
2652 #endif /* CONFIG_CODEC == MAS3587F */
2654 void audio_play(long offset)
2656 #ifdef SIMULATOR
2657 char* trackname;
2658 int steps=0;
2660 is_playing = true;
2662 do {
2663 trackname = playlist_peek( steps );
2664 if (!trackname)
2665 break;
2666 if(mp3info(&taginfo, trackname)) {
2667 /* bad mp3, move on */
2668 if(++steps > playlist_amount())
2669 break;
2670 continue;
2672 #ifdef HAVE_MPEG_PLAY
2673 real_mpeg_play(trackname);
2674 #endif
2675 playlist_next(steps);
2676 taginfo.offset = offset;
2677 set_elapsed(&taginfo);
2678 is_playing = true;
2679 playing = true;
2680 break;
2681 } while(1);
2682 #else /* !SIMULATOR */
2683 is_playing = true;
2685 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2686 #endif /* !SIMULATOR */
2688 mpeg_errno = 0;
2691 void audio_stop(void)
2693 #ifndef SIMULATOR
2694 if (playing)
2696 struct trackdata *track = get_trackdata(0);
2697 prev_track_elapsed = track->id3.elapsed;
2699 mpeg_stop_done = false;
2700 queue_post(&mpeg_queue, MPEG_STOP, 0);
2701 while(!mpeg_stop_done)
2702 yield();
2703 #else /* SIMULATOR */
2704 paused = false;
2705 is_playing = false;
2706 playing = false;
2707 #endif /* SIMULATOR */
2710 /* dummy */
2711 void audio_stop_recording(void)
2713 audio_stop();
2716 void audio_pause(void)
2718 #ifndef SIMULATOR
2719 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2720 #else /* SIMULATOR */
2721 is_playing = true;
2722 playing = false;
2723 paused = true;
2724 #endif /* SIMULATOR */
2727 void audio_resume(void)
2729 #ifndef SIMULATOR
2730 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2731 #else /* SIMULATOR */
2732 is_playing = true;
2733 playing = true;
2734 paused = false;
2735 #endif /* SIMULATOR */
2738 void audio_next(void)
2740 #ifndef SIMULATOR
2741 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2742 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2743 #else /* SIMULATOR */
2744 char* file;
2745 int steps = 1;
2746 int index;
2748 do {
2749 file = playlist_peek(steps);
2750 if(!file)
2751 break;
2752 if(mp3info(&taginfo, file)) {
2753 if(++steps > playlist_amount())
2754 break;
2755 continue;
2757 index = playlist_next(steps);
2758 taginfo.index = index;
2759 current_track_counter++;
2760 is_playing = true;
2761 playing = true;
2762 break;
2763 } while(1);
2764 #endif /* SIMULATOR */
2767 void audio_prev(void)
2769 #ifndef SIMULATOR
2770 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2771 queue_post(&mpeg_queue, MPEG_PREV, 0);
2772 #else /* SIMULATOR */
2773 char* file;
2774 int steps = -1;
2775 int index;
2777 do {
2778 file = playlist_peek(steps);
2779 if(!file)
2780 break;
2781 if(mp3info(&taginfo, file)) {
2782 steps--;
2783 continue;
2785 index = playlist_next(steps);
2786 taginfo.index = index;
2787 current_track_counter++;
2788 is_playing = true;
2789 playing = true;
2790 break;
2791 } while(1);
2792 #endif /* SIMULATOR */
2795 void audio_ff_rewind(long newpos)
2797 #ifndef SIMULATOR
2798 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2799 #else /* SIMULATOR */
2800 (void)newpos;
2801 #endif /* SIMULATOR */
2804 void audio_flush_and_reload_tracks(void)
2806 #ifndef SIMULATOR
2807 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2808 #endif /* !SIMULATOR*/
2811 int audio_status(void)
2813 int ret = 0;
2815 if(is_playing)
2816 ret |= AUDIO_STATUS_PLAY;
2818 if(paused)
2819 ret |= AUDIO_STATUS_PAUSE;
2821 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2822 if(is_recording && !is_prerecording)
2823 ret |= AUDIO_STATUS_RECORD;
2825 if(is_prerecording)
2826 ret |= AUDIO_STATUS_PRERECORD;
2827 #endif /* CONFIG_CODEC == MAS3587F */
2829 if(mpeg_errno)
2830 ret |= AUDIO_STATUS_ERROR;
2832 return ret;
2835 /* Unused function
2836 unsigned int audio_error(void)
2838 return mpeg_errno;
2842 void audio_error_clear(void)
2844 mpeg_errno = 0;
2847 #ifdef SIMULATOR
2848 static void mpeg_thread(void)
2850 struct mp3entry* id3;
2851 while ( 1 ) {
2852 if (is_playing) {
2853 id3 = audio_current_track();
2854 if (!paused)
2856 id3->elapsed+=1000;
2857 id3->offset+=1000;
2859 if (id3->elapsed>=id3->length)
2860 audio_next();
2862 sleep(HZ);
2865 #endif /* SIMULATOR */
2867 void audio_init(void)
2869 mpeg_errno = 0;
2870 /* cuesheet support */
2871 if (global_settings.cuesheet)
2872 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2874 #ifndef SIMULATOR
2875 audiobuflen = audiobufend - audiobuf;
2876 queue_init(&mpeg_queue, true);
2877 #endif /* !SIMULATOR */
2878 create_thread(mpeg_thread, mpeg_stack,
2879 sizeof(mpeg_stack), 0, mpeg_thread_name
2880 IF_PRIO(, PRIORITY_SYSTEM)
2881 IF_COP(, CPU));
2883 memset(trackdata, 0, sizeof(trackdata));
2885 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2886 if (HW_MASK & PR_ACTIVE_HIGH)
2887 and_b(~0x08, &PADRH);
2888 else
2889 or_b(0x08, &PADRH);
2890 #endif /* CONFIG_CODEC == MAS3587F */
2892 #ifdef DEBUG
2893 #ifndef SIMULATOR
2894 dbg_timer_start();
2895 dbg_cnt2us(0);
2896 #endif /* !SIMULATOR */
2897 #endif /* DEBUG */
2900 #endif /* CONFIG_CODEC != SWCODEC */