fuze+: scramble bootloader file
[maemo-rb.git] / apps / mpeg.c
blobae33ccc1bfbf9c43ed9258214bb960bc73ca2b0d
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 "core_alloc.h"
39 #include "mp3_playback.h"
40 #include "talk.h"
41 #include "sound.h"
42 #include "system.h"
43 #include "appevents.h"
44 #include "playlist.h"
45 #include "cuesheet.h"
46 #include "settings.h"
47 #ifndef SIMULATOR
48 #include "i2c.h"
49 #include "mas35xx.h"
50 #include "system.h"
51 #include "usb.h"
52 #include "file.h"
53 #include "hwcompat.h"
54 #endif /* !SIMULATOR */
55 #ifdef HAVE_LCD_BITMAP
56 #include "lcd.h"
57 #endif /* CONFIG_CODEC != SWCODEC */
59 #define MPEG_SWAP_CHUNKSIZE 0x2000
60 #define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
61 wouldn't be able to see the difference between
62 an empty buffer and a full one. */
63 #define MPEG_LOW_WATER 0x60000
64 #define MPEG_RECORDING_LOW_WATER 0x80000
65 #define MPEG_LOW_WATER_CHUNKSIZE 0x40000
66 #define MPEG_LOW_WATER_SWAP_CHUNKSIZE 0x10000
67 #if (CONFIG_STORAGE & STORAGE_MMC)
68 #define MPEG_PLAY_PENDING_THRESHOLD 0x20000
69 #define MPEG_PLAY_PENDING_SWAPSIZE 0x20000
70 #else
71 #define MPEG_PLAY_PENDING_THRESHOLD 0x10000
72 #define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
73 #endif
75 #define MPEG_MAX_PRERECORD_SECONDS 30
77 /* For ID3 info and VBR header */
78 #define MPEG_RESERVED_HEADER_SPACE (4096 + 576)
80 #ifndef SIMULATOR
81 extern unsigned long mas_version_code;
82 #endif
84 #if CONFIG_CODEC == MAS3587F
85 extern enum /* from mp3_playback.c */
87 MPEG_DECODER,
88 MPEG_ENCODER
89 } mpeg_mode;
90 #endif /* CONFIG_CODEC == MAS3587F */
92 #define MPEG_PLAY 1
93 #define MPEG_STOP 2
94 #define MPEG_PAUSE 3
95 #define MPEG_RESUME 4
96 #define MPEG_NEXT 5
97 #define MPEG_PREV 6
98 #define MPEG_FF_REWIND 7
99 #define MPEG_FLUSH_RELOAD 8
100 #define MPEG_RECORD 9
101 #define MPEG_INIT_RECORDING 10
102 #define MPEG_INIT_PLAYBACK 11
103 #define MPEG_NEW_FILE 12
104 #define MPEG_PAUSE_RECORDING 13
105 #define MPEG_RESUME_RECORDING 14
106 #define MPEG_NEED_DATA 100
107 #define MPEG_TRACK_CHANGE 101
108 #define MPEG_SAVE_DATA 102
109 #define MPEG_STOP_DONE 103
110 #define MPEG_PRERECORDING_TICK 104
112 /* indicator for MPEG_NEED_DATA */
113 #define GENERATE_UNBUFFER_EVENTS 1
115 /* list of tracks in memory */
116 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
117 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
119 struct trackdata
121 struct mp3entry id3;
122 int mempos;
123 int load_ahead_index;
126 static struct trackdata trackdata[MAX_TRACK_ENTRIES];
128 static unsigned int current_track_counter = 0;
130 #ifndef SIMULATOR
131 static void stop_playing(void);
132 /* Play time of the previous track */
133 static unsigned long prev_track_elapsed;
135 static int track_read_idx = 0;
136 static int track_write_idx = 0;
137 #endif /* !SIMULATOR */
139 /* Cuesheet support */
140 static struct cuesheet *curr_cuesheet = NULL;
141 static bool checked_for_cuesheet = false;
143 static const char mpeg_thread_name[] = "mpeg";
144 static unsigned int audio_thread_id;
145 static bool audio_is_initialized;
146 static unsigned int mpeg_errno;
148 static bool playing = false; /* We are playing an MP3 stream */
149 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
150 static bool paused; /* playback is paused */
151 static int audiobuf_handle; /* handle to the audio buffer */
152 static char* mpeg_audiobuf; /* poiunter to the audio buffer */
153 static long audiobuflen; /* length of the audio buffer */
155 #ifdef SIMULATOR
156 static char mpeg_stack[DEFAULT_STACK_SIZE];
157 static struct mp3entry taginfo;
158 #else /* !SIMULATOR */
159 static struct event_queue mpeg_queue SHAREDBSS_ATTR;
160 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
162 static int audiobuf_write;
163 static int audiobuf_swapwrite;
164 static long audiobuf_read;
166 static int mpeg_file;
168 static bool play_pending; /* We are about to start playing */
169 static bool play_pending_track_change; /* When starting play we're starting a new file */
170 static bool filling; /* We are filling the buffer with data from disk */
171 static bool dma_underrun; /* True when the DMA has stopped because of
172 slow disk reading (read error, shaking) */
173 static bool mpeg_stop_done;
175 static int last_dma_tick = 0;
176 static int last_dma_chunk_size;
178 static long low_watermark; /* Dynamic low watermark level */
179 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
180 static long lowest_watermark_level; /* Debug value to observe the buffer
181 usage */
182 #if CONFIG_CODEC == MAS3587F
183 static char recording_filename[MAX_PATH]; /* argument to thread */
184 static char delayed_filename[MAX_PATH]; /* internal copy of above */
186 static char xing_buffer[MAX_XING_HEADER_SIZE];
188 static bool init_recording_done;
189 static bool init_playback_done;
190 static bool prerecording; /* True if prerecording is enabled */
191 static bool is_prerecording; /* True if we are prerecording */
192 static bool is_recording; /* We are recording */
194 static enum {
195 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
196 BUFFER_FULL,
197 NEW_FILE,
198 STOP_RECORDING
199 } saving_status;
201 static int rec_frequency_index; /* For create_xing_header() calls */
202 static int rec_version_index; /* For create_xing_header() calls */
204 struct prerecord_info {
205 int mempos;
206 unsigned long framecount;
209 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
210 static int prerecord_index; /* Current index in the prerecord buffer */
211 static int prerecording_max_seconds; /* Max number of seconds to store */
212 static int prerecord_count; /* Number of seconds in the prerecord buffer */
213 static int prerecord_timeout; /* The tick count of the next prerecord data
214 store */
216 static unsigned long record_start_time; /* Value of current_tick when recording
217 was started */
218 static unsigned long pause_start_time; /* Value of current_tick when pause was
219 started */
220 static unsigned long last_rec_time;
221 static unsigned long num_rec_bytes;
222 static unsigned long last_rec_bytes;
223 static unsigned long frame_count_start;
224 static unsigned long frame_count_end;
225 static unsigned long saved_header = 0;
227 /* Shadow MAS registers */
228 unsigned long shadow_encoder_control = 0;
229 #endif /* CONFIG_CODEC == MAS3587F */
231 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
232 unsigned long shadow_io_control_main = 0;
233 unsigned long shadow_soft_mute = 0;
234 unsigned shadow_codec_reg0;
235 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
237 #ifdef HAVE_RECORDING
238 static const unsigned char empty_id3_header[] =
240 'I', 'D', '3', 0x03, 0x00, 0x00,
241 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
243 #endif /* HAVE_RECORDING */
246 static int get_unplayed_space(void);
247 static int get_playable_space(void);
248 static int get_unswapped_space(void);
249 #endif /* !SIMULATOR */
251 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
252 static void init_recording(void);
253 static void prepend_header(void);
254 static void update_header(void);
255 static void start_prerecording(void);
256 static void start_recording(void);
257 static void stop_recording(void);
258 static int get_unsaved_space(void);
259 static void pause_recording(void);
260 static void resume_recording(void);
261 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
264 #ifndef SIMULATOR
265 static int num_tracks_in_memory(void)
267 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
270 #ifdef DEBUG_TAGS
271 static void debug_tags(void)
273 int i;
275 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
277 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
279 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
280 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
282 #else /* !DEBUG_TAGS */
283 #define debug_tags()
284 #endif /* !DEBUG_TAGS */
286 static void remove_current_tag(void)
288 if(num_tracks_in_memory() > 0)
290 /* First move the index, so nobody tries to access the tag */
291 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
292 checked_for_cuesheet = false;
293 debug_tags();
295 else
297 DEBUGF("remove_current_tag: no tracks to remove\n");
301 static void remove_all_non_current_tags(void)
303 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
304 debug_tags();
307 static void remove_all_tags(void)
309 track_write_idx = track_read_idx;
311 debug_tags();
314 static struct trackdata *get_trackdata(int offset)
316 if(offset >= num_tracks_in_memory())
317 return NULL;
318 else
319 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
321 #endif /* !SIMULATOR */
323 /***********************************************************************/
324 /* audio event handling */
326 #define MAX_EVENT_HANDLERS 10
327 struct event_handlers_table
329 AUDIO_EVENT_HANDLER handler;
330 unsigned short mask;
332 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
333 static int event_handlers_count = 0;
335 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
337 if (event_handlers_count < MAX_EVENT_HANDLERS)
339 event_handlers[event_handlers_count].handler = handler;
340 event_handlers[event_handlers_count].mask = mask;
341 event_handlers_count++;
345 /* dispatch calls each handler in the order registered and returns after some
346 handler actually handles the event (the event is assumed to no longer be valid
347 after this, due to the handler changing some condition); returns true if someone
348 handled the event, which is expected to cause the caller to skip its own handling
349 of the event */
350 #ifndef SIMULATOR
351 static bool audio_dispatch_event(unsigned short event, unsigned long data)
353 int i = 0;
354 for(i=0; i < event_handlers_count; i++)
356 if ( event_handlers[i].mask & event )
358 int rc = event_handlers[i].handler(event, data);
359 if ( rc == AUDIO_EVENT_RC_HANDLED )
360 return true;
363 return false;
365 #endif
367 /***********************************************************************/
369 static void set_elapsed(struct mp3entry* id3)
371 if ( id3->vbr ) {
372 if ( id3->has_toc ) {
373 /* calculate elapsed time using TOC */
374 int i;
375 unsigned int remainder, plen, relpos, nextpos;
377 /* find wich percent we're at */
378 for (i=0; i<100; i++ )
380 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
382 break;
386 i--;
387 if (i < 0)
388 i = 0;
390 relpos = id3->toc[i];
392 if (i < 99)
394 nextpos = id3->toc[i+1];
396 else
398 nextpos = 256;
401 remainder = id3->offset - (relpos * (id3->filesize / 256));
403 /* set time for this percent (divide before multiply to prevent
404 overflow on long files. loss of precision is negligible on
405 short files) */
406 id3->elapsed = i * (id3->length / 100);
408 /* calculate remainder time */
409 plen = (nextpos - relpos) * (id3->filesize / 256);
410 id3->elapsed += (((remainder * 100) / plen) *
411 (id3->length / 10000));
413 else {
414 /* no TOC exists. set a rough estimate using average bitrate */
415 int tpk = id3->length / (id3->filesize / 1024);
416 id3->elapsed = id3->offset / 1024 * tpk;
419 else
420 /* constant bitrate, use exact calculation */
421 id3->elapsed = id3->offset / (id3->bitrate / 8);
424 int audio_get_file_pos(void)
426 int pos = -1;
427 struct mp3entry *id3 = audio_current_track();
429 if (id3->vbr)
431 if (id3->has_toc)
433 /* Use the TOC to find the new position */
434 unsigned int percent, remainder;
435 int curtoc, nexttoc, plen;
437 percent = (id3->elapsed*100)/id3->length;
438 if (percent > 99)
439 percent = 99;
441 curtoc = id3->toc[percent];
443 if (percent < 99)
444 nexttoc = id3->toc[percent+1];
445 else
446 nexttoc = 256;
448 pos = (id3->filesize/256)*curtoc;
450 /* Use the remainder to get a more accurate position */
451 remainder = (id3->elapsed*100)%id3->length;
452 remainder = (remainder*100)/id3->length;
453 plen = (nexttoc - curtoc)*(id3->filesize/256);
454 pos += (plen/100)*remainder;
456 else
458 /* No TOC exists, estimate the new position */
459 pos = (id3->filesize / (id3->length / 1000)) *
460 (id3->elapsed / 1000);
463 else if (id3->bitrate)
464 pos = id3->elapsed * (id3->bitrate / 8);
465 else
467 return -1;
470 if (pos >= (int)(id3->filesize - id3->id3v1len))
472 /* Don't seek right to the end of the file so that we can
473 transition properly to the next song */
474 pos = id3->filesize - id3->id3v1len - 1;
476 else if (pos < (int)id3->first_frame_offset)
478 /* skip past id3v2 tag and other leading garbage */
479 pos = id3->first_frame_offset;
481 return pos;
484 unsigned long mpeg_get_last_header(void)
486 #ifdef SIMULATOR
487 return 0;
488 #else /* !SIMULATOR */
489 unsigned long tmp[2];
491 /* Read the frame data from the MAS and reconstruct it with the
492 frame sync and all */
493 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
494 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
495 #endif /* !SIMULATOR */
498 static void do_stop(void)
500 is_playing = false;
501 paused = false;
503 #ifndef SIMULATOR
504 if (playing)
505 playlist_update_resume_info(audio_current_track());
507 stop_playing();
508 mpeg_stop_done = true;
509 #else
510 playing = false;
511 #endif
514 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize);
515 /* Buffer must not move. */
516 static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
518 long offset = audio_current_track()->offset;
519 bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY;
520 /* TODO: Do it without stopping playback, if possible */
521 /* don't call audio_hard_stop() as it frees this handle */
522 if (thread_self() == audio_thread_id)
523 { /* inline case MPEG_STOP (audio_stop()) response
524 * if we're in the audio thread since audio_stop() otherwise deadlocks */
525 do_stop();
527 else
528 audio_stop();
529 talk_buffer_steal(); /* we obtain control over the buffer */
531 /* we should be free to change the buffer now */
532 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
533 ssize_t size = (ssize_t)old_size - wanted_size;
534 switch (hints & BUFLIB_SHRINK_POS_MASK)
536 case BUFLIB_SHRINK_POS_BACK:
537 core_shrink(handle, start, size);
538 audio_reset_buffer_noalloc(start, size);
539 break;
540 case BUFLIB_SHRINK_POS_FRONT:
541 core_shrink(handle, start + wanted_size, size);
542 audio_reset_buffer_noalloc(start + wanted_size, size);
543 break;
545 if (playing)
546 { /* safe to call even from the audio thread (due to queue_post()) */
547 audio_play(offset);
550 return BUFLIB_CB_OK;
553 static struct buflib_callbacks ops = {
554 .move_callback = NULL,
555 .shrink_callback = shrink_callback,
558 static size_t audio_talkbuf_init(char *bufstart)
560 size_t ret = talkbuf_init(bufstart);
561 if (ret > (size_t)audiobuflen) /* does the voice even fit? */
563 talk_buffer_steal();
564 return 0;
566 return ret;
569 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
571 (void)talk_buf; /* always grab the voice buffer for now */
573 if (audio_is_initialized)
574 audio_hard_stop();
576 if (!buffer_size) /* special case for talk_init() */
577 return NULL;
579 if (!audiobuf_handle)
581 size_t bufsize;
582 /* audio_hard_stop() frees audiobuf, so re-aquire */
583 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
584 audiobuflen = bufsize;
585 if (buffer_size)
586 *buffer_size = audiobuflen;
588 mpeg_audiobuf = core_get_data(audiobuf_handle);
589 /* tell talk about the new buffer, don't re-enable just yet because the
590 * buffer is stolen */
591 audio_talkbuf_init(mpeg_audiobuf);
593 return mpeg_audiobuf;
597 #ifndef SIMULATOR
598 /* Send callback events to notify about removing old tracks. */
599 static void generate_unbuffer_events(void)
601 int i;
602 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
603 int cur_idx = track_write_idx;
605 for (i = 0; i < numentries; i++)
607 /* Send an event to notify that track has finished. */
608 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
609 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
613 /* Send callback events to notify about new tracks. */
614 static void generate_postbuffer_events(void)
616 int i;
617 int numentries = num_tracks_in_memory();
618 int cur_idx = track_read_idx;
620 for (i = 0; i < numentries; i++)
622 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
623 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
627 static void recalculate_watermark(int bitrate)
629 int bytes_per_sec;
630 int time = storage_spinup_time();
632 /* A bitrate of 0 probably means empty VBR header. We play safe
633 and set a high threshold */
634 if(bitrate == 0)
635 bitrate = 320;
637 bytes_per_sec = bitrate * 1000 / 8;
639 if(time)
641 /* No drive spins up faster than 3.5s */
642 if(time < 350)
643 time = 350;
645 time = time * 3;
646 low_watermark = ((low_watermark_margin * HZ + time) *
647 bytes_per_sec) / HZ;
649 else
651 low_watermark = MPEG_LOW_WATER;
655 #ifdef HAVE_DISK_STORAGE
656 void audio_set_buffer_margin(int setting)
658 low_watermark_margin = setting; /* in seconds */
660 #endif
662 void audio_get_debugdata(struct audio_debug *dbgdata)
664 dbgdata->audiobuflen = audiobuflen;
665 dbgdata->audiobuf_write = audiobuf_write;
666 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
667 dbgdata->audiobuf_read = audiobuf_read;
669 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
671 #if CONFIG_CPU == SH7034
672 dbgdata->dma_on = (SCR0 & 0x80) != 0;
673 #endif
674 dbgdata->playing = playing;
675 dbgdata->play_pending = play_pending;
676 dbgdata->is_playing = is_playing;
677 dbgdata->filling = filling;
678 dbgdata->dma_underrun = dma_underrun;
680 dbgdata->unplayed_space = get_unplayed_space();
681 dbgdata->playable_space = get_playable_space();
682 dbgdata->unswapped_space = get_unswapped_space();
684 dbgdata->low_watermark_level = low_watermark;
685 dbgdata->lowest_watermark_level = lowest_watermark_level;
688 #ifdef DEBUG
689 static void dbg_timer_start(void)
691 /* We are using timer 2 */
693 TSTR &= ~0x04; /* Stop the timer */
694 TSNC &= ~0x04; /* No synchronization */
695 TMDR &= ~0x44; /* Operate normally */
697 TCNT2 = 0; /* Start counting at 0 */
698 TCR2 = 0x03; /* Sysclock/8 */
700 TSTR |= 0x04; /* Start timer 2 */
703 static int dbg_cnt2us(unsigned int cnt)
705 return (cnt * 10000) / (FREQ/800);
707 #endif /* DEBUG */
709 static int get_unplayed_space(void)
711 int space = audiobuf_write - audiobuf_read;
712 if (space < 0)
713 space += audiobuflen;
714 return space;
717 static int get_playable_space(void)
719 int space = audiobuf_swapwrite - audiobuf_read;
720 if (space < 0)
721 space += audiobuflen;
722 return space;
725 static int get_unplayed_space_current_song(void)
727 int space;
729 if (num_tracks_in_memory() > 1)
731 space = get_trackdata(1)->mempos - audiobuf_read;
733 else
735 space = audiobuf_write - audiobuf_read;
738 if (space < 0)
739 space += audiobuflen;
741 return space;
744 static int get_unswapped_space(void)
746 int space = audiobuf_write - audiobuf_swapwrite;
747 if (space < 0)
748 space += audiobuflen;
749 return space;
752 #if CONFIG_CODEC == MAS3587F
753 static int get_unsaved_space(void)
755 int space = audiobuf_write - audiobuf_read;
756 if (space < 0)
757 space += audiobuflen;
758 return space;
761 static void drain_dma_buffer(void)
763 while (PBDRH & 0x40)
765 xor_b(0x08, &PADRH);
767 while (PBDRH & 0x80);
769 xor_b(0x08, &PADRH);
771 while (!(PBDRH & 0x80));
775 #ifdef DEBUG
776 static long timing_info_index = 0;
777 static long timing_info[1024];
778 #endif /* DEBUG */
780 void rec_tick (void) __attribute__ ((section (".icode")));
781 void rec_tick(void)
783 int i;
784 int delay;
785 char data;
787 if(is_recording && (PBDRH & 0x40))
789 #ifdef DEBUG
790 timing_info[timing_info_index++] = current_tick;
791 TCNT2 = 0;
792 #endif /* DEBUG */
793 /* Note: Although this loop is run in interrupt context, further
794 * optimisation will do no good. The MAS would then deliver bad
795 * frames occasionally, as observed in extended experiments. */
796 i = 0;
797 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
799 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
801 delay = 100;
802 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
804 if (--delay <= 0) /* Bail out if we have to wait too long */
805 { /* i.e. the MAS doesn't want to talk to us */
806 xor_b(0x08, &PADRH); /* Set PR inactive */
807 goto transfer_end; /* and get out of here */
811 data = *(unsigned char *)0x04000000; /* read data byte */
813 xor_b(0x08, &PADRH); /* Set PR inactive */
815 mpeg_audiobuf[audiobuf_write++] = data;
817 if (audiobuf_write >= audiobuflen)
818 audiobuf_write = 0;
820 i++;
822 transfer_end:
824 #ifdef DEBUG
825 timing_info[timing_info_index++] = TCNT2 + (i << 16);
826 timing_info_index &= 0x3ff;
827 #endif /* DEBUG */
829 num_rec_bytes += i;
831 if(is_prerecording)
833 if(TIME_AFTER(current_tick, prerecord_timeout))
835 prerecord_timeout = current_tick + HZ;
836 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
839 else
841 /* Signal to save the data if we are running out of buffer
842 space */
843 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
844 && saving_status == NOT_SAVING)
846 saving_status = BUFFER_FULL;
847 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
852 #endif /* CONFIG_CODEC == MAS3587F */
854 void playback_tick(void)
856 struct trackdata *ptd = get_trackdata(0);
857 if(ptd)
859 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
860 last_dma_tick = current_tick;
861 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
862 (unsigned long)ptd->id3.elapsed);
866 static void reset_mp3_buffer(void)
868 audiobuf_read = 0;
869 audiobuf_write = 0;
870 audiobuf_swapwrite = 0;
871 lowest_watermark_level = audiobuflen;
874 /* DMA transfer end interrupt callback */
875 static void transfer_end(unsigned char** ppbuf, size_t* psize)
877 if(playing && !paused)
879 int unplayed_space_left;
880 int space_until_end_of_buffer;
881 int track_offset = 1;
882 struct trackdata *track;
884 audiobuf_read += last_dma_chunk_size;
885 if(audiobuf_read >= audiobuflen)
886 audiobuf_read = 0;
888 /* First, check if we are on a track boundary */
889 if (num_tracks_in_memory() > 1)
891 if (audiobuf_read == get_trackdata(track_offset)->mempos)
893 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
895 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
896 track_offset++;
901 unplayed_space_left = get_unplayed_space();
903 space_until_end_of_buffer = audiobuflen - audiobuf_read;
905 if(!filling && unplayed_space_left < low_watermark)
907 filling = true;
908 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
911 if(unplayed_space_left)
913 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
914 last_dma_chunk_size = MIN(last_dma_chunk_size,
915 space_until_end_of_buffer);
917 /* several tracks loaded? */
918 track = get_trackdata(track_offset);
919 if(track)
921 /* will we move across the track boundary? */
922 if (( audiobuf_read < track->mempos ) &&
923 ((audiobuf_read+last_dma_chunk_size) >
924 track->mempos ))
926 /* Make sure that we end exactly on the boundary */
927 last_dma_chunk_size = track->mempos - audiobuf_read;
931 *psize = last_dma_chunk_size & 0xffff;
932 *ppbuf = mpeg_audiobuf + audiobuf_read;
933 track = get_trackdata(0);
934 if(track)
935 track->id3.offset += last_dma_chunk_size;
937 /* Update the watermark debug level */
938 if(unplayed_space_left < lowest_watermark_level)
939 lowest_watermark_level = unplayed_space_left;
941 else
943 /* Check if the end of data is because of a hard disk error.
944 If there is an open file handle, we are still playing music.
945 If not, the last file has been loaded, and the file handle is
946 closed. */
947 if(mpeg_file >= 0)
949 /* Update the watermark debug level */
950 if(unplayed_space_left < lowest_watermark_level)
951 lowest_watermark_level = unplayed_space_left;
953 DEBUGF("DMA underrun.\n");
954 dma_underrun = true;
956 else
958 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
960 DEBUGF("No more MP3 data. Stopping.\n");
961 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
962 playing = false;
965 *psize = 0; /* no more transfer */
970 static struct trackdata *add_track_to_tag_list(const char *filename)
972 struct trackdata *track;
973 bool send_nid3_event;
975 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
977 DEBUGF("Tag memory is full\n");
978 return NULL;
981 track = &trackdata[track_write_idx];
983 /* grab id3 tag of new file and
984 remember where in memory it starts */
985 if(mp3info(&track->id3, filename))
987 DEBUGF("Bad mp3\n");
988 return NULL;
990 track->mempos = audiobuf_write;
991 track->id3.elapsed = 0;
992 #ifdef HAVE_LCD_BITMAP
993 if (track->id3.title)
994 lcd_getstringsize(track->id3.title, NULL, NULL);
995 if (track->id3.artist)
996 lcd_getstringsize(track->id3.artist, NULL, NULL);
997 if (track->id3.album)
998 lcd_getstringsize(track->id3.album, NULL, NULL);
999 #endif
1001 /* if this track is the next track then let the UI know it can get it */
1002 send_nid3_event = (track_write_idx == track_read_idx + 1);
1003 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
1004 if (send_nid3_event)
1005 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
1006 debug_tags();
1007 return track;
1010 static int new_file(int steps)
1012 int max_steps = playlist_amount();
1013 int start = 0;
1014 int i;
1015 struct trackdata *track;
1016 char name_buf[MAX_PATH+1];
1017 const char *trackname;
1019 /* Find out how many steps to advance. The load_ahead_index field tells
1020 us how many playlist entries it had to skip to get to a valid one.
1021 We add those together to find out where to start. */
1022 if(steps > 0 && num_tracks_in_memory() > 1)
1024 /* Begin with the song after the currently playing one */
1025 i = 1;
1026 while((track = get_trackdata(i++)))
1028 start += track->load_ahead_index;
1032 do {
1033 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
1034 if ( !trackname )
1035 return -1;
1037 DEBUGF("Loading %s\n", trackname);
1039 mpeg_file = open(trackname, O_RDONLY);
1040 if(mpeg_file < 0) {
1041 DEBUGF("Couldn't open file: %s\n",trackname);
1042 if(steps < 0)
1043 steps--;
1044 else
1045 steps++;
1047 else
1049 struct trackdata *track = add_track_to_tag_list(trackname);
1051 if(!track)
1053 /* Bad mp3 file */
1054 if(steps < 0)
1055 steps--;
1056 else
1057 steps++;
1058 close(mpeg_file);
1059 mpeg_file = -1;
1061 else
1063 /* skip past id3v2 tag */
1064 lseek(mpeg_file,
1065 track->id3.first_frame_offset,
1066 SEEK_SET);
1067 track->id3.index = steps;
1068 track->load_ahead_index = steps;
1069 track->id3.offset = 0;
1071 if(track->id3.vbr)
1072 /* Average bitrate * 1.5 */
1073 recalculate_watermark(
1074 (track->id3.bitrate * 3) / 2);
1075 else
1076 recalculate_watermark(
1077 track->id3.bitrate);
1082 /* Bail out if no file could be opened */
1083 if(abs(steps) > max_steps)
1084 return -1;
1085 } while ( mpeg_file < 0 );
1087 return 0;
1090 static void stop_playing(void)
1092 struct trackdata *track;
1094 /* Stop the current stream */
1095 mp3_play_stop();
1096 playing = false;
1097 filling = false;
1099 track = get_trackdata(0);
1100 if (track != NULL)
1101 prev_track_elapsed = track->id3.elapsed;
1103 if(mpeg_file >= 0)
1104 close(mpeg_file);
1105 mpeg_file = -1;
1106 remove_all_tags();
1107 generate_unbuffer_events();
1108 reset_mp3_buffer();
1111 static void end_current_track(void) {
1112 struct trackdata *track;
1114 play_pending = false;
1115 playing = false;
1116 mp3_play_pause(false);
1118 track = get_trackdata(0);
1119 if (track != NULL)
1120 prev_track_elapsed = track->id3.elapsed;
1122 reset_mp3_buffer();
1123 remove_all_tags();
1124 generate_unbuffer_events();
1126 if(mpeg_file >= 0)
1127 close(mpeg_file);
1130 /* Is this a really the end of playback or is a new playlist starting */
1131 static void check_playlist_end(int direction)
1133 /* Use the largest possible step size to account for skipped tracks */
1134 int steps = playlist_amount();
1136 if (direction < 0)
1137 steps = -steps;
1139 if (playlist_next(steps) < 0)
1140 is_playing = false;
1143 static void update_playlist(void)
1145 if (num_tracks_in_memory() > 0)
1147 struct trackdata *track = get_trackdata(0);
1148 track->id3.index = playlist_next(track->id3.index);
1150 else
1152 /* End of playlist? */
1153 check_playlist_end(1);
1156 playlist_update_resume_info(audio_current_track());
1159 static void track_change(void)
1161 DEBUGF("Track change\n");
1163 struct trackdata *track = get_trackdata(0);
1164 prev_track_elapsed = track->id3.elapsed;
1166 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1167 /* Reset the AVC */
1168 sound_set_avc(-1);
1169 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1171 if (num_tracks_in_memory() > 0)
1173 remove_current_tag();
1174 update_playlist();
1175 if (is_playing)
1176 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1179 current_track_counter++;
1182 unsigned long audio_prev_elapsed(void)
1184 return prev_track_elapsed;
1187 #ifdef DEBUG
1188 void hexdump(const unsigned char *buf, int len)
1190 int i;
1192 for(i = 0;i < len;i++)
1194 if(i && (i & 15) == 0)
1196 DEBUGF("\n");
1198 DEBUGF("%02x ", buf[i]);
1200 DEBUGF("\n");
1202 #endif /* DEBUG */
1204 static void start_playback_if_ready(void)
1206 int playable_space;
1208 playable_space = audiobuf_swapwrite - audiobuf_read;
1209 if(playable_space < 0)
1210 playable_space += audiobuflen;
1212 /* See if we have started playing yet. If not, do it. */
1213 if(play_pending || dma_underrun)
1215 /* If the filling has stopped, and we still haven't reached
1216 the watermark, the file must be smaller than the
1217 watermark. We must still play it. */
1218 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1219 !filling || dma_underrun)
1221 DEBUGF("P\n");
1222 if (play_pending) /* don't do this when recovering from DMA underrun */
1224 generate_postbuffer_events(); /* signal first track as buffered */
1225 if (play_pending_track_change)
1227 play_pending_track_change = false;
1228 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1230 play_pending = false;
1232 playing = true;
1234 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1235 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1236 dma_underrun = false;
1238 if (!paused)
1240 last_dma_tick = current_tick;
1241 mp3_play_pause(true);
1244 /* Tell ourselves that we need more data */
1245 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1250 static bool swap_one_chunk(void)
1252 int free_space_left;
1253 int amount_to_swap;
1255 free_space_left = get_unswapped_space();
1257 if(free_space_left == 0 && !play_pending)
1258 return false;
1260 /* Swap in larger chunks when the user is waiting for the playback
1261 to start, or when there is dangerously little playable data left */
1262 if(play_pending)
1263 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1264 else
1266 if(get_playable_space() < low_watermark)
1267 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1268 free_space_left);
1269 else
1270 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1273 if(audiobuf_write < audiobuf_swapwrite)
1274 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1275 amount_to_swap);
1276 else
1277 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1278 amount_to_swap);
1280 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1282 audiobuf_swapwrite += amount_to_swap;
1283 if(audiobuf_swapwrite >= audiobuflen)
1285 audiobuf_swapwrite = 0;
1288 return true;
1291 static void mpeg_thread(void)
1293 static int pause_tick = 0;
1294 static unsigned int pause_track = 0;
1295 struct queue_event ev;
1296 int len;
1297 int free_space_left;
1298 int unplayed_space_left;
1299 int amount_to_read;
1300 int t1, t2;
1301 int start_offset;
1302 #if CONFIG_CODEC == MAS3587F
1303 int amount_to_save;
1304 int save_endpos = 0;
1305 int rc;
1306 int level;
1307 long offset;
1308 #endif /* CONFIG_CODEC == MAS3587F */
1310 is_playing = false;
1311 play_pending = false;
1312 playing = false;
1313 mpeg_file = -1;
1315 while(1)
1317 #if CONFIG_CODEC == MAS3587F
1318 if(mpeg_mode == MPEG_DECODER)
1320 #endif /* CONFIG_CODEC == MAS3587F */
1321 yield();
1323 /* Swap if necessary, and don't block on the queue_wait() */
1324 if(swap_one_chunk())
1326 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1328 else if (playing)
1330 /* periodically update resume info */
1331 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1333 else
1335 DEBUGF("S R:%x W:%x SW:%x\n",
1336 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1337 queue_wait(&mpeg_queue, &ev);
1340 start_playback_if_ready();
1342 switch(ev.id)
1344 case MPEG_PLAY:
1345 DEBUGF("MPEG_PLAY\n");
1347 #if CONFIG_TUNER
1348 /* Silence the A/D input, it may be on because the radio
1349 may be playing */
1350 mas_codec_writereg(6, 0x0000);
1351 #endif /* CONFIG_TUNER */
1353 /* Stop the current stream */
1354 paused = false;
1355 end_current_track();
1357 if ( new_file(0) == -1 )
1359 is_playing = false;
1360 track_change();
1361 break;
1364 start_offset = (int)ev.data;
1366 /* mid-song resume? */
1367 if (start_offset) {
1368 struct mp3entry* id3 = &get_trackdata(0)->id3;
1369 lseek(mpeg_file, start_offset, SEEK_SET);
1370 id3->offset = start_offset;
1371 set_elapsed(id3);
1373 else {
1374 /* skip past id3v2 tag */
1375 lseek(mpeg_file,
1376 get_trackdata(0)->id3.first_frame_offset,
1377 SEEK_SET);
1381 /* Make it read more data */
1382 filling = true;
1383 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1385 /* Tell the file loading code that we want to start playing
1386 as soon as we have some data */
1387 play_pending = true;
1388 play_pending_track_change = true;
1390 update_playlist();
1391 current_track_counter++;
1392 break;
1394 case MPEG_STOP:
1395 do_stop();
1396 break;
1398 case MPEG_PAUSE:
1399 DEBUGF("MPEG_PAUSE\n");
1400 /* Stop the current stream */
1401 if (playing)
1402 playlist_update_resume_info(audio_current_track());
1403 paused = true;
1404 playing = false;
1405 pause_tick = current_tick;
1406 pause_track = current_track_counter;
1407 mp3_play_pause(false);
1408 break;
1410 case MPEG_RESUME:
1411 DEBUGF("MPEG_RESUME\n");
1412 /* Continue the current stream */
1413 paused = false;
1414 if (!play_pending)
1416 playing = true;
1417 if ( current_track_counter == pause_track )
1418 last_dma_tick += current_tick - pause_tick;
1419 else
1420 last_dma_tick = current_tick;
1421 pause_tick = 0;
1422 mp3_play_pause(true);
1424 break;
1426 case MPEG_NEXT:
1427 DEBUGF("MPEG_NEXT\n");
1428 /* is next track in ram? */
1429 if ( num_tracks_in_memory() > 1 ) {
1430 int unplayed_space_left, unswapped_space_left;
1432 /* stop the current stream */
1433 play_pending = false;
1434 playing = false;
1435 mp3_play_pause(false);
1437 track_change();
1438 audiobuf_read = get_trackdata(0)->mempos;
1439 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1440 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1441 dma_underrun = false;
1442 last_dma_tick = current_tick;
1444 unplayed_space_left = get_unplayed_space();
1445 unswapped_space_left = get_unswapped_space();
1447 /* should we start reading more data? */
1448 if(!filling && (unplayed_space_left < low_watermark)) {
1449 filling = true;
1450 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1451 play_pending = true;
1452 } else if(unswapped_space_left &&
1453 unswapped_space_left > unplayed_space_left) {
1454 /* Stop swapping the data from the previous file */
1455 audiobuf_swapwrite = audiobuf_read;
1456 play_pending = true;
1457 } else {
1458 playing = true;
1459 if (!paused)
1460 mp3_play_pause(true);
1463 else {
1464 if (!playlist_check(1))
1465 break;
1467 /* stop the current stream */
1468 end_current_track();
1470 if (new_file(1) < 0) {
1471 DEBUGF("No more files to play\n");
1472 filling = false;
1474 check_playlist_end(1);
1475 current_track_counter++;
1476 } else {
1477 /* Make it read more data */
1478 filling = true;
1479 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1481 /* Tell the file loading code that we want
1482 to start playing as soon as we have some data */
1483 play_pending = true;
1484 play_pending_track_change = true;
1486 update_playlist();
1487 current_track_counter++;
1490 break;
1492 case MPEG_PREV: {
1493 DEBUGF("MPEG_PREV\n");
1495 if (!playlist_check(-1))
1496 break;
1498 /* stop the current stream */
1499 end_current_track();
1501 /* Open the next file */
1502 if (new_file(-1) < 0) {
1503 DEBUGF("No more files to play\n");
1504 filling = false;
1506 check_playlist_end(-1);
1507 current_track_counter++;
1508 } else {
1509 /* Make it read more data */
1510 filling = true;
1511 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1513 /* Tell the file loading code that we want to
1514 start playing as soon as we have some data */
1515 play_pending = true;
1516 play_pending_track_change = true;
1518 update_playlist();
1519 current_track_counter++;
1521 break;
1524 case MPEG_FF_REWIND: {
1525 struct mp3entry *id3 = audio_current_track();
1526 unsigned int oldtime = id3->elapsed;
1527 unsigned int newtime = (unsigned int)ev.data;
1528 int curpos, newpos, diffpos;
1529 DEBUGF("MPEG_FF_REWIND\n");
1531 id3->elapsed = newtime;
1533 newpos = audio_get_file_pos();
1534 if(newpos < 0)
1536 id3->elapsed = oldtime;
1537 break;
1540 if (mpeg_file >= 0)
1541 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1542 else
1543 curpos = id3->filesize;
1545 if (num_tracks_in_memory() > 1)
1547 /* We have started loading other tracks that need to be
1548 accounted for */
1549 struct trackdata *track;
1550 int i = 0;
1552 while((track = get_trackdata(i++)))
1554 curpos += track->id3.filesize;
1558 diffpos = curpos - newpos;
1560 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1562 int unplayed_space_left, unswapped_space_left;
1564 /* We are changing to a position that's already in
1565 memory, so we just move the DMA read pointer. */
1566 audiobuf_read = audiobuf_write - diffpos;
1567 if (audiobuf_read < 0)
1569 audiobuf_read += audiobuflen;
1572 unplayed_space_left = get_unplayed_space();
1573 unswapped_space_left = get_unswapped_space();
1575 /* If unswapped_space_left is larger than
1576 unplayed_space_left, it means that the swapwrite pointer
1577 hasn't yet advanced up to the new location of the read
1578 pointer. We just move it, there is no need to swap
1579 data that won't be played anyway. */
1581 if (unswapped_space_left > unplayed_space_left)
1583 DEBUGF("Moved swapwrite\n");
1584 audiobuf_swapwrite = audiobuf_read;
1585 play_pending = true;
1588 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1590 /* We need to load more data before starting */
1591 filling = true;
1592 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1593 play_pending = true;
1595 else
1597 /* resume will start at new position */
1598 last_dma_chunk_size =
1599 MIN(0x2000, get_unplayed_space_current_song());
1600 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1601 last_dma_chunk_size, transfer_end);
1602 dma_underrun = false;
1605 else
1607 /* Move to the new position in the file and start
1608 loading data */
1609 reset_mp3_buffer();
1611 if (num_tracks_in_memory() > 1)
1613 /* We have to reload the current track */
1614 close(mpeg_file);
1615 remove_all_non_current_tags();
1616 generate_unbuffer_events();
1617 mpeg_file = -1;
1620 if (mpeg_file < 0)
1622 mpeg_file = open(id3->path, O_RDONLY);
1623 if (mpeg_file < 0)
1625 id3->elapsed = oldtime;
1626 break;
1630 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1632 id3->elapsed = oldtime;
1633 break;
1636 filling = true;
1637 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1639 /* Tell the file loading code that we want to start playing
1640 as soon as we have some data */
1641 play_pending = true;
1644 id3->offset = newpos;
1646 break;
1649 case MPEG_FLUSH_RELOAD: {
1650 int numtracks = num_tracks_in_memory();
1651 bool reload_track = false;
1653 if (numtracks > 1)
1655 /* Reset the buffer */
1656 audiobuf_write = get_trackdata(1)->mempos;
1658 /* Reset swapwrite unless we're still swapping current
1659 track */
1660 if (get_unplayed_space() <= get_playable_space())
1661 audiobuf_swapwrite = audiobuf_write;
1663 close(mpeg_file);
1664 remove_all_non_current_tags();
1665 generate_unbuffer_events();
1666 mpeg_file = -1;
1667 reload_track = true;
1669 else if (numtracks == 1 && mpeg_file < 0)
1671 reload_track = true;
1674 if(reload_track && new_file(1) >= 0)
1676 /* Tell ourselves that we want more data */
1677 filling = true;
1678 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1681 break;
1684 case MPEG_NEED_DATA:
1685 free_space_left = audiobuf_read - audiobuf_write;
1687 /* We interpret 0 as "empty buffer" */
1688 if(free_space_left <= 0)
1689 free_space_left += audiobuflen;
1691 unplayed_space_left = audiobuflen - free_space_left;
1693 /* Make sure that we don't fill the entire buffer */
1694 free_space_left -= MPEG_HIGH_WATER;
1696 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1697 generate_unbuffer_events();
1699 /* do we have any more buffer space to fill? */
1700 if(free_space_left <= 0)
1702 DEBUGF("0\n");
1703 filling = false;
1704 generate_postbuffer_events();
1705 storage_sleep();
1706 break;
1709 /* Read small chunks while we are below the low water mark */
1710 if(unplayed_space_left < low_watermark)
1711 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1712 free_space_left);
1713 else
1714 amount_to_read = free_space_left;
1716 /* Don't read more than until the end of the buffer */
1717 amount_to_read = MIN(audiobuflen - audiobuf_write,
1718 amount_to_read);
1719 #if (CONFIG_STORAGE & STORAGE_MMC)
1720 /* MMC is slow, so don't read too large chunks */
1721 amount_to_read = MIN(0x40000, amount_to_read);
1722 #elif MEMORYSIZE == 8
1723 amount_to_read = MIN(0x100000, amount_to_read);
1724 #endif
1726 /* Read as much mpeg data as we can fit in the buffer */
1727 if(mpeg_file >= 0)
1729 DEBUGF("R\n");
1730 t1 = current_tick;
1731 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1732 amount_to_read);
1733 if(len > 0)
1735 t2 = current_tick;
1736 DEBUGF("time: %d\n", t2 - t1);
1737 DEBUGF("R: %x\n", len);
1739 /* Now make sure that we don't feed the MAS with ID3V1
1740 data */
1741 if (len < amount_to_read)
1743 int i;
1744 static const unsigned char tag[] = "TAG";
1745 int taglen = 128;
1746 int tagptr = audiobuf_write + len - 128;
1748 /* Really rare case: entire potential tag wasn't
1749 read in this call AND audiobuf_write < 128 */
1750 if (tagptr < 0)
1751 tagptr += audiobuflen;
1753 for(i = 0;i < 3;i++)
1755 if(tagptr >= audiobuflen)
1756 tagptr -= audiobuflen;
1758 if(mpeg_audiobuf[tagptr] != tag[i])
1760 taglen = 0;
1761 break;
1764 tagptr++;
1767 if(taglen)
1769 /* Skip id3v1 tag */
1770 DEBUGF("Skipping ID3v1 tag\n");
1771 len -= taglen;
1773 /* In the very rare case when the entire tag
1774 wasn't read in this read() len will be < 0.
1775 Take care of this when changing the write
1776 pointer. */
1780 audiobuf_write += len;
1782 if (audiobuf_write < 0)
1783 audiobuf_write += audiobuflen;
1785 if(audiobuf_write >= audiobuflen)
1787 audiobuf_write = 0;
1788 DEBUGF("W\n");
1791 /* Tell ourselves that we want more data */
1792 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1794 else
1796 if(len < 0)
1798 DEBUGF("MPEG read error\n");
1801 close(mpeg_file);
1802 mpeg_file = -1;
1804 if(new_file(1) < 0)
1806 /* No more data to play */
1807 DEBUGF("No more files to play\n");
1808 filling = false;
1810 else
1812 /* Tell ourselves that we want more data */
1813 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1817 break;
1819 case MPEG_TRACK_CHANGE:
1820 track_change();
1821 break;
1823 #ifndef USB_NONE
1824 case SYS_USB_CONNECTED:
1825 is_playing = false;
1826 paused = false;
1827 stop_playing();
1829 /* Tell the USB thread that we are safe */
1830 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1831 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1833 /* Wait until the USB cable is extracted again */
1834 usb_wait_for_disconnect(&mpeg_queue);
1835 break;
1836 #endif /* !USB_NONE */
1838 #if CONFIG_CODEC == MAS3587F
1839 case MPEG_INIT_RECORDING:
1840 init_recording();
1841 init_recording_done = true;
1842 break;
1843 #endif /* CONFIG_CODEC == MAS3587F */
1845 case SYS_TIMEOUT:
1846 if (playing)
1847 playlist_update_resume_info(audio_current_track());
1848 break;
1850 #if CONFIG_CODEC == MAS3587F
1852 else
1854 queue_wait(&mpeg_queue, &ev);
1855 switch(ev.id)
1857 case MPEG_RECORD:
1858 if (is_prerecording)
1860 int startpos;
1862 /* Go back prerecord_count seconds in the buffer */
1863 startpos = prerecord_index - prerecord_count;
1864 if(startpos < 0)
1865 startpos += prerecording_max_seconds;
1867 /* Read the position data from the prerecord buffer */
1868 frame_count_start = prerecord_buffer[startpos].framecount;
1869 startpos = prerecord_buffer[startpos].mempos;
1871 DEBUGF("Start looking at address %x (%x)\n",
1872 mpeg_audiobuf+startpos, startpos);
1874 saved_header = mpeg_get_last_header();
1876 mem_find_next_frame(startpos, &offset, 1800,
1877 saved_header, mpeg_audiobuf,
1878 audiobuflen);
1880 audiobuf_read = startpos + offset;
1881 if(audiobuf_read >= audiobuflen)
1882 audiobuf_read -= audiobuflen;
1884 DEBUGF("New audiobuf_read address: %x (%x)\n",
1885 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1887 level = disable_irq_save();
1888 num_rec_bytes = get_unsaved_space();
1889 restore_irq(level);
1891 else
1893 frame_count_start = 0;
1894 num_rec_bytes = 0;
1895 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1896 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1899 prepend_header();
1900 DEBUGF("Recording...\n");
1901 start_recording();
1903 /* Wait until at least one frame is encoded and get the
1904 frame header, for later use by the Xing header
1905 generation */
1906 sleep(HZ/5);
1907 saved_header = mpeg_get_last_header();
1909 /* delayed until buffer is saved, don't open yet */
1910 strcpy(delayed_filename, recording_filename);
1911 mpeg_file = -1;
1913 break;
1915 case MPEG_STOP:
1916 DEBUGF("MPEG_STOP\n");
1918 stop_recording();
1920 /* Save the remaining data in the buffer */
1921 save_endpos = audiobuf_write;
1922 saving_status = STOP_RECORDING;
1923 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1924 break;
1926 case MPEG_STOP_DONE:
1927 DEBUGF("MPEG_STOP_DONE\n");
1929 if (mpeg_file >= 0)
1930 close(mpeg_file);
1931 mpeg_file = -1;
1933 update_header();
1934 #ifdef DEBUG1
1936 int i;
1937 for(i = 0;i < 512;i++)
1939 DEBUGF("%d - %d us (%d bytes)\n",
1940 timing_info[i*2],
1941 (timing_info[i*2+1] & 0xffff) *
1942 10000 / 13824,
1943 timing_info[i*2+1] >> 16);
1946 #endif /* DEBUG1 */
1948 if (prerecording)
1950 start_prerecording();
1952 mpeg_stop_done = true;
1953 break;
1955 case MPEG_NEW_FILE:
1956 /* Bail out when a more important save is happening */
1957 if (saving_status > NEW_FILE)
1958 break;
1960 /* Make sure we have at least one complete frame
1961 in the buffer. If we haven't recorded a single
1962 frame within 200ms, the MAS is probably not recording
1963 anything, and we bail out. */
1964 amount_to_save = get_unsaved_space();
1965 if (amount_to_save < 1800)
1967 sleep(HZ/5);
1968 amount_to_save = get_unsaved_space();
1971 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1972 &frame_count_end, 1);
1974 last_rec_time = current_tick - record_start_time;
1975 record_start_time = current_tick;
1976 if (paused)
1977 pause_start_time = record_start_time;
1979 /* capture all values at one point */
1980 level = disable_irq_save();
1981 save_endpos = audiobuf_write;
1982 last_rec_bytes = num_rec_bytes;
1983 num_rec_bytes = 0;
1984 restore_irq(level);
1986 if (amount_to_save >= 1800)
1988 /* Now find a frame boundary to split at */
1989 save_endpos -= 1800;
1990 if (save_endpos < 0)
1991 save_endpos += audiobuflen;
1993 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1994 saved_header, mpeg_audiobuf,
1995 audiobuflen);
1996 if (!rc) /* No header found, save whole buffer */
1997 offset = 1800;
1999 save_endpos += offset;
2000 if (save_endpos >= audiobuflen)
2001 save_endpos -= audiobuflen;
2003 last_rec_bytes += offset - 1800;
2004 level = disable_irq_save();
2005 num_rec_bytes += 1800 - offset;
2006 restore_irq(level);
2009 saving_status = NEW_FILE;
2010 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2011 break;
2013 case MPEG_SAVE_DATA:
2014 if (saving_status == BUFFER_FULL)
2015 save_endpos = audiobuf_write;
2017 if (mpeg_file < 0) /* delayed file open */
2019 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
2021 if (mpeg_file < 0)
2022 panicf("recfile: %d", mpeg_file);
2025 amount_to_save = save_endpos - audiobuf_read;
2026 if (amount_to_save < 0)
2027 amount_to_save += audiobuflen;
2029 amount_to_save = MIN(amount_to_save,
2030 audiobuflen - audiobuf_read);
2031 #if (CONFIG_STORAGE & STORAGE_MMC)
2032 /* MMC is slow, so don't save too large chunks at once */
2033 amount_to_save = MIN(0x40000, amount_to_save);
2034 #elif MEMORYSIZE == 8
2035 amount_to_save = MIN(0x100000, amount_to_save);
2036 #endif
2037 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
2038 amount_to_save);
2039 if (rc < 0)
2041 if (errno == ENOSPC)
2043 mpeg_errno = AUDIOERR_DISK_FULL;
2044 stop_recording();
2045 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2046 /* will close the file */
2047 break;
2049 else
2050 panicf("rec wrt: %d", rc);
2053 audiobuf_read += amount_to_save;
2054 if (audiobuf_read >= audiobuflen)
2055 audiobuf_read = 0;
2057 if (audiobuf_read == save_endpos) /* all saved */
2059 switch (saving_status)
2061 case BUFFER_FULL:
2062 rc = fsync(mpeg_file);
2063 if (rc < 0)
2064 panicf("rec fls: %d", rc);
2065 storage_sleep();
2066 break;
2068 case NEW_FILE:
2069 /* Close the current file */
2070 rc = close(mpeg_file);
2071 if (rc < 0)
2072 panicf("rec cls: %d", rc);
2073 mpeg_file = -1;
2074 update_header();
2075 storage_sleep();
2077 /* copy new filename */
2078 strcpy(delayed_filename, recording_filename);
2079 prepend_header();
2080 frame_count_start = frame_count_end;
2081 break;
2083 case STOP_RECORDING:
2084 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2085 /* will close the file */
2086 break;
2088 default:
2089 break;
2091 saving_status = NOT_SAVING;
2093 else /* tell ourselves to save the next chunk */
2094 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2096 break;
2098 case MPEG_PRERECORDING_TICK:
2099 if(!is_prerecording)
2100 break;
2102 /* Store the write pointer every second */
2103 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2104 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2105 &prerecord_buffer[prerecord_index].framecount, 1);
2107 /* Wrap if necessary */
2108 if(++prerecord_index == prerecording_max_seconds)
2109 prerecord_index = 0;
2111 /* Update the number of seconds recorded */
2112 if(prerecord_count < prerecording_max_seconds)
2113 prerecord_count++;
2114 break;
2116 case MPEG_INIT_PLAYBACK:
2117 /* Stop the prerecording */
2118 stop_recording();
2119 reset_mp3_buffer();
2120 mp3_play_init();
2121 init_playback_done = true;
2122 break;
2124 case MPEG_PAUSE_RECORDING:
2125 pause_recording();
2126 break;
2128 case MPEG_RESUME_RECORDING:
2129 resume_recording();
2130 break;
2132 case SYS_USB_CONNECTED:
2133 /* We can safely go to USB mode if no recording
2134 is taking place */
2135 if((!is_recording || is_prerecording) && mpeg_stop_done)
2137 /* Even if we aren't recording, we still call this
2138 function, to put the MAS in monitoring mode,
2139 to save power. */
2140 stop_recording();
2142 /* Tell the USB thread that we are safe */
2143 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2144 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2146 /* Wait until the USB cable is extracted again */
2147 usb_wait_for_disconnect(&mpeg_queue);
2149 break;
2152 #endif /* CONFIG_CODEC == MAS3587F */
2155 #endif /* !SIMULATOR */
2157 struct mp3entry* audio_current_track(void)
2159 #ifdef SIMULATOR
2160 struct mp3entry *id3 = &taginfo;
2161 #else /* !SIMULATOR */
2162 if(num_tracks_in_memory())
2164 struct mp3entry *id3 = &get_trackdata(0)->id3;
2165 #endif
2166 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2168 checked_for_cuesheet = true; /* only check once per track */
2169 char cuepath[MAX_PATH];
2171 if (look_for_cuesheet_file(id3->path, cuepath) &&
2172 parse_cuesheet(cuepath, curr_cuesheet))
2174 id3->cuesheet = curr_cuesheet;
2177 return id3;
2178 #ifndef SIMULATOR
2180 else
2181 return NULL;
2182 #endif /* !SIMULATOR */
2185 struct mp3entry* audio_next_track(void)
2187 #ifdef SIMULATOR
2188 return &taginfo;
2189 #else /* !SIMULATOR */
2190 if(num_tracks_in_memory() > 1)
2191 return &get_trackdata(1)->id3;
2192 else
2193 return NULL;
2194 #endif /* !SIMULATOR */
2197 #if CONFIG_CODEC == MAS3587F
2198 #ifndef SIMULATOR
2199 void audio_init_playback(void)
2201 init_playback_done = false;
2202 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2204 while(!init_playback_done)
2205 sleep(1);
2209 /****************************************************************************
2210 * Recording functions
2211 ***************************************************************************/
2212 void audio_init_recording(void)
2214 init_recording_done = false;
2215 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2217 while(!init_recording_done)
2218 sleep(1);
2221 static void init_recording(void)
2223 unsigned long val;
2224 int rc;
2226 /* Disable IRQ6 */
2227 IPRB &= 0xff0f;
2229 stop_playing();
2230 is_playing = false;
2231 paused = false;
2233 /* Init the recording variables */
2234 is_recording = false;
2235 is_prerecording = false;
2237 mpeg_stop_done = true;
2239 mas_reset();
2241 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2242 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2243 if(rc < 0)
2244 panicf("mas_ctrl_w: %d", rc);
2246 /* Stop the current application */
2247 val = 0;
2248 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2251 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2252 } while(val);
2254 /* Perform black magic as described by the data sheet */
2255 if((mas_version_code & 0x0fff) == 0x0102)
2257 DEBUGF("Performing MAS black magic for B2 version\n");
2258 mas_writereg(0xa3, 0x98);
2259 mas_writereg(0x94, 0xfffff);
2260 val = 0;
2261 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2262 mas_writereg(0xa3, 0x90);
2265 /* Enable A/D Converters */
2266 shadow_codec_reg0 = 0xcccd;
2267 mas_codec_writereg(0x0, shadow_codec_reg0);
2269 /* Copy left channel to right (mono mode) */
2270 mas_codec_writereg(8, 0x8000);
2272 /* ADC scale 0%, DSP scale 100%
2273 We use the DSP output for monitoring, because it works with all
2274 sources including S/PDIF */
2275 mas_codec_writereg(6, 0x0000);
2276 mas_codec_writereg(7, 0x4000);
2278 /* No mute */
2279 shadow_soft_mute = 0;
2280 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2282 #ifdef HAVE_SPDIF_OUT
2283 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2284 #else
2285 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2286 #endif
2287 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2289 /* Set Demand mode, monitoring OFF and validate all settings */
2290 shadow_io_control_main = 0x125;
2291 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2293 /* Start the encoder application */
2294 val = 0x40;
2295 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2298 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2299 } while(!(val & 0x40));
2301 /* We have started the recording application with monitoring OFF.
2302 This is because we want to record at least one frame to fill the DMA
2303 buffer, because the silly MAS will not negate EOD until at least one
2304 DMA transfer has taken place.
2305 Now let's wait for some data to be encoded. */
2306 sleep(HZ/5);
2308 /* Now set it to Monitoring mode as default, saves power */
2309 shadow_io_control_main = 0x525;
2310 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2312 /* Wait until the DSP has accepted the settings */
2315 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2316 } while(val & 1);
2318 drain_dma_buffer();
2319 mpeg_mode = MPEG_ENCODER;
2321 DEBUGF("MAS Recording application started\n");
2323 /* At this point, all settings are the reset MAS defaults, next thing is to
2324 call mpeg_set_recording_options(). */
2327 void audio_record(const char *filename)
2329 mpeg_errno = 0;
2331 strlcpy(recording_filename, filename, MAX_PATH);
2333 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2336 void audio_pause_recording(void)
2338 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2341 void audio_resume_recording(void)
2343 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2346 static void prepend_header(void)
2348 int startpos;
2349 unsigned i;
2351 /* Make room for header */
2352 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2353 if(audiobuf_read < 0)
2355 /* Clear the bottom half */
2356 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2358 /* And the top half */
2359 audiobuf_read += audiobuflen;
2360 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2362 else
2364 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2366 /* Copy the empty ID3 header */
2367 startpos = audiobuf_read;
2368 for(i = 0; i < sizeof(empty_id3_header); i++)
2370 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2371 if(startpos == audiobuflen)
2372 startpos = 0;
2376 static void update_header(void)
2378 int fd, framelen;
2379 unsigned long frames;
2381 if (last_rec_bytes > 0)
2383 /* Create the Xing header */
2384 fd = open(delayed_filename, O_RDWR);
2385 if (fd < 0)
2386 panicf("rec upd: %d (%s)", fd, recording_filename);
2388 frames = frame_count_end - frame_count_start;
2389 /* If the number of recorded frames has reached 0x7ffff,
2390 we can no longer trust it */
2391 if (frame_count_end == 0x7ffff)
2392 frames = 0;
2394 /* saved_header is saved right before stopping the MAS */
2395 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2396 frames, last_rec_time * (1000/HZ),
2397 saved_header, NULL, false,
2398 mpeg_audiobuf, audiobuflen);
2400 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2401 write(fd, xing_buffer, framelen);
2402 close(fd);
2406 static void start_prerecording(void)
2408 unsigned long val;
2410 DEBUGF("Starting prerecording\n");
2412 prerecord_index = 0;
2413 prerecord_count = 0;
2414 prerecord_timeout = current_tick + HZ;
2415 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2416 reset_mp3_buffer();
2418 is_prerecording = true;
2420 /* Stop monitoring and start the encoder */
2421 shadow_io_control_main &= ~(1 << 10);
2422 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2423 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2425 /* Wait until the DSP has accepted the settings */
2428 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2429 } while(val & 1);
2431 is_recording = true;
2432 saving_status = NOT_SAVING;
2434 demand_irq_enable(true);
2437 static void start_recording(void)
2439 unsigned long val;
2441 if(is_prerecording)
2443 /* This will make the IRQ handler start recording
2444 for real, i.e send MPEG_SAVE_DATA messages when
2445 the buffer is full */
2446 is_prerecording = false;
2448 else
2450 /* If prerecording is off, we need to stop the monitoring
2451 and start the encoder */
2452 shadow_io_control_main &= ~(1 << 10);
2453 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 /* Wait until the DSP has accepted the settings */
2459 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2460 } while(val & 1);
2463 is_recording = true;
2464 saving_status = NOT_SAVING;
2465 paused = false;
2467 /* Store the current time */
2468 if(prerecording)
2469 record_start_time = current_tick - prerecord_count * HZ;
2470 else
2471 record_start_time = current_tick;
2473 pause_start_time = 0;
2475 demand_irq_enable(true);
2478 static void pause_recording(void)
2480 pause_start_time = current_tick;
2482 /* Set the pause bit */
2483 shadow_soft_mute |= 2;
2484 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2486 paused = true;
2489 static void resume_recording(void)
2491 paused = false;
2493 /* Clear the pause bit */
2494 shadow_soft_mute &= ~2;
2495 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2497 /* Compensate for the time we have been paused */
2498 if(pause_start_time)
2500 record_start_time =
2501 current_tick - (pause_start_time - record_start_time);
2502 pause_start_time = 0;
2506 static void stop_recording(void)
2508 unsigned long val;
2510 /* Let it finish the last frame */
2511 if(!paused)
2512 pause_recording();
2513 sleep(HZ/5);
2515 demand_irq_enable(false);
2517 is_recording = false;
2518 is_prerecording = false;
2520 last_rec_bytes = num_rec_bytes;
2521 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2522 last_rec_time = current_tick - record_start_time;
2524 /* Start monitoring */
2525 shadow_io_control_main |= (1 << 10);
2526 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2527 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2529 /* Wait until the DSP has accepted the settings */
2532 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2533 } while(val & 1);
2535 resume_recording();
2538 void audio_set_recording_options(struct audio_recording_options *options)
2540 bool is_mpeg1;
2542 is_mpeg1 = (options->rec_frequency < 3);
2544 rec_version_index = is_mpeg1?3:2;
2545 rec_frequency_index = options->rec_frequency % 3;
2547 shadow_encoder_control = (options->rec_quality << 17) |
2548 (rec_frequency_index << 10) |
2549 ((is_mpeg1?1:0) << 9) |
2550 (((options->rec_channels * 2 + 1) & 3) << 6) |
2551 (1 << 5) /* MS-stereo */ |
2552 (1 << 2) /* Is an original */;
2553 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2555 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2557 #if CONFIG_TUNER & S1A0903X01
2558 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2559 interference with the Samsung tuner. */
2560 if (rec_frequency_index)
2561 mas_store_pllfreq(24576000);
2562 else
2563 mas_store_pllfreq(22579000);
2564 #endif
2566 shadow_soft_mute = options->rec_editable?4:0;
2567 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2569 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2571 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2572 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2573 (1 << 5) | /* SDO strobe invert */
2574 ((is_mpeg1?0:1) << 3) |
2575 (1 << 2) | /* Inverted SIBC clock signal */
2576 1; /* Validate */
2577 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2579 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2581 if(options->rec_source == AUDIO_SRC_MIC)
2583 /* Copy left channel to right (mono mode) */
2584 mas_codec_writereg(8, 0x8000);
2586 else
2588 /* Stereo input mode */
2589 mas_codec_writereg(8, 0);
2592 prerecording_max_seconds = options->rec_prerecord_time;
2593 if(prerecording_max_seconds)
2595 prerecording = true;
2596 start_prerecording();
2598 else
2600 prerecording = false;
2601 is_prerecording = false;
2602 is_recording = false;
2606 /* If use_mic is true, the left gain is used */
2607 void audio_set_recording_gain(int left, int right, int type)
2609 /* Enable both left and right A/D */
2610 shadow_codec_reg0 = (left << 12) |
2611 (right << 8) |
2612 (left << 4) |
2613 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2614 0x0007;
2615 mas_codec_writereg(0x0, shadow_codec_reg0);
2618 /* try to make some kind of beep, also in recording mode */
2619 void audio_beep(int duration)
2621 long starttick = current_tick;
2623 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2624 * While this is still audible even without an external signal,
2625 * it doesn't affect the (pre-)recording. */
2626 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2627 mas_codec_writereg(0, shadow_codec_reg0);
2628 yield();
2630 while (current_tick - starttick < duration);
2633 void audio_new_file(const char *filename)
2635 mpeg_errno = 0;
2637 strlcpy(recording_filename, filename, MAX_PATH);
2639 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2642 unsigned long audio_recorded_time(void)
2644 if(is_prerecording)
2645 return prerecord_count * HZ;
2647 if(is_recording)
2649 if(paused)
2650 return pause_start_time - record_start_time;
2651 else
2652 return current_tick - record_start_time;
2655 return 0;
2658 unsigned long audio_num_recorded_bytes(void)
2660 int num_bytes;
2661 int index;
2663 if(is_recording)
2665 if(is_prerecording)
2667 index = prerecord_index - prerecord_count;
2668 if(index < 0)
2669 index += prerecording_max_seconds;
2671 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2672 if(num_bytes < 0)
2673 num_bytes += audiobuflen;
2675 return num_bytes;
2677 else
2678 return num_rec_bytes;
2680 else
2681 return 0;
2684 #else /* SIMULATOR */
2686 /* dummies coming up */
2688 void audio_init_playback(void)
2690 /* a dummy */
2692 unsigned long audio_recorded_time(void)
2694 /* a dummy */
2695 return 0;
2697 void audio_beep(int duration)
2699 /* a dummy */
2700 (void)duration;
2702 void audio_pause_recording(void)
2704 /* a dummy */
2706 void audio_resume_recording(void)
2708 /* a dummy */
2710 unsigned long audio_num_recorded_bytes(void)
2712 /* a dummy */
2713 return 0;
2715 void audio_record(const char *filename)
2717 /* a dummy */
2718 (void)filename;
2720 void audio_new_file(const char *filename)
2722 /* a dummy */
2723 (void)filename;
2726 void audio_set_recording_gain(int left, int right, int type)
2728 /* a dummy */
2729 (void)left;
2730 (void)right;
2731 (void)type;
2733 void audio_init_recording(void)
2735 /* a dummy */
2737 void audio_set_recording_options(struct audio_recording_options *options)
2739 /* a dummy */
2740 (void)options;
2742 #endif /* SIMULATOR */
2743 #endif /* CONFIG_CODEC == MAS3587F */
2745 size_t audio_buffer_available(void)
2747 if (audiobuf_handle > 0)
2748 return audiobuflen;
2749 return core_available();
2752 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize)
2754 talk_buffer_steal(); /* will use the mp3 buffer */
2755 mpeg_audiobuf = buf;
2756 audiobuflen = bufsize;
2757 if (global_settings.cuesheet)
2758 { /* enable cuesheet support */
2759 curr_cuesheet = (struct cuesheet*)mpeg_audiobuf;
2760 mpeg_audiobuf = SKIPBYTES(mpeg_audiobuf, sizeof(struct cuesheet));
2761 audiobuflen -= sizeof(struct cuesheet);
2763 audio_talkbuf_init(mpeg_audiobuf);
2766 static void audio_reset_buffer(void)
2768 size_t bufsize = audiobuflen;
2770 /* alloc buffer if it's was never allocated or freed by audio_hard_stop() */
2771 if (!audiobuf_handle)
2772 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
2774 audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize);
2777 void audio_play(long offset)
2779 audio_reset_buffer();
2780 #ifdef SIMULATOR
2781 char name_buf[MAX_PATH+1];
2782 const char* trackname;
2783 int steps=0;
2785 is_playing = true;
2787 do {
2788 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2789 if (!trackname)
2790 break;
2791 if(mp3info(&taginfo, trackname)) {
2792 /* bad mp3, move on */
2793 if(++steps > playlist_amount())
2794 break;
2795 continue;
2797 #ifdef HAVE_MPEG_PLAY
2798 real_mpeg_play(trackname);
2799 #endif
2800 playlist_next(steps);
2801 taginfo.offset = offset;
2802 set_elapsed(&taginfo);
2803 is_playing = true;
2804 playing = true;
2805 break;
2806 } while(1);
2807 #else /* !SIMULATOR */
2808 is_playing = true;
2809 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2810 #endif /* !SIMULATOR */
2812 mpeg_errno = 0;
2815 void audio_stop(void)
2817 #ifndef SIMULATOR
2818 if (playing)
2820 struct trackdata *track = get_trackdata(0);
2821 prev_track_elapsed = track->id3.elapsed;
2823 mpeg_stop_done = false;
2824 queue_post(&mpeg_queue, MPEG_STOP, 0);
2825 while(!mpeg_stop_done)
2826 yield();
2827 #else /* SIMULATOR */
2828 paused = false;
2829 is_playing = false;
2830 playing = false;
2831 #endif /* SIMULATOR */
2832 /* give voice our entire buffer */
2833 audio_talkbuf_init(mpeg_audiobuf);
2836 /* dummy */
2837 void audio_stop_recording(void)
2839 audio_stop();
2842 void audio_hard_stop(void)
2844 audio_stop();
2845 /* tell voice we obtain the buffer before freeing */
2846 talk_buffer_steal();
2847 if (audiobuf_handle > 0)
2849 audiobuf_handle = core_free(audiobuf_handle);
2850 mpeg_audiobuf = NULL;
2854 void audio_pause(void)
2856 #ifndef SIMULATOR
2857 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2858 #else /* SIMULATOR */
2859 is_playing = true;
2860 playing = false;
2861 paused = true;
2862 #endif /* SIMULATOR */
2865 void audio_resume(void)
2867 #ifndef SIMULATOR
2868 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2869 #else /* SIMULATOR */
2870 is_playing = true;
2871 playing = true;
2872 paused = false;
2873 #endif /* SIMULATOR */
2876 void audio_next(void)
2878 #ifndef SIMULATOR
2879 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2880 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2881 #else /* SIMULATOR */
2882 char name_buf[MAX_PATH+1];
2883 const char* file;
2884 int steps = 1;
2886 do {
2887 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2888 if(!file)
2889 break;
2890 if(mp3info(&taginfo, file)) {
2891 if(++steps > playlist_amount())
2892 break;
2893 continue;
2895 playlist_next(steps);
2896 current_track_counter++;
2897 is_playing = true;
2898 playing = true;
2899 break;
2900 } while(1);
2901 #endif /* SIMULATOR */
2904 void audio_prev(void)
2906 #ifndef SIMULATOR
2907 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2908 queue_post(&mpeg_queue, MPEG_PREV, 0);
2909 #else /* SIMULATOR */
2910 char name_buf[MAX_PATH+1];
2911 const char* file;
2912 int steps = -1;
2914 do {
2915 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2916 if(!file)
2917 break;
2918 if(mp3info(&taginfo, file)) {
2919 steps--;
2920 continue;
2922 playlist_next(steps);
2923 current_track_counter++;
2924 is_playing = true;
2925 playing = true;
2926 break;
2927 } while(1);
2928 #endif /* SIMULATOR */
2931 void audio_ff_rewind(long newpos)
2933 #ifndef SIMULATOR
2934 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2935 #else /* SIMULATOR */
2936 (void)newpos;
2937 #endif /* SIMULATOR */
2940 void audio_flush_and_reload_tracks(void)
2942 #ifndef SIMULATOR
2943 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2944 #endif /* !SIMULATOR*/
2947 int audio_status(void)
2949 int ret = 0;
2951 if(is_playing)
2952 ret |= AUDIO_STATUS_PLAY;
2954 if(paused)
2955 ret |= AUDIO_STATUS_PAUSE;
2957 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2958 if(is_recording && !is_prerecording)
2959 ret |= AUDIO_STATUS_RECORD;
2961 if(is_prerecording)
2962 ret |= AUDIO_STATUS_PRERECORD;
2963 #endif /* CONFIG_CODEC == MAS3587F */
2965 if(mpeg_errno)
2966 ret |= AUDIO_STATUS_ERROR;
2968 return ret;
2971 /* Unused function
2972 unsigned int audio_error(void)
2974 return mpeg_errno;
2978 void audio_error_clear(void)
2980 mpeg_errno = 0;
2983 #ifdef SIMULATOR
2984 static void mpeg_thread(void)
2986 struct mp3entry* id3;
2987 while ( 1 ) {
2988 if (is_playing) {
2989 id3 = audio_current_track();
2990 if (!paused)
2992 id3->elapsed+=1000;
2993 id3->offset+=1000;
2995 if (id3->elapsed>=id3->length)
2996 audio_next();
2998 sleep(HZ);
3001 #endif /* SIMULATOR */
3003 void audio_init(void)
3005 mpeg_errno = 0;
3007 talk_init();
3008 audio_reset_buffer();
3010 #ifndef SIMULATOR
3011 queue_init(&mpeg_queue, true);
3012 #endif /* !SIMULATOR */
3013 audio_thread_id = create_thread(mpeg_thread, mpeg_stack,
3014 sizeof(mpeg_stack), 0, mpeg_thread_name
3015 IF_PRIO(, PRIORITY_SYSTEM)
3016 IF_COP(, CPU));
3018 memset(trackdata, 0, sizeof(trackdata));
3020 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
3021 if (HW_MASK & PR_ACTIVE_HIGH)
3022 and_b(~0x08, &PADRH);
3023 else
3024 or_b(0x08, &PADRH);
3025 #endif /* CONFIG_CODEC == MAS3587F */
3027 #ifdef DEBUG
3028 #ifndef SIMULATOR
3029 dbg_timer_start();
3030 dbg_cnt2us(0);
3031 #endif /* !SIMULATOR */
3032 #endif /* DEBUG */
3033 audio_is_initialized = true;
3036 #endif /* CONFIG_CODEC != SWCODEC */