Fix charcell build
[maemo-rb.git] / apps / mpeg.c
blob904822613310ad1ba0f2f9e179ddc87aea40e247
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 int status = audio_status();
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 (!(status & AUDIO_STATUS_PAUSE))
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 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
560 (void)talk_buf; /* always grab the voice buffer for now */
562 if (audio_is_initialized)
563 audio_hard_stop();
565 if (!buffer_size) /* special case for talk_init() */
566 return NULL;
568 if (!audiobuf_handle)
570 size_t bufsize;
571 /* audio_hard_stop() frees audiobuf, so re-aquire */
572 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
573 audiobuflen = bufsize;
574 if (buffer_size)
575 *buffer_size = audiobuflen;
577 mpeg_audiobuf = core_get_data(audiobuf_handle);
578 /* tell talk about the new buffer, don't re-enable just yet because the
579 * buffer is stolen */
580 talkbuf_init(mpeg_audiobuf);
582 return mpeg_audiobuf;
586 #ifndef SIMULATOR
587 /* Send callback events to notify about removing old tracks. */
588 static void generate_unbuffer_events(void)
590 int i;
591 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
592 int cur_idx = track_write_idx;
594 for (i = 0; i < numentries; i++)
596 /* Send an event to notify that track has finished. */
597 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
598 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
602 /* Send callback events to notify about new tracks. */
603 static void generate_postbuffer_events(void)
605 int i;
606 int numentries = num_tracks_in_memory();
607 int cur_idx = track_read_idx;
609 for (i = 0; i < numentries; i++)
611 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
612 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
616 static void recalculate_watermark(int bitrate)
618 int bytes_per_sec;
619 int time = storage_spinup_time();
621 /* A bitrate of 0 probably means empty VBR header. We play safe
622 and set a high threshold */
623 if(bitrate == 0)
624 bitrate = 320;
626 bytes_per_sec = bitrate * 1000 / 8;
628 if(time)
630 /* No drive spins up faster than 3.5s */
631 if(time < 350)
632 time = 350;
634 time = time * 3;
635 low_watermark = ((low_watermark_margin * HZ + time) *
636 bytes_per_sec) / HZ;
638 else
640 low_watermark = MPEG_LOW_WATER;
644 #ifdef HAVE_DISK_STORAGE
645 void audio_set_buffer_margin(int setting)
647 low_watermark_margin = setting; /* in seconds */
649 #endif
651 void audio_get_debugdata(struct audio_debug *dbgdata)
653 dbgdata->audiobuflen = audiobuflen;
654 dbgdata->audiobuf_write = audiobuf_write;
655 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
656 dbgdata->audiobuf_read = audiobuf_read;
658 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
660 #if CONFIG_CPU == SH7034
661 dbgdata->dma_on = (SCR0 & 0x80) != 0;
662 #endif
663 dbgdata->playing = playing;
664 dbgdata->play_pending = play_pending;
665 dbgdata->is_playing = is_playing;
666 dbgdata->filling = filling;
667 dbgdata->dma_underrun = dma_underrun;
669 dbgdata->unplayed_space = get_unplayed_space();
670 dbgdata->playable_space = get_playable_space();
671 dbgdata->unswapped_space = get_unswapped_space();
673 dbgdata->low_watermark_level = low_watermark;
674 dbgdata->lowest_watermark_level = lowest_watermark_level;
677 #ifdef DEBUG
678 static void dbg_timer_start(void)
680 /* We are using timer 2 */
682 TSTR &= ~0x04; /* Stop the timer */
683 TSNC &= ~0x04; /* No synchronization */
684 TMDR &= ~0x44; /* Operate normally */
686 TCNT2 = 0; /* Start counting at 0 */
687 TCR2 = 0x03; /* Sysclock/8 */
689 TSTR |= 0x04; /* Start timer 2 */
692 static int dbg_cnt2us(unsigned int cnt)
694 return (cnt * 10000) / (FREQ/800);
696 #endif /* DEBUG */
698 static int get_unplayed_space(void)
700 int space = audiobuf_write - audiobuf_read;
701 if (space < 0)
702 space += audiobuflen;
703 return space;
706 static int get_playable_space(void)
708 int space = audiobuf_swapwrite - audiobuf_read;
709 if (space < 0)
710 space += audiobuflen;
711 return space;
714 static int get_unplayed_space_current_song(void)
716 int space;
718 if (num_tracks_in_memory() > 1)
720 space = get_trackdata(1)->mempos - audiobuf_read;
722 else
724 space = audiobuf_write - audiobuf_read;
727 if (space < 0)
728 space += audiobuflen;
730 return space;
733 static int get_unswapped_space(void)
735 int space = audiobuf_write - audiobuf_swapwrite;
736 if (space < 0)
737 space += audiobuflen;
738 return space;
741 #if CONFIG_CODEC == MAS3587F
742 static int get_unsaved_space(void)
744 int space = audiobuf_write - audiobuf_read;
745 if (space < 0)
746 space += audiobuflen;
747 return space;
750 static void drain_dma_buffer(void)
752 while (PBDRH & 0x40)
754 xor_b(0x08, &PADRH);
756 while (PBDRH & 0x80);
758 xor_b(0x08, &PADRH);
760 while (!(PBDRH & 0x80));
764 #ifdef DEBUG
765 static long timing_info_index = 0;
766 static long timing_info[1024];
767 #endif /* DEBUG */
769 void rec_tick (void) __attribute__ ((section (".icode")));
770 void rec_tick(void)
772 int i;
773 int delay;
774 char data;
776 if(is_recording && (PBDRH & 0x40))
778 #ifdef DEBUG
779 timing_info[timing_info_index++] = current_tick;
780 TCNT2 = 0;
781 #endif /* DEBUG */
782 /* Note: Although this loop is run in interrupt context, further
783 * optimisation will do no good. The MAS would then deliver bad
784 * frames occasionally, as observed in extended experiments. */
785 i = 0;
786 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
788 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
790 delay = 100;
791 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
793 if (--delay <= 0) /* Bail out if we have to wait too long */
794 { /* i.e. the MAS doesn't want to talk to us */
795 xor_b(0x08, &PADRH); /* Set PR inactive */
796 goto transfer_end; /* and get out of here */
800 data = *(unsigned char *)0x04000000; /* read data byte */
802 xor_b(0x08, &PADRH); /* Set PR inactive */
804 mpeg_audiobuf[audiobuf_write++] = data;
806 if (audiobuf_write >= audiobuflen)
807 audiobuf_write = 0;
809 i++;
811 transfer_end:
813 #ifdef DEBUG
814 timing_info[timing_info_index++] = TCNT2 + (i << 16);
815 timing_info_index &= 0x3ff;
816 #endif /* DEBUG */
818 num_rec_bytes += i;
820 if(is_prerecording)
822 if(TIME_AFTER(current_tick, prerecord_timeout))
824 prerecord_timeout = current_tick + HZ;
825 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
828 else
830 /* Signal to save the data if we are running out of buffer
831 space */
832 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
833 && saving_status == NOT_SAVING)
835 saving_status = BUFFER_FULL;
836 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
841 #endif /* CONFIG_CODEC == MAS3587F */
843 void playback_tick(void)
845 struct trackdata *ptd = get_trackdata(0);
846 if(ptd)
848 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
849 last_dma_tick = current_tick;
850 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
851 (unsigned long)ptd->id3.elapsed);
855 static void reset_mp3_buffer(void)
857 audiobuf_read = 0;
858 audiobuf_write = 0;
859 audiobuf_swapwrite = 0;
860 lowest_watermark_level = audiobuflen;
863 /* DMA transfer end interrupt callback */
864 static void transfer_end(unsigned char** ppbuf, size_t* psize)
866 if(playing && !paused)
868 int unplayed_space_left;
869 int space_until_end_of_buffer;
870 int track_offset = 1;
871 struct trackdata *track;
873 audiobuf_read += last_dma_chunk_size;
874 if(audiobuf_read >= audiobuflen)
875 audiobuf_read = 0;
877 /* First, check if we are on a track boundary */
878 if (num_tracks_in_memory() > 1)
880 if (audiobuf_read == get_trackdata(track_offset)->mempos)
882 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
884 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
885 track_offset++;
890 unplayed_space_left = get_unplayed_space();
892 space_until_end_of_buffer = audiobuflen - audiobuf_read;
894 if(!filling && unplayed_space_left < low_watermark)
896 filling = true;
897 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
900 if(unplayed_space_left)
902 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
903 last_dma_chunk_size = MIN(last_dma_chunk_size,
904 space_until_end_of_buffer);
906 /* several tracks loaded? */
907 track = get_trackdata(track_offset);
908 if(track)
910 /* will we move across the track boundary? */
911 if (( audiobuf_read < track->mempos ) &&
912 ((audiobuf_read+last_dma_chunk_size) >
913 track->mempos ))
915 /* Make sure that we end exactly on the boundary */
916 last_dma_chunk_size = track->mempos - audiobuf_read;
920 *psize = last_dma_chunk_size & 0xffff;
921 *ppbuf = mpeg_audiobuf + audiobuf_read;
922 track = get_trackdata(0);
923 if(track)
924 track->id3.offset += last_dma_chunk_size;
926 /* Update the watermark debug level */
927 if(unplayed_space_left < lowest_watermark_level)
928 lowest_watermark_level = unplayed_space_left;
930 else
932 /* Check if the end of data is because of a hard disk error.
933 If there is an open file handle, we are still playing music.
934 If not, the last file has been loaded, and the file handle is
935 closed. */
936 if(mpeg_file >= 0)
938 /* Update the watermark debug level */
939 if(unplayed_space_left < lowest_watermark_level)
940 lowest_watermark_level = unplayed_space_left;
942 DEBUGF("DMA underrun.\n");
943 dma_underrun = true;
945 else
947 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
949 DEBUGF("No more MP3 data. Stopping.\n");
950 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
951 playing = false;
954 *psize = 0; /* no more transfer */
959 static struct trackdata *add_track_to_tag_list(const char *filename)
961 struct trackdata *track;
962 bool send_nid3_event;
964 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
966 DEBUGF("Tag memory is full\n");
967 return NULL;
970 track = &trackdata[track_write_idx];
972 /* grab id3 tag of new file and
973 remember where in memory it starts */
974 if(mp3info(&track->id3, filename))
976 DEBUGF("Bad mp3\n");
977 return NULL;
979 track->mempos = audiobuf_write;
980 track->id3.elapsed = 0;
981 #ifdef HAVE_LCD_BITMAP
982 if (track->id3.title)
983 lcd_getstringsize(track->id3.title, NULL, NULL);
984 if (track->id3.artist)
985 lcd_getstringsize(track->id3.artist, NULL, NULL);
986 if (track->id3.album)
987 lcd_getstringsize(track->id3.album, NULL, NULL);
988 #endif
990 /* if this track is the next track then let the UI know it can get it */
991 send_nid3_event = (track_write_idx == track_read_idx + 1);
992 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
993 if (send_nid3_event)
994 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
995 debug_tags();
996 return track;
999 static int new_file(int steps)
1001 int max_steps = playlist_amount();
1002 int start = 0;
1003 int i;
1004 struct trackdata *track;
1005 char name_buf[MAX_PATH+1];
1006 const char *trackname;
1008 /* Find out how many steps to advance. The load_ahead_index field tells
1009 us how many playlist entries it had to skip to get to a valid one.
1010 We add those together to find out where to start. */
1011 if(steps > 0 && num_tracks_in_memory() > 1)
1013 /* Begin with the song after the currently playing one */
1014 i = 1;
1015 while((track = get_trackdata(i++)))
1017 start += track->load_ahead_index;
1021 do {
1022 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
1023 if ( !trackname )
1024 return -1;
1026 DEBUGF("Loading %s\n", trackname);
1028 mpeg_file = open(trackname, O_RDONLY);
1029 if(mpeg_file < 0) {
1030 DEBUGF("Couldn't open file: %s\n",trackname);
1031 if(steps < 0)
1032 steps--;
1033 else
1034 steps++;
1036 else
1038 struct trackdata *track = add_track_to_tag_list(trackname);
1040 if(!track)
1042 /* Bad mp3 file */
1043 if(steps < 0)
1044 steps--;
1045 else
1046 steps++;
1047 close(mpeg_file);
1048 mpeg_file = -1;
1050 else
1052 /* skip past id3v2 tag */
1053 lseek(mpeg_file,
1054 track->id3.first_frame_offset,
1055 SEEK_SET);
1056 track->id3.index = steps;
1057 track->load_ahead_index = steps;
1058 track->id3.offset = 0;
1060 if(track->id3.vbr)
1061 /* Average bitrate * 1.5 */
1062 recalculate_watermark(
1063 (track->id3.bitrate * 3) / 2);
1064 else
1065 recalculate_watermark(
1066 track->id3.bitrate);
1071 /* Bail out if no file could be opened */
1072 if(abs(steps) > max_steps)
1073 return -1;
1074 } while ( mpeg_file < 0 );
1076 return 0;
1079 static void stop_playing(void)
1081 struct trackdata *track;
1083 /* Stop the current stream */
1084 mp3_play_stop();
1085 playing = false;
1086 filling = false;
1088 track = get_trackdata(0);
1089 if (track != NULL)
1090 prev_track_elapsed = track->id3.elapsed;
1092 if(mpeg_file >= 0)
1093 close(mpeg_file);
1094 mpeg_file = -1;
1095 remove_all_tags();
1096 generate_unbuffer_events();
1097 reset_mp3_buffer();
1100 static void end_current_track(void) {
1101 struct trackdata *track;
1103 play_pending = false;
1104 playing = false;
1105 mp3_play_pause(false);
1107 track = get_trackdata(0);
1108 if (track != NULL)
1109 prev_track_elapsed = track->id3.elapsed;
1111 reset_mp3_buffer();
1112 remove_all_tags();
1113 generate_unbuffer_events();
1115 if(mpeg_file >= 0)
1116 close(mpeg_file);
1119 /* Is this a really the end of playback or is a new playlist starting */
1120 static void check_playlist_end(int direction)
1122 /* Use the largest possible step size to account for skipped tracks */
1123 int steps = playlist_amount();
1125 if (direction < 0)
1126 steps = -steps;
1128 if (playlist_next(steps) < 0)
1129 is_playing = false;
1132 static void update_playlist(void)
1134 if (num_tracks_in_memory() > 0)
1136 struct trackdata *track = get_trackdata(0);
1137 track->id3.index = playlist_next(track->id3.index);
1139 else
1141 /* End of playlist? */
1142 check_playlist_end(1);
1145 playlist_update_resume_info(audio_current_track());
1148 static void track_change(void)
1150 DEBUGF("Track change\n");
1152 struct trackdata *track = get_trackdata(0);
1153 prev_track_elapsed = track->id3.elapsed;
1155 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1156 /* Reset the AVC */
1157 sound_set_avc(-1);
1158 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1160 if (num_tracks_in_memory() > 0)
1162 remove_current_tag();
1163 update_playlist();
1164 if (is_playing)
1165 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1168 current_track_counter++;
1171 unsigned long audio_prev_elapsed(void)
1173 return prev_track_elapsed;
1176 #ifdef DEBUG
1177 void hexdump(const unsigned char *buf, int len)
1179 int i;
1181 for(i = 0;i < len;i++)
1183 if(i && (i & 15) == 0)
1185 DEBUGF("\n");
1187 DEBUGF("%02x ", buf[i]);
1189 DEBUGF("\n");
1191 #endif /* DEBUG */
1193 static void start_playback_if_ready(void)
1195 int playable_space;
1197 playable_space = audiobuf_swapwrite - audiobuf_read;
1198 if(playable_space < 0)
1199 playable_space += audiobuflen;
1201 /* See if we have started playing yet. If not, do it. */
1202 if(play_pending || dma_underrun)
1204 /* If the filling has stopped, and we still haven't reached
1205 the watermark, the file must be smaller than the
1206 watermark. We must still play it. */
1207 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1208 !filling || dma_underrun)
1210 DEBUGF("P\n");
1211 if (play_pending) /* don't do this when recovering from DMA underrun */
1213 generate_postbuffer_events(); /* signal first track as buffered */
1214 if (play_pending_track_change)
1216 play_pending_track_change = false;
1217 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1219 play_pending = false;
1221 playing = true;
1223 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1224 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1225 dma_underrun = false;
1227 if (!paused)
1229 last_dma_tick = current_tick;
1230 mp3_play_pause(true);
1233 /* Tell ourselves that we need more data */
1234 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1239 static bool swap_one_chunk(void)
1241 int free_space_left;
1242 int amount_to_swap;
1244 free_space_left = get_unswapped_space();
1246 if(free_space_left == 0 && !play_pending)
1247 return false;
1249 /* Swap in larger chunks when the user is waiting for the playback
1250 to start, or when there is dangerously little playable data left */
1251 if(play_pending)
1252 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1253 else
1255 if(get_playable_space() < low_watermark)
1256 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1257 free_space_left);
1258 else
1259 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1262 if(audiobuf_write < audiobuf_swapwrite)
1263 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1264 amount_to_swap);
1265 else
1266 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1267 amount_to_swap);
1269 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1271 audiobuf_swapwrite += amount_to_swap;
1272 if(audiobuf_swapwrite >= audiobuflen)
1274 audiobuf_swapwrite = 0;
1277 return true;
1280 static void mpeg_thread(void)
1282 static int pause_tick = 0;
1283 static unsigned int pause_track = 0;
1284 struct queue_event ev;
1285 int len;
1286 int free_space_left;
1287 int unplayed_space_left;
1288 int amount_to_read;
1289 int t1, t2;
1290 int start_offset;
1291 #if CONFIG_CODEC == MAS3587F
1292 int amount_to_save;
1293 int save_endpos = 0;
1294 int rc;
1295 int level;
1296 long offset;
1297 #endif /* CONFIG_CODEC == MAS3587F */
1299 is_playing = false;
1300 play_pending = false;
1301 playing = false;
1302 mpeg_file = -1;
1304 while(1)
1306 #if CONFIG_CODEC == MAS3587F
1307 if(mpeg_mode == MPEG_DECODER)
1309 #endif /* CONFIG_CODEC == MAS3587F */
1310 yield();
1312 /* Swap if necessary, and don't block on the queue_wait() */
1313 if(swap_one_chunk())
1315 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1317 else if (playing)
1319 /* periodically update resume info */
1320 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1322 else
1324 DEBUGF("S R:%x W:%x SW:%x\n",
1325 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1326 queue_wait(&mpeg_queue, &ev);
1329 start_playback_if_ready();
1331 switch(ev.id)
1333 case MPEG_PLAY:
1334 DEBUGF("MPEG_PLAY\n");
1336 #if CONFIG_TUNER
1337 /* Silence the A/D input, it may be on because the radio
1338 may be playing */
1339 mas_codec_writereg(6, 0x0000);
1340 #endif /* CONFIG_TUNER */
1342 /* Stop the current stream */
1343 paused = false;
1344 end_current_track();
1346 if ( new_file(0) == -1 )
1348 is_playing = false;
1349 track_change();
1350 break;
1353 start_offset = (int)ev.data;
1355 /* mid-song resume? */
1356 if (start_offset) {
1357 struct mp3entry* id3 = &get_trackdata(0)->id3;
1358 lseek(mpeg_file, start_offset, SEEK_SET);
1359 id3->offset = start_offset;
1360 set_elapsed(id3);
1362 else {
1363 /* skip past id3v2 tag */
1364 lseek(mpeg_file,
1365 get_trackdata(0)->id3.first_frame_offset,
1366 SEEK_SET);
1370 /* Make it read more data */
1371 filling = true;
1372 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1374 /* Tell the file loading code that we want to start playing
1375 as soon as we have some data */
1376 play_pending = true;
1377 play_pending_track_change = true;
1379 update_playlist();
1380 current_track_counter++;
1381 break;
1383 case MPEG_STOP:
1384 do_stop();
1385 break;
1387 case MPEG_PAUSE:
1388 DEBUGF("MPEG_PAUSE\n");
1389 /* Stop the current stream */
1390 if (playing)
1391 playlist_update_resume_info(audio_current_track());
1392 paused = true;
1393 playing = false;
1394 pause_tick = current_tick;
1395 pause_track = current_track_counter;
1396 mp3_play_pause(false);
1397 break;
1399 case MPEG_RESUME:
1400 DEBUGF("MPEG_RESUME\n");
1401 /* Continue the current stream */
1402 paused = false;
1403 if (!play_pending)
1405 playing = true;
1406 if ( current_track_counter == pause_track )
1407 last_dma_tick += current_tick - pause_tick;
1408 else
1409 last_dma_tick = current_tick;
1410 pause_tick = 0;
1411 mp3_play_pause(true);
1413 break;
1415 case MPEG_NEXT:
1416 DEBUGF("MPEG_NEXT\n");
1417 /* is next track in ram? */
1418 if ( num_tracks_in_memory() > 1 ) {
1419 int unplayed_space_left, unswapped_space_left;
1421 /* stop the current stream */
1422 play_pending = false;
1423 playing = false;
1424 mp3_play_pause(false);
1426 track_change();
1427 audiobuf_read = get_trackdata(0)->mempos;
1428 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1429 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1430 dma_underrun = false;
1431 last_dma_tick = current_tick;
1433 unplayed_space_left = get_unplayed_space();
1434 unswapped_space_left = get_unswapped_space();
1436 /* should we start reading more data? */
1437 if(!filling && (unplayed_space_left < low_watermark)) {
1438 filling = true;
1439 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1440 play_pending = true;
1441 } else if(unswapped_space_left &&
1442 unswapped_space_left > unplayed_space_left) {
1443 /* Stop swapping the data from the previous file */
1444 audiobuf_swapwrite = audiobuf_read;
1445 play_pending = true;
1446 } else {
1447 playing = true;
1448 if (!paused)
1449 mp3_play_pause(true);
1452 else {
1453 if (!playlist_check(1))
1454 break;
1456 /* stop the current stream */
1457 end_current_track();
1459 if (new_file(1) < 0) {
1460 DEBUGF("No more files to play\n");
1461 filling = false;
1463 check_playlist_end(1);
1464 current_track_counter++;
1465 } else {
1466 /* Make it read more data */
1467 filling = true;
1468 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1470 /* Tell the file loading code that we want
1471 to start playing as soon as we have some data */
1472 play_pending = true;
1473 play_pending_track_change = true;
1475 update_playlist();
1476 current_track_counter++;
1479 break;
1481 case MPEG_PREV: {
1482 DEBUGF("MPEG_PREV\n");
1484 if (!playlist_check(-1))
1485 break;
1487 /* stop the current stream */
1488 end_current_track();
1490 /* Open the next file */
1491 if (new_file(-1) < 0) {
1492 DEBUGF("No more files to play\n");
1493 filling = false;
1495 check_playlist_end(-1);
1496 current_track_counter++;
1497 } else {
1498 /* Make it read more data */
1499 filling = true;
1500 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1502 /* Tell the file loading code that we want to
1503 start playing as soon as we have some data */
1504 play_pending = true;
1505 play_pending_track_change = true;
1507 update_playlist();
1508 current_track_counter++;
1510 break;
1513 case MPEG_FF_REWIND: {
1514 struct mp3entry *id3 = audio_current_track();
1515 unsigned int oldtime = id3->elapsed;
1516 unsigned int newtime = (unsigned int)ev.data;
1517 int curpos, newpos, diffpos;
1518 DEBUGF("MPEG_FF_REWIND\n");
1520 id3->elapsed = newtime;
1522 newpos = audio_get_file_pos();
1523 if(newpos < 0)
1525 id3->elapsed = oldtime;
1526 break;
1529 if (mpeg_file >= 0)
1530 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1531 else
1532 curpos = id3->filesize;
1534 if (num_tracks_in_memory() > 1)
1536 /* We have started loading other tracks that need to be
1537 accounted for */
1538 struct trackdata *track;
1539 int i = 0;
1541 while((track = get_trackdata(i++)))
1543 curpos += track->id3.filesize;
1547 diffpos = curpos - newpos;
1549 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1551 int unplayed_space_left, unswapped_space_left;
1553 /* We are changing to a position that's already in
1554 memory, so we just move the DMA read pointer. */
1555 audiobuf_read = audiobuf_write - diffpos;
1556 if (audiobuf_read < 0)
1558 audiobuf_read += audiobuflen;
1561 unplayed_space_left = get_unplayed_space();
1562 unswapped_space_left = get_unswapped_space();
1564 /* If unswapped_space_left is larger than
1565 unplayed_space_left, it means that the swapwrite pointer
1566 hasn't yet advanced up to the new location of the read
1567 pointer. We just move it, there is no need to swap
1568 data that won't be played anyway. */
1570 if (unswapped_space_left > unplayed_space_left)
1572 DEBUGF("Moved swapwrite\n");
1573 audiobuf_swapwrite = audiobuf_read;
1574 play_pending = true;
1577 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1579 /* We need to load more data before starting */
1580 filling = true;
1581 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1582 play_pending = true;
1584 else
1586 /* resume will start at new position */
1587 last_dma_chunk_size =
1588 MIN(0x2000, get_unplayed_space_current_song());
1589 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1590 last_dma_chunk_size, transfer_end);
1591 dma_underrun = false;
1594 else
1596 /* Move to the new position in the file and start
1597 loading data */
1598 reset_mp3_buffer();
1600 if (num_tracks_in_memory() > 1)
1602 /* We have to reload the current track */
1603 close(mpeg_file);
1604 remove_all_non_current_tags();
1605 generate_unbuffer_events();
1606 mpeg_file = -1;
1609 if (mpeg_file < 0)
1611 mpeg_file = open(id3->path, O_RDONLY);
1612 if (mpeg_file < 0)
1614 id3->elapsed = oldtime;
1615 break;
1619 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1621 id3->elapsed = oldtime;
1622 break;
1625 filling = true;
1626 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1628 /* Tell the file loading code that we want to start playing
1629 as soon as we have some data */
1630 play_pending = true;
1633 id3->offset = newpos;
1635 break;
1638 case MPEG_FLUSH_RELOAD: {
1639 int numtracks = num_tracks_in_memory();
1640 bool reload_track = false;
1642 if (numtracks > 1)
1644 /* Reset the buffer */
1645 audiobuf_write = get_trackdata(1)->mempos;
1647 /* Reset swapwrite unless we're still swapping current
1648 track */
1649 if (get_unplayed_space() <= get_playable_space())
1650 audiobuf_swapwrite = audiobuf_write;
1652 close(mpeg_file);
1653 remove_all_non_current_tags();
1654 generate_unbuffer_events();
1655 mpeg_file = -1;
1656 reload_track = true;
1658 else if (numtracks == 1 && mpeg_file < 0)
1660 reload_track = true;
1663 if(reload_track && new_file(1) >= 0)
1665 /* Tell ourselves that we want more data */
1666 filling = true;
1667 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1670 break;
1673 case MPEG_NEED_DATA:
1674 free_space_left = audiobuf_read - audiobuf_write;
1676 /* We interpret 0 as "empty buffer" */
1677 if(free_space_left <= 0)
1678 free_space_left += audiobuflen;
1680 unplayed_space_left = audiobuflen - free_space_left;
1682 /* Make sure that we don't fill the entire buffer */
1683 free_space_left -= MPEG_HIGH_WATER;
1685 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1686 generate_unbuffer_events();
1688 /* do we have any more buffer space to fill? */
1689 if(free_space_left <= 0)
1691 DEBUGF("0\n");
1692 filling = false;
1693 generate_postbuffer_events();
1694 storage_sleep();
1695 break;
1698 /* Read small chunks while we are below the low water mark */
1699 if(unplayed_space_left < low_watermark)
1700 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1701 free_space_left);
1702 else
1703 amount_to_read = free_space_left;
1705 /* Don't read more than until the end of the buffer */
1706 amount_to_read = MIN(audiobuflen - audiobuf_write,
1707 amount_to_read);
1708 #if (CONFIG_STORAGE & STORAGE_MMC)
1709 /* MMC is slow, so don't read too large chunks */
1710 amount_to_read = MIN(0x40000, amount_to_read);
1711 #elif MEMORYSIZE == 8
1712 amount_to_read = MIN(0x100000, amount_to_read);
1713 #endif
1715 /* Read as much mpeg data as we can fit in the buffer */
1716 if(mpeg_file >= 0)
1718 DEBUGF("R\n");
1719 t1 = current_tick;
1720 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1721 amount_to_read);
1722 if(len > 0)
1724 t2 = current_tick;
1725 DEBUGF("time: %d\n", t2 - t1);
1726 DEBUGF("R: %x\n", len);
1728 /* Now make sure that we don't feed the MAS with ID3V1
1729 data */
1730 if (len < amount_to_read)
1732 int i;
1733 static const unsigned char tag[] = "TAG";
1734 int taglen = 128;
1735 int tagptr = audiobuf_write + len - 128;
1737 /* Really rare case: entire potential tag wasn't
1738 read in this call AND audiobuf_write < 128 */
1739 if (tagptr < 0)
1740 tagptr += audiobuflen;
1742 for(i = 0;i < 3;i++)
1744 if(tagptr >= audiobuflen)
1745 tagptr -= audiobuflen;
1747 if(mpeg_audiobuf[tagptr] != tag[i])
1749 taglen = 0;
1750 break;
1753 tagptr++;
1756 if(taglen)
1758 /* Skip id3v1 tag */
1759 DEBUGF("Skipping ID3v1 tag\n");
1760 len -= taglen;
1762 /* In the very rare case when the entire tag
1763 wasn't read in this read() len will be < 0.
1764 Take care of this when changing the write
1765 pointer. */
1769 audiobuf_write += len;
1771 if (audiobuf_write < 0)
1772 audiobuf_write += audiobuflen;
1774 if(audiobuf_write >= audiobuflen)
1776 audiobuf_write = 0;
1777 DEBUGF("W\n");
1780 /* Tell ourselves that we want more data */
1781 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1783 else
1785 if(len < 0)
1787 DEBUGF("MPEG read error\n");
1790 close(mpeg_file);
1791 mpeg_file = -1;
1793 if(new_file(1) < 0)
1795 /* No more data to play */
1796 DEBUGF("No more files to play\n");
1797 filling = false;
1799 else
1801 /* Tell ourselves that we want more data */
1802 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1806 break;
1808 case MPEG_TRACK_CHANGE:
1809 track_change();
1810 break;
1812 #ifndef USB_NONE
1813 case SYS_USB_CONNECTED:
1814 is_playing = false;
1815 paused = false;
1816 stop_playing();
1818 /* Tell the USB thread that we are safe */
1819 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1820 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1822 /* Wait until the USB cable is extracted again */
1823 usb_wait_for_disconnect(&mpeg_queue);
1824 break;
1825 #endif /* !USB_NONE */
1827 #if CONFIG_CODEC == MAS3587F
1828 case MPEG_INIT_RECORDING:
1829 init_recording();
1830 init_recording_done = true;
1831 break;
1832 #endif /* CONFIG_CODEC == MAS3587F */
1834 case SYS_TIMEOUT:
1835 if (playing)
1836 playlist_update_resume_info(audio_current_track());
1837 break;
1839 #if CONFIG_CODEC == MAS3587F
1841 else
1843 queue_wait(&mpeg_queue, &ev);
1844 switch(ev.id)
1846 case MPEG_RECORD:
1847 if (is_prerecording)
1849 int startpos;
1851 /* Go back prerecord_count seconds in the buffer */
1852 startpos = prerecord_index - prerecord_count;
1853 if(startpos < 0)
1854 startpos += prerecording_max_seconds;
1856 /* Read the position data from the prerecord buffer */
1857 frame_count_start = prerecord_buffer[startpos].framecount;
1858 startpos = prerecord_buffer[startpos].mempos;
1860 DEBUGF("Start looking at address %x (%x)\n",
1861 mpeg_audiobuf+startpos, startpos);
1863 saved_header = mpeg_get_last_header();
1865 mem_find_next_frame(startpos, &offset, 1800,
1866 saved_header, mpeg_audiobuf,
1867 audiobuflen);
1869 audiobuf_read = startpos + offset;
1870 if(audiobuf_read >= audiobuflen)
1871 audiobuf_read -= audiobuflen;
1873 DEBUGF("New audiobuf_read address: %x (%x)\n",
1874 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1876 level = disable_irq_save();
1877 num_rec_bytes = get_unsaved_space();
1878 restore_irq(level);
1880 else
1882 frame_count_start = 0;
1883 num_rec_bytes = 0;
1884 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1885 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1888 prepend_header();
1889 DEBUGF("Recording...\n");
1890 start_recording();
1892 /* Wait until at least one frame is encoded and get the
1893 frame header, for later use by the Xing header
1894 generation */
1895 sleep(HZ/5);
1896 saved_header = mpeg_get_last_header();
1898 /* delayed until buffer is saved, don't open yet */
1899 strcpy(delayed_filename, recording_filename);
1900 mpeg_file = -1;
1902 break;
1904 case MPEG_STOP:
1905 DEBUGF("MPEG_STOP\n");
1907 stop_recording();
1909 /* Save the remaining data in the buffer */
1910 save_endpos = audiobuf_write;
1911 saving_status = STOP_RECORDING;
1912 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1913 break;
1915 case MPEG_STOP_DONE:
1916 DEBUGF("MPEG_STOP_DONE\n");
1918 if (mpeg_file >= 0)
1919 close(mpeg_file);
1920 mpeg_file = -1;
1922 update_header();
1923 #ifdef DEBUG1
1925 int i;
1926 for(i = 0;i < 512;i++)
1928 DEBUGF("%d - %d us (%d bytes)\n",
1929 timing_info[i*2],
1930 (timing_info[i*2+1] & 0xffff) *
1931 10000 / 13824,
1932 timing_info[i*2+1] >> 16);
1935 #endif /* DEBUG1 */
1937 if (prerecording)
1939 start_prerecording();
1941 mpeg_stop_done = true;
1942 break;
1944 case MPEG_NEW_FILE:
1945 /* Bail out when a more important save is happening */
1946 if (saving_status > NEW_FILE)
1947 break;
1949 /* Make sure we have at least one complete frame
1950 in the buffer. If we haven't recorded a single
1951 frame within 200ms, the MAS is probably not recording
1952 anything, and we bail out. */
1953 amount_to_save = get_unsaved_space();
1954 if (amount_to_save < 1800)
1956 sleep(HZ/5);
1957 amount_to_save = get_unsaved_space();
1960 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1961 &frame_count_end, 1);
1963 last_rec_time = current_tick - record_start_time;
1964 record_start_time = current_tick;
1965 if (paused)
1966 pause_start_time = record_start_time;
1968 /* capture all values at one point */
1969 level = disable_irq_save();
1970 save_endpos = audiobuf_write;
1971 last_rec_bytes = num_rec_bytes;
1972 num_rec_bytes = 0;
1973 restore_irq(level);
1975 if (amount_to_save >= 1800)
1977 /* Now find a frame boundary to split at */
1978 save_endpos -= 1800;
1979 if (save_endpos < 0)
1980 save_endpos += audiobuflen;
1982 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1983 saved_header, mpeg_audiobuf,
1984 audiobuflen);
1985 if (!rc) /* No header found, save whole buffer */
1986 offset = 1800;
1988 save_endpos += offset;
1989 if (save_endpos >= audiobuflen)
1990 save_endpos -= audiobuflen;
1992 last_rec_bytes += offset - 1800;
1993 level = disable_irq_save();
1994 num_rec_bytes += 1800 - offset;
1995 restore_irq(level);
1998 saving_status = NEW_FILE;
1999 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2000 break;
2002 case MPEG_SAVE_DATA:
2003 if (saving_status == BUFFER_FULL)
2004 save_endpos = audiobuf_write;
2006 if (mpeg_file < 0) /* delayed file open */
2008 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
2010 if (mpeg_file < 0)
2011 panicf("recfile: %d", mpeg_file);
2014 amount_to_save = save_endpos - audiobuf_read;
2015 if (amount_to_save < 0)
2016 amount_to_save += audiobuflen;
2018 amount_to_save = MIN(amount_to_save,
2019 audiobuflen - audiobuf_read);
2020 #if (CONFIG_STORAGE & STORAGE_MMC)
2021 /* MMC is slow, so don't save too large chunks at once */
2022 amount_to_save = MIN(0x40000, amount_to_save);
2023 #elif MEMORYSIZE == 8
2024 amount_to_save = MIN(0x100000, amount_to_save);
2025 #endif
2026 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
2027 amount_to_save);
2028 if (rc < 0)
2030 if (errno == ENOSPC)
2032 mpeg_errno = AUDIOERR_DISK_FULL;
2033 stop_recording();
2034 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2035 /* will close the file */
2036 break;
2038 else
2039 panicf("rec wrt: %d", rc);
2042 audiobuf_read += amount_to_save;
2043 if (audiobuf_read >= audiobuflen)
2044 audiobuf_read = 0;
2046 if (audiobuf_read == save_endpos) /* all saved */
2048 switch (saving_status)
2050 case BUFFER_FULL:
2051 rc = fsync(mpeg_file);
2052 if (rc < 0)
2053 panicf("rec fls: %d", rc);
2054 storage_sleep();
2055 break;
2057 case NEW_FILE:
2058 /* Close the current file */
2059 rc = close(mpeg_file);
2060 if (rc < 0)
2061 panicf("rec cls: %d", rc);
2062 mpeg_file = -1;
2063 update_header();
2064 storage_sleep();
2066 /* copy new filename */
2067 strcpy(delayed_filename, recording_filename);
2068 prepend_header();
2069 frame_count_start = frame_count_end;
2070 break;
2072 case STOP_RECORDING:
2073 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2074 /* will close the file */
2075 break;
2077 default:
2078 break;
2080 saving_status = NOT_SAVING;
2082 else /* tell ourselves to save the next chunk */
2083 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2085 break;
2087 case MPEG_PRERECORDING_TICK:
2088 if(!is_prerecording)
2089 break;
2091 /* Store the write pointer every second */
2092 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2093 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2094 &prerecord_buffer[prerecord_index].framecount, 1);
2096 /* Wrap if necessary */
2097 if(++prerecord_index == prerecording_max_seconds)
2098 prerecord_index = 0;
2100 /* Update the number of seconds recorded */
2101 if(prerecord_count < prerecording_max_seconds)
2102 prerecord_count++;
2103 break;
2105 case MPEG_INIT_PLAYBACK:
2106 /* Stop the prerecording */
2107 stop_recording();
2108 reset_mp3_buffer();
2109 mp3_play_init();
2110 init_playback_done = true;
2111 break;
2113 case MPEG_PAUSE_RECORDING:
2114 pause_recording();
2115 break;
2117 case MPEG_RESUME_RECORDING:
2118 resume_recording();
2119 break;
2121 case SYS_USB_CONNECTED:
2122 /* We can safely go to USB mode if no recording
2123 is taking place */
2124 if((!is_recording || is_prerecording) && mpeg_stop_done)
2126 /* Even if we aren't recording, we still call this
2127 function, to put the MAS in monitoring mode,
2128 to save power. */
2129 stop_recording();
2131 /* Tell the USB thread that we are safe */
2132 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2133 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2135 /* Wait until the USB cable is extracted again */
2136 usb_wait_for_disconnect(&mpeg_queue);
2138 break;
2141 #endif /* CONFIG_CODEC == MAS3587F */
2144 #endif /* !SIMULATOR */
2146 struct mp3entry* audio_current_track(void)
2148 #ifdef SIMULATOR
2149 struct mp3entry *id3 = &taginfo;
2150 #else /* !SIMULATOR */
2151 if(num_tracks_in_memory())
2153 struct mp3entry *id3 = &get_trackdata(0)->id3;
2154 #endif
2155 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2157 checked_for_cuesheet = true; /* only check once per track */
2158 char cuepath[MAX_PATH];
2160 if (look_for_cuesheet_file(id3->path, cuepath) &&
2161 parse_cuesheet(cuepath, curr_cuesheet))
2163 id3->cuesheet = curr_cuesheet;
2166 return id3;
2167 #ifndef SIMULATOR
2169 else
2170 return NULL;
2171 #endif /* !SIMULATOR */
2174 struct mp3entry* audio_next_track(void)
2176 #ifdef SIMULATOR
2177 return &taginfo;
2178 #else /* !SIMULATOR */
2179 if(num_tracks_in_memory() > 1)
2180 return &get_trackdata(1)->id3;
2181 else
2182 return NULL;
2183 #endif /* !SIMULATOR */
2186 #if CONFIG_CODEC == MAS3587F
2187 #ifndef SIMULATOR
2188 void audio_init_playback(void)
2190 init_playback_done = false;
2191 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2193 while(!init_playback_done)
2194 sleep(1);
2198 /****************************************************************************
2199 * Recording functions
2200 ***************************************************************************/
2201 void audio_init_recording(void)
2203 init_recording_done = false;
2204 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2206 while(!init_recording_done)
2207 sleep(1);
2210 static void init_recording(void)
2212 unsigned long val;
2213 int rc;
2215 /* Disable IRQ6 */
2216 IPRB &= 0xff0f;
2218 stop_playing();
2219 is_playing = false;
2220 paused = false;
2222 /* Init the recording variables */
2223 is_recording = false;
2224 is_prerecording = false;
2226 mpeg_stop_done = true;
2228 mas_reset();
2230 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2231 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2232 if(rc < 0)
2233 panicf("mas_ctrl_w: %d", rc);
2235 /* Stop the current application */
2236 val = 0;
2237 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2240 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2241 } while(val);
2243 /* Perform black magic as described by the data sheet */
2244 if((mas_version_code & 0x0fff) == 0x0102)
2246 DEBUGF("Performing MAS black magic for B2 version\n");
2247 mas_writereg(0xa3, 0x98);
2248 mas_writereg(0x94, 0xfffff);
2249 val = 0;
2250 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2251 mas_writereg(0xa3, 0x90);
2254 /* Enable A/D Converters */
2255 shadow_codec_reg0 = 0xcccd;
2256 mas_codec_writereg(0x0, shadow_codec_reg0);
2258 /* Copy left channel to right (mono mode) */
2259 mas_codec_writereg(8, 0x8000);
2261 /* ADC scale 0%, DSP scale 100%
2262 We use the DSP output for monitoring, because it works with all
2263 sources including S/PDIF */
2264 mas_codec_writereg(6, 0x0000);
2265 mas_codec_writereg(7, 0x4000);
2267 /* No mute */
2268 shadow_soft_mute = 0;
2269 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2271 #ifdef HAVE_SPDIF_OUT
2272 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2273 #else
2274 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2275 #endif
2276 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2278 /* Set Demand mode, monitoring OFF and validate all settings */
2279 shadow_io_control_main = 0x125;
2280 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2282 /* Start the encoder application */
2283 val = 0x40;
2284 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2287 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2288 } while(!(val & 0x40));
2290 /* We have started the recording application with monitoring OFF.
2291 This is because we want to record at least one frame to fill the DMA
2292 buffer, because the silly MAS will not negate EOD until at least one
2293 DMA transfer has taken place.
2294 Now let's wait for some data to be encoded. */
2295 sleep(HZ/5);
2297 /* Now set it to Monitoring mode as default, saves power */
2298 shadow_io_control_main = 0x525;
2299 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2301 /* Wait until the DSP has accepted the settings */
2304 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2305 } while(val & 1);
2307 drain_dma_buffer();
2308 mpeg_mode = MPEG_ENCODER;
2310 DEBUGF("MAS Recording application started\n");
2312 /* At this point, all settings are the reset MAS defaults, next thing is to
2313 call mpeg_set_recording_options(). */
2316 void audio_record(const char *filename)
2318 mpeg_errno = 0;
2320 strlcpy(recording_filename, filename, MAX_PATH);
2322 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2325 void audio_pause_recording(void)
2327 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2330 void audio_resume_recording(void)
2332 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2335 static void prepend_header(void)
2337 int startpos;
2338 unsigned i;
2340 /* Make room for header */
2341 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2342 if(audiobuf_read < 0)
2344 /* Clear the bottom half */
2345 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2347 /* And the top half */
2348 audiobuf_read += audiobuflen;
2349 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2351 else
2353 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2355 /* Copy the empty ID3 header */
2356 startpos = audiobuf_read;
2357 for(i = 0; i < sizeof(empty_id3_header); i++)
2359 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2360 if(startpos == audiobuflen)
2361 startpos = 0;
2365 static void update_header(void)
2367 int fd, framelen;
2368 unsigned long frames;
2370 if (last_rec_bytes > 0)
2372 /* Create the Xing header */
2373 fd = open(delayed_filename, O_RDWR);
2374 if (fd < 0)
2375 panicf("rec upd: %d (%s)", fd, recording_filename);
2377 frames = frame_count_end - frame_count_start;
2378 /* If the number of recorded frames has reached 0x7ffff,
2379 we can no longer trust it */
2380 if (frame_count_end == 0x7ffff)
2381 frames = 0;
2383 /* saved_header is saved right before stopping the MAS */
2384 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2385 frames, last_rec_time * (1000/HZ),
2386 saved_header, NULL, false,
2387 mpeg_audiobuf, audiobuflen);
2389 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2390 write(fd, xing_buffer, framelen);
2391 close(fd);
2395 static void start_prerecording(void)
2397 unsigned long val;
2399 DEBUGF("Starting prerecording\n");
2401 prerecord_index = 0;
2402 prerecord_count = 0;
2403 prerecord_timeout = current_tick + HZ;
2404 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2405 reset_mp3_buffer();
2407 is_prerecording = true;
2409 /* Stop monitoring and start the encoder */
2410 shadow_io_control_main &= ~(1 << 10);
2411 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2412 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2414 /* Wait until the DSP has accepted the settings */
2417 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2418 } while(val & 1);
2420 is_recording = true;
2421 saving_status = NOT_SAVING;
2423 demand_irq_enable(true);
2426 static void start_recording(void)
2428 unsigned long val;
2430 if(is_prerecording)
2432 /* This will make the IRQ handler start recording
2433 for real, i.e send MPEG_SAVE_DATA messages when
2434 the buffer is full */
2435 is_prerecording = false;
2437 else
2439 /* If prerecording is off, we need to stop the monitoring
2440 and start the encoder */
2441 shadow_io_control_main &= ~(1 << 10);
2442 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2443 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2445 /* Wait until the DSP has accepted the settings */
2448 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2449 } while(val & 1);
2452 is_recording = true;
2453 saving_status = NOT_SAVING;
2454 paused = false;
2456 /* Store the current time */
2457 if(prerecording)
2458 record_start_time = current_tick - prerecord_count * HZ;
2459 else
2460 record_start_time = current_tick;
2462 pause_start_time = 0;
2464 demand_irq_enable(true);
2467 static void pause_recording(void)
2469 pause_start_time = current_tick;
2471 /* Set the pause bit */
2472 shadow_soft_mute |= 2;
2473 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2475 paused = true;
2478 static void resume_recording(void)
2480 paused = false;
2482 /* Clear the pause bit */
2483 shadow_soft_mute &= ~2;
2484 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2486 /* Compensate for the time we have been paused */
2487 if(pause_start_time)
2489 record_start_time =
2490 current_tick - (pause_start_time - record_start_time);
2491 pause_start_time = 0;
2495 static void stop_recording(void)
2497 unsigned long val;
2499 /* Let it finish the last frame */
2500 if(!paused)
2501 pause_recording();
2502 sleep(HZ/5);
2504 demand_irq_enable(false);
2506 is_recording = false;
2507 is_prerecording = false;
2509 last_rec_bytes = num_rec_bytes;
2510 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2511 last_rec_time = current_tick - record_start_time;
2513 /* Start monitoring */
2514 shadow_io_control_main |= (1 << 10);
2515 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2516 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2518 /* Wait until the DSP has accepted the settings */
2521 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2522 } while(val & 1);
2524 resume_recording();
2527 void audio_set_recording_options(struct audio_recording_options *options)
2529 bool is_mpeg1;
2531 is_mpeg1 = (options->rec_frequency < 3);
2533 rec_version_index = is_mpeg1?3:2;
2534 rec_frequency_index = options->rec_frequency % 3;
2536 shadow_encoder_control = (options->rec_quality << 17) |
2537 (rec_frequency_index << 10) |
2538 ((is_mpeg1?1:0) << 9) |
2539 (((options->rec_channels * 2 + 1) & 3) << 6) |
2540 (1 << 5) /* MS-stereo */ |
2541 (1 << 2) /* Is an original */;
2542 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2544 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2546 #if CONFIG_TUNER & S1A0903X01
2547 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2548 interference with the Samsung tuner. */
2549 if (rec_frequency_index)
2550 mas_store_pllfreq(24576000);
2551 else
2552 mas_store_pllfreq(22579000);
2553 #endif
2555 shadow_soft_mute = options->rec_editable?4:0;
2556 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2558 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2560 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2561 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2562 (1 << 5) | /* SDO strobe invert */
2563 ((is_mpeg1?0:1) << 3) |
2564 (1 << 2) | /* Inverted SIBC clock signal */
2565 1; /* Validate */
2566 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2568 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2570 if(options->rec_source == AUDIO_SRC_MIC)
2572 /* Copy left channel to right (mono mode) */
2573 mas_codec_writereg(8, 0x8000);
2575 else
2577 /* Stereo input mode */
2578 mas_codec_writereg(8, 0);
2581 prerecording_max_seconds = options->rec_prerecord_time;
2582 if(prerecording_max_seconds)
2584 prerecording = true;
2585 start_prerecording();
2587 else
2589 prerecording = false;
2590 is_prerecording = false;
2591 is_recording = false;
2595 /* If use_mic is true, the left gain is used */
2596 void audio_set_recording_gain(int left, int right, int type)
2598 /* Enable both left and right A/D */
2599 shadow_codec_reg0 = (left << 12) |
2600 (right << 8) |
2601 (left << 4) |
2602 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2603 0x0007;
2604 mas_codec_writereg(0x0, shadow_codec_reg0);
2607 /* try to make some kind of beep, also in recording mode */
2608 void audio_beep(int duration)
2610 long starttick = current_tick;
2612 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2613 * While this is still audible even without an external signal,
2614 * it doesn't affect the (pre-)recording. */
2615 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2616 mas_codec_writereg(0, shadow_codec_reg0);
2617 yield();
2619 while (current_tick - starttick < duration);
2622 void audio_new_file(const char *filename)
2624 mpeg_errno = 0;
2626 strlcpy(recording_filename, filename, MAX_PATH);
2628 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2631 unsigned long audio_recorded_time(void)
2633 if(is_prerecording)
2634 return prerecord_count * HZ;
2636 if(is_recording)
2638 if(paused)
2639 return pause_start_time - record_start_time;
2640 else
2641 return current_tick - record_start_time;
2644 return 0;
2647 unsigned long audio_num_recorded_bytes(void)
2649 int num_bytes;
2650 int index;
2652 if(is_recording)
2654 if(is_prerecording)
2656 index = prerecord_index - prerecord_count;
2657 if(index < 0)
2658 index += prerecording_max_seconds;
2660 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2661 if(num_bytes < 0)
2662 num_bytes += audiobuflen;
2664 return num_bytes;
2666 else
2667 return num_rec_bytes;
2669 else
2670 return 0;
2673 #else /* SIMULATOR */
2675 /* dummies coming up */
2677 void audio_init_playback(void)
2679 /* a dummy */
2681 unsigned long audio_recorded_time(void)
2683 /* a dummy */
2684 return 0;
2686 void audio_beep(int duration)
2688 /* a dummy */
2689 (void)duration;
2691 void audio_pause_recording(void)
2693 /* a dummy */
2695 void audio_resume_recording(void)
2697 /* a dummy */
2699 unsigned long audio_num_recorded_bytes(void)
2701 /* a dummy */
2702 return 0;
2704 void audio_record(const char *filename)
2706 /* a dummy */
2707 (void)filename;
2709 void audio_new_file(const char *filename)
2711 /* a dummy */
2712 (void)filename;
2715 void audio_set_recording_gain(int left, int right, int type)
2717 /* a dummy */
2718 (void)left;
2719 (void)right;
2720 (void)type;
2722 void audio_init_recording(void)
2724 /* a dummy */
2726 void audio_set_recording_options(struct audio_recording_options *options)
2728 /* a dummy */
2729 (void)options;
2731 #endif /* SIMULATOR */
2732 #endif /* CONFIG_CODEC == MAS3587F */
2734 size_t audio_buffer_available(void)
2736 if (audiobuf_handle > 0)
2737 return audiobuflen;
2738 return core_available();
2741 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize)
2743 talk_buffer_steal(); /* will use the mp3 buffer */
2744 mpeg_audiobuf = buf;
2745 audiobuflen = bufsize;
2746 if (global_settings.cuesheet)
2747 { /* enable cuesheet support */
2748 curr_cuesheet = (struct cuesheet*)mpeg_audiobuf;
2749 mpeg_audiobuf = SKIPBYTES(mpeg_audiobuf, sizeof(struct cuesheet));
2750 audiobuflen -= sizeof(struct cuesheet);
2752 talkbuf_init(mpeg_audiobuf);
2755 static void audio_reset_buffer(void)
2757 size_t bufsize = audiobuflen;
2759 /* alloc buffer if it's was never allocated or freed by audio_hard_stop() */
2760 if (!audiobuf_handle)
2761 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
2763 audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize);
2766 void audio_play(long offset)
2768 audio_reset_buffer();
2769 #ifdef SIMULATOR
2770 char name_buf[MAX_PATH+1];
2771 const char* trackname;
2772 int steps=0;
2774 is_playing = true;
2776 do {
2777 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2778 if (!trackname)
2779 break;
2780 if(mp3info(&taginfo, trackname)) {
2781 /* bad mp3, move on */
2782 if(++steps > playlist_amount())
2783 break;
2784 continue;
2786 #ifdef HAVE_MPEG_PLAY
2787 real_mpeg_play(trackname);
2788 #endif
2789 playlist_next(steps);
2790 taginfo.offset = offset;
2791 set_elapsed(&taginfo);
2792 is_playing = true;
2793 playing = true;
2794 break;
2795 } while(1);
2796 #else /* !SIMULATOR */
2797 is_playing = true;
2798 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2799 #endif /* !SIMULATOR */
2801 mpeg_errno = 0;
2804 void audio_stop(void)
2806 #ifndef SIMULATOR
2807 if (playing)
2809 struct trackdata *track = get_trackdata(0);
2810 prev_track_elapsed = track->id3.elapsed;
2812 mpeg_stop_done = false;
2813 queue_post(&mpeg_queue, MPEG_STOP, 0);
2814 while(!mpeg_stop_done)
2815 yield();
2816 #else /* SIMULATOR */
2817 paused = false;
2818 is_playing = false;
2819 playing = false;
2820 #endif /* SIMULATOR */
2821 /* give voice our entire buffer */
2822 talkbuf_init(mpeg_audiobuf);
2825 /* dummy */
2826 void audio_stop_recording(void)
2828 audio_stop();
2831 void audio_hard_stop(void)
2833 audio_stop();
2834 /* tell voice we obtain the buffer before freeing */
2835 talk_buffer_steal();
2836 if (audiobuf_handle > 0)
2838 audiobuf_handle = core_free(audiobuf_handle);
2839 mpeg_audiobuf = NULL;
2843 void audio_pause(void)
2845 #ifndef SIMULATOR
2846 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2847 #else /* SIMULATOR */
2848 is_playing = true;
2849 playing = false;
2850 paused = true;
2851 #endif /* SIMULATOR */
2854 void audio_resume(void)
2856 #ifndef SIMULATOR
2857 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2858 #else /* SIMULATOR */
2859 is_playing = true;
2860 playing = true;
2861 paused = false;
2862 #endif /* SIMULATOR */
2865 void audio_next(void)
2867 #ifndef SIMULATOR
2868 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2869 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2870 #else /* SIMULATOR */
2871 char name_buf[MAX_PATH+1];
2872 const char* file;
2873 int steps = 1;
2875 do {
2876 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2877 if(!file)
2878 break;
2879 if(mp3info(&taginfo, file)) {
2880 if(++steps > playlist_amount())
2881 break;
2882 continue;
2884 playlist_next(steps);
2885 current_track_counter++;
2886 is_playing = true;
2887 playing = true;
2888 break;
2889 } while(1);
2890 #endif /* SIMULATOR */
2893 void audio_prev(void)
2895 #ifndef SIMULATOR
2896 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2897 queue_post(&mpeg_queue, MPEG_PREV, 0);
2898 #else /* SIMULATOR */
2899 char name_buf[MAX_PATH+1];
2900 const char* file;
2901 int steps = -1;
2903 do {
2904 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2905 if(!file)
2906 break;
2907 if(mp3info(&taginfo, file)) {
2908 steps--;
2909 continue;
2911 playlist_next(steps);
2912 current_track_counter++;
2913 is_playing = true;
2914 playing = true;
2915 break;
2916 } while(1);
2917 #endif /* SIMULATOR */
2920 void audio_ff_rewind(long newpos)
2922 #ifndef SIMULATOR
2923 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2924 #else /* SIMULATOR */
2925 (void)newpos;
2926 #endif /* SIMULATOR */
2929 void audio_flush_and_reload_tracks(void)
2931 #ifndef SIMULATOR
2932 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2933 #endif /* !SIMULATOR*/
2936 int audio_status(void)
2938 int ret = 0;
2940 if(is_playing)
2941 ret |= AUDIO_STATUS_PLAY;
2943 if(paused)
2944 ret |= AUDIO_STATUS_PAUSE;
2946 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2947 if(is_recording && !is_prerecording)
2948 ret |= AUDIO_STATUS_RECORD;
2950 if(is_prerecording)
2951 ret |= AUDIO_STATUS_PRERECORD;
2952 #endif /* CONFIG_CODEC == MAS3587F */
2954 if(mpeg_errno)
2955 ret |= AUDIO_STATUS_ERROR;
2957 return ret;
2960 /* Unused function
2961 unsigned int audio_error(void)
2963 return mpeg_errno;
2967 void audio_error_clear(void)
2969 mpeg_errno = 0;
2972 #ifdef SIMULATOR
2973 static void mpeg_thread(void)
2975 struct mp3entry* id3;
2976 while ( 1 ) {
2977 if (is_playing) {
2978 id3 = audio_current_track();
2979 if (!paused)
2981 id3->elapsed+=1000;
2982 id3->offset+=1000;
2984 if (id3->elapsed>=id3->length)
2985 audio_next();
2987 sleep(HZ);
2990 #endif /* SIMULATOR */
2992 void audio_init(void)
2994 mpeg_errno = 0;
2996 talk_init();
2997 audio_reset_buffer();
2999 #ifndef SIMULATOR
3000 queue_init(&mpeg_queue, true);
3001 #endif /* !SIMULATOR */
3002 audio_thread_id = create_thread(mpeg_thread, mpeg_stack,
3003 sizeof(mpeg_stack), 0, mpeg_thread_name
3004 IF_PRIO(, PRIORITY_SYSTEM)
3005 IF_COP(, CPU));
3007 memset(trackdata, 0, sizeof(trackdata));
3009 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
3010 if (HW_MASK & PR_ACTIVE_HIGH)
3011 and_b(~0x08, &PADRH);
3012 else
3013 or_b(0x08, &PADRH);
3014 #endif /* CONFIG_CODEC == MAS3587F */
3016 #ifdef DEBUG
3017 #ifndef SIMULATOR
3018 dbg_timer_start();
3019 dbg_cnt2us(0);
3020 #endif /* !SIMULATOR */
3021 #endif /* DEBUG */
3022 audio_is_initialized = true;
3025 #endif /* CONFIG_CODEC != SWCODEC */