FS#10317 - Sansa AMS 32-bit timers. Configure the timers for 32-bit mode instead...
[kugel-rb.git] / apps / mpeg.c
blob8518ab68e61e73ffd030840b6d7a6abb47b3a05b
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;
111 /* Play time of the previous track */
112 unsigned long prev_track_elapsed;
114 #ifndef SIMULATOR
115 static int track_read_idx = 0;
116 static int track_write_idx = 0;
117 #endif /* !SIMULATOR */
119 /* Cuesheet callback */
120 static bool (*cuesheet_callback)(const char *filename) = NULL;
122 static const char mpeg_thread_name[] = "mpeg";
123 static unsigned int mpeg_errno;
125 static bool playing = false; /* We are playing an MP3 stream */
126 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
127 static bool paused; /* playback is paused */
129 #ifdef SIMULATOR
130 static char mpeg_stack[DEFAULT_STACK_SIZE];
131 static struct mp3entry taginfo;
133 #else /* !SIMULATOR */
134 static struct event_queue mpeg_queue;
135 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
137 static int audiobuflen;
138 static int audiobuf_write;
139 static int audiobuf_swapwrite;
140 static int audiobuf_read;
142 static int mpeg_file;
144 static bool play_pending; /* We are about to start playing */
145 static bool play_pending_track_change; /* When starting play we're starting a new file */
146 static bool filling; /* We are filling the buffer with data from disk */
147 static bool dma_underrun; /* True when the DMA has stopped because of
148 slow disk reading (read error, shaking) */
149 static bool mpeg_stop_done;
151 static int last_dma_tick = 0;
152 static int last_dma_chunk_size;
154 static long low_watermark; /* Dynamic low watermark level */
155 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
156 static long lowest_watermark_level; /* Debug value to observe the buffer
157 usage */
158 #if CONFIG_CODEC == MAS3587F
159 static char recording_filename[MAX_PATH]; /* argument to thread */
160 static char delayed_filename[MAX_PATH]; /* internal copy of above */
162 static char xing_buffer[MAX_XING_HEADER_SIZE];
164 static bool init_recording_done;
165 static bool init_playback_done;
166 static bool prerecording; /* True if prerecording is enabled */
167 static bool is_prerecording; /* True if we are prerecording */
168 static bool is_recording; /* We are recording */
170 static enum {
171 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
172 BUFFER_FULL,
173 NEW_FILE,
174 STOP_RECORDING
175 } saving_status;
177 static int rec_frequency_index; /* For create_xing_header() calls */
178 static int rec_version_index; /* For create_xing_header() calls */
180 struct prerecord_info {
181 int mempos;
182 unsigned long framecount;
185 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
186 static int prerecord_index; /* Current index in the prerecord buffer */
187 static int prerecording_max_seconds; /* Max number of seconds to store */
188 static int prerecord_count; /* Number of seconds in the prerecord buffer */
189 static int prerecord_timeout; /* The tick count of the next prerecord data
190 store */
192 unsigned long record_start_time; /* Value of current_tick when recording
193 was started */
194 unsigned long pause_start_time; /* Value of current_tick when pause was
195 started */
196 static unsigned long last_rec_time;
197 static unsigned long num_rec_bytes;
198 static unsigned long last_rec_bytes;
199 static unsigned long frame_count_start;
200 static unsigned long frame_count_end;
201 static unsigned long saved_header = 0;
203 /* Shadow MAS registers */
204 unsigned long shadow_encoder_control = 0;
205 #endif /* CONFIG_CODEC == MAS3587F */
207 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
208 unsigned long shadow_io_control_main = 0;
209 unsigned long shadow_soft_mute = 0;
210 unsigned shadow_codec_reg0;
211 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
213 #ifdef HAVE_RECORDING
214 static const unsigned char empty_id3_header[] =
216 'I', 'D', '3', 0x03, 0x00, 0x00,
217 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
219 #endif /* HAVE_RECORDING */
222 static int get_unplayed_space(void);
223 static int get_playable_space(void);
224 static int get_unswapped_space(void);
225 #endif /* !SIMULATOR */
227 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
228 static void init_recording(void);
229 static void prepend_header(void);
230 static void update_header(void);
231 static void start_prerecording(void);
232 static void start_recording(void);
233 static void stop_recording(void);
234 static int get_unsaved_space(void);
235 static void pause_recording(void);
236 static void resume_recording(void);
237 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
240 #ifndef SIMULATOR
241 static int num_tracks_in_memory(void)
243 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
246 #ifdef DEBUG_TAGS
247 static void debug_tags(void)
249 int i;
251 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
253 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
255 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
256 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
258 #else /* !DEBUG_TAGS */
259 #define debug_tags()
260 #endif /* !DEBUG_TAGS */
262 static void remove_current_tag(void)
264 if(num_tracks_in_memory() > 0)
266 /* First move the index, so nobody tries to access the tag */
267 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
268 debug_tags();
270 else
272 DEBUGF("remove_current_tag: no tracks to remove\n");
276 static void remove_all_non_current_tags(void)
278 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
279 debug_tags();
282 static void remove_all_tags(void)
284 track_write_idx = track_read_idx;
286 debug_tags();
289 static struct trackdata *get_trackdata(int offset)
291 if(offset >= num_tracks_in_memory())
292 return NULL;
293 else
294 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
296 #endif /* !SIMULATOR */
298 /***********************************************************************/
299 /* audio event handling */
301 #define MAX_EVENT_HANDLERS 10
302 struct event_handlers_table
304 AUDIO_EVENT_HANDLER handler;
305 unsigned short mask;
307 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
308 static int event_handlers_count = 0;
310 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
312 if (event_handlers_count < MAX_EVENT_HANDLERS)
314 event_handlers[event_handlers_count].handler = handler;
315 event_handlers[event_handlers_count].mask = mask;
316 event_handlers_count++;
320 /* dispatch calls each handler in the order registered and returns after some
321 handler actually handles the event (the event is assumed to no longer be valid
322 after this, due to the handler changing some condition); returns true if someone
323 handled the event, which is expected to cause the caller to skip its own handling
324 of the event */
325 #ifndef SIMULATOR
326 static bool audio_dispatch_event(unsigned short event, unsigned long data)
328 int i = 0;
329 for(i=0; i < event_handlers_count; i++)
331 if ( event_handlers[i].mask & event )
333 int rc = event_handlers[i].handler(event, data);
334 if ( rc == AUDIO_EVENT_RC_HANDLED )
335 return true;
338 return false;
340 #endif
342 /***********************************************************************/
344 static void set_elapsed(struct mp3entry* id3)
346 if ( id3->vbr ) {
347 if ( id3->has_toc ) {
348 /* calculate elapsed time using TOC */
349 int i;
350 unsigned int remainder, plen, relpos, nextpos;
352 /* find wich percent we're at */
353 for (i=0; i<100; i++ )
355 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
357 break;
361 i--;
362 if (i < 0)
363 i = 0;
365 relpos = id3->toc[i];
367 if (i < 99)
369 nextpos = id3->toc[i+1];
371 else
373 nextpos = 256;
376 remainder = id3->offset - (relpos * (id3->filesize / 256));
378 /* set time for this percent (divide before multiply to prevent
379 overflow on long files. loss of precision is negligible on
380 short files) */
381 id3->elapsed = i * (id3->length / 100);
383 /* calculate remainder time */
384 plen = (nextpos - relpos) * (id3->filesize / 256);
385 id3->elapsed += (((remainder * 100) / plen) *
386 (id3->length / 10000));
388 else {
389 /* no TOC exists. set a rough estimate using average bitrate */
390 int tpk = id3->length / (id3->filesize / 1024);
391 id3->elapsed = id3->offset / 1024 * tpk;
394 else
395 /* constant bitrate, use exact calculation */
396 id3->elapsed = id3->offset / (id3->bitrate / 8);
399 int audio_get_file_pos(void)
401 int pos = -1;
402 struct mp3entry *id3 = audio_current_track();
404 if (id3->vbr)
406 if (id3->has_toc)
408 /* Use the TOC to find the new position */
409 unsigned int percent, remainder;
410 int curtoc, nexttoc, plen;
412 percent = (id3->elapsed*100)/id3->length;
413 if (percent > 99)
414 percent = 99;
416 curtoc = id3->toc[percent];
418 if (percent < 99)
419 nexttoc = id3->toc[percent+1];
420 else
421 nexttoc = 256;
423 pos = (id3->filesize/256)*curtoc;
425 /* Use the remainder to get a more accurate position */
426 remainder = (id3->elapsed*100)%id3->length;
427 remainder = (remainder*100)/id3->length;
428 plen = (nexttoc - curtoc)*(id3->filesize/256);
429 pos += (plen/100)*remainder;
431 else
433 /* No TOC exists, estimate the new position */
434 pos = (id3->filesize / (id3->length / 1000)) *
435 (id3->elapsed / 1000);
438 else if (id3->bitrate)
439 pos = id3->elapsed * (id3->bitrate / 8);
440 else
442 return -1;
445 if (pos >= (int)(id3->filesize - id3->id3v1len))
447 /* Don't seek right to the end of the file so that we can
448 transition properly to the next song */
449 pos = id3->filesize - id3->id3v1len - 1;
451 else if (pos < (int)id3->first_frame_offset)
453 /* skip past id3v2 tag and other leading garbage */
454 pos = id3->first_frame_offset;
456 return pos;
459 unsigned long mpeg_get_last_header(void)
461 #ifdef SIMULATOR
462 return 0;
463 #else /* !SIMULATOR */
464 unsigned long tmp[2];
466 /* Read the frame data from the MAS and reconstruct it with the
467 frame sync and all */
468 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
469 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
470 #endif /* !SIMULATOR */
473 void audio_set_cuesheet_callback(bool (*handler)(const char *filename))
475 cuesheet_callback = handler;
478 #ifndef SIMULATOR
479 /* Send callback events to notify about removing old tracks. */
480 static void generate_unbuffer_events(void)
482 int i;
483 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
484 int cur_idx = track_write_idx;
486 for (i = 0; i < numentries; i++)
488 /* Send an event to notify that track has finished. */
489 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
490 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
494 /* Send callback events to notify about new tracks. */
495 static void generate_postbuffer_events(void)
497 int i;
498 int numentries = num_tracks_in_memory();
499 int cur_idx = track_read_idx;
501 for (i = 0; i < numentries; i++)
503 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
504 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
508 static void recalculate_watermark(int bitrate)
510 int bytes_per_sec;
511 int time = storage_spinup_time();
513 /* A bitrate of 0 probably means empty VBR header. We play safe
514 and set a high threshold */
515 if(bitrate == 0)
516 bitrate = 320;
518 bytes_per_sec = bitrate * 1000 / 8;
520 if(time)
522 /* No drive spins up faster than 3.5s */
523 if(time < 350)
524 time = 350;
526 time = time * 3;
527 low_watermark = ((low_watermark_margin * HZ + time) *
528 bytes_per_sec) / HZ;
530 else
532 low_watermark = MPEG_LOW_WATER;
536 #ifdef HAVE_DISK_STORAGE
537 void audio_set_buffer_margin(int seconds)
539 low_watermark_margin = seconds;
541 #endif
543 void audio_get_debugdata(struct audio_debug *dbgdata)
545 dbgdata->audiobuflen = audiobuflen;
546 dbgdata->audiobuf_write = audiobuf_write;
547 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
548 dbgdata->audiobuf_read = audiobuf_read;
550 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
552 #if CONFIG_CPU == SH7034
553 dbgdata->dma_on = (SCR0 & 0x80) != 0;
554 #endif
555 dbgdata->playing = playing;
556 dbgdata->play_pending = play_pending;
557 dbgdata->is_playing = is_playing;
558 dbgdata->filling = filling;
559 dbgdata->dma_underrun = dma_underrun;
561 dbgdata->unplayed_space = get_unplayed_space();
562 dbgdata->playable_space = get_playable_space();
563 dbgdata->unswapped_space = get_unswapped_space();
565 dbgdata->low_watermark_level = low_watermark;
566 dbgdata->lowest_watermark_level = lowest_watermark_level;
569 #ifdef DEBUG
570 static void dbg_timer_start(void)
572 /* We are using timer 2 */
574 TSTR &= ~0x04; /* Stop the timer */
575 TSNC &= ~0x04; /* No synchronization */
576 TMDR &= ~0x44; /* Operate normally */
578 TCNT2 = 0; /* Start counting at 0 */
579 TCR2 = 0x03; /* Sysclock/8 */
581 TSTR |= 0x04; /* Start timer 2 */
584 static int dbg_cnt2us(unsigned int cnt)
586 return (cnt * 10000) / (FREQ/800);
588 #endif /* DEBUG */
590 static int get_unplayed_space(void)
592 int space = audiobuf_write - audiobuf_read;
593 if (space < 0)
594 space += audiobuflen;
595 return space;
598 static int get_playable_space(void)
600 int space = audiobuf_swapwrite - audiobuf_read;
601 if (space < 0)
602 space += audiobuflen;
603 return space;
606 static int get_unplayed_space_current_song(void)
608 int space;
610 if (num_tracks_in_memory() > 1)
612 space = get_trackdata(1)->mempos - audiobuf_read;
614 else
616 space = audiobuf_write - audiobuf_read;
619 if (space < 0)
620 space += audiobuflen;
622 return space;
625 static int get_unswapped_space(void)
627 int space = audiobuf_write - audiobuf_swapwrite;
628 if (space < 0)
629 space += audiobuflen;
630 return space;
633 #if CONFIG_CODEC == MAS3587F
634 static int get_unsaved_space(void)
636 int space = audiobuf_write - audiobuf_read;
637 if (space < 0)
638 space += audiobuflen;
639 return space;
642 static void drain_dma_buffer(void)
644 while (PBDRH & 0x40)
646 xor_b(0x08, &PADRH);
648 while (PBDRH & 0x80);
650 xor_b(0x08, &PADRH);
652 while (!(PBDRH & 0x80));
656 #ifdef DEBUG
657 static long timing_info_index = 0;
658 static long timing_info[1024];
659 #endif /* DEBUG */
661 void rec_tick (void) __attribute__ ((section (".icode")));
662 void rec_tick(void)
664 int i;
665 int delay;
666 char data;
668 if(is_recording && (PBDRH & 0x40))
670 #ifdef DEBUG
671 timing_info[timing_info_index++] = current_tick;
672 TCNT2 = 0;
673 #endif /* DEBUG */
674 /* Note: Although this loop is run in interrupt context, further
675 * optimisation will do no good. The MAS would then deliver bad
676 * frames occasionally, as observed in extended experiments. */
677 i = 0;
678 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
680 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
682 delay = 100;
683 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
685 if (--delay <= 0) /* Bail out if we have to wait too long */
686 { /* i.e. the MAS doesn't want to talk to us */
687 xor_b(0x08, &PADRH); /* Set PR inactive */
688 goto transfer_end; /* and get out of here */
692 data = *(unsigned char *)0x04000000; /* read data byte */
694 xor_b(0x08, &PADRH); /* Set PR inactive */
696 audiobuf[audiobuf_write++] = data;
698 if (audiobuf_write >= audiobuflen)
699 audiobuf_write = 0;
701 i++;
703 transfer_end:
705 #ifdef DEBUG
706 timing_info[timing_info_index++] = TCNT2 + (i << 16);
707 timing_info_index &= 0x3ff;
708 #endif /* DEBUG */
710 num_rec_bytes += i;
712 if(is_prerecording)
714 if(TIME_AFTER(current_tick, prerecord_timeout))
716 prerecord_timeout = current_tick + HZ;
717 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
720 else
722 /* Signal to save the data if we are running out of buffer
723 space */
724 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
725 && saving_status == NOT_SAVING)
727 saving_status = BUFFER_FULL;
728 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
733 #endif /* CONFIG_CODEC == MAS3587F */
735 void playback_tick(void)
737 struct trackdata *ptd = get_trackdata(0);
738 if(ptd)
740 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
741 last_dma_tick = current_tick;
742 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
743 (unsigned long)ptd->id3.elapsed);
747 static void reset_mp3_buffer(void)
749 audiobuf_read = 0;
750 audiobuf_write = 0;
751 audiobuf_swapwrite = 0;
752 lowest_watermark_level = audiobuflen;
755 /* DMA transfer end interrupt callback */
756 static void transfer_end(unsigned char** ppbuf, size_t* psize)
758 if(playing && !paused)
760 int unplayed_space_left;
761 int space_until_end_of_buffer;
762 int track_offset = 1;
763 struct trackdata *track;
765 audiobuf_read += last_dma_chunk_size;
766 if(audiobuf_read >= audiobuflen)
767 audiobuf_read = 0;
769 /* First, check if we are on a track boundary */
770 if (num_tracks_in_memory() > 1)
772 if (audiobuf_read == get_trackdata(track_offset)->mempos)
774 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
776 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
777 track_offset++;
782 unplayed_space_left = get_unplayed_space();
784 space_until_end_of_buffer = audiobuflen - audiobuf_read;
786 if(!filling && unplayed_space_left < low_watermark)
788 filling = true;
789 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
792 if(unplayed_space_left)
794 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
795 last_dma_chunk_size = MIN(last_dma_chunk_size,
796 space_until_end_of_buffer);
798 /* several tracks loaded? */
799 track = get_trackdata(track_offset);
800 if(track)
802 /* will we move across the track boundary? */
803 if (( audiobuf_read < track->mempos ) &&
804 ((audiobuf_read+last_dma_chunk_size) >
805 track->mempos ))
807 /* Make sure that we end exactly on the boundary */
808 last_dma_chunk_size = track->mempos - audiobuf_read;
812 *psize = last_dma_chunk_size & 0xffff;
813 *ppbuf = audiobuf + audiobuf_read;
814 track = get_trackdata(0);
815 if(track)
816 track->id3.offset += last_dma_chunk_size;
818 /* Update the watermark debug level */
819 if(unplayed_space_left < lowest_watermark_level)
820 lowest_watermark_level = unplayed_space_left;
822 else
824 /* Check if the end of data is because of a hard disk error.
825 If there is an open file handle, we are still playing music.
826 If not, the last file has been loaded, and the file handle is
827 closed. */
828 if(mpeg_file >= 0)
830 /* Update the watermark debug level */
831 if(unplayed_space_left < lowest_watermark_level)
832 lowest_watermark_level = unplayed_space_left;
834 DEBUGF("DMA underrun.\n");
835 dma_underrun = true;
837 else
839 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
841 DEBUGF("No more MP3 data. Stopping.\n");
842 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
843 playing = false;
846 *psize = 0; /* no more transfer */
851 static struct trackdata *add_track_to_tag_list(const char *filename)
853 struct trackdata *track;
854 bool send_nid3_event;
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 /* if this track is the next track then let the UI know it can get it */
886 send_nid3_event = (track_write_idx == track_read_idx + 1);
887 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
888 if (send_nid3_event)
889 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
890 debug_tags();
891 return track;
894 static int new_file(int steps)
896 int max_steps = playlist_amount();
897 int start = 0;
898 int i;
899 struct trackdata *track;
901 /* Find out how many steps to advance. The load_ahead_index field tells
902 us how many playlist entries it had to skip to get to a valid one.
903 We add those together to find out where to start. */
904 if(steps > 0 && num_tracks_in_memory() > 1)
906 /* Begin with the song after the currently playing one */
907 i = 1;
908 while((track = get_trackdata(i++)))
910 start += track->load_ahead_index;
914 do {
915 char *trackname;
917 trackname = playlist_peek( start + steps );
918 if ( !trackname )
919 return -1;
921 DEBUGF("Loading %s\n", trackname);
923 mpeg_file = open(trackname, O_RDONLY);
924 if(mpeg_file < 0) {
925 DEBUGF("Couldn't open file: %s\n",trackname);
926 if(steps < 0)
927 steps--;
928 else
929 steps++;
931 else
933 struct trackdata *track = add_track_to_tag_list(trackname);
935 if(!track)
937 /* Bad mp3 file */
938 if(steps < 0)
939 steps--;
940 else
941 steps++;
942 close(mpeg_file);
943 mpeg_file = -1;
945 else
947 /* skip past id3v2 tag */
948 lseek(mpeg_file,
949 track->id3.first_frame_offset,
950 SEEK_SET);
951 track->id3.index = steps;
952 track->load_ahead_index = steps;
953 track->id3.offset = 0;
955 if(track->id3.vbr)
956 /* Average bitrate * 1.5 */
957 recalculate_watermark(
958 (track->id3.bitrate * 3) / 2);
959 else
960 recalculate_watermark(
961 track->id3.bitrate);
966 /* Bail out if no file could be opened */
967 if(abs(steps) > max_steps)
968 return -1;
969 } while ( mpeg_file < 0 );
971 return 0;
974 static void stop_playing(void)
976 struct trackdata *track;
978 /* Stop the current stream */
979 mp3_play_stop();
980 playing = false;
981 filling = false;
983 track = get_trackdata(0);
984 if (track != NULL)
985 prev_track_elapsed = track->id3.elapsed;
987 if(mpeg_file >= 0)
988 close(mpeg_file);
989 mpeg_file = -1;
990 remove_all_tags();
991 generate_unbuffer_events();
992 reset_mp3_buffer();
995 static void end_current_track(void) {
996 struct trackdata *track;
998 play_pending = false;
999 playing = false;
1000 mp3_play_pause(false);
1002 track = get_trackdata(0);
1003 if (track != NULL)
1004 prev_track_elapsed = track->id3.elapsed;
1006 reset_mp3_buffer();
1007 remove_all_tags();
1008 generate_unbuffer_events();
1010 if(mpeg_file >= 0)
1011 close(mpeg_file);
1014 /* Is this a really the end of playback or is a new playlist starting */
1015 static void check_playlist_end(int direction)
1017 /* Use the largest possible step size to account for skipped tracks */
1018 int steps = playlist_amount();
1020 if (direction < 0)
1021 steps = -steps;
1023 if (playlist_next(steps) < 0)
1024 is_playing = false;
1027 static void update_playlist(void)
1029 if (num_tracks_in_memory() > 0)
1031 struct trackdata *track = get_trackdata(0);
1032 track->id3.index = playlist_next(track->id3.index);
1034 else
1036 /* End of playlist? */
1037 check_playlist_end(1);
1040 playlist_update_resume_info(audio_current_track());
1043 static void track_change(void)
1045 DEBUGF("Track change\n");
1047 struct trackdata *track = get_trackdata(0);
1048 prev_track_elapsed = track->id3.elapsed;
1050 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1051 /* Reset the AVC */
1052 sound_set_avc(-1);
1053 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1055 if (num_tracks_in_memory() > 0)
1057 remove_current_tag();
1058 update_playlist();
1059 if (is_playing)
1060 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1063 current_track_counter++;
1066 unsigned long audio_prev_elapsed(void)
1068 return prev_track_elapsed;
1071 #ifdef DEBUG
1072 void hexdump(const unsigned char *buf, int len)
1074 int i;
1076 for(i = 0;i < len;i++)
1078 if(i && (i & 15) == 0)
1080 DEBUGF("\n");
1082 DEBUGF("%02x ", buf[i]);
1084 DEBUGF("\n");
1086 #endif /* DEBUG */
1088 static void start_playback_if_ready(void)
1090 int playable_space;
1092 playable_space = audiobuf_swapwrite - audiobuf_read;
1093 if(playable_space < 0)
1094 playable_space += audiobuflen;
1096 /* See if we have started playing yet. If not, do it. */
1097 if(play_pending || dma_underrun)
1099 /* If the filling has stopped, and we still haven't reached
1100 the watermark, the file must be smaller than the
1101 watermark. We must still play it. */
1102 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1103 !filling || dma_underrun)
1105 DEBUGF("P\n");
1106 if (play_pending) /* don't do this when recovering from DMA underrun */
1108 generate_postbuffer_events(); /* signal first track as buffered */
1109 if (play_pending_track_change)
1111 play_pending_track_change = false;
1112 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1114 play_pending = false;
1116 playing = true;
1118 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1119 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1120 dma_underrun = false;
1122 if (!paused)
1124 last_dma_tick = current_tick;
1125 mp3_play_pause(true);
1128 /* Tell ourselves that we need more data */
1129 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1134 static bool swap_one_chunk(void)
1136 int free_space_left;
1137 int amount_to_swap;
1139 free_space_left = get_unswapped_space();
1141 if(free_space_left == 0 && !play_pending)
1142 return false;
1144 /* Swap in larger chunks when the user is waiting for the playback
1145 to start, or when there is dangerously little playable data left */
1146 if(play_pending)
1147 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1148 else
1150 if(get_playable_space() < low_watermark)
1151 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1152 free_space_left);
1153 else
1154 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1157 if(audiobuf_write < audiobuf_swapwrite)
1158 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1159 amount_to_swap);
1160 else
1161 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1162 amount_to_swap);
1164 bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap);
1166 audiobuf_swapwrite += amount_to_swap;
1167 if(audiobuf_swapwrite >= audiobuflen)
1169 audiobuf_swapwrite = 0;
1172 return true;
1175 static void mpeg_thread(void)
1177 static int pause_tick = 0;
1178 static unsigned int pause_track = 0;
1179 struct queue_event ev;
1180 int len;
1181 int free_space_left;
1182 int unplayed_space_left;
1183 int amount_to_read;
1184 int t1, t2;
1185 int start_offset;
1186 #if CONFIG_CODEC == MAS3587F
1187 int amount_to_save;
1188 int save_endpos = 0;
1189 int rc;
1190 int level;
1191 long offset;
1192 #endif /* CONFIG_CODEC == MAS3587F */
1194 is_playing = false;
1195 play_pending = false;
1196 playing = false;
1197 mpeg_file = -1;
1199 while(1)
1201 #if CONFIG_CODEC == MAS3587F
1202 if(mpeg_mode == MPEG_DECODER)
1204 #endif /* CONFIG_CODEC == MAS3587F */
1205 yield();
1207 /* Swap if necessary, and don't block on the queue_wait() */
1208 if(swap_one_chunk())
1210 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1212 else if (playing)
1214 /* periodically update resume info */
1215 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1217 else
1219 DEBUGF("S R:%x W:%x SW:%x\n",
1220 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1221 queue_wait(&mpeg_queue, &ev);
1224 start_playback_if_ready();
1226 switch(ev.id)
1228 case MPEG_PLAY:
1229 DEBUGF("MPEG_PLAY\n");
1231 #if CONFIG_TUNER
1232 /* Silence the A/D input, it may be on because the radio
1233 may be playing */
1234 mas_codec_writereg(6, 0x0000);
1235 #endif /* CONFIG_TUNER */
1237 /* Stop the current stream */
1238 paused = false;
1239 end_current_track();
1241 if ( new_file(0) == -1 )
1243 is_playing = false;
1244 track_change();
1245 break;
1248 start_offset = (int)ev.data;
1250 /* mid-song resume? */
1251 if (start_offset) {
1252 struct mp3entry* id3 = &get_trackdata(0)->id3;
1253 lseek(mpeg_file, start_offset, SEEK_SET);
1254 id3->offset = start_offset;
1255 set_elapsed(id3);
1257 else {
1258 /* skip past id3v2 tag */
1259 lseek(mpeg_file,
1260 get_trackdata(0)->id3.first_frame_offset,
1261 SEEK_SET);
1265 /* Make it read more data */
1266 filling = true;
1267 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1269 /* Tell the file loading code that we want to start playing
1270 as soon as we have some data */
1271 play_pending = true;
1272 play_pending_track_change = true;
1274 update_playlist();
1275 current_track_counter++;
1276 break;
1278 case MPEG_STOP:
1279 DEBUGF("MPEG_STOP\n");
1280 is_playing = false;
1281 paused = false;
1283 if (playing)
1284 playlist_update_resume_info(audio_current_track());
1286 stop_playing();
1287 mpeg_stop_done = true;
1288 break;
1290 case MPEG_PAUSE:
1291 DEBUGF("MPEG_PAUSE\n");
1292 /* Stop the current stream */
1293 if (playing)
1294 playlist_update_resume_info(audio_current_track());
1295 paused = true;
1296 playing = false;
1297 pause_tick = current_tick;
1298 pause_track = current_track_counter;
1299 mp3_play_pause(false);
1300 break;
1302 case MPEG_RESUME:
1303 DEBUGF("MPEG_RESUME\n");
1304 /* Continue the current stream */
1305 paused = false;
1306 if (!play_pending)
1308 playing = true;
1309 if ( current_track_counter == pause_track )
1310 last_dma_tick += current_tick - pause_tick;
1311 else
1312 last_dma_tick = current_tick;
1313 pause_tick = 0;
1314 mp3_play_pause(true);
1316 break;
1318 case MPEG_NEXT:
1319 DEBUGF("MPEG_NEXT\n");
1320 /* is next track in ram? */
1321 if ( num_tracks_in_memory() > 1 ) {
1322 int unplayed_space_left, unswapped_space_left;
1324 /* stop the current stream */
1325 play_pending = false;
1326 playing = false;
1327 mp3_play_pause(false);
1329 track_change();
1330 audiobuf_read = get_trackdata(0)->mempos;
1331 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1332 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1333 dma_underrun = false;
1334 last_dma_tick = current_tick;
1336 unplayed_space_left = get_unplayed_space();
1337 unswapped_space_left = get_unswapped_space();
1339 /* should we start reading more data? */
1340 if(!filling && (unplayed_space_left < low_watermark)) {
1341 filling = true;
1342 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1343 play_pending = true;
1344 } else if(unswapped_space_left &&
1345 unswapped_space_left > unplayed_space_left) {
1346 /* Stop swapping the data from the previous file */
1347 audiobuf_swapwrite = audiobuf_read;
1348 play_pending = true;
1349 } else {
1350 playing = true;
1351 if (!paused)
1352 mp3_play_pause(true);
1355 else {
1356 if (!playlist_check(1))
1357 break;
1359 /* stop the current stream */
1360 end_current_track();
1362 if (new_file(1) < 0) {
1363 DEBUGF("No more files to play\n");
1364 filling = false;
1366 check_playlist_end(1);
1367 current_track_counter++;
1368 } else {
1369 /* Make it read more data */
1370 filling = true;
1371 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1373 /* Tell the file loading code that we want
1374 to start playing as soon as we have some data */
1375 play_pending = true;
1376 play_pending_track_change = true;
1378 update_playlist();
1379 current_track_counter++;
1382 break;
1384 case MPEG_PREV: {
1385 DEBUGF("MPEG_PREV\n");
1387 if (!playlist_check(-1))
1388 break;
1390 /* stop the current stream */
1391 end_current_track();
1393 /* Open the next file */
1394 if (new_file(-1) < 0) {
1395 DEBUGF("No more files to play\n");
1396 filling = false;
1398 check_playlist_end(-1);
1399 current_track_counter++;
1400 } else {
1401 /* Make it read more data */
1402 filling = true;
1403 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1405 /* Tell the file loading code that we want to
1406 start playing as soon as we have some data */
1407 play_pending = true;
1408 play_pending_track_change = true;
1410 update_playlist();
1411 current_track_counter++;
1413 break;
1416 case MPEG_FF_REWIND: {
1417 struct mp3entry *id3 = audio_current_track();
1418 unsigned int oldtime = id3->elapsed;
1419 unsigned int newtime = (unsigned int)ev.data;
1420 int curpos, newpos, diffpos;
1421 DEBUGF("MPEG_FF_REWIND\n");
1423 id3->elapsed = newtime;
1425 newpos = audio_get_file_pos();
1426 if(newpos < 0)
1428 id3->elapsed = oldtime;
1429 break;
1432 if (mpeg_file >= 0)
1433 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1434 else
1435 curpos = id3->filesize;
1437 if (num_tracks_in_memory() > 1)
1439 /* We have started loading other tracks that need to be
1440 accounted for */
1441 struct trackdata *track;
1442 int i = 0;
1444 while((track = get_trackdata(i++)))
1446 curpos += track->id3.filesize;
1450 diffpos = curpos - newpos;
1452 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1454 int unplayed_space_left, unswapped_space_left;
1456 /* We are changing to a position that's already in
1457 memory, so we just move the DMA read pointer. */
1458 audiobuf_read = audiobuf_write - diffpos;
1459 if (audiobuf_read < 0)
1461 audiobuf_read += audiobuflen;
1464 unplayed_space_left = get_unplayed_space();
1465 unswapped_space_left = get_unswapped_space();
1467 /* If unswapped_space_left is larger than
1468 unplayed_space_left, it means that the swapwrite pointer
1469 hasn't yet advanced up to the new location of the read
1470 pointer. We just move it, there is no need to swap
1471 data that won't be played anyway. */
1473 if (unswapped_space_left > unplayed_space_left)
1475 DEBUGF("Moved swapwrite\n");
1476 audiobuf_swapwrite = audiobuf_read;
1477 play_pending = true;
1480 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1482 /* We need to load more data before starting */
1483 filling = true;
1484 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1485 play_pending = true;
1487 else
1489 /* resume will start at new position */
1490 last_dma_chunk_size =
1491 MIN(0x2000, get_unplayed_space_current_song());
1492 mp3_play_data(audiobuf + audiobuf_read,
1493 last_dma_chunk_size, transfer_end);
1494 dma_underrun = false;
1497 else
1499 /* Move to the new position in the file and start
1500 loading data */
1501 reset_mp3_buffer();
1503 if (num_tracks_in_memory() > 1)
1505 /* We have to reload the current track */
1506 close(mpeg_file);
1507 remove_all_non_current_tags();
1508 generate_unbuffer_events();
1509 mpeg_file = -1;
1512 if (mpeg_file < 0)
1514 mpeg_file = open(id3->path, O_RDONLY);
1515 if (mpeg_file < 0)
1517 id3->elapsed = oldtime;
1518 break;
1522 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1524 id3->elapsed = oldtime;
1525 break;
1528 filling = true;
1529 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1531 /* Tell the file loading code that we want to start playing
1532 as soon as we have some data */
1533 play_pending = true;
1536 id3->offset = newpos;
1538 break;
1541 case MPEG_FLUSH_RELOAD: {
1542 int numtracks = num_tracks_in_memory();
1543 bool reload_track = false;
1545 if (numtracks > 1)
1547 /* Reset the buffer */
1548 audiobuf_write = get_trackdata(1)->mempos;
1550 /* Reset swapwrite unless we're still swapping current
1551 track */
1552 if (get_unplayed_space() <= get_playable_space())
1553 audiobuf_swapwrite = audiobuf_write;
1555 close(mpeg_file);
1556 remove_all_non_current_tags();
1557 generate_unbuffer_events();
1558 mpeg_file = -1;
1559 reload_track = true;
1561 else if (numtracks == 1 && mpeg_file < 0)
1563 reload_track = true;
1566 if(reload_track && new_file(1) >= 0)
1568 /* Tell ourselves that we want more data */
1569 filling = true;
1570 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1573 break;
1576 case MPEG_NEED_DATA:
1577 free_space_left = audiobuf_read - audiobuf_write;
1579 /* We interpret 0 as "empty buffer" */
1580 if(free_space_left <= 0)
1581 free_space_left += audiobuflen;
1583 unplayed_space_left = audiobuflen - free_space_left;
1585 /* Make sure that we don't fill the entire buffer */
1586 free_space_left -= MPEG_HIGH_WATER;
1588 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1589 generate_unbuffer_events();
1591 /* do we have any more buffer space to fill? */
1592 if(free_space_left <= 0)
1594 DEBUGF("0\n");
1595 filling = false;
1596 generate_postbuffer_events();
1597 storage_sleep();
1598 break;
1601 /* Read small chunks while we are below the low water mark */
1602 if(unplayed_space_left < low_watermark)
1603 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1604 free_space_left);
1605 else
1606 amount_to_read = free_space_left;
1608 /* Don't read more than until the end of the buffer */
1609 amount_to_read = MIN(audiobuflen - audiobuf_write,
1610 amount_to_read);
1611 #if (CONFIG_STORAGE & STORAGE_MMC)
1612 /* MMC is slow, so don't read too large chunks */
1613 amount_to_read = MIN(0x40000, amount_to_read);
1614 #elif MEM == 8
1615 amount_to_read = MIN(0x100000, amount_to_read);
1616 #endif
1618 /* Read as much mpeg data as we can fit in the buffer */
1619 if(mpeg_file >= 0)
1621 DEBUGF("R\n");
1622 t1 = current_tick;
1623 len = read(mpeg_file, audiobuf + audiobuf_write,
1624 amount_to_read);
1625 if(len > 0)
1627 t2 = current_tick;
1628 DEBUGF("time: %d\n", t2 - t1);
1629 DEBUGF("R: %x\n", len);
1631 /* Now make sure that we don't feed the MAS with ID3V1
1632 data */
1633 if (len < amount_to_read)
1635 int i;
1636 static const unsigned char tag[] = "TAG";
1637 int taglen = 128;
1638 int tagptr = audiobuf_write + len - 128;
1640 /* Really rare case: entire potential tag wasn't
1641 read in this call AND audiobuf_write < 128 */
1642 if (tagptr < 0)
1643 tagptr += audiobuflen;
1645 for(i = 0;i < 3;i++)
1647 if(tagptr >= audiobuflen)
1648 tagptr -= audiobuflen;
1650 if(audiobuf[tagptr] != tag[i])
1652 taglen = 0;
1653 break;
1656 tagptr++;
1659 if(taglen)
1661 /* Skip id3v1 tag */
1662 DEBUGF("Skipping ID3v1 tag\n");
1663 len -= taglen;
1665 /* In the very rare case when the entire tag
1666 wasn't read in this read() len will be < 0.
1667 Take care of this when changing the write
1668 pointer. */
1672 audiobuf_write += len;
1674 if (audiobuf_write < 0)
1675 audiobuf_write += audiobuflen;
1677 if(audiobuf_write >= audiobuflen)
1679 audiobuf_write = 0;
1680 DEBUGF("W\n");
1683 /* Tell ourselves that we want more data */
1684 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1686 else
1688 if(len < 0)
1690 DEBUGF("MPEG read error\n");
1693 close(mpeg_file);
1694 mpeg_file = -1;
1696 if(new_file(1) < 0)
1698 /* No more data to play */
1699 DEBUGF("No more files to play\n");
1700 filling = false;
1702 else
1704 /* Tell ourselves that we want more data */
1705 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1709 break;
1711 case MPEG_TRACK_CHANGE:
1712 track_change();
1713 break;
1715 #ifndef USB_NONE
1716 case SYS_USB_CONNECTED:
1717 is_playing = false;
1718 paused = false;
1719 stop_playing();
1721 /* Tell the USB thread that we are safe */
1722 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1723 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1725 /* Wait until the USB cable is extracted again */
1726 usb_wait_for_disconnect(&mpeg_queue);
1727 break;
1728 #endif /* !USB_NONE */
1730 #if CONFIG_CODEC == MAS3587F
1731 case MPEG_INIT_RECORDING:
1732 init_recording();
1733 init_recording_done = true;
1734 break;
1735 #endif /* CONFIG_CODEC == MAS3587F */
1737 case SYS_TIMEOUT:
1738 if (playing)
1739 playlist_update_resume_info(audio_current_track());
1740 break;
1742 #if CONFIG_CODEC == MAS3587F
1744 else
1746 queue_wait(&mpeg_queue, &ev);
1747 switch(ev.id)
1749 case MPEG_RECORD:
1750 if (is_prerecording)
1752 int startpos;
1754 /* Go back prerecord_count seconds in the buffer */
1755 startpos = prerecord_index - prerecord_count;
1756 if(startpos < 0)
1757 startpos += prerecording_max_seconds;
1759 /* Read the position data from the prerecord buffer */
1760 frame_count_start = prerecord_buffer[startpos].framecount;
1761 startpos = prerecord_buffer[startpos].mempos;
1763 DEBUGF("Start looking at address %x (%x)\n",
1764 audiobuf+startpos, startpos);
1766 saved_header = mpeg_get_last_header();
1768 mem_find_next_frame(startpos, &offset, 1800,
1769 saved_header);
1771 audiobuf_read = startpos + offset;
1772 if(audiobuf_read >= audiobuflen)
1773 audiobuf_read -= audiobuflen;
1775 DEBUGF("New audiobuf_read address: %x (%x)\n",
1776 audiobuf+audiobuf_read, audiobuf_read);
1778 level = disable_irq_save();
1779 num_rec_bytes = get_unsaved_space();
1780 restore_irq(level);
1782 else
1784 frame_count_start = 0;
1785 num_rec_bytes = 0;
1786 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1787 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1790 prepend_header();
1791 DEBUGF("Recording...\n");
1792 start_recording();
1794 /* Wait until at least one frame is encoded and get the
1795 frame header, for later use by the Xing header
1796 generation */
1797 sleep(HZ/5);
1798 saved_header = mpeg_get_last_header();
1800 /* delayed until buffer is saved, don't open yet */
1801 strcpy(delayed_filename, recording_filename);
1802 mpeg_file = -1;
1804 break;
1806 case MPEG_STOP:
1807 DEBUGF("MPEG_STOP\n");
1809 stop_recording();
1811 /* Save the remaining data in the buffer */
1812 save_endpos = audiobuf_write;
1813 saving_status = STOP_RECORDING;
1814 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1815 break;
1817 case MPEG_STOP_DONE:
1818 DEBUGF("MPEG_STOP_DONE\n");
1820 if (mpeg_file >= 0)
1821 close(mpeg_file);
1822 mpeg_file = -1;
1824 update_header();
1825 #ifdef DEBUG1
1827 int i;
1828 for(i = 0;i < 512;i++)
1830 DEBUGF("%d - %d us (%d bytes)\n",
1831 timing_info[i*2],
1832 (timing_info[i*2+1] & 0xffff) *
1833 10000 / 13824,
1834 timing_info[i*2+1] >> 16);
1837 #endif /* DEBUG1 */
1839 if (prerecording)
1841 start_prerecording();
1843 mpeg_stop_done = true;
1844 break;
1846 case MPEG_NEW_FILE:
1847 /* Bail out when a more important save is happening */
1848 if (saving_status > NEW_FILE)
1849 break;
1851 /* Make sure we have at least one complete frame
1852 in the buffer. If we haven't recorded a single
1853 frame within 200ms, the MAS is probably not recording
1854 anything, and we bail out. */
1855 amount_to_save = get_unsaved_space();
1856 if (amount_to_save < 1800)
1858 sleep(HZ/5);
1859 amount_to_save = get_unsaved_space();
1862 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1863 &frame_count_end, 1);
1865 last_rec_time = current_tick - record_start_time;
1866 record_start_time = current_tick;
1867 if (paused)
1868 pause_start_time = record_start_time;
1870 /* capture all values at one point */
1871 level = disable_irq_save();
1872 save_endpos = audiobuf_write;
1873 last_rec_bytes = num_rec_bytes;
1874 num_rec_bytes = 0;
1875 restore_irq(level);
1877 if (amount_to_save >= 1800)
1879 /* Now find a frame boundary to split at */
1880 save_endpos -= 1800;
1881 if (save_endpos < 0)
1882 save_endpos += audiobuflen;
1884 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1885 saved_header);
1886 if (!rc) /* No header found, save whole buffer */
1887 offset = 1800;
1889 save_endpos += offset;
1890 if (save_endpos >= audiobuflen)
1891 save_endpos -= audiobuflen;
1893 last_rec_bytes += offset - 1800;
1894 level = disable_irq_save();
1895 num_rec_bytes += 1800 - offset;
1896 restore_irq(level);
1899 saving_status = NEW_FILE;
1900 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1901 break;
1903 case MPEG_SAVE_DATA:
1904 if (saving_status == BUFFER_FULL)
1905 save_endpos = audiobuf_write;
1907 if (mpeg_file < 0) /* delayed file open */
1909 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT);
1911 if (mpeg_file < 0)
1912 panicf("recfile: %d", mpeg_file);
1915 amount_to_save = save_endpos - audiobuf_read;
1916 if (amount_to_save < 0)
1917 amount_to_save += audiobuflen;
1919 amount_to_save = MIN(amount_to_save,
1920 audiobuflen - audiobuf_read);
1921 #if (CONFIG_STORAGE & STORAGE_MMC)
1922 /* MMC is slow, so don't save too large chunks at once */
1923 amount_to_save = MIN(0x40000, amount_to_save);
1924 #elif MEM == 8
1925 amount_to_save = MIN(0x100000, amount_to_save);
1926 #endif
1927 rc = write(mpeg_file, audiobuf + audiobuf_read,
1928 amount_to_save);
1929 if (rc < 0)
1931 if (errno == ENOSPC)
1933 mpeg_errno = AUDIOERR_DISK_FULL;
1934 stop_recording();
1935 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1936 /* will close the file */
1937 break;
1939 else
1940 panicf("rec wrt: %d", rc);
1943 audiobuf_read += amount_to_save;
1944 if (audiobuf_read >= audiobuflen)
1945 audiobuf_read = 0;
1947 if (audiobuf_read == save_endpos) /* all saved */
1949 switch (saving_status)
1951 case BUFFER_FULL:
1952 rc = fsync(mpeg_file);
1953 if (rc < 0)
1954 panicf("rec fls: %d", rc);
1955 storage_sleep();
1956 break;
1958 case NEW_FILE:
1959 /* Close the current file */
1960 rc = close(mpeg_file);
1961 if (rc < 0)
1962 panicf("rec cls: %d", rc);
1963 mpeg_file = -1;
1964 update_header();
1965 storage_sleep();
1967 /* copy new filename */
1968 strcpy(delayed_filename, recording_filename);
1969 prepend_header();
1970 frame_count_start = frame_count_end;
1971 break;
1973 case STOP_RECORDING:
1974 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1975 /* will close the file */
1976 break;
1978 default:
1979 break;
1981 saving_status = NOT_SAVING;
1983 else /* tell ourselves to save the next chunk */
1984 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1986 break;
1988 case MPEG_PRERECORDING_TICK:
1989 if(!is_prerecording)
1990 break;
1992 /* Store the write pointer every second */
1993 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
1994 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1995 &prerecord_buffer[prerecord_index].framecount, 1);
1997 /* Wrap if necessary */
1998 if(++prerecord_index == prerecording_max_seconds)
1999 prerecord_index = 0;
2001 /* Update the number of seconds recorded */
2002 if(prerecord_count < prerecording_max_seconds)
2003 prerecord_count++;
2004 break;
2006 case MPEG_INIT_PLAYBACK:
2007 /* Stop the prerecording */
2008 stop_recording();
2009 reset_mp3_buffer();
2010 mp3_play_init();
2011 init_playback_done = true;
2012 break;
2014 case MPEG_PAUSE_RECORDING:
2015 pause_recording();
2016 break;
2018 case MPEG_RESUME_RECORDING:
2019 resume_recording();
2020 break;
2022 case SYS_USB_CONNECTED:
2023 /* We can safely go to USB mode if no recording
2024 is taking place */
2025 if((!is_recording || is_prerecording) && mpeg_stop_done)
2027 /* Even if we aren't recording, we still call this
2028 function, to put the MAS in monitoring mode,
2029 to save power. */
2030 stop_recording();
2032 /* Tell the USB thread that we are safe */
2033 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2034 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2036 /* Wait until the USB cable is extracted again */
2037 usb_wait_for_disconnect(&mpeg_queue);
2039 break;
2042 #endif /* CONFIG_CODEC == MAS3587F */
2045 #endif /* !SIMULATOR */
2047 struct mp3entry* audio_current_track()
2049 #ifdef SIMULATOR
2050 return &taginfo;
2051 #else /* !SIMULATOR */
2052 if(num_tracks_in_memory())
2053 return &get_trackdata(0)->id3;
2054 else
2055 return NULL;
2056 #endif /* !SIMULATOR */
2059 struct mp3entry* audio_next_track()
2061 #ifdef SIMULATOR
2062 return &taginfo;
2063 #else /* !SIMULATOR */
2064 if(num_tracks_in_memory() > 1)
2065 return &get_trackdata(1)->id3;
2066 else
2067 return NULL;
2068 #endif /* !SIMULATOR */
2071 #if CONFIG_CODEC == MAS3587F
2072 #ifndef SIMULATOR
2073 void audio_init_playback(void)
2075 init_playback_done = false;
2076 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2078 while(!init_playback_done)
2079 sleep(1);
2083 /****************************************************************************
2084 * Recording functions
2085 ***************************************************************************/
2086 void audio_init_recording(unsigned int buffer_offset)
2088 buffer_offset = buffer_offset;
2089 init_recording_done = false;
2090 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2092 while(!init_recording_done)
2093 sleep(1);
2096 static void init_recording(void)
2098 unsigned long val;
2099 int rc;
2101 /* Disable IRQ6 */
2102 IPRB &= 0xff0f;
2104 stop_playing();
2105 is_playing = false;
2106 paused = false;
2108 /* Init the recording variables */
2109 is_recording = false;
2110 is_prerecording = false;
2112 mpeg_stop_done = true;
2114 mas_reset();
2116 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2117 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2118 if(rc < 0)
2119 panicf("mas_ctrl_w: %d", rc);
2121 /* Stop the current application */
2122 val = 0;
2123 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2126 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2127 } while(val);
2129 /* Perform black magic as described by the data sheet */
2130 if((mas_version_code & 0x0fff) == 0x0102)
2132 DEBUGF("Performing MAS black magic for B2 version\n");
2133 mas_writereg(0xa3, 0x98);
2134 mas_writereg(0x94, 0xfffff);
2135 val = 0;
2136 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2137 mas_writereg(0xa3, 0x90);
2140 /* Enable A/D Converters */
2141 shadow_codec_reg0 = 0xcccd;
2142 mas_codec_writereg(0x0, shadow_codec_reg0);
2144 /* Copy left channel to right (mono mode) */
2145 mas_codec_writereg(8, 0x8000);
2147 /* ADC scale 0%, DSP scale 100%
2148 We use the DSP output for monitoring, because it works with all
2149 sources including S/PDIF */
2150 mas_codec_writereg(6, 0x0000);
2151 mas_codec_writereg(7, 0x4000);
2153 /* No mute */
2154 shadow_soft_mute = 0;
2155 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2157 #ifdef HAVE_SPDIF_OUT
2158 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2159 #else
2160 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2161 #endif
2162 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2164 /* Set Demand mode, monitoring OFF and validate all settings */
2165 shadow_io_control_main = 0x125;
2166 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2168 /* Start the encoder application */
2169 val = 0x40;
2170 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2173 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2174 } while(!(val & 0x40));
2176 /* We have started the recording application with monitoring OFF.
2177 This is because we want to record at least one frame to fill the DMA
2178 buffer, because the silly MAS will not negate EOD until at least one
2179 DMA transfer has taken place.
2180 Now let's wait for some data to be encoded. */
2181 sleep(HZ/5);
2183 /* Now set it to Monitoring mode as default, saves power */
2184 shadow_io_control_main = 0x525;
2185 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2187 /* Wait until the DSP has accepted the settings */
2190 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2191 } while(val & 1);
2193 drain_dma_buffer();
2194 mpeg_mode = MPEG_ENCODER;
2196 DEBUGF("MAS Recording application started\n");
2198 /* At this point, all settings are the reset MAS defaults, next thing is to
2199 call mpeg_set_recording_options(). */
2202 void audio_record(const char *filename)
2204 mpeg_errno = 0;
2206 strncpy(recording_filename, filename, MAX_PATH - 1);
2207 recording_filename[MAX_PATH - 1] = 0;
2209 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2212 void audio_pause_recording(void)
2214 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2217 void audio_resume_recording(void)
2219 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2222 static void prepend_header(void)
2224 int startpos;
2225 unsigned i;
2227 /* Make room for header */
2228 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2229 if(audiobuf_read < 0)
2231 /* Clear the bottom half */
2232 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2234 /* And the top half */
2235 audiobuf_read += audiobuflen;
2236 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2238 else
2240 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2242 /* Copy the empty ID3 header */
2243 startpos = audiobuf_read;
2244 for(i = 0; i < sizeof(empty_id3_header); i++)
2246 audiobuf[startpos++] = empty_id3_header[i];
2247 if(startpos == audiobuflen)
2248 startpos = 0;
2252 static void update_header(void)
2254 int fd, framelen;
2255 unsigned long frames;
2257 if (last_rec_bytes > 0)
2259 /* Create the Xing header */
2260 fd = open(delayed_filename, O_RDWR);
2261 if (fd < 0)
2262 panicf("rec upd: %d (%s)", fd, recording_filename);
2264 frames = frame_count_end - frame_count_start;
2265 /* If the number of recorded frames has reached 0x7ffff,
2266 we can no longer trust it */
2267 if (frame_count_end == 0x7ffff)
2268 frames = 0;
2270 /* saved_header is saved right before stopping the MAS */
2271 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2272 frames, last_rec_time * (1000/HZ),
2273 saved_header, NULL, false);
2275 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2276 write(fd, xing_buffer, framelen);
2277 close(fd);
2281 static void start_prerecording(void)
2283 unsigned long val;
2285 DEBUGF("Starting prerecording\n");
2287 prerecord_index = 0;
2288 prerecord_count = 0;
2289 prerecord_timeout = current_tick + HZ;
2290 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2291 reset_mp3_buffer();
2293 is_prerecording = true;
2295 /* Stop monitoring and start the encoder */
2296 shadow_io_control_main &= ~(1 << 10);
2297 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2298 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2300 /* Wait until the DSP has accepted the settings */
2303 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2304 } while(val & 1);
2306 is_recording = true;
2307 saving_status = NOT_SAVING;
2309 demand_irq_enable(true);
2312 static void start_recording(void)
2314 unsigned long val;
2316 if(is_prerecording)
2318 /* This will make the IRQ handler start recording
2319 for real, i.e send MPEG_SAVE_DATA messages when
2320 the buffer is full */
2321 is_prerecording = false;
2323 else
2325 /* If prerecording is off, we need to stop the monitoring
2326 and start the encoder */
2327 shadow_io_control_main &= ~(1 << 10);
2328 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2329 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2331 /* Wait until the DSP has accepted the settings */
2334 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2335 } while(val & 1);
2338 is_recording = true;
2339 saving_status = NOT_SAVING;
2340 paused = false;
2342 /* Store the current time */
2343 if(prerecording)
2344 record_start_time = current_tick - prerecord_count * HZ;
2345 else
2346 record_start_time = current_tick;
2348 pause_start_time = 0;
2350 demand_irq_enable(true);
2353 static void pause_recording(void)
2355 pause_start_time = current_tick;
2357 /* Set the pause bit */
2358 shadow_soft_mute |= 2;
2359 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2361 paused = true;
2364 static void resume_recording(void)
2366 paused = false;
2368 /* Clear the pause bit */
2369 shadow_soft_mute &= ~2;
2370 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2372 /* Compensate for the time we have been paused */
2373 if(pause_start_time)
2375 record_start_time =
2376 current_tick - (pause_start_time - record_start_time);
2377 pause_start_time = 0;
2381 static void stop_recording(void)
2383 unsigned long val;
2385 /* Let it finish the last frame */
2386 if(!paused)
2387 pause_recording();
2388 sleep(HZ/5);
2390 demand_irq_enable(false);
2392 is_recording = false;
2393 is_prerecording = false;
2395 last_rec_bytes = num_rec_bytes;
2396 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2397 last_rec_time = current_tick - record_start_time;
2399 /* Start monitoring */
2400 shadow_io_control_main |= (1 << 10);
2401 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2402 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2404 /* Wait until the DSP has accepted the settings */
2407 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2408 } while(val & 1);
2410 resume_recording();
2413 void audio_set_recording_options(struct audio_recording_options *options)
2415 bool is_mpeg1;
2417 is_mpeg1 = (options->rec_frequency < 3);
2419 rec_version_index = is_mpeg1?3:2;
2420 rec_frequency_index = options->rec_frequency % 3;
2422 shadow_encoder_control = (options->rec_quality << 17) |
2423 (rec_frequency_index << 10) |
2424 ((is_mpeg1?1:0) << 9) |
2425 (((options->rec_channels * 2 + 1) & 3) << 6) |
2426 (1 << 5) /* MS-stereo */ |
2427 (1 << 2) /* Is an original */;
2428 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2430 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2432 #if CONFIG_TUNER & S1A0903X01
2433 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2434 interference with the Samsung tuner. */
2435 if (rec_frequency_index)
2436 mas_store_pllfreq(24576000);
2437 else
2438 mas_store_pllfreq(22579000);
2439 #endif
2441 shadow_soft_mute = options->rec_editable?4:0;
2442 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2444 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2446 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2447 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2448 (1 << 5) | /* SDO strobe invert */
2449 ((is_mpeg1?0:1) << 3) |
2450 (1 << 2) | /* Inverted SIBC clock signal */
2451 1; /* Validate */
2452 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2454 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2456 if(options->rec_source == AUDIO_SRC_MIC)
2458 /* Copy left channel to right (mono mode) */
2459 mas_codec_writereg(8, 0x8000);
2461 else
2463 /* Stereo input mode */
2464 mas_codec_writereg(8, 0);
2467 prerecording_max_seconds = options->rec_prerecord_time;
2468 if(prerecording_max_seconds)
2470 prerecording = true;
2471 start_prerecording();
2473 else
2475 prerecording = false;
2476 is_prerecording = false;
2477 is_recording = false;
2481 /* If use_mic is true, the left gain is used */
2482 void audio_set_recording_gain(int left, int right, int type)
2484 /* Enable both left and right A/D */
2485 shadow_codec_reg0 = (left << 12) |
2486 (right << 8) |
2487 (left << 4) |
2488 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2489 0x0007;
2490 mas_codec_writereg(0x0, shadow_codec_reg0);
2493 /* try to make some kind of beep, also in recording mode */
2494 void audio_beep(int duration)
2496 long starttick = current_tick;
2498 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2499 * While this is still audible even without an external signal,
2500 * it doesn't affect the (pre-)recording. */
2501 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2502 mas_codec_writereg(0, shadow_codec_reg0);
2503 yield();
2505 while (current_tick - starttick < duration);
2508 void audio_new_file(const char *filename)
2510 mpeg_errno = 0;
2512 strncpy(recording_filename, filename, MAX_PATH - 1);
2513 recording_filename[MAX_PATH - 1] = 0;
2515 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2518 unsigned long audio_recorded_time(void)
2520 if(is_prerecording)
2521 return prerecord_count * HZ;
2523 if(is_recording)
2525 if(paused)
2526 return pause_start_time - record_start_time;
2527 else
2528 return current_tick - record_start_time;
2531 return 0;
2534 unsigned long audio_num_recorded_bytes(void)
2536 int num_bytes;
2537 int index;
2539 if(is_recording)
2541 if(is_prerecording)
2543 index = prerecord_index - prerecord_count;
2544 if(index < 0)
2545 index += prerecording_max_seconds;
2547 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2548 if(num_bytes < 0)
2549 num_bytes += audiobuflen;
2551 return num_bytes;
2553 else
2554 return num_rec_bytes;
2556 else
2557 return 0;
2560 #else /* SIMULATOR */
2562 /* dummies coming up */
2564 void audio_init_playback(void)
2566 /* a dummy */
2568 unsigned long audio_recorded_time(void)
2570 /* a dummy */
2571 return 0;
2573 void audio_beep(int duration)
2575 /* a dummy */
2576 (void)duration;
2578 void audio_pause_recording(void)
2580 /* a dummy */
2582 void audio_resume_recording(void)
2584 /* a dummy */
2586 unsigned long audio_num_recorded_bytes(void)
2588 /* a dummy */
2589 return 0;
2591 void audio_record(const char *filename)
2593 /* a dummy */
2594 (void)filename;
2596 void audio_new_file(const char *filename)
2598 /* a dummy */
2599 (void)filename;
2602 void audio_set_recording_gain(int left, int right, int type)
2604 /* a dummy */
2605 (void)left;
2606 (void)right;
2607 (void)type;
2609 void audio_init_recording(unsigned int buffer_offset)
2611 /* a dummy */
2612 (void)buffer_offset;
2614 void audio_set_recording_options(struct audio_recording_options *options)
2616 /* a dummy */
2617 (void)options;
2619 #endif /* SIMULATOR */
2620 #endif /* CONFIG_CODEC == MAS3587F */
2622 void audio_play(long offset)
2624 #ifdef SIMULATOR
2625 char* trackname;
2626 int steps=0;
2628 is_playing = true;
2630 do {
2631 trackname = playlist_peek( steps );
2632 if (!trackname)
2633 break;
2634 if(mp3info(&taginfo, trackname)) {
2635 /* bad mp3, move on */
2636 if(++steps > playlist_amount())
2637 break;
2638 continue;
2640 #ifdef HAVE_MPEG_PLAY
2641 real_mpeg_play(trackname);
2642 #endif
2643 playlist_next(steps);
2644 taginfo.offset = offset;
2645 set_elapsed(&taginfo);
2646 is_playing = true;
2647 playing = true;
2648 break;
2649 } while(1);
2650 #else /* !SIMULATOR */
2651 is_playing = true;
2653 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2654 #endif /* !SIMULATOR */
2656 mpeg_errno = 0;
2659 void audio_stop(void)
2661 #ifndef SIMULATOR
2662 if (playing)
2664 struct trackdata *track = get_trackdata(0);
2665 prev_track_elapsed = track->id3.elapsed;
2667 mpeg_stop_done = false;
2668 queue_post(&mpeg_queue, MPEG_STOP, 0);
2669 while(!mpeg_stop_done)
2670 yield();
2671 #else /* SIMULATOR */
2672 paused = false;
2673 is_playing = false;
2674 playing = false;
2675 #endif /* SIMULATOR */
2678 /* dummy */
2679 void audio_stop_recording(void)
2681 audio_stop();
2684 void audio_pause(void)
2686 #ifndef SIMULATOR
2687 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2688 #else /* SIMULATOR */
2689 is_playing = true;
2690 playing = false;
2691 paused = true;
2692 #endif /* SIMULATOR */
2695 void audio_resume(void)
2697 #ifndef SIMULATOR
2698 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2699 #else /* SIMULATOR */
2700 is_playing = true;
2701 playing = true;
2702 paused = false;
2703 #endif /* SIMULATOR */
2706 void audio_next(void)
2708 #ifndef SIMULATOR
2709 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2710 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2711 #else /* SIMULATOR */
2712 char* file;
2713 int steps = 1;
2714 int index;
2716 do {
2717 file = playlist_peek(steps);
2718 if(!file)
2719 break;
2720 if(mp3info(&taginfo, file)) {
2721 if(++steps > playlist_amount())
2722 break;
2723 continue;
2725 index = playlist_next(steps);
2726 taginfo.index = index;
2727 current_track_counter++;
2728 is_playing = true;
2729 playing = true;
2730 break;
2731 } while(1);
2732 #endif /* SIMULATOR */
2735 void audio_prev(void)
2737 #ifndef SIMULATOR
2738 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2739 queue_post(&mpeg_queue, MPEG_PREV, 0);
2740 #else /* SIMULATOR */
2741 char* file;
2742 int steps = -1;
2743 int index;
2745 do {
2746 file = playlist_peek(steps);
2747 if(!file)
2748 break;
2749 if(mp3info(&taginfo, file)) {
2750 steps--;
2751 continue;
2753 index = playlist_next(steps);
2754 taginfo.index = index;
2755 current_track_counter++;
2756 is_playing = true;
2757 playing = true;
2758 break;
2759 } while(1);
2760 #endif /* SIMULATOR */
2763 void audio_ff_rewind(long newtime)
2765 #ifndef SIMULATOR
2766 queue_post(&mpeg_queue, MPEG_FF_REWIND, newtime);
2767 #else /* SIMULATOR */
2768 (void)newtime;
2769 #endif /* SIMULATOR */
2772 void audio_flush_and_reload_tracks(void)
2774 #ifndef SIMULATOR
2775 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2776 #endif /* !SIMULATOR*/
2779 int audio_status(void)
2781 int ret = 0;
2783 if(is_playing)
2784 ret |= AUDIO_STATUS_PLAY;
2786 if(paused)
2787 ret |= AUDIO_STATUS_PAUSE;
2789 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2790 if(is_recording && !is_prerecording)
2791 ret |= AUDIO_STATUS_RECORD;
2793 if(is_prerecording)
2794 ret |= AUDIO_STATUS_PRERECORD;
2795 #endif /* CONFIG_CODEC == MAS3587F */
2797 if(mpeg_errno)
2798 ret |= AUDIO_STATUS_ERROR;
2800 return ret;
2803 unsigned int audio_error(void)
2805 return mpeg_errno;
2808 void audio_error_clear(void)
2810 mpeg_errno = 0;
2813 #ifdef SIMULATOR
2814 static void mpeg_thread(void)
2816 struct mp3entry* id3;
2817 while ( 1 ) {
2818 if (is_playing) {
2819 id3 = audio_current_track();
2820 if (!paused)
2822 id3->elapsed+=1000;
2823 id3->offset+=1000;
2825 if (id3->elapsed>=id3->length)
2826 audio_next();
2828 sleep(HZ);
2831 #endif /* SIMULATOR */
2833 void audio_init(void)
2835 mpeg_errno = 0;
2837 #ifndef SIMULATOR
2838 audiobuflen = audiobufend - audiobuf;
2839 queue_init(&mpeg_queue, true);
2840 #endif /* !SIMULATOR */
2841 create_thread(mpeg_thread, mpeg_stack,
2842 sizeof(mpeg_stack), 0, mpeg_thread_name
2843 IF_PRIO(, PRIORITY_SYSTEM)
2844 IF_COP(, CPU));
2846 memset(trackdata, 0, sizeof(trackdata));
2848 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2849 if (HW_MASK & PR_ACTIVE_HIGH)
2850 and_b(~0x08, &PADRH);
2851 else
2852 or_b(0x08, &PADRH);
2853 #endif /* CONFIG_CODEC == MAS3587F */
2855 #ifdef DEBUG
2856 #ifndef SIMULATOR
2857 dbg_timer_start();
2858 dbg_cnt2us(0);
2859 #endif /* !SIMULATOR */
2860 #endif /* DEBUG */
2863 #endif /* CONFIG_CODEC != SWCODEC */