Build doom on clipv2 and clip+
[kugel-rb.git] / apps / mpeg.c
blob1ba491ce8917ccaff43afa61f57e34938a6deb64
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 const 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 const 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;
2084 return id3;
2085 #ifndef SIMULATOR
2087 else
2088 return NULL;
2089 #endif /* !SIMULATOR */
2092 struct mp3entry* audio_next_track(void)
2094 #ifdef SIMULATOR
2095 return &taginfo;
2096 #else /* !SIMULATOR */
2097 if(num_tracks_in_memory() > 1)
2098 return &get_trackdata(1)->id3;
2099 else
2100 return NULL;
2101 #endif /* !SIMULATOR */
2104 #if CONFIG_CODEC == MAS3587F
2105 #ifndef SIMULATOR
2106 void audio_init_playback(void)
2108 init_playback_done = false;
2109 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2111 while(!init_playback_done)
2112 sleep(1);
2116 /****************************************************************************
2117 * Recording functions
2118 ***************************************************************************/
2119 void audio_init_recording(unsigned int buffer_offset)
2121 buffer_offset = buffer_offset;
2122 init_recording_done = false;
2123 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2125 while(!init_recording_done)
2126 sleep(1);
2129 static void init_recording(void)
2131 unsigned long val;
2132 int rc;
2134 /* Disable IRQ6 */
2135 IPRB &= 0xff0f;
2137 stop_playing();
2138 is_playing = false;
2139 paused = false;
2141 /* Init the recording variables */
2142 is_recording = false;
2143 is_prerecording = false;
2145 mpeg_stop_done = true;
2147 mas_reset();
2149 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2150 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2151 if(rc < 0)
2152 panicf("mas_ctrl_w: %d", rc);
2154 /* Stop the current application */
2155 val = 0;
2156 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2159 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2160 } while(val);
2162 /* Perform black magic as described by the data sheet */
2163 if((mas_version_code & 0x0fff) == 0x0102)
2165 DEBUGF("Performing MAS black magic for B2 version\n");
2166 mas_writereg(0xa3, 0x98);
2167 mas_writereg(0x94, 0xfffff);
2168 val = 0;
2169 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2170 mas_writereg(0xa3, 0x90);
2173 /* Enable A/D Converters */
2174 shadow_codec_reg0 = 0xcccd;
2175 mas_codec_writereg(0x0, shadow_codec_reg0);
2177 /* Copy left channel to right (mono mode) */
2178 mas_codec_writereg(8, 0x8000);
2180 /* ADC scale 0%, DSP scale 100%
2181 We use the DSP output for monitoring, because it works with all
2182 sources including S/PDIF */
2183 mas_codec_writereg(6, 0x0000);
2184 mas_codec_writereg(7, 0x4000);
2186 /* No mute */
2187 shadow_soft_mute = 0;
2188 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2190 #ifdef HAVE_SPDIF_OUT
2191 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2192 #else
2193 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2194 #endif
2195 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2197 /* Set Demand mode, monitoring OFF and validate all settings */
2198 shadow_io_control_main = 0x125;
2199 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2201 /* Start the encoder application */
2202 val = 0x40;
2203 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2206 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2207 } while(!(val & 0x40));
2209 /* We have started the recording application with monitoring OFF.
2210 This is because we want to record at least one frame to fill the DMA
2211 buffer, because the silly MAS will not negate EOD until at least one
2212 DMA transfer has taken place.
2213 Now let's wait for some data to be encoded. */
2214 sleep(HZ/5);
2216 /* Now set it to Monitoring mode as default, saves power */
2217 shadow_io_control_main = 0x525;
2218 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2220 /* Wait until the DSP has accepted the settings */
2223 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2224 } while(val & 1);
2226 drain_dma_buffer();
2227 mpeg_mode = MPEG_ENCODER;
2229 DEBUGF("MAS Recording application started\n");
2231 /* At this point, all settings are the reset MAS defaults, next thing is to
2232 call mpeg_set_recording_options(). */
2235 void audio_record(const char *filename)
2237 mpeg_errno = 0;
2239 strlcpy(recording_filename, filename, MAX_PATH);
2241 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2244 void audio_pause_recording(void)
2246 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2249 void audio_resume_recording(void)
2251 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2254 static void prepend_header(void)
2256 int startpos;
2257 unsigned i;
2259 /* Make room for header */
2260 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2261 if(audiobuf_read < 0)
2263 /* Clear the bottom half */
2264 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2266 /* And the top half */
2267 audiobuf_read += audiobuflen;
2268 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2270 else
2272 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2274 /* Copy the empty ID3 header */
2275 startpos = audiobuf_read;
2276 for(i = 0; i < sizeof(empty_id3_header); i++)
2278 audiobuf[startpos++] = empty_id3_header[i];
2279 if(startpos == audiobuflen)
2280 startpos = 0;
2284 static void update_header(void)
2286 int fd, framelen;
2287 unsigned long frames;
2289 if (last_rec_bytes > 0)
2291 /* Create the Xing header */
2292 fd = open(delayed_filename, O_RDWR);
2293 if (fd < 0)
2294 panicf("rec upd: %d (%s)", fd, recording_filename);
2296 frames = frame_count_end - frame_count_start;
2297 /* If the number of recorded frames has reached 0x7ffff,
2298 we can no longer trust it */
2299 if (frame_count_end == 0x7ffff)
2300 frames = 0;
2302 /* saved_header is saved right before stopping the MAS */
2303 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2304 frames, last_rec_time * (1000/HZ),
2305 saved_header, NULL, false);
2307 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2308 write(fd, xing_buffer, framelen);
2309 close(fd);
2313 static void start_prerecording(void)
2315 unsigned long val;
2317 DEBUGF("Starting prerecording\n");
2319 prerecord_index = 0;
2320 prerecord_count = 0;
2321 prerecord_timeout = current_tick + HZ;
2322 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2323 reset_mp3_buffer();
2325 is_prerecording = true;
2327 /* Stop monitoring and start the encoder */
2328 shadow_io_control_main &= ~(1 << 10);
2329 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2330 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2332 /* Wait until the DSP has accepted the settings */
2335 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2336 } while(val & 1);
2338 is_recording = true;
2339 saving_status = NOT_SAVING;
2341 demand_irq_enable(true);
2344 static void start_recording(void)
2346 unsigned long val;
2348 if(is_prerecording)
2350 /* This will make the IRQ handler start recording
2351 for real, i.e send MPEG_SAVE_DATA messages when
2352 the buffer is full */
2353 is_prerecording = false;
2355 else
2357 /* If prerecording is off, we need to stop the monitoring
2358 and start the encoder */
2359 shadow_io_control_main &= ~(1 << 10);
2360 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2361 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2363 /* Wait until the DSP has accepted the settings */
2366 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2367 } while(val & 1);
2370 is_recording = true;
2371 saving_status = NOT_SAVING;
2372 paused = false;
2374 /* Store the current time */
2375 if(prerecording)
2376 record_start_time = current_tick - prerecord_count * HZ;
2377 else
2378 record_start_time = current_tick;
2380 pause_start_time = 0;
2382 demand_irq_enable(true);
2385 static void pause_recording(void)
2387 pause_start_time = current_tick;
2389 /* Set the pause bit */
2390 shadow_soft_mute |= 2;
2391 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2393 paused = true;
2396 static void resume_recording(void)
2398 paused = false;
2400 /* Clear the pause bit */
2401 shadow_soft_mute &= ~2;
2402 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2404 /* Compensate for the time we have been paused */
2405 if(pause_start_time)
2407 record_start_time =
2408 current_tick - (pause_start_time - record_start_time);
2409 pause_start_time = 0;
2413 static void stop_recording(void)
2415 unsigned long val;
2417 /* Let it finish the last frame */
2418 if(!paused)
2419 pause_recording();
2420 sleep(HZ/5);
2422 demand_irq_enable(false);
2424 is_recording = false;
2425 is_prerecording = false;
2427 last_rec_bytes = num_rec_bytes;
2428 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2429 last_rec_time = current_tick - record_start_time;
2431 /* Start monitoring */
2432 shadow_io_control_main |= (1 << 10);
2433 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2434 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2436 /* Wait until the DSP has accepted the settings */
2439 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2440 } while(val & 1);
2442 resume_recording();
2445 void audio_set_recording_options(struct audio_recording_options *options)
2447 bool is_mpeg1;
2449 is_mpeg1 = (options->rec_frequency < 3);
2451 rec_version_index = is_mpeg1?3:2;
2452 rec_frequency_index = options->rec_frequency % 3;
2454 shadow_encoder_control = (options->rec_quality << 17) |
2455 (rec_frequency_index << 10) |
2456 ((is_mpeg1?1:0) << 9) |
2457 (((options->rec_channels * 2 + 1) & 3) << 6) |
2458 (1 << 5) /* MS-stereo */ |
2459 (1 << 2) /* Is an original */;
2460 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2462 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2464 #if CONFIG_TUNER & S1A0903X01
2465 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2466 interference with the Samsung tuner. */
2467 if (rec_frequency_index)
2468 mas_store_pllfreq(24576000);
2469 else
2470 mas_store_pllfreq(22579000);
2471 #endif
2473 shadow_soft_mute = options->rec_editable?4:0;
2474 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2476 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2478 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2479 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2480 (1 << 5) | /* SDO strobe invert */
2481 ((is_mpeg1?0:1) << 3) |
2482 (1 << 2) | /* Inverted SIBC clock signal */
2483 1; /* Validate */
2484 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2486 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2488 if(options->rec_source == AUDIO_SRC_MIC)
2490 /* Copy left channel to right (mono mode) */
2491 mas_codec_writereg(8, 0x8000);
2493 else
2495 /* Stereo input mode */
2496 mas_codec_writereg(8, 0);
2499 prerecording_max_seconds = options->rec_prerecord_time;
2500 if(prerecording_max_seconds)
2502 prerecording = true;
2503 start_prerecording();
2505 else
2507 prerecording = false;
2508 is_prerecording = false;
2509 is_recording = false;
2513 /* If use_mic is true, the left gain is used */
2514 void audio_set_recording_gain(int left, int right, int type)
2516 /* Enable both left and right A/D */
2517 shadow_codec_reg0 = (left << 12) |
2518 (right << 8) |
2519 (left << 4) |
2520 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2521 0x0007;
2522 mas_codec_writereg(0x0, shadow_codec_reg0);
2525 /* try to make some kind of beep, also in recording mode */
2526 void audio_beep(int duration)
2528 long starttick = current_tick;
2530 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2531 * While this is still audible even without an external signal,
2532 * it doesn't affect the (pre-)recording. */
2533 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2534 mas_codec_writereg(0, shadow_codec_reg0);
2535 yield();
2537 while (current_tick - starttick < duration);
2540 void audio_new_file(const char *filename)
2542 mpeg_errno = 0;
2544 strlcpy(recording_filename, filename, MAX_PATH);
2546 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2549 unsigned long audio_recorded_time(void)
2551 if(is_prerecording)
2552 return prerecord_count * HZ;
2554 if(is_recording)
2556 if(paused)
2557 return pause_start_time - record_start_time;
2558 else
2559 return current_tick - record_start_time;
2562 return 0;
2565 unsigned long audio_num_recorded_bytes(void)
2567 int num_bytes;
2568 int index;
2570 if(is_recording)
2572 if(is_prerecording)
2574 index = prerecord_index - prerecord_count;
2575 if(index < 0)
2576 index += prerecording_max_seconds;
2578 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2579 if(num_bytes < 0)
2580 num_bytes += audiobuflen;
2582 return num_bytes;
2584 else
2585 return num_rec_bytes;
2587 else
2588 return 0;
2591 #else /* SIMULATOR */
2593 /* dummies coming up */
2595 void audio_init_playback(void)
2597 /* a dummy */
2599 unsigned long audio_recorded_time(void)
2601 /* a dummy */
2602 return 0;
2604 void audio_beep(int duration)
2606 /* a dummy */
2607 (void)duration;
2609 void audio_pause_recording(void)
2611 /* a dummy */
2613 void audio_resume_recording(void)
2615 /* a dummy */
2617 unsigned long audio_num_recorded_bytes(void)
2619 /* a dummy */
2620 return 0;
2622 void audio_record(const char *filename)
2624 /* a dummy */
2625 (void)filename;
2627 void audio_new_file(const char *filename)
2629 /* a dummy */
2630 (void)filename;
2633 void audio_set_recording_gain(int left, int right, int type)
2635 /* a dummy */
2636 (void)left;
2637 (void)right;
2638 (void)type;
2640 void audio_init_recording(unsigned int buffer_offset)
2642 /* a dummy */
2643 (void)buffer_offset;
2645 void audio_set_recording_options(struct audio_recording_options *options)
2647 /* a dummy */
2648 (void)options;
2650 #endif /* SIMULATOR */
2651 #endif /* CONFIG_CODEC == MAS3587F */
2653 void audio_play(long offset)
2655 #ifdef SIMULATOR
2656 const char* trackname;
2657 int steps=0;
2659 is_playing = true;
2661 do {
2662 trackname = playlist_peek( steps );
2663 if (!trackname)
2664 break;
2665 if(mp3info(&taginfo, trackname)) {
2666 /* bad mp3, move on */
2667 if(++steps > playlist_amount())
2668 break;
2669 continue;
2671 #ifdef HAVE_MPEG_PLAY
2672 real_mpeg_play(trackname);
2673 #endif
2674 playlist_next(steps);
2675 taginfo.offset = offset;
2676 set_elapsed(&taginfo);
2677 is_playing = true;
2678 playing = true;
2679 break;
2680 } while(1);
2681 #else /* !SIMULATOR */
2682 is_playing = true;
2684 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2685 #endif /* !SIMULATOR */
2687 mpeg_errno = 0;
2690 void audio_stop(void)
2692 #ifndef SIMULATOR
2693 if (playing)
2695 struct trackdata *track = get_trackdata(0);
2696 prev_track_elapsed = track->id3.elapsed;
2698 mpeg_stop_done = false;
2699 queue_post(&mpeg_queue, MPEG_STOP, 0);
2700 while(!mpeg_stop_done)
2701 yield();
2702 #else /* SIMULATOR */
2703 paused = false;
2704 is_playing = false;
2705 playing = false;
2706 #endif /* SIMULATOR */
2709 /* dummy */
2710 void audio_stop_recording(void)
2712 audio_stop();
2715 void audio_pause(void)
2717 #ifndef SIMULATOR
2718 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2719 #else /* SIMULATOR */
2720 is_playing = true;
2721 playing = false;
2722 paused = true;
2723 #endif /* SIMULATOR */
2726 void audio_resume(void)
2728 #ifndef SIMULATOR
2729 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2730 #else /* SIMULATOR */
2731 is_playing = true;
2732 playing = true;
2733 paused = false;
2734 #endif /* SIMULATOR */
2737 void audio_next(void)
2739 #ifndef SIMULATOR
2740 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2741 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2742 #else /* SIMULATOR */
2743 const char* file;
2744 int steps = 1;
2745 int index;
2747 do {
2748 file = playlist_peek(steps);
2749 if(!file)
2750 break;
2751 if(mp3info(&taginfo, file)) {
2752 if(++steps > playlist_amount())
2753 break;
2754 continue;
2756 index = playlist_next(steps);
2757 taginfo.index = index;
2758 current_track_counter++;
2759 is_playing = true;
2760 playing = true;
2761 break;
2762 } while(1);
2763 #endif /* SIMULATOR */
2766 void audio_prev(void)
2768 #ifndef SIMULATOR
2769 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2770 queue_post(&mpeg_queue, MPEG_PREV, 0);
2771 #else /* SIMULATOR */
2772 const char* file;
2773 int steps = -1;
2774 int index;
2776 do {
2777 file = playlist_peek(steps);
2778 if(!file)
2779 break;
2780 if(mp3info(&taginfo, file)) {
2781 steps--;
2782 continue;
2784 index = playlist_next(steps);
2785 taginfo.index = index;
2786 current_track_counter++;
2787 is_playing = true;
2788 playing = true;
2789 break;
2790 } while(1);
2791 #endif /* SIMULATOR */
2794 void audio_ff_rewind(long newpos)
2796 #ifndef SIMULATOR
2797 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2798 #else /* SIMULATOR */
2799 (void)newpos;
2800 #endif /* SIMULATOR */
2803 void audio_flush_and_reload_tracks(void)
2805 #ifndef SIMULATOR
2806 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2807 #endif /* !SIMULATOR*/
2810 int audio_status(void)
2812 int ret = 0;
2814 if(is_playing)
2815 ret |= AUDIO_STATUS_PLAY;
2817 if(paused)
2818 ret |= AUDIO_STATUS_PAUSE;
2820 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2821 if(is_recording && !is_prerecording)
2822 ret |= AUDIO_STATUS_RECORD;
2824 if(is_prerecording)
2825 ret |= AUDIO_STATUS_PRERECORD;
2826 #endif /* CONFIG_CODEC == MAS3587F */
2828 if(mpeg_errno)
2829 ret |= AUDIO_STATUS_ERROR;
2831 return ret;
2834 /* Unused function
2835 unsigned int audio_error(void)
2837 return mpeg_errno;
2841 void audio_error_clear(void)
2843 mpeg_errno = 0;
2846 #ifdef SIMULATOR
2847 static void mpeg_thread(void)
2849 struct mp3entry* id3;
2850 while ( 1 ) {
2851 if (is_playing) {
2852 id3 = audio_current_track();
2853 if (!paused)
2855 id3->elapsed+=1000;
2856 id3->offset+=1000;
2858 if (id3->elapsed>=id3->length)
2859 audio_next();
2861 sleep(HZ);
2864 #endif /* SIMULATOR */
2866 void audio_init(void)
2868 mpeg_errno = 0;
2869 /* cuesheet support */
2870 if (global_settings.cuesheet)
2871 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2873 #ifndef SIMULATOR
2874 audiobuflen = audiobufend - audiobuf;
2875 queue_init(&mpeg_queue, true);
2876 #endif /* !SIMULATOR */
2877 create_thread(mpeg_thread, mpeg_stack,
2878 sizeof(mpeg_stack), 0, mpeg_thread_name
2879 IF_PRIO(, PRIORITY_SYSTEM)
2880 IF_COP(, CPU));
2882 memset(trackdata, 0, sizeof(trackdata));
2884 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2885 if (HW_MASK & PR_ACTIVE_HIGH)
2886 and_b(~0x08, &PADRH);
2887 else
2888 or_b(0x08, &PADRH);
2889 #endif /* CONFIG_CODEC == MAS3587F */
2891 #ifdef DEBUG
2892 #ifndef SIMULATOR
2893 dbg_timer_start();
2894 dbg_cnt2us(0);
2895 #endif /* !SIMULATOR */
2896 #endif /* DEBUG */
2899 #endif /* CONFIG_CODEC != SWCODEC */