Remove .a files before running ar, to avoid problems with renamed files remaining...
[kugel-rb.git] / apps / mpeg.c
blobf6d48bf42ca42f028ddd5ab6fa89324203159081
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 #ifndef SIMULATOR
44 #include "i2c.h"
45 #include "mas.h"
46 #include "system.h"
47 #include "usb.h"
48 #include "file.h"
49 #include "hwcompat.h"
50 #endif /* !SIMULATOR */
51 #ifdef HAVE_LCD_BITMAP
52 #include "lcd.h"
53 #endif
55 #ifndef SIMULATOR
56 extern unsigned long mas_version_code;
57 #endif
59 #if CONFIG_CODEC == MAS3587F
60 extern enum /* from mp3_playback.c */
62 MPEG_DECODER,
63 MPEG_ENCODER
64 } mpeg_mode;
65 #endif /* CONFIG_CODEC == MAS3587F */
67 extern char* playlist_peek(int steps);
68 extern bool playlist_check(int steps);
69 extern int playlist_next(int steps);
70 extern int playlist_amount(void);
71 extern int playlist_update_resume_info(const struct mp3entry* id3);
73 #define MPEG_PLAY 1
74 #define MPEG_STOP 2
75 #define MPEG_PAUSE 3
76 #define MPEG_RESUME 4
77 #define MPEG_NEXT 5
78 #define MPEG_PREV 6
79 #define MPEG_FF_REWIND 7
80 #define MPEG_FLUSH_RELOAD 8
81 #define MPEG_RECORD 9
82 #define MPEG_INIT_RECORDING 10
83 #define MPEG_INIT_PLAYBACK 11
84 #define MPEG_NEW_FILE 12
85 #define MPEG_PAUSE_RECORDING 13
86 #define MPEG_RESUME_RECORDING 14
87 #define MPEG_NEED_DATA 100
88 #define MPEG_TRACK_CHANGE 101
89 #define MPEG_SAVE_DATA 102
90 #define MPEG_STOP_DONE 103
91 #define MPEG_PRERECORDING_TICK 104
93 /* indicator for MPEG_NEED_DATA */
94 #define GENERATE_UNBUFFER_EVENTS 1
96 /* list of tracks in memory */
97 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
98 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
100 struct trackdata
102 struct mp3entry id3;
103 int mempos;
104 int load_ahead_index;
107 static struct trackdata trackdata[MAX_TRACK_ENTRIES];
109 static unsigned int current_track_counter = 0;
110 static unsigned int last_track_counter = 0;
112 /* Play time of the previous track */
113 unsigned long prev_track_elapsed;
115 #ifndef SIMULATOR
116 static int track_read_idx = 0;
117 static int track_write_idx = 0;
118 #endif /* !SIMULATOR */
120 /* Cuesheet callback */
121 static bool (*cuesheet_callback)(const char *filename) = NULL;
123 static const char mpeg_thread_name[] = "mpeg";
124 static unsigned int mpeg_errno;
126 static bool playing = false; /* We are playing an MP3 stream */
127 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
128 static bool paused; /* playback is paused */
130 #ifdef SIMULATOR
131 static char mpeg_stack[DEFAULT_STACK_SIZE];
132 static struct mp3entry taginfo;
134 #else /* !SIMULATOR */
135 static struct event_queue mpeg_queue;
136 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
138 static int audiobuflen;
139 static int audiobuf_write;
140 static int audiobuf_swapwrite;
141 static int audiobuf_read;
143 static int mpeg_file;
145 static bool play_pending; /* We are about to start playing */
146 static bool play_pending_track_change; /* When starting play we're starting a new file */
147 static bool filling; /* We are filling the buffer with data from disk */
148 static bool dma_underrun; /* True when the DMA has stopped because of
149 slow disk reading (read error, shaking) */
150 static bool mpeg_stop_done;
152 static int last_dma_tick = 0;
153 static int last_dma_chunk_size;
155 static long low_watermark; /* Dynamic low watermark level */
156 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
157 static long lowest_watermark_level; /* Debug value to observe the buffer
158 usage */
159 #if CONFIG_CODEC == MAS3587F
160 static char recording_filename[MAX_PATH]; /* argument to thread */
161 static char delayed_filename[MAX_PATH]; /* internal copy of above */
163 static char xing_buffer[MAX_XING_HEADER_SIZE];
165 static bool init_recording_done;
166 static bool init_playback_done;
167 static bool prerecording; /* True if prerecording is enabled */
168 static bool is_prerecording; /* True if we are prerecording */
169 static bool is_recording; /* We are recording */
171 static enum {
172 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
173 BUFFER_FULL,
174 NEW_FILE,
175 STOP_RECORDING
176 } saving_status;
178 static int rec_frequency_index; /* For create_xing_header() calls */
179 static int rec_version_index; /* For create_xing_header() calls */
181 struct prerecord_info {
182 int mempos;
183 unsigned long framecount;
186 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
187 static int prerecord_index; /* Current index in the prerecord buffer */
188 static int prerecording_max_seconds; /* Max number of seconds to store */
189 static int prerecord_count; /* Number of seconds in the prerecord buffer */
190 static int prerecord_timeout; /* The tick count of the next prerecord data
191 store */
193 unsigned long record_start_time; /* Value of current_tick when recording
194 was started */
195 unsigned long pause_start_time; /* Value of current_tick when pause was
196 started */
197 static unsigned long last_rec_time;
198 static unsigned long num_rec_bytes;
199 static unsigned long last_rec_bytes;
200 static unsigned long frame_count_start;
201 static unsigned long frame_count_end;
202 static unsigned long saved_header = 0;
204 /* Shadow MAS registers */
205 unsigned long shadow_encoder_control = 0;
206 #endif /* CONFIG_CODEC == MAS3587F */
208 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
209 unsigned long shadow_io_control_main = 0;
210 unsigned long shadow_soft_mute = 0;
211 unsigned shadow_codec_reg0;
212 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
214 #ifdef HAVE_RECORDING
215 static const unsigned char empty_id3_header[] =
217 'I', 'D', '3', 0x03, 0x00, 0x00,
218 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
220 #endif /* HAVE_RECORDING */
223 static int get_unplayed_space(void);
224 static int get_playable_space(void);
225 static int get_unswapped_space(void);
226 #endif /* !SIMULATOR */
228 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
229 static void init_recording(void);
230 static void prepend_header(void);
231 static void update_header(void);
232 static void start_prerecording(void);
233 static void start_recording(void);
234 static void stop_recording(void);
235 static int get_unsaved_space(void);
236 static void pause_recording(void);
237 static void resume_recording(void);
238 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
241 #ifndef SIMULATOR
242 static int num_tracks_in_memory(void)
244 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
247 #ifdef DEBUG_TAGS
248 static void debug_tags(void)
250 int i;
252 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
254 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
256 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
257 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
259 #else /* !DEBUG_TAGS */
260 #define debug_tags()
261 #endif /* !DEBUG_TAGS */
263 static void remove_current_tag(void)
265 if(num_tracks_in_memory() > 0)
267 /* First move the index, so nobody tries to access the tag */
268 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
269 debug_tags();
271 else
273 DEBUGF("remove_current_tag: no tracks to remove\n");
277 static void remove_all_non_current_tags(void)
279 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
280 debug_tags();
283 static void remove_all_tags(void)
285 track_write_idx = track_read_idx;
287 debug_tags();
290 static struct trackdata *get_trackdata(int offset)
292 if(offset >= num_tracks_in_memory())
293 return NULL;
294 else
295 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
297 #endif /* !SIMULATOR */
299 /***********************************************************************/
300 /* audio event handling */
302 #define MAX_EVENT_HANDLERS 10
303 struct event_handlers_table
305 AUDIO_EVENT_HANDLER handler;
306 unsigned short mask;
308 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
309 static int event_handlers_count = 0;
311 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
313 if (event_handlers_count < MAX_EVENT_HANDLERS)
315 event_handlers[event_handlers_count].handler = handler;
316 event_handlers[event_handlers_count].mask = mask;
317 event_handlers_count++;
321 /* dispatch calls each handler in the order registered and returns after some
322 handler actually handles the event (the event is assumed to no longer be valid
323 after this, due to the handler changing some condition); returns true if someone
324 handled the event, which is expected to cause the caller to skip its own handling
325 of the event */
326 #ifndef SIMULATOR
327 static bool audio_dispatch_event(unsigned short event, unsigned long data)
329 int i = 0;
330 for(i=0; i < event_handlers_count; i++)
332 if ( event_handlers[i].mask & event )
334 int rc = event_handlers[i].handler(event, data);
335 if ( rc == AUDIO_EVENT_RC_HANDLED )
336 return true;
339 return false;
341 #endif
343 /***********************************************************************/
345 static void set_elapsed(struct mp3entry* id3)
347 if ( id3->vbr ) {
348 if ( id3->has_toc ) {
349 /* calculate elapsed time using TOC */
350 int i;
351 unsigned int remainder, plen, relpos, nextpos;
353 /* find wich percent we're at */
354 for (i=0; i<100; i++ )
356 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
358 break;
362 i--;
363 if (i < 0)
364 i = 0;
366 relpos = id3->toc[i];
368 if (i < 99)
370 nextpos = id3->toc[i+1];
372 else
374 nextpos = 256;
377 remainder = id3->offset - (relpos * (id3->filesize / 256));
379 /* set time for this percent (divide before multiply to prevent
380 overflow on long files. loss of precision is negligible on
381 short files) */
382 id3->elapsed = i * (id3->length / 100);
384 /* calculate remainder time */
385 plen = (nextpos - relpos) * (id3->filesize / 256);
386 id3->elapsed += (((remainder * 100) / plen) *
387 (id3->length / 10000));
389 else {
390 /* no TOC exists. set a rough estimate using average bitrate */
391 int tpk = id3->length / (id3->filesize / 1024);
392 id3->elapsed = id3->offset / 1024 * tpk;
395 else
396 /* constant bitrate, use exact calculation */
397 id3->elapsed = id3->offset / (id3->bitrate / 8);
400 int audio_get_file_pos(void)
402 int pos = -1;
403 struct mp3entry *id3 = audio_current_track();
405 if (id3->vbr)
407 if (id3->has_toc)
409 /* Use the TOC to find the new position */
410 unsigned int percent, remainder;
411 int curtoc, nexttoc, plen;
413 percent = (id3->elapsed*100)/id3->length;
414 if (percent > 99)
415 percent = 99;
417 curtoc = id3->toc[percent];
419 if (percent < 99)
420 nexttoc = id3->toc[percent+1];
421 else
422 nexttoc = 256;
424 pos = (id3->filesize/256)*curtoc;
426 /* Use the remainder to get a more accurate position */
427 remainder = (id3->elapsed*100)%id3->length;
428 remainder = (remainder*100)/id3->length;
429 plen = (nexttoc - curtoc)*(id3->filesize/256);
430 pos += (plen/100)*remainder;
432 else
434 /* No TOC exists, estimate the new position */
435 pos = (id3->filesize / (id3->length / 1000)) *
436 (id3->elapsed / 1000);
439 else if (id3->bitrate)
440 pos = id3->elapsed * (id3->bitrate / 8);
441 else
443 return -1;
446 if (pos >= (int)(id3->filesize - id3->id3v1len))
448 /* Don't seek right to the end of the file so that we can
449 transition properly to the next song */
450 pos = id3->filesize - id3->id3v1len - 1;
452 else if (pos < (int)id3->first_frame_offset)
454 /* skip past id3v2 tag and other leading garbage */
455 pos = id3->first_frame_offset;
457 return pos;
460 unsigned long mpeg_get_last_header(void)
462 #ifdef SIMULATOR
463 return 0;
464 #else /* !SIMULATOR */
465 unsigned long tmp[2];
467 /* Read the frame data from the MAS and reconstruct it with the
468 frame sync and all */
469 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
470 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
471 #endif /* !SIMULATOR */
474 void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
476 cuesheet_callback = handler;
479 #ifndef SIMULATOR
480 /* Send callback events to notify about removing old tracks. */
481 static void generate_unbuffer_events(void)
483 int i;
484 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
485 int cur_idx = track_write_idx;
487 for (i = 0; i < numentries; i++)
489 /* Send an event to notify that track has finished. */
490 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
491 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
495 /* Send callback events to notify about new tracks. */
496 static void generate_postbuffer_events(void)
498 int i;
499 int numentries = num_tracks_in_memory();
500 int cur_idx = track_read_idx;
502 for (i = 0; i < numentries; i++)
504 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
505 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
509 static void recalculate_watermark(int bitrate)
511 int bytes_per_sec;
512 int time = storage_spinup_time();
514 /* A bitrate of 0 probably means empty VBR header. We play safe
515 and set a high threshold */
516 if(bitrate == 0)
517 bitrate = 320;
519 bytes_per_sec = bitrate * 1000 / 8;
521 if(time)
523 /* No drive spins up faster than 3.5s */
524 if(time < 350)
525 time = 350;
527 time = time * 3;
528 low_watermark = ((low_watermark_margin * HZ + time) *
529 bytes_per_sec) / HZ;
531 else
533 low_watermark = MPEG_LOW_WATER;
537 #ifdef HAVE_DISK_STORAGE
538 void audio_set_buffer_margin(int seconds)
540 low_watermark_margin = seconds;
542 #endif
544 void audio_get_debugdata(struct audio_debug *dbgdata)
546 dbgdata->audiobuflen = audiobuflen;
547 dbgdata->audiobuf_write = audiobuf_write;
548 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
549 dbgdata->audiobuf_read = audiobuf_read;
551 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
553 #if CONFIG_CPU == SH7034
554 dbgdata->dma_on = (SCR0 & 0x80) != 0;
555 #endif
556 dbgdata->playing = playing;
557 dbgdata->play_pending = play_pending;
558 dbgdata->is_playing = is_playing;
559 dbgdata->filling = filling;
560 dbgdata->dma_underrun = dma_underrun;
562 dbgdata->unplayed_space = get_unplayed_space();
563 dbgdata->playable_space = get_playable_space();
564 dbgdata->unswapped_space = get_unswapped_space();
566 dbgdata->low_watermark_level = low_watermark;
567 dbgdata->lowest_watermark_level = lowest_watermark_level;
570 #ifdef DEBUG
571 static void dbg_timer_start(void)
573 /* We are using timer 2 */
575 TSTR &= ~0x04; /* Stop the timer */
576 TSNC &= ~0x04; /* No synchronization */
577 TMDR &= ~0x44; /* Operate normally */
579 TCNT2 = 0; /* Start counting at 0 */
580 TCR2 = 0x03; /* Sysclock/8 */
582 TSTR |= 0x04; /* Start timer 2 */
585 static int dbg_cnt2us(unsigned int cnt)
587 return (cnt * 10000) / (FREQ/800);
589 #endif /* DEBUG */
591 static int get_unplayed_space(void)
593 int space = audiobuf_write - audiobuf_read;
594 if (space < 0)
595 space += audiobuflen;
596 return space;
599 static int get_playable_space(void)
601 int space = audiobuf_swapwrite - audiobuf_read;
602 if (space < 0)
603 space += audiobuflen;
604 return space;
607 static int get_unplayed_space_current_song(void)
609 int space;
611 if (num_tracks_in_memory() > 1)
613 space = get_trackdata(1)->mempos - audiobuf_read;
615 else
617 space = audiobuf_write - audiobuf_read;
620 if (space < 0)
621 space += audiobuflen;
623 return space;
626 static int get_unswapped_space(void)
628 int space = audiobuf_write - audiobuf_swapwrite;
629 if (space < 0)
630 space += audiobuflen;
631 return space;
634 #if CONFIG_CODEC == MAS3587F
635 static int get_unsaved_space(void)
637 int space = audiobuf_write - audiobuf_read;
638 if (space < 0)
639 space += audiobuflen;
640 return space;
643 static void drain_dma_buffer(void)
645 while (PBDRH & 0x40)
647 xor_b(0x08, &PADRH);
649 while (PBDRH & 0x80);
651 xor_b(0x08, &PADRH);
653 while (!(PBDRH & 0x80));
657 #ifdef DEBUG
658 static long timing_info_index = 0;
659 static long timing_info[1024];
660 #endif /* DEBUG */
662 void rec_tick (void) __attribute__ ((section (".icode")));
663 void rec_tick(void)
665 int i;
666 int delay;
667 char data;
669 if(is_recording && (PBDRH & 0x40))
671 #ifdef DEBUG
672 timing_info[timing_info_index++] = current_tick;
673 TCNT2 = 0;
674 #endif /* DEBUG */
675 /* Note: Although this loop is run in interrupt context, further
676 * optimisation will do no good. The MAS would then deliver bad
677 * frames occasionally, as observed in extended experiments. */
678 i = 0;
679 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
681 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
683 delay = 100;
684 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
686 if (--delay <= 0) /* Bail out if we have to wait too long */
687 { /* i.e. the MAS doesn't want to talk to us */
688 xor_b(0x08, &PADRH); /* Set PR inactive */
689 goto transfer_end; /* and get out of here */
693 data = *(unsigned char *)0x04000000; /* read data byte */
695 xor_b(0x08, &PADRH); /* Set PR inactive */
697 audiobuf[audiobuf_write++] = data;
699 if (audiobuf_write >= audiobuflen)
700 audiobuf_write = 0;
702 i++;
704 transfer_end:
706 #ifdef DEBUG
707 timing_info[timing_info_index++] = TCNT2 + (i << 16);
708 timing_info_index &= 0x3ff;
709 #endif /* DEBUG */
711 num_rec_bytes += i;
713 if(is_prerecording)
715 if(TIME_AFTER(current_tick, prerecord_timeout))
717 prerecord_timeout = current_tick + HZ;
718 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
721 else
723 /* Signal to save the data if we are running out of buffer
724 space */
725 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
726 && saving_status == NOT_SAVING)
728 saving_status = BUFFER_FULL;
729 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
734 #endif /* CONFIG_CODEC == MAS3587F */
736 void playback_tick(void)
738 struct trackdata *ptd = get_trackdata(0);
739 if(ptd)
741 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
742 last_dma_tick = current_tick;
743 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
744 (unsigned long)ptd->id3.elapsed);
748 static void reset_mp3_buffer(void)
750 audiobuf_read = 0;
751 audiobuf_write = 0;
752 audiobuf_swapwrite = 0;
753 lowest_watermark_level = audiobuflen;
756 /* DMA transfer end interrupt callback */
757 static void transfer_end(unsigned char** ppbuf, size_t* psize)
759 if(playing && !paused)
761 int unplayed_space_left;
762 int space_until_end_of_buffer;
763 int track_offset = 1;
764 struct trackdata *track;
766 audiobuf_read += last_dma_chunk_size;
767 if(audiobuf_read >= audiobuflen)
768 audiobuf_read = 0;
770 /* First, check if we are on a track boundary */
771 if (num_tracks_in_memory() > 1)
773 if (audiobuf_read == get_trackdata(track_offset)->mempos)
775 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
777 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
778 track_offset++;
783 unplayed_space_left = get_unplayed_space();
785 space_until_end_of_buffer = audiobuflen - audiobuf_read;
787 if(!filling && unplayed_space_left < low_watermark)
789 filling = true;
790 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
793 if(unplayed_space_left)
795 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
796 last_dma_chunk_size = MIN(last_dma_chunk_size,
797 space_until_end_of_buffer);
799 /* several tracks loaded? */
800 track = get_trackdata(track_offset);
801 if(track)
803 /* will we move across the track boundary? */
804 if (( audiobuf_read < track->mempos ) &&
805 ((audiobuf_read+last_dma_chunk_size) >
806 track->mempos ))
808 /* Make sure that we end exactly on the boundary */
809 last_dma_chunk_size = track->mempos - audiobuf_read;
813 *psize = last_dma_chunk_size & 0xffff;
814 *ppbuf = audiobuf + audiobuf_read;
815 track = get_trackdata(0);
816 if(track)
817 track->id3.offset += last_dma_chunk_size;
819 /* Update the watermark debug level */
820 if(unplayed_space_left < lowest_watermark_level)
821 lowest_watermark_level = unplayed_space_left;
823 else
825 /* Check if the end of data is because of a hard disk error.
826 If there is an open file handle, we are still playing music.
827 If not, the last file has been loaded, and the file handle is
828 closed. */
829 if(mpeg_file >= 0)
831 /* Update the watermark debug level */
832 if(unplayed_space_left < lowest_watermark_level)
833 lowest_watermark_level = unplayed_space_left;
835 DEBUGF("DMA underrun.\n");
836 dma_underrun = true;
838 else
840 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
842 DEBUGF("No more MP3 data. Stopping.\n");
843 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
844 playing = false;
847 *psize = 0; /* no more transfer */
852 static struct trackdata *add_track_to_tag_list(const char *filename)
854 struct trackdata *track;
856 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
858 DEBUGF("Tag memory is full\n");
859 return NULL;
862 track = &trackdata[track_write_idx];
864 /* grab id3 tag of new file and
865 remember where in memory it starts */
866 if(mp3info(&track->id3, filename))
868 DEBUGF("Bad mp3\n");
869 return NULL;
871 track->mempos = audiobuf_write;
872 track->id3.elapsed = 0;
873 #ifdef HAVE_LCD_BITMAP
874 if (track->id3.title)
875 lcd_getstringsize(track->id3.title, NULL, NULL);
876 if (track->id3.artist)
877 lcd_getstringsize(track->id3.artist, NULL, NULL);
878 if (track->id3.album)
879 lcd_getstringsize(track->id3.album, NULL, NULL);
880 #endif
881 if (cuesheet_callback)
882 if (cuesheet_callback(filename))
883 track->id3.cuesheet_type = 1;
885 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
886 debug_tags();
887 return track;
890 static int new_file(int steps)
892 int max_steps = playlist_amount();
893 int start = 0;
894 int i;
895 struct trackdata *track;
897 /* Find out how many steps to advance. The load_ahead_index field tells
898 us how many playlist entries it had to skip to get to a valid one.
899 We add those together to find out where to start. */
900 if(steps > 0 && num_tracks_in_memory() > 1)
902 /* Begin with the song after the currently playing one */
903 i = 1;
904 while((track = get_trackdata(i++)))
906 start += track->load_ahead_index;
910 do {
911 char *trackname;
913 trackname = playlist_peek( start + steps );
914 if ( !trackname )
915 return -1;
917 DEBUGF("Loading %s\n", trackname);
919 mpeg_file = open(trackname, O_RDONLY);
920 if(mpeg_file < 0) {
921 DEBUGF("Couldn't open file: %s\n",trackname);
922 if(steps < 0)
923 steps--;
924 else
925 steps++;
927 else
929 struct trackdata *track = add_track_to_tag_list(trackname);
931 if(!track)
933 /* Bad mp3 file */
934 if(steps < 0)
935 steps--;
936 else
937 steps++;
938 close(mpeg_file);
939 mpeg_file = -1;
941 else
943 /* skip past id3v2 tag */
944 lseek(mpeg_file,
945 track->id3.first_frame_offset,
946 SEEK_SET);
947 track->id3.index = steps;
948 track->load_ahead_index = steps;
949 track->id3.offset = 0;
951 if(track->id3.vbr)
952 /* Average bitrate * 1.5 */
953 recalculate_watermark(
954 (track->id3.bitrate * 3) / 2);
955 else
956 recalculate_watermark(
957 track->id3.bitrate);
962 /* Bail out if no file could be opened */
963 if(abs(steps) > max_steps)
964 return -1;
965 } while ( mpeg_file < 0 );
967 return 0;
970 static void stop_playing(void)
972 struct trackdata *track;
974 /* Stop the current stream */
975 mp3_play_stop();
976 playing = false;
977 filling = false;
979 track = get_trackdata(0);
980 if (track != NULL)
981 prev_track_elapsed = track->id3.elapsed;
983 if(mpeg_file >= 0)
984 close(mpeg_file);
985 mpeg_file = -1;
986 remove_all_tags();
987 generate_unbuffer_events();
988 reset_mp3_buffer();
991 static void end_current_track(void) {
992 struct trackdata *track;
994 play_pending = false;
995 playing = false;
996 mp3_play_pause(false);
998 track = get_trackdata(0);
999 if (track != NULL)
1000 prev_track_elapsed = track->id3.elapsed;
1002 reset_mp3_buffer();
1003 remove_all_tags();
1004 generate_unbuffer_events();
1006 if(mpeg_file >= 0)
1007 close(mpeg_file);
1010 /* Is this a really the end of playback or is a new playlist starting */
1011 static void check_playlist_end(int direction)
1013 /* Use the largest possible step size to account for skipped tracks */
1014 int steps = playlist_amount();
1016 if (direction < 0)
1017 steps = -steps;
1019 if (playlist_next(steps) < 0)
1020 is_playing = false;
1023 static void update_playlist(void)
1025 if (num_tracks_in_memory() > 0)
1027 struct trackdata *track = get_trackdata(0);
1028 track->id3.index = playlist_next(track->id3.index);
1030 else
1032 /* End of playlist? */
1033 check_playlist_end(1);
1036 playlist_update_resume_info(audio_current_track());
1039 static void track_change(void)
1041 DEBUGF("Track change\n");
1043 struct trackdata *track = get_trackdata(0);
1044 prev_track_elapsed = track->id3.elapsed;
1046 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1047 /* Reset the AVC */
1048 sound_set_avc(-1);
1049 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1051 if (num_tracks_in_memory() > 0)
1053 remove_current_tag();
1054 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1055 update_playlist();
1058 current_track_counter++;
1061 unsigned long audio_prev_elapsed(void)
1063 return prev_track_elapsed;
1066 #ifdef DEBUG
1067 void hexdump(const unsigned char *buf, int len)
1069 int i;
1071 for(i = 0;i < len;i++)
1073 if(i && (i & 15) == 0)
1075 DEBUGF("\n");
1077 DEBUGF("%02x ", buf[i]);
1079 DEBUGF("\n");
1081 #endif /* DEBUG */
1083 static void start_playback_if_ready(void)
1085 int playable_space;
1087 playable_space = audiobuf_swapwrite - audiobuf_read;
1088 if(playable_space < 0)
1089 playable_space += audiobuflen;
1091 /* See if we have started playing yet. If not, do it. */
1092 if(play_pending || dma_underrun)
1094 /* If the filling has stopped, and we still haven't reached
1095 the watermark, the file must be smaller than the
1096 watermark. We must still play it. */
1097 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1098 !filling || dma_underrun)
1100 DEBUGF("P\n");
1101 if (play_pending) /* don't do this when recovering from DMA underrun */
1103 generate_postbuffer_events(); /* signal first track as buffered */
1104 if (play_pending_track_change)
1106 play_pending_track_change = false;
1107 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1109 play_pending = false;
1111 playing = true;
1113 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1114 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1115 dma_underrun = false;
1117 if (!paused)
1119 last_dma_tick = current_tick;
1120 mp3_play_pause(true);
1123 /* Tell ourselves that we need more data */
1124 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1129 static bool swap_one_chunk(void)
1131 int free_space_left;
1132 int amount_to_swap;
1134 free_space_left = get_unswapped_space();
1136 if(free_space_left == 0 && !play_pending)
1137 return false;
1139 /* Swap in larger chunks when the user is waiting for the playback
1140 to start, or when there is dangerously little playable data left */
1141 if(play_pending)
1142 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1143 else
1145 if(get_playable_space() < low_watermark)
1146 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1147 free_space_left);
1148 else
1149 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1152 if(audiobuf_write < audiobuf_swapwrite)
1153 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1154 amount_to_swap);
1155 else
1156 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1157 amount_to_swap);
1159 bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap);
1161 audiobuf_swapwrite += amount_to_swap;
1162 if(audiobuf_swapwrite >= audiobuflen)
1164 audiobuf_swapwrite = 0;
1167 return true;
1170 static void mpeg_thread(void)
1172 static int pause_tick = 0;
1173 static unsigned int pause_track = 0;
1174 struct queue_event ev;
1175 int len;
1176 int free_space_left;
1177 int unplayed_space_left;
1178 int amount_to_read;
1179 int t1, t2;
1180 int start_offset;
1181 #if CONFIG_CODEC == MAS3587F
1182 int amount_to_save;
1183 int save_endpos = 0;
1184 int rc;
1185 int level;
1186 long offset;
1187 #endif /* CONFIG_CODEC == MAS3587F */
1189 is_playing = false;
1190 play_pending = false;
1191 playing = false;
1192 mpeg_file = -1;
1194 while(1)
1196 #if CONFIG_CODEC == MAS3587F
1197 if(mpeg_mode == MPEG_DECODER)
1199 #endif /* CONFIG_CODEC == MAS3587F */
1200 yield();
1202 /* Swap if necessary, and don't block on the queue_wait() */
1203 if(swap_one_chunk())
1205 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1207 else if (playing)
1209 /* periodically update resume info */
1210 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1212 else
1214 DEBUGF("S R:%x W:%x SW:%x\n",
1215 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1216 queue_wait(&mpeg_queue, &ev);
1219 start_playback_if_ready();
1221 switch(ev.id)
1223 case MPEG_PLAY:
1224 DEBUGF("MPEG_PLAY\n");
1226 #if CONFIG_TUNER
1227 /* Silence the A/D input, it may be on because the radio
1228 may be playing */
1229 mas_codec_writereg(6, 0x0000);
1230 #endif /* CONFIG_TUNER */
1232 /* Stop the current stream */
1233 paused = false;
1234 end_current_track();
1236 if ( new_file(0) == -1 )
1238 is_playing = false;
1239 track_change();
1240 break;
1243 start_offset = (int)ev.data;
1245 /* mid-song resume? */
1246 if (start_offset) {
1247 struct mp3entry* id3 = &get_trackdata(0)->id3;
1248 lseek(mpeg_file, start_offset, SEEK_SET);
1249 id3->offset = start_offset;
1250 set_elapsed(id3);
1252 else {
1253 /* skip past id3v2 tag */
1254 lseek(mpeg_file,
1255 get_trackdata(0)->id3.first_frame_offset,
1256 SEEK_SET);
1260 /* Make it read more data */
1261 filling = true;
1262 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1264 /* Tell the file loading code that we want to start playing
1265 as soon as we have some data */
1266 play_pending = true;
1267 play_pending_track_change = true;
1269 update_playlist();
1270 current_track_counter++;
1271 break;
1273 case MPEG_STOP:
1274 DEBUGF("MPEG_STOP\n");
1275 is_playing = false;
1276 paused = false;
1278 if (playing)
1279 playlist_update_resume_info(audio_current_track());
1281 stop_playing();
1282 mpeg_stop_done = true;
1283 break;
1285 case MPEG_PAUSE:
1286 DEBUGF("MPEG_PAUSE\n");
1287 /* Stop the current stream */
1288 if (playing)
1289 playlist_update_resume_info(audio_current_track());
1290 paused = true;
1291 playing = false;
1292 pause_tick = current_tick;
1293 pause_track = current_track_counter;
1294 mp3_play_pause(false);
1295 break;
1297 case MPEG_RESUME:
1298 DEBUGF("MPEG_RESUME\n");
1299 /* Continue the current stream */
1300 paused = false;
1301 if (!play_pending)
1303 playing = true;
1304 if ( current_track_counter == pause_track )
1305 last_dma_tick += current_tick - pause_tick;
1306 else
1307 last_dma_tick = current_tick;
1308 pause_tick = 0;
1309 mp3_play_pause(true);
1311 break;
1313 case MPEG_NEXT:
1314 DEBUGF("MPEG_NEXT\n");
1315 /* is next track in ram? */
1316 if ( num_tracks_in_memory() > 1 ) {
1317 int unplayed_space_left, unswapped_space_left;
1319 /* stop the current stream */
1320 play_pending = false;
1321 playing = false;
1322 mp3_play_pause(false);
1324 track_change();
1325 audiobuf_read = get_trackdata(0)->mempos;
1326 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1327 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1328 dma_underrun = false;
1329 last_dma_tick = current_tick;
1331 unplayed_space_left = get_unplayed_space();
1332 unswapped_space_left = get_unswapped_space();
1334 /* should we start reading more data? */
1335 if(!filling && (unplayed_space_left < low_watermark)) {
1336 filling = true;
1337 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1338 play_pending = true;
1339 } else if(unswapped_space_left &&
1340 unswapped_space_left > unplayed_space_left) {
1341 /* Stop swapping the data from the previous file */
1342 audiobuf_swapwrite = audiobuf_read;
1343 play_pending = true;
1344 } else {
1345 playing = true;
1346 if (!paused)
1347 mp3_play_pause(true);
1350 else {
1351 if (!playlist_check(1))
1352 break;
1354 /* stop the current stream */
1355 end_current_track();
1357 if (new_file(1) < 0) {
1358 DEBUGF("No more files to play\n");
1359 filling = false;
1361 check_playlist_end(1);
1362 current_track_counter++;
1363 } else {
1364 /* Make it read more data */
1365 filling = true;
1366 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1368 /* Tell the file loading code that we want
1369 to start playing as soon as we have some data */
1370 play_pending = true;
1371 play_pending_track_change = true;
1373 update_playlist();
1374 current_track_counter++;
1377 break;
1379 case MPEG_PREV: {
1380 DEBUGF("MPEG_PREV\n");
1382 if (!playlist_check(-1))
1383 break;
1385 /* stop the current stream */
1386 end_current_track();
1388 /* Open the next file */
1389 if (new_file(-1) < 0) {
1390 DEBUGF("No more files to play\n");
1391 filling = false;
1393 check_playlist_end(-1);
1394 current_track_counter++;
1395 } else {
1396 /* Make it read more data */
1397 filling = true;
1398 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1400 /* Tell the file loading code that we want to
1401 start playing as soon as we have some data */
1402 play_pending = true;
1403 play_pending_track_change = true;
1405 update_playlist();
1406 current_track_counter++;
1408 break;
1411 case MPEG_FF_REWIND: {
1412 struct mp3entry *id3 = audio_current_track();
1413 unsigned int oldtime = id3->elapsed;
1414 unsigned int newtime = (unsigned int)ev.data;
1415 int curpos, newpos, diffpos;
1416 DEBUGF("MPEG_FF_REWIND\n");
1418 id3->elapsed = newtime;
1420 newpos = audio_get_file_pos();
1421 if(newpos < 0)
1423 id3->elapsed = oldtime;
1424 break;
1427 if (mpeg_file >= 0)
1428 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1429 else
1430 curpos = id3->filesize;
1432 if (num_tracks_in_memory() > 1)
1434 /* We have started loading other tracks that need to be
1435 accounted for */
1436 struct trackdata *track;
1437 int i = 0;
1439 while((track = get_trackdata(i++)))
1441 curpos += track->id3.filesize;
1445 diffpos = curpos - newpos;
1447 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1449 int unplayed_space_left, unswapped_space_left;
1451 /* We are changing to a position that's already in
1452 memory, so we just move the DMA read pointer. */
1453 audiobuf_read = audiobuf_write - diffpos;
1454 if (audiobuf_read < 0)
1456 audiobuf_read += audiobuflen;
1459 unplayed_space_left = get_unplayed_space();
1460 unswapped_space_left = get_unswapped_space();
1462 /* If unswapped_space_left is larger than
1463 unplayed_space_left, it means that the swapwrite pointer
1464 hasn't yet advanced up to the new location of the read
1465 pointer. We just move it, there is no need to swap
1466 data that won't be played anyway. */
1468 if (unswapped_space_left > unplayed_space_left)
1470 DEBUGF("Moved swapwrite\n");
1471 audiobuf_swapwrite = audiobuf_read;
1472 play_pending = true;
1475 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1477 /* We need to load more data before starting */
1478 filling = true;
1479 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1480 play_pending = true;
1482 else
1484 /* resume will start at new position */
1485 last_dma_chunk_size =
1486 MIN(0x2000, get_unplayed_space_current_song());
1487 mp3_play_data(audiobuf + audiobuf_read,
1488 last_dma_chunk_size, transfer_end);
1489 dma_underrun = false;
1492 else
1494 /* Move to the new position in the file and start
1495 loading data */
1496 reset_mp3_buffer();
1498 if (num_tracks_in_memory() > 1)
1500 /* We have to reload the current track */
1501 close(mpeg_file);
1502 remove_all_non_current_tags();
1503 generate_unbuffer_events();
1504 mpeg_file = -1;
1507 if (mpeg_file < 0)
1509 mpeg_file = open(id3->path, O_RDONLY);
1510 if (mpeg_file < 0)
1512 id3->elapsed = oldtime;
1513 break;
1517 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1519 id3->elapsed = oldtime;
1520 break;
1523 filling = true;
1524 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1526 /* Tell the file loading code that we want to start playing
1527 as soon as we have some data */
1528 play_pending = true;
1531 id3->offset = newpos;
1533 break;
1536 case MPEG_FLUSH_RELOAD: {
1537 int numtracks = num_tracks_in_memory();
1538 bool reload_track = false;
1540 if (numtracks > 1)
1542 /* Reset the buffer */
1543 audiobuf_write = get_trackdata(1)->mempos;
1545 /* Reset swapwrite unless we're still swapping current
1546 track */
1547 if (get_unplayed_space() <= get_playable_space())
1548 audiobuf_swapwrite = audiobuf_write;
1550 close(mpeg_file);
1551 remove_all_non_current_tags();
1552 generate_unbuffer_events();
1553 mpeg_file = -1;
1554 reload_track = true;
1556 else if (numtracks == 1 && mpeg_file < 0)
1558 reload_track = true;
1561 if(reload_track && new_file(1) >= 0)
1563 /* Tell ourselves that we want more data */
1564 filling = true;
1565 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1568 break;
1571 case MPEG_NEED_DATA:
1572 free_space_left = audiobuf_read - audiobuf_write;
1574 /* We interpret 0 as "empty buffer" */
1575 if(free_space_left <= 0)
1576 free_space_left += audiobuflen;
1578 unplayed_space_left = audiobuflen - free_space_left;
1580 /* Make sure that we don't fill the entire buffer */
1581 free_space_left -= MPEG_HIGH_WATER;
1583 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1584 generate_unbuffer_events();
1586 /* do we have any more buffer space to fill? */
1587 if(free_space_left <= 0)
1589 DEBUGF("0\n");
1590 filling = false;
1591 generate_postbuffer_events();
1592 storage_sleep();
1593 break;
1596 /* Read small chunks while we are below the low water mark */
1597 if(unplayed_space_left < low_watermark)
1598 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1599 free_space_left);
1600 else
1601 amount_to_read = free_space_left;
1603 /* Don't read more than until the end of the buffer */
1604 amount_to_read = MIN(audiobuflen - audiobuf_write,
1605 amount_to_read);
1606 #if (CONFIG_STORAGE & STORAGE_MMC)
1607 /* MMC is slow, so don't read too large chunks */
1608 amount_to_read = MIN(0x40000, amount_to_read);
1609 #elif MEM == 8
1610 amount_to_read = MIN(0x100000, amount_to_read);
1611 #endif
1613 /* Read as much mpeg data as we can fit in the buffer */
1614 if(mpeg_file >= 0)
1616 DEBUGF("R\n");
1617 t1 = current_tick;
1618 len = read(mpeg_file, audiobuf + audiobuf_write,
1619 amount_to_read);
1620 if(len > 0)
1622 t2 = current_tick;
1623 DEBUGF("time: %d\n", t2 - t1);
1624 DEBUGF("R: %x\n", len);
1626 /* Now make sure that we don't feed the MAS with ID3V1
1627 data */
1628 if (len < amount_to_read)
1630 int i;
1631 static const unsigned char tag[] = "TAG";
1632 int taglen = 128;
1633 int tagptr = audiobuf_write + len - 128;
1635 /* Really rare case: entire potential tag wasn't
1636 read in this call AND audiobuf_write < 128 */
1637 if (tagptr < 0)
1638 tagptr += audiobuflen;
1640 for(i = 0;i < 3;i++)
1642 if(tagptr >= audiobuflen)
1643 tagptr -= audiobuflen;
1645 if(audiobuf[tagptr] != tag[i])
1647 taglen = 0;
1648 break;
1651 tagptr++;
1654 if(taglen)
1656 /* Skip id3v1 tag */
1657 DEBUGF("Skipping ID3v1 tag\n");
1658 len -= taglen;
1660 /* In the very rare case when the entire tag
1661 wasn't read in this read() len will be < 0.
1662 Take care of this when changing the write
1663 pointer. */
1667 audiobuf_write += len;
1669 if (audiobuf_write < 0)
1670 audiobuf_write += audiobuflen;
1672 if(audiobuf_write >= audiobuflen)
1674 audiobuf_write = 0;
1675 DEBUGF("W\n");
1678 /* Tell ourselves that we want more data */
1679 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1681 else
1683 if(len < 0)
1685 DEBUGF("MPEG read error\n");
1688 close(mpeg_file);
1689 mpeg_file = -1;
1691 if(new_file(1) < 0)
1693 /* No more data to play */
1694 DEBUGF("No more files to play\n");
1695 filling = false;
1697 else
1699 /* Tell ourselves that we want more data */
1700 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1704 break;
1706 case MPEG_TRACK_CHANGE:
1707 track_change();
1708 break;
1710 #ifndef USB_NONE
1711 case SYS_USB_CONNECTED:
1712 is_playing = false;
1713 paused = false;
1714 stop_playing();
1716 /* Tell the USB thread that we are safe */
1717 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1718 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1720 /* Wait until the USB cable is extracted again */
1721 usb_wait_for_disconnect(&mpeg_queue);
1722 break;
1723 #endif /* !USB_NONE */
1725 #if CONFIG_CODEC == MAS3587F
1726 case MPEG_INIT_RECORDING:
1727 init_recording();
1728 init_recording_done = true;
1729 break;
1730 #endif /* CONFIG_CODEC == MAS3587F */
1732 case SYS_TIMEOUT:
1733 if (playing)
1734 playlist_update_resume_info(audio_current_track());
1735 break;
1737 #if CONFIG_CODEC == MAS3587F
1739 else
1741 queue_wait(&mpeg_queue, &ev);
1742 switch(ev.id)
1744 case MPEG_RECORD:
1745 if (is_prerecording)
1747 int startpos;
1749 /* Go back prerecord_count seconds in the buffer */
1750 startpos = prerecord_index - prerecord_count;
1751 if(startpos < 0)
1752 startpos += prerecording_max_seconds;
1754 /* Read the position data from the prerecord buffer */
1755 frame_count_start = prerecord_buffer[startpos].framecount;
1756 startpos = prerecord_buffer[startpos].mempos;
1758 DEBUGF("Start looking at address %x (%x)\n",
1759 audiobuf+startpos, startpos);
1761 saved_header = mpeg_get_last_header();
1763 mem_find_next_frame(startpos, &offset, 1800,
1764 saved_header);
1766 audiobuf_read = startpos + offset;
1767 if(audiobuf_read >= audiobuflen)
1768 audiobuf_read -= audiobuflen;
1770 DEBUGF("New audiobuf_read address: %x (%x)\n",
1771 audiobuf+audiobuf_read, audiobuf_read);
1773 level = disable_irq_save();
1774 num_rec_bytes = get_unsaved_space();
1775 restore_irq(level);
1777 else
1779 frame_count_start = 0;
1780 num_rec_bytes = 0;
1781 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1782 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1785 prepend_header();
1786 DEBUGF("Recording...\n");
1787 start_recording();
1789 /* Wait until at least one frame is encoded and get the
1790 frame header, for later use by the Xing header
1791 generation */
1792 sleep(HZ/5);
1793 saved_header = mpeg_get_last_header();
1795 /* delayed until buffer is saved, don't open yet */
1796 strcpy(delayed_filename, recording_filename);
1797 mpeg_file = -1;
1799 break;
1801 case MPEG_STOP:
1802 DEBUGF("MPEG_STOP\n");
1804 stop_recording();
1806 /* Save the remaining data in the buffer */
1807 save_endpos = audiobuf_write;
1808 saving_status = STOP_RECORDING;
1809 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1810 break;
1812 case MPEG_STOP_DONE:
1813 DEBUGF("MPEG_STOP_DONE\n");
1815 if (mpeg_file >= 0)
1816 close(mpeg_file);
1817 mpeg_file = -1;
1819 update_header();
1820 #ifdef DEBUG1
1822 int i;
1823 for(i = 0;i < 512;i++)
1825 DEBUGF("%d - %d us (%d bytes)\n",
1826 timing_info[i*2],
1827 (timing_info[i*2+1] & 0xffff) *
1828 10000 / 13824,
1829 timing_info[i*2+1] >> 16);
1832 #endif /* DEBUG1 */
1834 if (prerecording)
1836 start_prerecording();
1838 mpeg_stop_done = true;
1839 break;
1841 case MPEG_NEW_FILE:
1842 /* Bail out when a more important save is happening */
1843 if (saving_status > NEW_FILE)
1844 break;
1846 /* Make sure we have at least one complete frame
1847 in the buffer. If we haven't recorded a single
1848 frame within 200ms, the MAS is probably not recording
1849 anything, and we bail out. */
1850 amount_to_save = get_unsaved_space();
1851 if (amount_to_save < 1800)
1853 sleep(HZ/5);
1854 amount_to_save = get_unsaved_space();
1857 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1858 &frame_count_end, 1);
1860 last_rec_time = current_tick - record_start_time;
1861 record_start_time = current_tick;
1862 if (paused)
1863 pause_start_time = record_start_time;
1865 /* capture all values at one point */
1866 level = disable_irq_save();
1867 save_endpos = audiobuf_write;
1868 last_rec_bytes = num_rec_bytes;
1869 num_rec_bytes = 0;
1870 restore_irq(level);
1872 if (amount_to_save >= 1800)
1874 /* Now find a frame boundary to split at */
1875 save_endpos -= 1800;
1876 if (save_endpos < 0)
1877 save_endpos += audiobuflen;
1879 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1880 saved_header);
1881 if (!rc) /* No header found, save whole buffer */
1882 offset = 1800;
1884 save_endpos += offset;
1885 if (save_endpos >= audiobuflen)
1886 save_endpos -= audiobuflen;
1888 last_rec_bytes += offset - 1800;
1889 level = disable_irq_save();
1890 num_rec_bytes += 1800 - offset;
1891 restore_irq(level);
1894 saving_status = NEW_FILE;
1895 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1896 break;
1898 case MPEG_SAVE_DATA:
1899 if (saving_status == BUFFER_FULL)
1900 save_endpos = audiobuf_write;
1902 if (mpeg_file < 0) /* delayed file open */
1904 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT);
1906 if (mpeg_file < 0)
1907 panicf("recfile: %d", mpeg_file);
1910 amount_to_save = save_endpos - audiobuf_read;
1911 if (amount_to_save < 0)
1912 amount_to_save += audiobuflen;
1914 amount_to_save = MIN(amount_to_save,
1915 audiobuflen - audiobuf_read);
1916 #if (CONFIG_STORAGE & STORAGE_MMC)
1917 /* MMC is slow, so don't save too large chunks at once */
1918 amount_to_save = MIN(0x40000, amount_to_save);
1919 #elif MEM == 8
1920 amount_to_save = MIN(0x100000, amount_to_save);
1921 #endif
1922 rc = write(mpeg_file, audiobuf + audiobuf_read,
1923 amount_to_save);
1924 if (rc < 0)
1926 if (errno == ENOSPC)
1928 mpeg_errno = AUDIOERR_DISK_FULL;
1929 stop_recording();
1930 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1931 /* will close the file */
1932 break;
1934 else
1935 panicf("rec wrt: %d", rc);
1938 audiobuf_read += amount_to_save;
1939 if (audiobuf_read >= audiobuflen)
1940 audiobuf_read = 0;
1942 if (audiobuf_read == save_endpos) /* all saved */
1944 switch (saving_status)
1946 case BUFFER_FULL:
1947 rc = fsync(mpeg_file);
1948 if (rc < 0)
1949 panicf("rec fls: %d", rc);
1950 storage_sleep();
1951 break;
1953 case NEW_FILE:
1954 /* Close the current file */
1955 rc = close(mpeg_file);
1956 if (rc < 0)
1957 panicf("rec cls: %d", rc);
1958 mpeg_file = -1;
1959 update_header();
1960 storage_sleep();
1962 /* copy new filename */
1963 strcpy(delayed_filename, recording_filename);
1964 prepend_header();
1965 frame_count_start = frame_count_end;
1966 break;
1968 case STOP_RECORDING:
1969 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1970 /* will close the file */
1971 break;
1973 default:
1974 break;
1976 saving_status = NOT_SAVING;
1978 else /* tell ourselves to save the next chunk */
1979 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1981 break;
1983 case MPEG_PRERECORDING_TICK:
1984 if(!is_prerecording)
1985 break;
1987 /* Store the write pointer every second */
1988 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
1989 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1990 &prerecord_buffer[prerecord_index].framecount, 1);
1992 /* Wrap if necessary */
1993 if(++prerecord_index == prerecording_max_seconds)
1994 prerecord_index = 0;
1996 /* Update the number of seconds recorded */
1997 if(prerecord_count < prerecording_max_seconds)
1998 prerecord_count++;
1999 break;
2001 case MPEG_INIT_PLAYBACK:
2002 /* Stop the prerecording */
2003 stop_recording();
2004 reset_mp3_buffer();
2005 mp3_play_init();
2006 init_playback_done = true;
2007 break;
2009 case MPEG_PAUSE_RECORDING:
2010 pause_recording();
2011 break;
2013 case MPEG_RESUME_RECORDING:
2014 resume_recording();
2015 break;
2017 case SYS_USB_CONNECTED:
2018 /* We can safely go to USB mode if no recording
2019 is taking place */
2020 if((!is_recording || is_prerecording) && mpeg_stop_done)
2022 /* Even if we aren't recording, we still call this
2023 function, to put the MAS in monitoring mode,
2024 to save power. */
2025 stop_recording();
2027 /* Tell the USB thread that we are safe */
2028 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2029 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2031 /* Wait until the USB cable is extracted again */
2032 usb_wait_for_disconnect(&mpeg_queue);
2034 break;
2037 #endif /* CONFIG_CODEC == MAS3587F */
2040 #endif /* !SIMULATOR */
2042 struct mp3entry* audio_current_track()
2044 #ifdef SIMULATOR
2045 return &taginfo;
2046 #else /* !SIMULATOR */
2047 if(num_tracks_in_memory())
2048 return &get_trackdata(0)->id3;
2049 else
2050 return NULL;
2051 #endif /* !SIMULATOR */
2054 struct mp3entry* audio_next_track()
2056 #ifdef SIMULATOR
2057 return &taginfo;
2058 #else /* !SIMULATOR */
2059 if(num_tracks_in_memory() > 1)
2060 return &get_trackdata(1)->id3;
2061 else
2062 return NULL;
2063 #endif /* !SIMULATOR */
2066 bool audio_has_changed_track(void)
2068 if(last_track_counter != current_track_counter)
2070 last_track_counter = current_track_counter;
2071 return true;
2073 return false;
2076 #if CONFIG_CODEC == MAS3587F
2077 #ifndef SIMULATOR
2078 void audio_init_playback(void)
2080 init_playback_done = false;
2081 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2083 while(!init_playback_done)
2084 sleep(1);
2088 /****************************************************************************
2089 * Recording functions
2090 ***************************************************************************/
2091 void audio_init_recording(unsigned int buffer_offset)
2093 buffer_offset = buffer_offset;
2094 init_recording_done = false;
2095 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2097 while(!init_recording_done)
2098 sleep(1);
2101 static void init_recording(void)
2103 unsigned long val;
2104 int rc;
2106 /* Disable IRQ6 */
2107 IPRB &= 0xff0f;
2109 stop_playing();
2110 is_playing = false;
2111 paused = false;
2113 /* Init the recording variables */
2114 is_recording = false;
2115 is_prerecording = false;
2117 mpeg_stop_done = true;
2119 mas_reset();
2121 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2122 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2123 if(rc < 0)
2124 panicf("mas_ctrl_w: %d", rc);
2126 /* Stop the current application */
2127 val = 0;
2128 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2131 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2132 } while(val);
2134 /* Perform black magic as described by the data sheet */
2135 if((mas_version_code & 0x0fff) == 0x0102)
2137 DEBUGF("Performing MAS black magic for B2 version\n");
2138 mas_writereg(0xa3, 0x98);
2139 mas_writereg(0x94, 0xfffff);
2140 val = 0;
2141 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2142 mas_writereg(0xa3, 0x90);
2145 /* Enable A/D Converters */
2146 shadow_codec_reg0 = 0xcccd;
2147 mas_codec_writereg(0x0, shadow_codec_reg0);
2149 /* Copy left channel to right (mono mode) */
2150 mas_codec_writereg(8, 0x8000);
2152 /* ADC scale 0%, DSP scale 100%
2153 We use the DSP output for monitoring, because it works with all
2154 sources including S/PDIF */
2155 mas_codec_writereg(6, 0x0000);
2156 mas_codec_writereg(7, 0x4000);
2158 /* No mute */
2159 shadow_soft_mute = 0;
2160 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2162 #ifdef HAVE_SPDIF_OUT
2163 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2164 #else
2165 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2166 #endif
2167 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2169 /* Set Demand mode, monitoring OFF and validate all settings */
2170 shadow_io_control_main = 0x125;
2171 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2173 /* Start the encoder application */
2174 val = 0x40;
2175 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2178 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2179 } while(!(val & 0x40));
2181 /* We have started the recording application with monitoring OFF.
2182 This is because we want to record at least one frame to fill the DMA
2183 buffer, because the silly MAS will not negate EOD until at least one
2184 DMA transfer has taken place.
2185 Now let's wait for some data to be encoded. */
2186 sleep(HZ/5);
2188 /* Now set it to Monitoring mode as default, saves power */
2189 shadow_io_control_main = 0x525;
2190 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2192 /* Wait until the DSP has accepted the settings */
2195 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2196 } while(val & 1);
2198 drain_dma_buffer();
2199 mpeg_mode = MPEG_ENCODER;
2201 DEBUGF("MAS Recording application started\n");
2203 /* At this point, all settings are the reset MAS defaults, next thing is to
2204 call mpeg_set_recording_options(). */
2207 void audio_record(const char *filename)
2209 mpeg_errno = 0;
2211 strncpy(recording_filename, filename, MAX_PATH - 1);
2212 recording_filename[MAX_PATH - 1] = 0;
2214 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2217 void audio_pause_recording(void)
2219 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2222 void audio_resume_recording(void)
2224 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2227 static void prepend_header(void)
2229 int startpos;
2230 unsigned i;
2232 /* Make room for header */
2233 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2234 if(audiobuf_read < 0)
2236 /* Clear the bottom half */
2237 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2239 /* And the top half */
2240 audiobuf_read += audiobuflen;
2241 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2243 else
2245 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2247 /* Copy the empty ID3 header */
2248 startpos = audiobuf_read;
2249 for(i = 0; i < sizeof(empty_id3_header); i++)
2251 audiobuf[startpos++] = empty_id3_header[i];
2252 if(startpos == audiobuflen)
2253 startpos = 0;
2257 static void update_header(void)
2259 int fd, framelen;
2260 unsigned long frames;
2262 if (last_rec_bytes > 0)
2264 /* Create the Xing header */
2265 fd = open(delayed_filename, O_RDWR);
2266 if (fd < 0)
2267 panicf("rec upd: %d (%s)", fd, recording_filename);
2269 frames = frame_count_end - frame_count_start;
2270 /* If the number of recorded frames has reached 0x7ffff,
2271 we can no longer trust it */
2272 if (frame_count_end == 0x7ffff)
2273 frames = 0;
2275 /* saved_header is saved right before stopping the MAS */
2276 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2277 frames, last_rec_time * (1000/HZ),
2278 saved_header, NULL, false);
2280 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2281 write(fd, xing_buffer, framelen);
2282 close(fd);
2286 static void start_prerecording(void)
2288 unsigned long val;
2290 DEBUGF("Starting prerecording\n");
2292 prerecord_index = 0;
2293 prerecord_count = 0;
2294 prerecord_timeout = current_tick + HZ;
2295 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2296 reset_mp3_buffer();
2298 is_prerecording = true;
2300 /* Stop monitoring and start the encoder */
2301 shadow_io_control_main &= ~(1 << 10);
2302 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2303 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2305 /* Wait until the DSP has accepted the settings */
2308 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2309 } while(val & 1);
2311 is_recording = true;
2312 saving_status = NOT_SAVING;
2314 demand_irq_enable(true);
2317 static void start_recording(void)
2319 unsigned long val;
2321 if(is_prerecording)
2323 /* This will make the IRQ handler start recording
2324 for real, i.e send MPEG_SAVE_DATA messages when
2325 the buffer is full */
2326 is_prerecording = false;
2328 else
2330 /* If prerecording is off, we need to stop the monitoring
2331 and start the encoder */
2332 shadow_io_control_main &= ~(1 << 10);
2333 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2334 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2336 /* Wait until the DSP has accepted the settings */
2339 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2340 } while(val & 1);
2343 is_recording = true;
2344 saving_status = NOT_SAVING;
2345 paused = false;
2347 /* Store the current time */
2348 if(prerecording)
2349 record_start_time = current_tick - prerecord_count * HZ;
2350 else
2351 record_start_time = current_tick;
2353 pause_start_time = 0;
2355 demand_irq_enable(true);
2358 static void pause_recording(void)
2360 pause_start_time = current_tick;
2362 /* Set the pause bit */
2363 shadow_soft_mute |= 2;
2364 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2366 paused = true;
2369 static void resume_recording(void)
2371 paused = false;
2373 /* Clear the pause bit */
2374 shadow_soft_mute &= ~2;
2375 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2377 /* Compensate for the time we have been paused */
2378 if(pause_start_time)
2380 record_start_time =
2381 current_tick - (pause_start_time - record_start_time);
2382 pause_start_time = 0;
2386 static void stop_recording(void)
2388 unsigned long val;
2390 /* Let it finish the last frame */
2391 if(!paused)
2392 pause_recording();
2393 sleep(HZ/5);
2395 demand_irq_enable(false);
2397 is_recording = false;
2398 is_prerecording = false;
2400 last_rec_bytes = num_rec_bytes;
2401 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2402 last_rec_time = current_tick - record_start_time;
2404 /* Start monitoring */
2405 shadow_io_control_main |= (1 << 10);
2406 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2407 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2409 /* Wait until the DSP has accepted the settings */
2412 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2413 } while(val & 1);
2415 resume_recording();
2418 void audio_set_recording_options(struct audio_recording_options *options)
2420 bool is_mpeg1;
2422 is_mpeg1 = (options->rec_frequency < 3)?true:false;
2424 rec_version_index = is_mpeg1?3:2;
2425 rec_frequency_index = options->rec_frequency % 3;
2427 shadow_encoder_control = (options->rec_quality << 17) |
2428 (rec_frequency_index << 10) |
2429 ((is_mpeg1?1:0) << 9) |
2430 (((options->rec_channels * 2 + 1) & 3) << 6) |
2431 (1 << 5) /* MS-stereo */ |
2432 (1 << 2) /* Is an original */;
2433 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2435 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2437 #if CONFIG_TUNER & S1A0903X01
2438 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2439 interference with the Samsung tuner. */
2440 if (rec_frequency_index)
2441 mas_store_pllfreq(24576000);
2442 else
2443 mas_store_pllfreq(22579000);
2444 #endif
2446 shadow_soft_mute = options->rec_editable?4:0;
2447 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2449 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2451 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2452 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2453 (1 << 5) | /* SDO strobe invert */
2454 ((is_mpeg1?0:1) << 3) |
2455 (1 << 2) | /* Inverted SIBC clock signal */
2456 1; /* Validate */
2457 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2459 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2461 if(options->rec_source == AUDIO_SRC_MIC)
2463 /* Copy left channel to right (mono mode) */
2464 mas_codec_writereg(8, 0x8000);
2466 else
2468 /* Stereo input mode */
2469 mas_codec_writereg(8, 0);
2472 prerecording_max_seconds = options->rec_prerecord_time;
2473 if(prerecording_max_seconds)
2475 prerecording = true;
2476 start_prerecording();
2478 else
2480 prerecording = false;
2481 is_prerecording = false;
2482 is_recording = false;
2486 /* If use_mic is true, the left gain is used */
2487 void audio_set_recording_gain(int left, int right, int type)
2489 /* Enable both left and right A/D */
2490 shadow_codec_reg0 = (left << 12) |
2491 (right << 8) |
2492 (left << 4) |
2493 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2494 0x0007;
2495 mas_codec_writereg(0x0, shadow_codec_reg0);
2498 /* try to make some kind of beep, also in recording mode */
2499 void audio_beep(int duration)
2501 long starttick = current_tick;
2503 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2504 * While this is still audible even without an external signal,
2505 * it doesn't affect the (pre-)recording. */
2506 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2507 mas_codec_writereg(0, shadow_codec_reg0);
2508 yield();
2510 while (current_tick - starttick < duration);
2513 void audio_new_file(const char *filename)
2515 mpeg_errno = 0;
2517 strncpy(recording_filename, filename, MAX_PATH - 1);
2518 recording_filename[MAX_PATH - 1] = 0;
2520 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2523 unsigned long audio_recorded_time(void)
2525 if(is_prerecording)
2526 return prerecord_count * HZ;
2528 if(is_recording)
2530 if(paused)
2531 return pause_start_time - record_start_time;
2532 else
2533 return current_tick - record_start_time;
2536 return 0;
2539 unsigned long audio_num_recorded_bytes(void)
2541 int num_bytes;
2542 int index;
2544 if(is_recording)
2546 if(is_prerecording)
2548 index = prerecord_index - prerecord_count;
2549 if(index < 0)
2550 index += prerecording_max_seconds;
2552 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2553 if(num_bytes < 0)
2554 num_bytes += audiobuflen;
2556 return num_bytes;;
2558 else
2559 return num_rec_bytes;
2561 else
2562 return 0;
2565 #else /* SIMULATOR */
2567 /* dummies coming up */
2569 void audio_init_playback(void)
2571 /* a dummy */
2573 unsigned long audio_recorded_time(void)
2575 /* a dummy */
2576 return 0;
2578 void audio_beep(int duration)
2580 /* a dummy */
2581 (void)duration;
2583 void audio_pause_recording(void)
2585 /* a dummy */
2587 void audio_resume_recording(void)
2589 /* a dummy */
2591 unsigned long audio_num_recorded_bytes(void)
2593 /* a dummy */
2594 return 0;
2596 void audio_record(const char *filename)
2598 /* a dummy */
2599 (void)filename;
2601 void audio_new_file(const char *filename)
2603 /* a dummy */
2604 (void)filename;
2607 void audio_set_recording_gain(int left, int right, int type)
2609 /* a dummy */
2610 (void)left;
2611 (void)right;
2612 (void)type;
2614 void audio_init_recording(unsigned int buffer_offset)
2616 /* a dummy */
2617 (void)buffer_offset;
2619 void audio_set_recording_options(struct audio_recording_options *options)
2621 /* a dummy */
2622 (void)options;
2624 #endif /* SIMULATOR */
2625 #endif /* CONFIG_CODEC == MAS3587F */
2627 void audio_play(long offset)
2629 #ifdef SIMULATOR
2630 char* trackname;
2631 int steps=0;
2633 is_playing = true;
2635 do {
2636 trackname = playlist_peek( steps );
2637 if (!trackname)
2638 break;
2639 if(mp3info(&taginfo, trackname)) {
2640 /* bad mp3, move on */
2641 if(++steps > playlist_amount())
2642 break;
2643 continue;
2645 #ifdef HAVE_MPEG_PLAY
2646 real_mpeg_play(trackname);
2647 #endif
2648 playlist_next(steps);
2649 taginfo.offset = offset;
2650 set_elapsed(&taginfo);
2651 is_playing = true;
2652 playing = true;
2653 break;
2654 } while(1);
2655 #else /* !SIMULATOR */
2656 is_playing = true;
2658 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2659 #endif /* !SIMULATOR */
2661 mpeg_errno = 0;
2664 void audio_stop(void)
2666 #ifndef SIMULATOR
2667 if (playing)
2669 struct trackdata *track = get_trackdata(0);
2670 prev_track_elapsed = track->id3.elapsed;
2672 mpeg_stop_done = false;
2673 queue_post(&mpeg_queue, MPEG_STOP, 0);
2674 while(!mpeg_stop_done)
2675 yield();
2676 #else /* SIMULATOR */
2677 paused = false;
2678 is_playing = false;
2679 playing = false;
2680 #endif /* SIMULATOR */
2683 /* dummy */
2684 void audio_stop_recording(void)
2686 audio_stop();
2689 void audio_pause(void)
2691 #ifndef SIMULATOR
2692 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2693 #else /* SIMULATOR */
2694 is_playing = true;
2695 playing = false;
2696 paused = true;
2697 #endif /* SIMULATOR */
2700 void audio_resume(void)
2702 #ifndef SIMULATOR
2703 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2704 #else /* SIMULATOR */
2705 is_playing = true;
2706 playing = true;
2707 paused = false;
2708 #endif /* SIMULATOR */
2711 void audio_next(void)
2713 #ifndef SIMULATOR
2714 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2715 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2716 #else /* SIMULATOR */
2717 char* file;
2718 int steps = 1;
2719 int index;
2721 do {
2722 file = playlist_peek(steps);
2723 if(!file)
2724 break;
2725 if(mp3info(&taginfo, file)) {
2726 if(++steps > playlist_amount())
2727 break;
2728 continue;
2730 index = playlist_next(steps);
2731 taginfo.index = index;
2732 current_track_counter++;
2733 is_playing = true;
2734 playing = true;
2735 break;
2736 } while(1);
2737 #endif /* SIMULATOR */
2740 void audio_prev(void)
2742 #ifndef SIMULATOR
2743 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2744 queue_post(&mpeg_queue, MPEG_PREV, 0);
2745 #else /* SIMULATOR */
2746 char* file;
2747 int steps = -1;
2748 int index;
2750 do {
2751 file = playlist_peek(steps);
2752 if(!file)
2753 break;
2754 if(mp3info(&taginfo, file)) {
2755 steps--;
2756 continue;
2758 index = playlist_next(steps);
2759 taginfo.index = index;
2760 current_track_counter++;
2761 is_playing = true;
2762 playing = true;
2763 break;
2764 } while(1);
2765 #endif /* SIMULATOR */
2768 void audio_ff_rewind(long newtime)
2770 #ifndef SIMULATOR
2771 queue_post(&mpeg_queue, MPEG_FF_REWIND, newtime);
2772 #else /* SIMULATOR */
2773 (void)newtime;
2774 #endif /* SIMULATOR */
2777 void audio_flush_and_reload_tracks(void)
2779 #ifndef SIMULATOR
2780 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2781 #endif /* !SIMULATOR*/
2784 int audio_status(void)
2786 int ret = 0;
2788 if(is_playing)
2789 ret |= AUDIO_STATUS_PLAY;
2791 if(paused)
2792 ret |= AUDIO_STATUS_PAUSE;
2794 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2795 if(is_recording && !is_prerecording)
2796 ret |= AUDIO_STATUS_RECORD;
2798 if(is_prerecording)
2799 ret |= AUDIO_STATUS_PRERECORD;
2800 #endif /* CONFIG_CODEC == MAS3587F */
2802 if(mpeg_errno)
2803 ret |= AUDIO_STATUS_ERROR;
2805 return ret;
2808 unsigned int audio_error(void)
2810 return mpeg_errno;
2813 void audio_error_clear(void)
2815 mpeg_errno = 0;
2818 #ifdef SIMULATOR
2819 static void mpeg_thread(void)
2821 struct mp3entry* id3;
2822 while ( 1 ) {
2823 if (is_playing) {
2824 id3 = audio_current_track();
2825 if (!paused)
2827 id3->elapsed+=1000;
2828 id3->offset+=1000;
2830 if (id3->elapsed>=id3->length)
2831 audio_next();
2833 sleep(HZ);
2836 #endif /* SIMULATOR */
2838 void audio_init(void)
2840 mpeg_errno = 0;
2842 #ifndef SIMULATOR
2843 audiobuflen = audiobufend - audiobuf;
2844 queue_init(&mpeg_queue, true);
2845 #endif /* !SIMULATOR */
2846 create_thread(mpeg_thread, mpeg_stack,
2847 sizeof(mpeg_stack), 0, mpeg_thread_name
2848 IF_PRIO(, PRIORITY_SYSTEM)
2849 IF_COP(, CPU));
2851 memset(trackdata, sizeof(trackdata), 0);
2853 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2854 if (HW_MASK & PR_ACTIVE_HIGH)
2855 and_b(~0x08, &PADRH);
2856 else
2857 or_b(0x08, &PADRH);
2858 #endif /* CONFIG_CODEC == MAS3587F */
2860 #ifdef DEBUG
2861 #ifndef SIMULATOR
2862 dbg_timer_start();
2863 dbg_cnt2us(0);
2864 #endif /* !SIMULATOR */
2865 #endif /* DEBUG */
2868 #endif /* CONFIG_CODEC != SWCODEC */