Rockbox Utility: make the window icon also include a larger one.
[maemo-rb.git] / apps / mpeg.c
blob2a2821bcdac59c2e5d5c3ef09b9ac30c0b7b486a
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 unsigned int mpeg_errno;
147 static bool playing = false; /* We are playing an MP3 stream */
148 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
149 static bool paused; /* playback is paused */
150 static int audiobuf_handle; /* handle to the audio buffer */
151 static char* mpeg_audiobuf; /* poiunter to the audio buffer */
152 static long audiobuflen; /* length of the audio buffer */
154 #ifdef SIMULATOR
155 static char mpeg_stack[DEFAULT_STACK_SIZE];
156 static struct mp3entry taginfo;
157 #else /* !SIMULATOR */
158 static struct event_queue mpeg_queue SHAREDBSS_ATTR;
159 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
161 static int audiobuf_write;
162 static int audiobuf_swapwrite;
163 static long audiobuf_read;
165 static int mpeg_file;
167 static bool play_pending; /* We are about to start playing */
168 static bool play_pending_track_change; /* When starting play we're starting a new file */
169 static bool filling; /* We are filling the buffer with data from disk */
170 static bool dma_underrun; /* True when the DMA has stopped because of
171 slow disk reading (read error, shaking) */
172 static bool mpeg_stop_done;
174 static int last_dma_tick = 0;
175 static int last_dma_chunk_size;
177 static long low_watermark; /* Dynamic low watermark level */
178 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
179 static long lowest_watermark_level; /* Debug value to observe the buffer
180 usage */
181 #if CONFIG_CODEC == MAS3587F
182 static char recording_filename[MAX_PATH]; /* argument to thread */
183 static char delayed_filename[MAX_PATH]; /* internal copy of above */
185 static char xing_buffer[MAX_XING_HEADER_SIZE];
187 static bool init_recording_done;
188 static bool init_playback_done;
189 static bool prerecording; /* True if prerecording is enabled */
190 static bool is_prerecording; /* True if we are prerecording */
191 static bool is_recording; /* We are recording */
193 static enum {
194 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
195 BUFFER_FULL,
196 NEW_FILE,
197 STOP_RECORDING
198 } saving_status;
200 static int rec_frequency_index; /* For create_xing_header() calls */
201 static int rec_version_index; /* For create_xing_header() calls */
203 struct prerecord_info {
204 int mempos;
205 unsigned long framecount;
208 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
209 static int prerecord_index; /* Current index in the prerecord buffer */
210 static int prerecording_max_seconds; /* Max number of seconds to store */
211 static int prerecord_count; /* Number of seconds in the prerecord buffer */
212 static int prerecord_timeout; /* The tick count of the next prerecord data
213 store */
215 static unsigned long record_start_time; /* Value of current_tick when recording
216 was started */
217 static unsigned long pause_start_time; /* Value of current_tick when pause was
218 started */
219 static unsigned long last_rec_time;
220 static unsigned long num_rec_bytes;
221 static unsigned long last_rec_bytes;
222 static unsigned long frame_count_start;
223 static unsigned long frame_count_end;
224 static unsigned long saved_header = 0;
226 /* Shadow MAS registers */
227 unsigned long shadow_encoder_control = 0;
228 #endif /* CONFIG_CODEC == MAS3587F */
230 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
231 unsigned long shadow_io_control_main = 0;
232 unsigned long shadow_soft_mute = 0;
233 unsigned shadow_codec_reg0;
234 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
236 #ifdef HAVE_RECORDING
237 static const unsigned char empty_id3_header[] =
239 'I', 'D', '3', 0x03, 0x00, 0x00,
240 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
242 #endif /* HAVE_RECORDING */
245 static int get_unplayed_space(void);
246 static int get_playable_space(void);
247 static int get_unswapped_space(void);
248 #endif /* !SIMULATOR */
250 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
251 static void init_recording(void);
252 static void prepend_header(void);
253 static void update_header(void);
254 static void start_prerecording(void);
255 static void start_recording(void);
256 static void stop_recording(void);
257 static int get_unsaved_space(void);
258 static void pause_recording(void);
259 static void resume_recording(void);
260 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
263 #ifndef SIMULATOR
264 static int num_tracks_in_memory(void)
266 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
269 #ifdef DEBUG_TAGS
270 static void debug_tags(void)
272 int i;
274 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
276 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
278 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
279 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
281 #else /* !DEBUG_TAGS */
282 #define debug_tags()
283 #endif /* !DEBUG_TAGS */
285 static void remove_current_tag(void)
287 if(num_tracks_in_memory() > 0)
289 /* First move the index, so nobody tries to access the tag */
290 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
291 checked_for_cuesheet = false;
292 debug_tags();
294 else
296 DEBUGF("remove_current_tag: no tracks to remove\n");
300 static void remove_all_non_current_tags(void)
302 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
303 debug_tags();
306 static void remove_all_tags(void)
308 track_write_idx = track_read_idx;
310 debug_tags();
313 static struct trackdata *get_trackdata(int offset)
315 if(offset >= num_tracks_in_memory())
316 return NULL;
317 else
318 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
320 #endif /* !SIMULATOR */
322 /***********************************************************************/
323 /* audio event handling */
325 #define MAX_EVENT_HANDLERS 10
326 struct event_handlers_table
328 AUDIO_EVENT_HANDLER handler;
329 unsigned short mask;
331 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
332 static int event_handlers_count = 0;
334 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
336 if (event_handlers_count < MAX_EVENT_HANDLERS)
338 event_handlers[event_handlers_count].handler = handler;
339 event_handlers[event_handlers_count].mask = mask;
340 event_handlers_count++;
344 /* dispatch calls each handler in the order registered and returns after some
345 handler actually handles the event (the event is assumed to no longer be valid
346 after this, due to the handler changing some condition); returns true if someone
347 handled the event, which is expected to cause the caller to skip its own handling
348 of the event */
349 #ifndef SIMULATOR
350 static bool audio_dispatch_event(unsigned short event, unsigned long data)
352 int i = 0;
353 for(i=0; i < event_handlers_count; i++)
355 if ( event_handlers[i].mask & event )
357 int rc = event_handlers[i].handler(event, data);
358 if ( rc == AUDIO_EVENT_RC_HANDLED )
359 return true;
362 return false;
364 #endif
366 /***********************************************************************/
368 static void set_elapsed(struct mp3entry* id3)
370 if ( id3->vbr ) {
371 if ( id3->has_toc ) {
372 /* calculate elapsed time using TOC */
373 int i;
374 unsigned int remainder, plen, relpos, nextpos;
376 /* find wich percent we're at */
377 for (i=0; i<100; i++ )
379 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
381 break;
385 i--;
386 if (i < 0)
387 i = 0;
389 relpos = id3->toc[i];
391 if (i < 99)
393 nextpos = id3->toc[i+1];
395 else
397 nextpos = 256;
400 remainder = id3->offset - (relpos * (id3->filesize / 256));
402 /* set time for this percent (divide before multiply to prevent
403 overflow on long files. loss of precision is negligible on
404 short files) */
405 id3->elapsed = i * (id3->length / 100);
407 /* calculate remainder time */
408 plen = (nextpos - relpos) * (id3->filesize / 256);
409 id3->elapsed += (((remainder * 100) / plen) *
410 (id3->length / 10000));
412 else {
413 /* no TOC exists. set a rough estimate using average bitrate */
414 int tpk = id3->length / (id3->filesize / 1024);
415 id3->elapsed = id3->offset / 1024 * tpk;
418 else
419 /* constant bitrate, use exact calculation */
420 id3->elapsed = id3->offset / (id3->bitrate / 8);
423 int audio_get_file_pos(void)
425 int pos = -1;
426 struct mp3entry *id3 = audio_current_track();
428 if (id3->vbr)
430 if (id3->has_toc)
432 /* Use the TOC to find the new position */
433 unsigned int percent, remainder;
434 int curtoc, nexttoc, plen;
436 percent = (id3->elapsed*100)/id3->length;
437 if (percent > 99)
438 percent = 99;
440 curtoc = id3->toc[percent];
442 if (percent < 99)
443 nexttoc = id3->toc[percent+1];
444 else
445 nexttoc = 256;
447 pos = (id3->filesize/256)*curtoc;
449 /* Use the remainder to get a more accurate position */
450 remainder = (id3->elapsed*100)%id3->length;
451 remainder = (remainder*100)/id3->length;
452 plen = (nexttoc - curtoc)*(id3->filesize/256);
453 pos += (plen/100)*remainder;
455 else
457 /* No TOC exists, estimate the new position */
458 pos = (id3->filesize / (id3->length / 1000)) *
459 (id3->elapsed / 1000);
462 else if (id3->bitrate)
463 pos = id3->elapsed * (id3->bitrate / 8);
464 else
466 return -1;
469 if (pos >= (int)(id3->filesize - id3->id3v1len))
471 /* Don't seek right to the end of the file so that we can
472 transition properly to the next song */
473 pos = id3->filesize - id3->id3v1len - 1;
475 else if (pos < (int)id3->first_frame_offset)
477 /* skip past id3v2 tag and other leading garbage */
478 pos = id3->first_frame_offset;
480 return pos;
483 unsigned long mpeg_get_last_header(void)
485 #ifdef SIMULATOR
486 return 0;
487 #else /* !SIMULATOR */
488 unsigned long tmp[2];
490 /* Read the frame data from the MAS and reconstruct it with the
491 frame sync and all */
492 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
493 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
494 #endif /* !SIMULATOR */
497 static void do_stop(void)
499 is_playing = false;
500 paused = false;
502 #ifndef SIMULATOR
503 if (playing)
504 playlist_update_resume_info(audio_current_track());
506 stop_playing();
507 mpeg_stop_done = true;
508 #else
509 playing = false;
510 #endif
513 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize);
514 /* Buffer must not move. */
515 static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
517 long offset = audio_current_track()->offset;
518 int status = audio_status();
519 /* TODO: Do it without stopping playback, if possible */
520 /* don't call audio_hard_stop() as it frees this handle */
521 if (thread_self() == audio_thread_id)
522 { /* inline case MPEG_STOP (audio_stop()) response
523 * if we're in the audio thread since audio_stop() otherwise deadlocks */
524 do_stop();
526 else
527 audio_stop();
528 talk_buffer_steal(); /* we obtain control over the buffer */
530 /* we should be free to change the buffer now */
531 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
532 ssize_t size = (ssize_t)old_size - wanted_size;
533 switch (hints & BUFLIB_SHRINK_POS_MASK)
535 case BUFLIB_SHRINK_POS_BACK:
536 core_shrink(handle, start, size);
537 audio_reset_buffer_noalloc(start, size);
538 break;
539 case BUFLIB_SHRINK_POS_FRONT:
540 core_shrink(handle, start + wanted_size, size);
541 audio_reset_buffer_noalloc(start + wanted_size, size);
542 break;
544 if (!(status & AUDIO_STATUS_PAUSE))
545 { /* safe to call even from the audio thread (due to queue_post()) */
546 audio_play(offset);
549 return BUFLIB_CB_OK;
552 static struct buflib_callbacks ops = {
553 .move_callback = NULL,
554 .shrink_callback = shrink_callback,
557 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
559 (void)talk_buf; /* always grab the voice buffer for now */
561 if (buffer_size) /* special case for talk_init() */
562 audio_hard_stop();
564 if (!audiobuf_handle)
566 size_t bufsize;
567 /* audio_hard_stop() frees audiobuf, so re-aquire */
568 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
569 audiobuflen = bufsize;
570 if (buffer_size)
571 *buffer_size = audiobuflen;
573 mpeg_audiobuf = core_get_data(audiobuf_handle);
575 if (!buffer_size) /* special case for talk_init() */
576 talkbuf_init(mpeg_audiobuf);
578 return mpeg_audiobuf;
582 #ifndef SIMULATOR
583 /* Send callback events to notify about removing old tracks. */
584 static void generate_unbuffer_events(void)
586 int i;
587 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
588 int cur_idx = track_write_idx;
590 for (i = 0; i < numentries; i++)
592 /* Send an event to notify that track has finished. */
593 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
594 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
598 /* Send callback events to notify about new tracks. */
599 static void generate_postbuffer_events(void)
601 int i;
602 int numentries = num_tracks_in_memory();
603 int cur_idx = track_read_idx;
605 for (i = 0; i < numentries; i++)
607 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
608 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
612 static void recalculate_watermark(int bitrate)
614 int bytes_per_sec;
615 int time = storage_spinup_time();
617 /* A bitrate of 0 probably means empty VBR header. We play safe
618 and set a high threshold */
619 if(bitrate == 0)
620 bitrate = 320;
622 bytes_per_sec = bitrate * 1000 / 8;
624 if(time)
626 /* No drive spins up faster than 3.5s */
627 if(time < 350)
628 time = 350;
630 time = time * 3;
631 low_watermark = ((low_watermark_margin * HZ + time) *
632 bytes_per_sec) / HZ;
634 else
636 low_watermark = MPEG_LOW_WATER;
640 #ifdef HAVE_DISK_STORAGE
641 void audio_set_buffer_margin(int setting)
643 low_watermark_margin = setting; /* in seconds */
645 #endif
647 void audio_get_debugdata(struct audio_debug *dbgdata)
649 dbgdata->audiobuflen = audiobuflen;
650 dbgdata->audiobuf_write = audiobuf_write;
651 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
652 dbgdata->audiobuf_read = audiobuf_read;
654 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
656 #if CONFIG_CPU == SH7034
657 dbgdata->dma_on = (SCR0 & 0x80) != 0;
658 #endif
659 dbgdata->playing = playing;
660 dbgdata->play_pending = play_pending;
661 dbgdata->is_playing = is_playing;
662 dbgdata->filling = filling;
663 dbgdata->dma_underrun = dma_underrun;
665 dbgdata->unplayed_space = get_unplayed_space();
666 dbgdata->playable_space = get_playable_space();
667 dbgdata->unswapped_space = get_unswapped_space();
669 dbgdata->low_watermark_level = low_watermark;
670 dbgdata->lowest_watermark_level = lowest_watermark_level;
673 #ifdef DEBUG
674 static void dbg_timer_start(void)
676 /* We are using timer 2 */
678 TSTR &= ~0x04; /* Stop the timer */
679 TSNC &= ~0x04; /* No synchronization */
680 TMDR &= ~0x44; /* Operate normally */
682 TCNT2 = 0; /* Start counting at 0 */
683 TCR2 = 0x03; /* Sysclock/8 */
685 TSTR |= 0x04; /* Start timer 2 */
688 static int dbg_cnt2us(unsigned int cnt)
690 return (cnt * 10000) / (FREQ/800);
692 #endif /* DEBUG */
694 static int get_unplayed_space(void)
696 int space = audiobuf_write - audiobuf_read;
697 if (space < 0)
698 space += audiobuflen;
699 return space;
702 static int get_playable_space(void)
704 int space = audiobuf_swapwrite - audiobuf_read;
705 if (space < 0)
706 space += audiobuflen;
707 return space;
710 static int get_unplayed_space_current_song(void)
712 int space;
714 if (num_tracks_in_memory() > 1)
716 space = get_trackdata(1)->mempos - audiobuf_read;
718 else
720 space = audiobuf_write - audiobuf_read;
723 if (space < 0)
724 space += audiobuflen;
726 return space;
729 static int get_unswapped_space(void)
731 int space = audiobuf_write - audiobuf_swapwrite;
732 if (space < 0)
733 space += audiobuflen;
734 return space;
737 #if CONFIG_CODEC == MAS3587F
738 static int get_unsaved_space(void)
740 int space = audiobuf_write - audiobuf_read;
741 if (space < 0)
742 space += audiobuflen;
743 return space;
746 static void drain_dma_buffer(void)
748 while (PBDRH & 0x40)
750 xor_b(0x08, &PADRH);
752 while (PBDRH & 0x80);
754 xor_b(0x08, &PADRH);
756 while (!(PBDRH & 0x80));
760 #ifdef DEBUG
761 static long timing_info_index = 0;
762 static long timing_info[1024];
763 #endif /* DEBUG */
765 void rec_tick (void) __attribute__ ((section (".icode")));
766 void rec_tick(void)
768 int i;
769 int delay;
770 char data;
772 if(is_recording && (PBDRH & 0x40))
774 #ifdef DEBUG
775 timing_info[timing_info_index++] = current_tick;
776 TCNT2 = 0;
777 #endif /* DEBUG */
778 /* Note: Although this loop is run in interrupt context, further
779 * optimisation will do no good. The MAS would then deliver bad
780 * frames occasionally, as observed in extended experiments. */
781 i = 0;
782 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
784 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
786 delay = 100;
787 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
789 if (--delay <= 0) /* Bail out if we have to wait too long */
790 { /* i.e. the MAS doesn't want to talk to us */
791 xor_b(0x08, &PADRH); /* Set PR inactive */
792 goto transfer_end; /* and get out of here */
796 data = *(unsigned char *)0x04000000; /* read data byte */
798 xor_b(0x08, &PADRH); /* Set PR inactive */
800 mpeg_audiobuf[audiobuf_write++] = data;
802 if (audiobuf_write >= audiobuflen)
803 audiobuf_write = 0;
805 i++;
807 transfer_end:
809 #ifdef DEBUG
810 timing_info[timing_info_index++] = TCNT2 + (i << 16);
811 timing_info_index &= 0x3ff;
812 #endif /* DEBUG */
814 num_rec_bytes += i;
816 if(is_prerecording)
818 if(TIME_AFTER(current_tick, prerecord_timeout))
820 prerecord_timeout = current_tick + HZ;
821 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
824 else
826 /* Signal to save the data if we are running out of buffer
827 space */
828 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
829 && saving_status == NOT_SAVING)
831 saving_status = BUFFER_FULL;
832 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
837 #endif /* CONFIG_CODEC == MAS3587F */
839 void playback_tick(void)
841 struct trackdata *ptd = get_trackdata(0);
842 if(ptd)
844 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
845 last_dma_tick = current_tick;
846 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
847 (unsigned long)ptd->id3.elapsed);
851 static void reset_mp3_buffer(void)
853 audiobuf_read = 0;
854 audiobuf_write = 0;
855 audiobuf_swapwrite = 0;
856 lowest_watermark_level = audiobuflen;
859 /* DMA transfer end interrupt callback */
860 static void transfer_end(unsigned char** ppbuf, size_t* psize)
862 if(playing && !paused)
864 int unplayed_space_left;
865 int space_until_end_of_buffer;
866 int track_offset = 1;
867 struct trackdata *track;
869 audiobuf_read += last_dma_chunk_size;
870 if(audiobuf_read >= audiobuflen)
871 audiobuf_read = 0;
873 /* First, check if we are on a track boundary */
874 if (num_tracks_in_memory() > 1)
876 if (audiobuf_read == get_trackdata(track_offset)->mempos)
878 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
880 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
881 track_offset++;
886 unplayed_space_left = get_unplayed_space();
888 space_until_end_of_buffer = audiobuflen - audiobuf_read;
890 if(!filling && unplayed_space_left < low_watermark)
892 filling = true;
893 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
896 if(unplayed_space_left)
898 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
899 last_dma_chunk_size = MIN(last_dma_chunk_size,
900 space_until_end_of_buffer);
902 /* several tracks loaded? */
903 track = get_trackdata(track_offset);
904 if(track)
906 /* will we move across the track boundary? */
907 if (( audiobuf_read < track->mempos ) &&
908 ((audiobuf_read+last_dma_chunk_size) >
909 track->mempos ))
911 /* Make sure that we end exactly on the boundary */
912 last_dma_chunk_size = track->mempos - audiobuf_read;
916 *psize = last_dma_chunk_size & 0xffff;
917 *ppbuf = mpeg_audiobuf + audiobuf_read;
918 track = get_trackdata(0);
919 if(track)
920 track->id3.offset += last_dma_chunk_size;
922 /* Update the watermark debug level */
923 if(unplayed_space_left < lowest_watermark_level)
924 lowest_watermark_level = unplayed_space_left;
926 else
928 /* Check if the end of data is because of a hard disk error.
929 If there is an open file handle, we are still playing music.
930 If not, the last file has been loaded, and the file handle is
931 closed. */
932 if(mpeg_file >= 0)
934 /* Update the watermark debug level */
935 if(unplayed_space_left < lowest_watermark_level)
936 lowest_watermark_level = unplayed_space_left;
938 DEBUGF("DMA underrun.\n");
939 dma_underrun = true;
941 else
943 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
945 DEBUGF("No more MP3 data. Stopping.\n");
946 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
947 playing = false;
950 *psize = 0; /* no more transfer */
955 static struct trackdata *add_track_to_tag_list(const char *filename)
957 struct trackdata *track;
958 bool send_nid3_event;
960 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
962 DEBUGF("Tag memory is full\n");
963 return NULL;
966 track = &trackdata[track_write_idx];
968 /* grab id3 tag of new file and
969 remember where in memory it starts */
970 if(mp3info(&track->id3, filename))
972 DEBUGF("Bad mp3\n");
973 return NULL;
975 track->mempos = audiobuf_write;
976 track->id3.elapsed = 0;
977 #ifdef HAVE_LCD_BITMAP
978 if (track->id3.title)
979 lcd_getstringsize(track->id3.title, NULL, NULL);
980 if (track->id3.artist)
981 lcd_getstringsize(track->id3.artist, NULL, NULL);
982 if (track->id3.album)
983 lcd_getstringsize(track->id3.album, NULL, NULL);
984 #endif
986 /* if this track is the next track then let the UI know it can get it */
987 send_nid3_event = (track_write_idx == track_read_idx + 1);
988 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
989 if (send_nid3_event)
990 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
991 debug_tags();
992 return track;
995 static int new_file(int steps)
997 int max_steps = playlist_amount();
998 int start = 0;
999 int i;
1000 struct trackdata *track;
1001 char name_buf[MAX_PATH+1];
1002 const char *trackname;
1004 /* Find out how many steps to advance. The load_ahead_index field tells
1005 us how many playlist entries it had to skip to get to a valid one.
1006 We add those together to find out where to start. */
1007 if(steps > 0 && num_tracks_in_memory() > 1)
1009 /* Begin with the song after the currently playing one */
1010 i = 1;
1011 while((track = get_trackdata(i++)))
1013 start += track->load_ahead_index;
1017 do {
1018 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
1019 if ( !trackname )
1020 return -1;
1022 DEBUGF("Loading %s\n", trackname);
1024 mpeg_file = open(trackname, O_RDONLY);
1025 if(mpeg_file < 0) {
1026 DEBUGF("Couldn't open file: %s\n",trackname);
1027 if(steps < 0)
1028 steps--;
1029 else
1030 steps++;
1032 else
1034 struct trackdata *track = add_track_to_tag_list(trackname);
1036 if(!track)
1038 /* Bad mp3 file */
1039 if(steps < 0)
1040 steps--;
1041 else
1042 steps++;
1043 close(mpeg_file);
1044 mpeg_file = -1;
1046 else
1048 /* skip past id3v2 tag */
1049 lseek(mpeg_file,
1050 track->id3.first_frame_offset,
1051 SEEK_SET);
1052 track->id3.index = steps;
1053 track->load_ahead_index = steps;
1054 track->id3.offset = 0;
1056 if(track->id3.vbr)
1057 /* Average bitrate * 1.5 */
1058 recalculate_watermark(
1059 (track->id3.bitrate * 3) / 2);
1060 else
1061 recalculate_watermark(
1062 track->id3.bitrate);
1067 /* Bail out if no file could be opened */
1068 if(abs(steps) > max_steps)
1069 return -1;
1070 } while ( mpeg_file < 0 );
1072 return 0;
1075 static void stop_playing(void)
1077 struct trackdata *track;
1079 /* Stop the current stream */
1080 mp3_play_stop();
1081 playing = false;
1082 filling = false;
1084 track = get_trackdata(0);
1085 if (track != NULL)
1086 prev_track_elapsed = track->id3.elapsed;
1088 if(mpeg_file >= 0)
1089 close(mpeg_file);
1090 mpeg_file = -1;
1091 remove_all_tags();
1092 generate_unbuffer_events();
1093 reset_mp3_buffer();
1096 static void end_current_track(void) {
1097 struct trackdata *track;
1099 play_pending = false;
1100 playing = false;
1101 mp3_play_pause(false);
1103 track = get_trackdata(0);
1104 if (track != NULL)
1105 prev_track_elapsed = track->id3.elapsed;
1107 reset_mp3_buffer();
1108 remove_all_tags();
1109 generate_unbuffer_events();
1111 if(mpeg_file >= 0)
1112 close(mpeg_file);
1115 /* Is this a really the end of playback or is a new playlist starting */
1116 static void check_playlist_end(int direction)
1118 /* Use the largest possible step size to account for skipped tracks */
1119 int steps = playlist_amount();
1121 if (direction < 0)
1122 steps = -steps;
1124 if (playlist_next(steps) < 0)
1125 is_playing = false;
1128 static void update_playlist(void)
1130 if (num_tracks_in_memory() > 0)
1132 struct trackdata *track = get_trackdata(0);
1133 track->id3.index = playlist_next(track->id3.index);
1135 else
1137 /* End of playlist? */
1138 check_playlist_end(1);
1141 playlist_update_resume_info(audio_current_track());
1144 static void track_change(void)
1146 DEBUGF("Track change\n");
1148 struct trackdata *track = get_trackdata(0);
1149 prev_track_elapsed = track->id3.elapsed;
1151 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1152 /* Reset the AVC */
1153 sound_set_avc(-1);
1154 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1156 if (num_tracks_in_memory() > 0)
1158 remove_current_tag();
1159 update_playlist();
1160 if (is_playing)
1161 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1164 current_track_counter++;
1167 unsigned long audio_prev_elapsed(void)
1169 return prev_track_elapsed;
1172 #ifdef DEBUG
1173 void hexdump(const unsigned char *buf, int len)
1175 int i;
1177 for(i = 0;i < len;i++)
1179 if(i && (i & 15) == 0)
1181 DEBUGF("\n");
1183 DEBUGF("%02x ", buf[i]);
1185 DEBUGF("\n");
1187 #endif /* DEBUG */
1189 static void start_playback_if_ready(void)
1191 int playable_space;
1193 playable_space = audiobuf_swapwrite - audiobuf_read;
1194 if(playable_space < 0)
1195 playable_space += audiobuflen;
1197 /* See if we have started playing yet. If not, do it. */
1198 if(play_pending || dma_underrun)
1200 /* If the filling has stopped, and we still haven't reached
1201 the watermark, the file must be smaller than the
1202 watermark. We must still play it. */
1203 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1204 !filling || dma_underrun)
1206 DEBUGF("P\n");
1207 if (play_pending) /* don't do this when recovering from DMA underrun */
1209 generate_postbuffer_events(); /* signal first track as buffered */
1210 if (play_pending_track_change)
1212 play_pending_track_change = false;
1213 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1215 play_pending = false;
1217 playing = true;
1219 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1220 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1221 dma_underrun = false;
1223 if (!paused)
1225 last_dma_tick = current_tick;
1226 mp3_play_pause(true);
1229 /* Tell ourselves that we need more data */
1230 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1235 static bool swap_one_chunk(void)
1237 int free_space_left;
1238 int amount_to_swap;
1240 free_space_left = get_unswapped_space();
1242 if(free_space_left == 0 && !play_pending)
1243 return false;
1245 /* Swap in larger chunks when the user is waiting for the playback
1246 to start, or when there is dangerously little playable data left */
1247 if(play_pending)
1248 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1249 else
1251 if(get_playable_space() < low_watermark)
1252 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1253 free_space_left);
1254 else
1255 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1258 if(audiobuf_write < audiobuf_swapwrite)
1259 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1260 amount_to_swap);
1261 else
1262 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1263 amount_to_swap);
1265 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1267 audiobuf_swapwrite += amount_to_swap;
1268 if(audiobuf_swapwrite >= audiobuflen)
1270 audiobuf_swapwrite = 0;
1273 return true;
1276 static void mpeg_thread(void)
1278 static int pause_tick = 0;
1279 static unsigned int pause_track = 0;
1280 struct queue_event ev;
1281 int len;
1282 int free_space_left;
1283 int unplayed_space_left;
1284 int amount_to_read;
1285 int t1, t2;
1286 int start_offset;
1287 #if CONFIG_CODEC == MAS3587F
1288 int amount_to_save;
1289 int save_endpos = 0;
1290 int rc;
1291 int level;
1292 long offset;
1293 #endif /* CONFIG_CODEC == MAS3587F */
1295 is_playing = false;
1296 play_pending = false;
1297 playing = false;
1298 mpeg_file = -1;
1300 while(1)
1302 #if CONFIG_CODEC == MAS3587F
1303 if(mpeg_mode == MPEG_DECODER)
1305 #endif /* CONFIG_CODEC == MAS3587F */
1306 yield();
1308 /* Swap if necessary, and don't block on the queue_wait() */
1309 if(swap_one_chunk())
1311 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1313 else if (playing)
1315 /* periodically update resume info */
1316 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1318 else
1320 DEBUGF("S R:%x W:%x SW:%x\n",
1321 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1322 queue_wait(&mpeg_queue, &ev);
1325 start_playback_if_ready();
1327 switch(ev.id)
1329 case MPEG_PLAY:
1330 DEBUGF("MPEG_PLAY\n");
1332 #if CONFIG_TUNER
1333 /* Silence the A/D input, it may be on because the radio
1334 may be playing */
1335 mas_codec_writereg(6, 0x0000);
1336 #endif /* CONFIG_TUNER */
1338 /* Stop the current stream */
1339 paused = false;
1340 end_current_track();
1342 if ( new_file(0) == -1 )
1344 is_playing = false;
1345 track_change();
1346 break;
1349 start_offset = (int)ev.data;
1351 /* mid-song resume? */
1352 if (start_offset) {
1353 struct mp3entry* id3 = &get_trackdata(0)->id3;
1354 lseek(mpeg_file, start_offset, SEEK_SET);
1355 id3->offset = start_offset;
1356 set_elapsed(id3);
1358 else {
1359 /* skip past id3v2 tag */
1360 lseek(mpeg_file,
1361 get_trackdata(0)->id3.first_frame_offset,
1362 SEEK_SET);
1366 /* Make it read more data */
1367 filling = true;
1368 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1370 /* Tell the file loading code that we want to start playing
1371 as soon as we have some data */
1372 play_pending = true;
1373 play_pending_track_change = true;
1375 update_playlist();
1376 current_track_counter++;
1377 break;
1379 case MPEG_STOP:
1380 do_stop();
1381 break;
1383 case MPEG_PAUSE:
1384 DEBUGF("MPEG_PAUSE\n");
1385 /* Stop the current stream */
1386 if (playing)
1387 playlist_update_resume_info(audio_current_track());
1388 paused = true;
1389 playing = false;
1390 pause_tick = current_tick;
1391 pause_track = current_track_counter;
1392 mp3_play_pause(false);
1393 break;
1395 case MPEG_RESUME:
1396 DEBUGF("MPEG_RESUME\n");
1397 /* Continue the current stream */
1398 paused = false;
1399 if (!play_pending)
1401 playing = true;
1402 if ( current_track_counter == pause_track )
1403 last_dma_tick += current_tick - pause_tick;
1404 else
1405 last_dma_tick = current_tick;
1406 pause_tick = 0;
1407 mp3_play_pause(true);
1409 break;
1411 case MPEG_NEXT:
1412 DEBUGF("MPEG_NEXT\n");
1413 /* is next track in ram? */
1414 if ( num_tracks_in_memory() > 1 ) {
1415 int unplayed_space_left, unswapped_space_left;
1417 /* stop the current stream */
1418 play_pending = false;
1419 playing = false;
1420 mp3_play_pause(false);
1422 track_change();
1423 audiobuf_read = get_trackdata(0)->mempos;
1424 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1425 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1426 dma_underrun = false;
1427 last_dma_tick = current_tick;
1429 unplayed_space_left = get_unplayed_space();
1430 unswapped_space_left = get_unswapped_space();
1432 /* should we start reading more data? */
1433 if(!filling && (unplayed_space_left < low_watermark)) {
1434 filling = true;
1435 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1436 play_pending = true;
1437 } else if(unswapped_space_left &&
1438 unswapped_space_left > unplayed_space_left) {
1439 /* Stop swapping the data from the previous file */
1440 audiobuf_swapwrite = audiobuf_read;
1441 play_pending = true;
1442 } else {
1443 playing = true;
1444 if (!paused)
1445 mp3_play_pause(true);
1448 else {
1449 if (!playlist_check(1))
1450 break;
1452 /* stop the current stream */
1453 end_current_track();
1455 if (new_file(1) < 0) {
1456 DEBUGF("No more files to play\n");
1457 filling = false;
1459 check_playlist_end(1);
1460 current_track_counter++;
1461 } else {
1462 /* Make it read more data */
1463 filling = true;
1464 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1466 /* Tell the file loading code that we want
1467 to start playing as soon as we have some data */
1468 play_pending = true;
1469 play_pending_track_change = true;
1471 update_playlist();
1472 current_track_counter++;
1475 break;
1477 case MPEG_PREV: {
1478 DEBUGF("MPEG_PREV\n");
1480 if (!playlist_check(-1))
1481 break;
1483 /* stop the current stream */
1484 end_current_track();
1486 /* Open the next file */
1487 if (new_file(-1) < 0) {
1488 DEBUGF("No more files to play\n");
1489 filling = false;
1491 check_playlist_end(-1);
1492 current_track_counter++;
1493 } else {
1494 /* Make it read more data */
1495 filling = true;
1496 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1498 /* Tell the file loading code that we want to
1499 start playing as soon as we have some data */
1500 play_pending = true;
1501 play_pending_track_change = true;
1503 update_playlist();
1504 current_track_counter++;
1506 break;
1509 case MPEG_FF_REWIND: {
1510 struct mp3entry *id3 = audio_current_track();
1511 unsigned int oldtime = id3->elapsed;
1512 unsigned int newtime = (unsigned int)ev.data;
1513 int curpos, newpos, diffpos;
1514 DEBUGF("MPEG_FF_REWIND\n");
1516 id3->elapsed = newtime;
1518 newpos = audio_get_file_pos();
1519 if(newpos < 0)
1521 id3->elapsed = oldtime;
1522 break;
1525 if (mpeg_file >= 0)
1526 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1527 else
1528 curpos = id3->filesize;
1530 if (num_tracks_in_memory() > 1)
1532 /* We have started loading other tracks that need to be
1533 accounted for */
1534 struct trackdata *track;
1535 int i = 0;
1537 while((track = get_trackdata(i++)))
1539 curpos += track->id3.filesize;
1543 diffpos = curpos - newpos;
1545 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1547 int unplayed_space_left, unswapped_space_left;
1549 /* We are changing to a position that's already in
1550 memory, so we just move the DMA read pointer. */
1551 audiobuf_read = audiobuf_write - diffpos;
1552 if (audiobuf_read < 0)
1554 audiobuf_read += audiobuflen;
1557 unplayed_space_left = get_unplayed_space();
1558 unswapped_space_left = get_unswapped_space();
1560 /* If unswapped_space_left is larger than
1561 unplayed_space_left, it means that the swapwrite pointer
1562 hasn't yet advanced up to the new location of the read
1563 pointer. We just move it, there is no need to swap
1564 data that won't be played anyway. */
1566 if (unswapped_space_left > unplayed_space_left)
1568 DEBUGF("Moved swapwrite\n");
1569 audiobuf_swapwrite = audiobuf_read;
1570 play_pending = true;
1573 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1575 /* We need to load more data before starting */
1576 filling = true;
1577 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1578 play_pending = true;
1580 else
1582 /* resume will start at new position */
1583 last_dma_chunk_size =
1584 MIN(0x2000, get_unplayed_space_current_song());
1585 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1586 last_dma_chunk_size, transfer_end);
1587 dma_underrun = false;
1590 else
1592 /* Move to the new position in the file and start
1593 loading data */
1594 reset_mp3_buffer();
1596 if (num_tracks_in_memory() > 1)
1598 /* We have to reload the current track */
1599 close(mpeg_file);
1600 remove_all_non_current_tags();
1601 generate_unbuffer_events();
1602 mpeg_file = -1;
1605 if (mpeg_file < 0)
1607 mpeg_file = open(id3->path, O_RDONLY);
1608 if (mpeg_file < 0)
1610 id3->elapsed = oldtime;
1611 break;
1615 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1617 id3->elapsed = oldtime;
1618 break;
1621 filling = true;
1622 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1624 /* Tell the file loading code that we want to start playing
1625 as soon as we have some data */
1626 play_pending = true;
1629 id3->offset = newpos;
1631 break;
1634 case MPEG_FLUSH_RELOAD: {
1635 int numtracks = num_tracks_in_memory();
1636 bool reload_track = false;
1638 if (numtracks > 1)
1640 /* Reset the buffer */
1641 audiobuf_write = get_trackdata(1)->mempos;
1643 /* Reset swapwrite unless we're still swapping current
1644 track */
1645 if (get_unplayed_space() <= get_playable_space())
1646 audiobuf_swapwrite = audiobuf_write;
1648 close(mpeg_file);
1649 remove_all_non_current_tags();
1650 generate_unbuffer_events();
1651 mpeg_file = -1;
1652 reload_track = true;
1654 else if (numtracks == 1 && mpeg_file < 0)
1656 reload_track = true;
1659 if(reload_track && new_file(1) >= 0)
1661 /* Tell ourselves that we want more data */
1662 filling = true;
1663 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1666 break;
1669 case MPEG_NEED_DATA:
1670 free_space_left = audiobuf_read - audiobuf_write;
1672 /* We interpret 0 as "empty buffer" */
1673 if(free_space_left <= 0)
1674 free_space_left += audiobuflen;
1676 unplayed_space_left = audiobuflen - free_space_left;
1678 /* Make sure that we don't fill the entire buffer */
1679 free_space_left -= MPEG_HIGH_WATER;
1681 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1682 generate_unbuffer_events();
1684 /* do we have any more buffer space to fill? */
1685 if(free_space_left <= 0)
1687 DEBUGF("0\n");
1688 filling = false;
1689 generate_postbuffer_events();
1690 storage_sleep();
1691 break;
1694 /* Read small chunks while we are below the low water mark */
1695 if(unplayed_space_left < low_watermark)
1696 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1697 free_space_left);
1698 else
1699 amount_to_read = free_space_left;
1701 /* Don't read more than until the end of the buffer */
1702 amount_to_read = MIN(audiobuflen - audiobuf_write,
1703 amount_to_read);
1704 #if (CONFIG_STORAGE & STORAGE_MMC)
1705 /* MMC is slow, so don't read too large chunks */
1706 amount_to_read = MIN(0x40000, amount_to_read);
1707 #elif MEMORYSIZE == 8
1708 amount_to_read = MIN(0x100000, amount_to_read);
1709 #endif
1711 /* Read as much mpeg data as we can fit in the buffer */
1712 if(mpeg_file >= 0)
1714 DEBUGF("R\n");
1715 t1 = current_tick;
1716 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1717 amount_to_read);
1718 if(len > 0)
1720 t2 = current_tick;
1721 DEBUGF("time: %d\n", t2 - t1);
1722 DEBUGF("R: %x\n", len);
1724 /* Now make sure that we don't feed the MAS with ID3V1
1725 data */
1726 if (len < amount_to_read)
1728 int i;
1729 static const unsigned char tag[] = "TAG";
1730 int taglen = 128;
1731 int tagptr = audiobuf_write + len - 128;
1733 /* Really rare case: entire potential tag wasn't
1734 read in this call AND audiobuf_write < 128 */
1735 if (tagptr < 0)
1736 tagptr += audiobuflen;
1738 for(i = 0;i < 3;i++)
1740 if(tagptr >= audiobuflen)
1741 tagptr -= audiobuflen;
1743 if(mpeg_audiobuf[tagptr] != tag[i])
1745 taglen = 0;
1746 break;
1749 tagptr++;
1752 if(taglen)
1754 /* Skip id3v1 tag */
1755 DEBUGF("Skipping ID3v1 tag\n");
1756 len -= taglen;
1758 /* In the very rare case when the entire tag
1759 wasn't read in this read() len will be < 0.
1760 Take care of this when changing the write
1761 pointer. */
1765 audiobuf_write += len;
1767 if (audiobuf_write < 0)
1768 audiobuf_write += audiobuflen;
1770 if(audiobuf_write >= audiobuflen)
1772 audiobuf_write = 0;
1773 DEBUGF("W\n");
1776 /* Tell ourselves that we want more data */
1777 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1779 else
1781 if(len < 0)
1783 DEBUGF("MPEG read error\n");
1786 close(mpeg_file);
1787 mpeg_file = -1;
1789 if(new_file(1) < 0)
1791 /* No more data to play */
1792 DEBUGF("No more files to play\n");
1793 filling = false;
1795 else
1797 /* Tell ourselves that we want more data */
1798 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1802 break;
1804 case MPEG_TRACK_CHANGE:
1805 track_change();
1806 break;
1808 #ifndef USB_NONE
1809 case SYS_USB_CONNECTED:
1810 is_playing = false;
1811 paused = false;
1812 stop_playing();
1814 /* Tell the USB thread that we are safe */
1815 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1816 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1818 /* Wait until the USB cable is extracted again */
1819 usb_wait_for_disconnect(&mpeg_queue);
1820 break;
1821 #endif /* !USB_NONE */
1823 #if CONFIG_CODEC == MAS3587F
1824 case MPEG_INIT_RECORDING:
1825 init_recording();
1826 init_recording_done = true;
1827 break;
1828 #endif /* CONFIG_CODEC == MAS3587F */
1830 case SYS_TIMEOUT:
1831 if (playing)
1832 playlist_update_resume_info(audio_current_track());
1833 break;
1835 #if CONFIG_CODEC == MAS3587F
1837 else
1839 queue_wait(&mpeg_queue, &ev);
1840 switch(ev.id)
1842 case MPEG_RECORD:
1843 if (is_prerecording)
1845 int startpos;
1847 /* Go back prerecord_count seconds in the buffer */
1848 startpos = prerecord_index - prerecord_count;
1849 if(startpos < 0)
1850 startpos += prerecording_max_seconds;
1852 /* Read the position data from the prerecord buffer */
1853 frame_count_start = prerecord_buffer[startpos].framecount;
1854 startpos = prerecord_buffer[startpos].mempos;
1856 DEBUGF("Start looking at address %x (%x)\n",
1857 mpeg_audiobuf+startpos, startpos);
1859 saved_header = mpeg_get_last_header();
1861 mem_find_next_frame(startpos, &offset, 1800,
1862 saved_header, mpeg_audiobuf,
1863 audiobuflen);
1865 audiobuf_read = startpos + offset;
1866 if(audiobuf_read >= audiobuflen)
1867 audiobuf_read -= audiobuflen;
1869 DEBUGF("New audiobuf_read address: %x (%x)\n",
1870 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1872 level = disable_irq_save();
1873 num_rec_bytes = get_unsaved_space();
1874 restore_irq(level);
1876 else
1878 frame_count_start = 0;
1879 num_rec_bytes = 0;
1880 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1881 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1884 prepend_header();
1885 DEBUGF("Recording...\n");
1886 start_recording();
1888 /* Wait until at least one frame is encoded and get the
1889 frame header, for later use by the Xing header
1890 generation */
1891 sleep(HZ/5);
1892 saved_header = mpeg_get_last_header();
1894 /* delayed until buffer is saved, don't open yet */
1895 strcpy(delayed_filename, recording_filename);
1896 mpeg_file = -1;
1898 break;
1900 case MPEG_STOP:
1901 DEBUGF("MPEG_STOP\n");
1903 stop_recording();
1905 /* Save the remaining data in the buffer */
1906 save_endpos = audiobuf_write;
1907 saving_status = STOP_RECORDING;
1908 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1909 break;
1911 case MPEG_STOP_DONE:
1912 DEBUGF("MPEG_STOP_DONE\n");
1914 if (mpeg_file >= 0)
1915 close(mpeg_file);
1916 mpeg_file = -1;
1918 update_header();
1919 #ifdef DEBUG1
1921 int i;
1922 for(i = 0;i < 512;i++)
1924 DEBUGF("%d - %d us (%d bytes)\n",
1925 timing_info[i*2],
1926 (timing_info[i*2+1] & 0xffff) *
1927 10000 / 13824,
1928 timing_info[i*2+1] >> 16);
1931 #endif /* DEBUG1 */
1933 if (prerecording)
1935 start_prerecording();
1937 mpeg_stop_done = true;
1938 break;
1940 case MPEG_NEW_FILE:
1941 /* Bail out when a more important save is happening */
1942 if (saving_status > NEW_FILE)
1943 break;
1945 /* Make sure we have at least one complete frame
1946 in the buffer. If we haven't recorded a single
1947 frame within 200ms, the MAS is probably not recording
1948 anything, and we bail out. */
1949 amount_to_save = get_unsaved_space();
1950 if (amount_to_save < 1800)
1952 sleep(HZ/5);
1953 amount_to_save = get_unsaved_space();
1956 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1957 &frame_count_end, 1);
1959 last_rec_time = current_tick - record_start_time;
1960 record_start_time = current_tick;
1961 if (paused)
1962 pause_start_time = record_start_time;
1964 /* capture all values at one point */
1965 level = disable_irq_save();
1966 save_endpos = audiobuf_write;
1967 last_rec_bytes = num_rec_bytes;
1968 num_rec_bytes = 0;
1969 restore_irq(level);
1971 if (amount_to_save >= 1800)
1973 /* Now find a frame boundary to split at */
1974 save_endpos -= 1800;
1975 if (save_endpos < 0)
1976 save_endpos += audiobuflen;
1978 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1979 saved_header, mpeg_audiobuf,
1980 audiobuflen);
1981 if (!rc) /* No header found, save whole buffer */
1982 offset = 1800;
1984 save_endpos += offset;
1985 if (save_endpos >= audiobuflen)
1986 save_endpos -= audiobuflen;
1988 last_rec_bytes += offset - 1800;
1989 level = disable_irq_save();
1990 num_rec_bytes += 1800 - offset;
1991 restore_irq(level);
1994 saving_status = NEW_FILE;
1995 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1996 break;
1998 case MPEG_SAVE_DATA:
1999 if (saving_status == BUFFER_FULL)
2000 save_endpos = audiobuf_write;
2002 if (mpeg_file < 0) /* delayed file open */
2004 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
2006 if (mpeg_file < 0)
2007 panicf("recfile: %d", mpeg_file);
2010 amount_to_save = save_endpos - audiobuf_read;
2011 if (amount_to_save < 0)
2012 amount_to_save += audiobuflen;
2014 amount_to_save = MIN(amount_to_save,
2015 audiobuflen - audiobuf_read);
2016 #if (CONFIG_STORAGE & STORAGE_MMC)
2017 /* MMC is slow, so don't save too large chunks at once */
2018 amount_to_save = MIN(0x40000, amount_to_save);
2019 #elif MEMORYSIZE == 8
2020 amount_to_save = MIN(0x100000, amount_to_save);
2021 #endif
2022 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
2023 amount_to_save);
2024 if (rc < 0)
2026 if (errno == ENOSPC)
2028 mpeg_errno = AUDIOERR_DISK_FULL;
2029 stop_recording();
2030 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2031 /* will close the file */
2032 break;
2034 else
2035 panicf("rec wrt: %d", rc);
2038 audiobuf_read += amount_to_save;
2039 if (audiobuf_read >= audiobuflen)
2040 audiobuf_read = 0;
2042 if (audiobuf_read == save_endpos) /* all saved */
2044 switch (saving_status)
2046 case BUFFER_FULL:
2047 rc = fsync(mpeg_file);
2048 if (rc < 0)
2049 panicf("rec fls: %d", rc);
2050 storage_sleep();
2051 break;
2053 case NEW_FILE:
2054 /* Close the current file */
2055 rc = close(mpeg_file);
2056 if (rc < 0)
2057 panicf("rec cls: %d", rc);
2058 mpeg_file = -1;
2059 update_header();
2060 storage_sleep();
2062 /* copy new filename */
2063 strcpy(delayed_filename, recording_filename);
2064 prepend_header();
2065 frame_count_start = frame_count_end;
2066 break;
2068 case STOP_RECORDING:
2069 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2070 /* will close the file */
2071 break;
2073 default:
2074 break;
2076 saving_status = NOT_SAVING;
2078 else /* tell ourselves to save the next chunk */
2079 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2081 break;
2083 case MPEG_PRERECORDING_TICK:
2084 if(!is_prerecording)
2085 break;
2087 /* Store the write pointer every second */
2088 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2089 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2090 &prerecord_buffer[prerecord_index].framecount, 1);
2092 /* Wrap if necessary */
2093 if(++prerecord_index == prerecording_max_seconds)
2094 prerecord_index = 0;
2096 /* Update the number of seconds recorded */
2097 if(prerecord_count < prerecording_max_seconds)
2098 prerecord_count++;
2099 break;
2101 case MPEG_INIT_PLAYBACK:
2102 /* Stop the prerecording */
2103 stop_recording();
2104 reset_mp3_buffer();
2105 mp3_play_init();
2106 init_playback_done = true;
2107 break;
2109 case MPEG_PAUSE_RECORDING:
2110 pause_recording();
2111 break;
2113 case MPEG_RESUME_RECORDING:
2114 resume_recording();
2115 break;
2117 case SYS_USB_CONNECTED:
2118 /* We can safely go to USB mode if no recording
2119 is taking place */
2120 if((!is_recording || is_prerecording) && mpeg_stop_done)
2122 /* Even if we aren't recording, we still call this
2123 function, to put the MAS in monitoring mode,
2124 to save power. */
2125 stop_recording();
2127 /* Tell the USB thread that we are safe */
2128 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2129 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2131 /* Wait until the USB cable is extracted again */
2132 usb_wait_for_disconnect(&mpeg_queue);
2134 break;
2137 #endif /* CONFIG_CODEC == MAS3587F */
2140 #endif /* !SIMULATOR */
2142 struct mp3entry* audio_current_track(void)
2144 #ifdef SIMULATOR
2145 struct mp3entry *id3 = &taginfo;
2146 #else /* !SIMULATOR */
2147 if(num_tracks_in_memory())
2149 struct mp3entry *id3 = &get_trackdata(0)->id3;
2150 #endif
2151 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2153 checked_for_cuesheet = true; /* only check once per track */
2154 char cuepath[MAX_PATH];
2156 if (look_for_cuesheet_file(id3->path, cuepath) &&
2157 parse_cuesheet(cuepath, curr_cuesheet))
2159 id3->cuesheet = curr_cuesheet;
2162 return id3;
2163 #ifndef SIMULATOR
2165 else
2166 return NULL;
2167 #endif /* !SIMULATOR */
2170 struct mp3entry* audio_next_track(void)
2172 #ifdef SIMULATOR
2173 return &taginfo;
2174 #else /* !SIMULATOR */
2175 if(num_tracks_in_memory() > 1)
2176 return &get_trackdata(1)->id3;
2177 else
2178 return NULL;
2179 #endif /* !SIMULATOR */
2182 #if CONFIG_CODEC == MAS3587F
2183 #ifndef SIMULATOR
2184 void audio_init_playback(void)
2186 init_playback_done = false;
2187 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2189 while(!init_playback_done)
2190 sleep(1);
2194 /****************************************************************************
2195 * Recording functions
2196 ***************************************************************************/
2197 void audio_init_recording(void)
2199 init_recording_done = false;
2200 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2202 while(!init_recording_done)
2203 sleep(1);
2206 static void init_recording(void)
2208 unsigned long val;
2209 int rc;
2211 /* Disable IRQ6 */
2212 IPRB &= 0xff0f;
2214 stop_playing();
2215 is_playing = false;
2216 paused = false;
2218 /* Init the recording variables */
2219 is_recording = false;
2220 is_prerecording = false;
2222 mpeg_stop_done = true;
2224 mas_reset();
2226 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2227 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2228 if(rc < 0)
2229 panicf("mas_ctrl_w: %d", rc);
2231 /* Stop the current application */
2232 val = 0;
2233 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2236 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2237 } while(val);
2239 /* Perform black magic as described by the data sheet */
2240 if((mas_version_code & 0x0fff) == 0x0102)
2242 DEBUGF("Performing MAS black magic for B2 version\n");
2243 mas_writereg(0xa3, 0x98);
2244 mas_writereg(0x94, 0xfffff);
2245 val = 0;
2246 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2247 mas_writereg(0xa3, 0x90);
2250 /* Enable A/D Converters */
2251 shadow_codec_reg0 = 0xcccd;
2252 mas_codec_writereg(0x0, shadow_codec_reg0);
2254 /* Copy left channel to right (mono mode) */
2255 mas_codec_writereg(8, 0x8000);
2257 /* ADC scale 0%, DSP scale 100%
2258 We use the DSP output for monitoring, because it works with all
2259 sources including S/PDIF */
2260 mas_codec_writereg(6, 0x0000);
2261 mas_codec_writereg(7, 0x4000);
2263 /* No mute */
2264 shadow_soft_mute = 0;
2265 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2267 #ifdef HAVE_SPDIF_OUT
2268 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2269 #else
2270 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2271 #endif
2272 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2274 /* Set Demand mode, monitoring OFF and validate all settings */
2275 shadow_io_control_main = 0x125;
2276 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2278 /* Start the encoder application */
2279 val = 0x40;
2280 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2283 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2284 } while(!(val & 0x40));
2286 /* We have started the recording application with monitoring OFF.
2287 This is because we want to record at least one frame to fill the DMA
2288 buffer, because the silly MAS will not negate EOD until at least one
2289 DMA transfer has taken place.
2290 Now let's wait for some data to be encoded. */
2291 sleep(HZ/5);
2293 /* Now set it to Monitoring mode as default, saves power */
2294 shadow_io_control_main = 0x525;
2295 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2297 /* Wait until the DSP has accepted the settings */
2300 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2301 } while(val & 1);
2303 drain_dma_buffer();
2304 mpeg_mode = MPEG_ENCODER;
2306 DEBUGF("MAS Recording application started\n");
2308 /* At this point, all settings are the reset MAS defaults, next thing is to
2309 call mpeg_set_recording_options(). */
2312 void audio_record(const char *filename)
2314 mpeg_errno = 0;
2316 strlcpy(recording_filename, filename, MAX_PATH);
2318 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2321 void audio_pause_recording(void)
2323 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2326 void audio_resume_recording(void)
2328 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2331 static void prepend_header(void)
2333 int startpos;
2334 unsigned i;
2336 /* Make room for header */
2337 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2338 if(audiobuf_read < 0)
2340 /* Clear the bottom half */
2341 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2343 /* And the top half */
2344 audiobuf_read += audiobuflen;
2345 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2347 else
2349 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2351 /* Copy the empty ID3 header */
2352 startpos = audiobuf_read;
2353 for(i = 0; i < sizeof(empty_id3_header); i++)
2355 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2356 if(startpos == audiobuflen)
2357 startpos = 0;
2361 static void update_header(void)
2363 int fd, framelen;
2364 unsigned long frames;
2366 if (last_rec_bytes > 0)
2368 /* Create the Xing header */
2369 fd = open(delayed_filename, O_RDWR);
2370 if (fd < 0)
2371 panicf("rec upd: %d (%s)", fd, recording_filename);
2373 frames = frame_count_end - frame_count_start;
2374 /* If the number of recorded frames has reached 0x7ffff,
2375 we can no longer trust it */
2376 if (frame_count_end == 0x7ffff)
2377 frames = 0;
2379 /* saved_header is saved right before stopping the MAS */
2380 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2381 frames, last_rec_time * (1000/HZ),
2382 saved_header, NULL, false,
2383 mpeg_audiobuf, audiobuflen);
2385 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2386 write(fd, xing_buffer, framelen);
2387 close(fd);
2391 static void start_prerecording(void)
2393 unsigned long val;
2395 DEBUGF("Starting prerecording\n");
2397 prerecord_index = 0;
2398 prerecord_count = 0;
2399 prerecord_timeout = current_tick + HZ;
2400 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2401 reset_mp3_buffer();
2403 is_prerecording = true;
2405 /* Stop monitoring and start the encoder */
2406 shadow_io_control_main &= ~(1 << 10);
2407 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2408 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2410 /* Wait until the DSP has accepted the settings */
2413 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2414 } while(val & 1);
2416 is_recording = true;
2417 saving_status = NOT_SAVING;
2419 demand_irq_enable(true);
2422 static void start_recording(void)
2424 unsigned long val;
2426 if(is_prerecording)
2428 /* This will make the IRQ handler start recording
2429 for real, i.e send MPEG_SAVE_DATA messages when
2430 the buffer is full */
2431 is_prerecording = false;
2433 else
2435 /* If prerecording is off, we need to stop the monitoring
2436 and start the encoder */
2437 shadow_io_control_main &= ~(1 << 10);
2438 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2439 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2441 /* Wait until the DSP has accepted the settings */
2444 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2445 } while(val & 1);
2448 is_recording = true;
2449 saving_status = NOT_SAVING;
2450 paused = false;
2452 /* Store the current time */
2453 if(prerecording)
2454 record_start_time = current_tick - prerecord_count * HZ;
2455 else
2456 record_start_time = current_tick;
2458 pause_start_time = 0;
2460 demand_irq_enable(true);
2463 static void pause_recording(void)
2465 pause_start_time = current_tick;
2467 /* Set the pause bit */
2468 shadow_soft_mute |= 2;
2469 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2471 paused = true;
2474 static void resume_recording(void)
2476 paused = false;
2478 /* Clear the pause bit */
2479 shadow_soft_mute &= ~2;
2480 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2482 /* Compensate for the time we have been paused */
2483 if(pause_start_time)
2485 record_start_time =
2486 current_tick - (pause_start_time - record_start_time);
2487 pause_start_time = 0;
2491 static void stop_recording(void)
2493 unsigned long val;
2495 /* Let it finish the last frame */
2496 if(!paused)
2497 pause_recording();
2498 sleep(HZ/5);
2500 demand_irq_enable(false);
2502 is_recording = false;
2503 is_prerecording = false;
2505 last_rec_bytes = num_rec_bytes;
2506 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2507 last_rec_time = current_tick - record_start_time;
2509 /* Start monitoring */
2510 shadow_io_control_main |= (1 << 10);
2511 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2512 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2514 /* Wait until the DSP has accepted the settings */
2517 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2518 } while(val & 1);
2520 resume_recording();
2523 void audio_set_recording_options(struct audio_recording_options *options)
2525 bool is_mpeg1;
2527 is_mpeg1 = (options->rec_frequency < 3);
2529 rec_version_index = is_mpeg1?3:2;
2530 rec_frequency_index = options->rec_frequency % 3;
2532 shadow_encoder_control = (options->rec_quality << 17) |
2533 (rec_frequency_index << 10) |
2534 ((is_mpeg1?1:0) << 9) |
2535 (((options->rec_channels * 2 + 1) & 3) << 6) |
2536 (1 << 5) /* MS-stereo */ |
2537 (1 << 2) /* Is an original */;
2538 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2540 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2542 #if CONFIG_TUNER & S1A0903X01
2543 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2544 interference with the Samsung tuner. */
2545 if (rec_frequency_index)
2546 mas_store_pllfreq(24576000);
2547 else
2548 mas_store_pllfreq(22579000);
2549 #endif
2551 shadow_soft_mute = options->rec_editable?4:0;
2552 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2554 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2556 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2557 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2558 (1 << 5) | /* SDO strobe invert */
2559 ((is_mpeg1?0:1) << 3) |
2560 (1 << 2) | /* Inverted SIBC clock signal */
2561 1; /* Validate */
2562 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2564 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2566 if(options->rec_source == AUDIO_SRC_MIC)
2568 /* Copy left channel to right (mono mode) */
2569 mas_codec_writereg(8, 0x8000);
2571 else
2573 /* Stereo input mode */
2574 mas_codec_writereg(8, 0);
2577 prerecording_max_seconds = options->rec_prerecord_time;
2578 if(prerecording_max_seconds)
2580 prerecording = true;
2581 start_prerecording();
2583 else
2585 prerecording = false;
2586 is_prerecording = false;
2587 is_recording = false;
2591 /* If use_mic is true, the left gain is used */
2592 void audio_set_recording_gain(int left, int right, int type)
2594 /* Enable both left and right A/D */
2595 shadow_codec_reg0 = (left << 12) |
2596 (right << 8) |
2597 (left << 4) |
2598 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2599 0x0007;
2600 mas_codec_writereg(0x0, shadow_codec_reg0);
2603 /* try to make some kind of beep, also in recording mode */
2604 void audio_beep(int duration)
2606 long starttick = current_tick;
2608 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2609 * While this is still audible even without an external signal,
2610 * it doesn't affect the (pre-)recording. */
2611 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2612 mas_codec_writereg(0, shadow_codec_reg0);
2613 yield();
2615 while (current_tick - starttick < duration);
2618 void audio_new_file(const char *filename)
2620 mpeg_errno = 0;
2622 strlcpy(recording_filename, filename, MAX_PATH);
2624 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2627 unsigned long audio_recorded_time(void)
2629 if(is_prerecording)
2630 return prerecord_count * HZ;
2632 if(is_recording)
2634 if(paused)
2635 return pause_start_time - record_start_time;
2636 else
2637 return current_tick - record_start_time;
2640 return 0;
2643 unsigned long audio_num_recorded_bytes(void)
2645 int num_bytes;
2646 int index;
2648 if(is_recording)
2650 if(is_prerecording)
2652 index = prerecord_index - prerecord_count;
2653 if(index < 0)
2654 index += prerecording_max_seconds;
2656 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2657 if(num_bytes < 0)
2658 num_bytes += audiobuflen;
2660 return num_bytes;
2662 else
2663 return num_rec_bytes;
2665 else
2666 return 0;
2669 #else /* SIMULATOR */
2671 /* dummies coming up */
2673 void audio_init_playback(void)
2675 /* a dummy */
2677 unsigned long audio_recorded_time(void)
2679 /* a dummy */
2680 return 0;
2682 void audio_beep(int duration)
2684 /* a dummy */
2685 (void)duration;
2687 void audio_pause_recording(void)
2689 /* a dummy */
2691 void audio_resume_recording(void)
2693 /* a dummy */
2695 unsigned long audio_num_recorded_bytes(void)
2697 /* a dummy */
2698 return 0;
2700 void audio_record(const char *filename)
2702 /* a dummy */
2703 (void)filename;
2705 void audio_new_file(const char *filename)
2707 /* a dummy */
2708 (void)filename;
2711 void audio_set_recording_gain(int left, int right, int type)
2713 /* a dummy */
2714 (void)left;
2715 (void)right;
2716 (void)type;
2718 void audio_init_recording(void)
2720 /* a dummy */
2722 void audio_set_recording_options(struct audio_recording_options *options)
2724 /* a dummy */
2725 (void)options;
2727 #endif /* SIMULATOR */
2728 #endif /* CONFIG_CODEC == MAS3587F */
2730 size_t audio_buffer_available(void)
2732 if (audiobuf_handle > 0)
2733 return audiobuflen;
2734 return core_available();
2737 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize)
2739 talk_buffer_steal(); /* will use the mp3 buffer */
2740 mpeg_audiobuf = buf;
2741 audiobuflen = bufsize;
2742 if (global_settings.cuesheet)
2743 { /* enable cuesheet support */
2744 curr_cuesheet = (struct cuesheet*)mpeg_audiobuf;
2745 mpeg_audiobuf = SKIPBYTES(mpeg_audiobuf, sizeof(struct cuesheet));
2746 audiobuflen -= sizeof(struct cuesheet);
2748 talkbuf_init(mpeg_audiobuf);
2751 static void audio_reset_buffer(void)
2753 size_t bufsize = audiobuflen;
2755 /* alloc buffer if it's was never allocated or freed by audio_hard_stop() */
2756 if (!audiobuf_handle)
2757 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
2759 audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize);
2762 void audio_play(long offset)
2764 audio_reset_buffer();
2765 #ifdef SIMULATOR
2766 char name_buf[MAX_PATH+1];
2767 const char* trackname;
2768 int steps=0;
2770 is_playing = true;
2772 do {
2773 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2774 if (!trackname)
2775 break;
2776 if(mp3info(&taginfo, trackname)) {
2777 /* bad mp3, move on */
2778 if(++steps > playlist_amount())
2779 break;
2780 continue;
2782 #ifdef HAVE_MPEG_PLAY
2783 real_mpeg_play(trackname);
2784 #endif
2785 playlist_next(steps);
2786 taginfo.offset = offset;
2787 set_elapsed(&taginfo);
2788 is_playing = true;
2789 playing = true;
2790 break;
2791 } while(1);
2792 #else /* !SIMULATOR */
2793 is_playing = true;
2794 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2795 #endif /* !SIMULATOR */
2797 mpeg_errno = 0;
2800 void audio_stop(void)
2802 #ifndef SIMULATOR
2803 if (playing)
2805 struct trackdata *track = get_trackdata(0);
2806 prev_track_elapsed = track->id3.elapsed;
2808 mpeg_stop_done = false;
2809 queue_post(&mpeg_queue, MPEG_STOP, 0);
2810 while(!mpeg_stop_done)
2811 yield();
2812 #else /* SIMULATOR */
2813 paused = false;
2814 is_playing = false;
2815 playing = false;
2816 #endif /* SIMULATOR */
2817 /* give voice our entire buffer */
2818 talkbuf_init(mpeg_audiobuf);
2821 /* dummy */
2822 void audio_stop_recording(void)
2824 audio_stop();
2827 void audio_hard_stop(void)
2829 audio_stop();
2830 /* tell voice we obtain the buffer before freeing */
2831 talk_buffer_steal();
2832 if (audiobuf_handle > 0)
2834 audiobuf_handle = core_free(audiobuf_handle);
2835 mpeg_audiobuf = NULL;
2839 void audio_pause(void)
2841 #ifndef SIMULATOR
2842 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2843 #else /* SIMULATOR */
2844 is_playing = true;
2845 playing = false;
2846 paused = true;
2847 #endif /* SIMULATOR */
2850 void audio_resume(void)
2852 #ifndef SIMULATOR
2853 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2854 #else /* SIMULATOR */
2855 is_playing = true;
2856 playing = true;
2857 paused = false;
2858 #endif /* SIMULATOR */
2861 void audio_next(void)
2863 #ifndef SIMULATOR
2864 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2865 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2866 #else /* SIMULATOR */
2867 char name_buf[MAX_PATH+1];
2868 const char* file;
2869 int steps = 1;
2871 do {
2872 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2873 if(!file)
2874 break;
2875 if(mp3info(&taginfo, file)) {
2876 if(++steps > playlist_amount())
2877 break;
2878 continue;
2880 playlist_next(steps);
2881 current_track_counter++;
2882 is_playing = true;
2883 playing = true;
2884 break;
2885 } while(1);
2886 #endif /* SIMULATOR */
2889 void audio_prev(void)
2891 #ifndef SIMULATOR
2892 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2893 queue_post(&mpeg_queue, MPEG_PREV, 0);
2894 #else /* SIMULATOR */
2895 char name_buf[MAX_PATH+1];
2896 const char* file;
2897 int steps = -1;
2899 do {
2900 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2901 if(!file)
2902 break;
2903 if(mp3info(&taginfo, file)) {
2904 steps--;
2905 continue;
2907 playlist_next(steps);
2908 current_track_counter++;
2909 is_playing = true;
2910 playing = true;
2911 break;
2912 } while(1);
2913 #endif /* SIMULATOR */
2916 void audio_ff_rewind(long newpos)
2918 #ifndef SIMULATOR
2919 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2920 #else /* SIMULATOR */
2921 (void)newpos;
2922 #endif /* SIMULATOR */
2925 void audio_flush_and_reload_tracks(void)
2927 #ifndef SIMULATOR
2928 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2929 #endif /* !SIMULATOR*/
2932 int audio_status(void)
2934 int ret = 0;
2936 if(is_playing)
2937 ret |= AUDIO_STATUS_PLAY;
2939 if(paused)
2940 ret |= AUDIO_STATUS_PAUSE;
2942 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2943 if(is_recording && !is_prerecording)
2944 ret |= AUDIO_STATUS_RECORD;
2946 if(is_prerecording)
2947 ret |= AUDIO_STATUS_PRERECORD;
2948 #endif /* CONFIG_CODEC == MAS3587F */
2950 if(mpeg_errno)
2951 ret |= AUDIO_STATUS_ERROR;
2953 return ret;
2956 /* Unused function
2957 unsigned int audio_error(void)
2959 return mpeg_errno;
2963 void audio_error_clear(void)
2965 mpeg_errno = 0;
2968 #ifdef SIMULATOR
2969 static void mpeg_thread(void)
2971 struct mp3entry* id3;
2972 while ( 1 ) {
2973 if (is_playing) {
2974 id3 = audio_current_track();
2975 if (!paused)
2977 id3->elapsed+=1000;
2978 id3->offset+=1000;
2980 if (id3->elapsed>=id3->length)
2981 audio_next();
2983 sleep(HZ);
2986 #endif /* SIMULATOR */
2988 void audio_init(void)
2990 mpeg_errno = 0;
2992 talk_init();
2993 audio_reset_buffer();
2995 #ifndef SIMULATOR
2996 queue_init(&mpeg_queue, true);
2997 #endif /* !SIMULATOR */
2998 audio_thread_id = create_thread(mpeg_thread, mpeg_stack,
2999 sizeof(mpeg_stack), 0, mpeg_thread_name
3000 IF_PRIO(, PRIORITY_SYSTEM)
3001 IF_COP(, CPU));
3003 memset(trackdata, 0, sizeof(trackdata));
3005 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
3006 if (HW_MASK & PR_ACTIVE_HIGH)
3007 and_b(~0x08, &PADRH);
3008 else
3009 or_b(0x08, &PADRH);
3010 #endif /* CONFIG_CODEC == MAS3587F */
3012 #ifdef DEBUG
3013 #ifndef SIMULATOR
3014 dbg_timer_start();
3015 dbg_cnt2us(0);
3016 #endif /* !SIMULATOR */
3017 #endif /* DEBUG */
3020 #endif /* CONFIG_CODEC != SWCODEC */