GSoC/Buflib: Enable compaction in buflib.
[kugel-rb.git] / apps / mpeg.c
blob8bc9aed958e942cd53d29a8a53277b5f544cce37
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 /* Play time of the previous track */
132 static unsigned long prev_track_elapsed;
134 static int track_read_idx = 0;
135 static int track_write_idx = 0;
136 #endif /* !SIMULATOR */
138 /* Cuesheet support */
139 static struct cuesheet *curr_cuesheet = NULL;
140 static bool checked_for_cuesheet = false;
142 static const char mpeg_thread_name[] = "mpeg";
143 static unsigned int audio_thread_id;
144 static unsigned int mpeg_errno;
146 static bool playing = false; /* We are playing an MP3 stream */
147 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
148 static bool paused; /* playback is paused */
149 static int audiobuf_handle; /* handle to the audio buffer */
150 static char* mpeg_audiobuf; /* poiunter to the audio buffer */
151 static long audiobuflen; /* length of the audio buffer */
153 #ifdef SIMULATOR
154 static char mpeg_stack[DEFAULT_STACK_SIZE];
155 static struct mp3entry taginfo;
156 #else /* !SIMULATOR */
157 static struct event_queue mpeg_queue SHAREDBSS_ATTR;
158 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
160 static int audiobuf_write;
161 static int audiobuf_swapwrite;
162 static long audiobuf_read;
164 static int mpeg_file;
166 static bool play_pending; /* We are about to start playing */
167 static bool play_pending_track_change; /* When starting play we're starting a new file */
168 static bool filling; /* We are filling the buffer with data from disk */
169 static bool dma_underrun; /* True when the DMA has stopped because of
170 slow disk reading (read error, shaking) */
171 static bool mpeg_stop_done;
173 static int last_dma_tick = 0;
174 static int last_dma_chunk_size;
176 static long low_watermark; /* Dynamic low watermark level */
177 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
178 static long lowest_watermark_level; /* Debug value to observe the buffer
179 usage */
180 #if CONFIG_CODEC == MAS3587F
181 static char recording_filename[MAX_PATH]; /* argument to thread */
182 static char delayed_filename[MAX_PATH]; /* internal copy of above */
184 static char xing_buffer[MAX_XING_HEADER_SIZE];
186 static bool init_recording_done;
187 static bool init_playback_done;
188 static bool prerecording; /* True if prerecording is enabled */
189 static bool is_prerecording; /* True if we are prerecording */
190 static bool is_recording; /* We are recording */
192 static enum {
193 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
194 BUFFER_FULL,
195 NEW_FILE,
196 STOP_RECORDING
197 } saving_status;
199 static int rec_frequency_index; /* For create_xing_header() calls */
200 static int rec_version_index; /* For create_xing_header() calls */
202 struct prerecord_info {
203 int mempos;
204 unsigned long framecount;
207 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
208 static int prerecord_index; /* Current index in the prerecord buffer */
209 static int prerecording_max_seconds; /* Max number of seconds to store */
210 static int prerecord_count; /* Number of seconds in the prerecord buffer */
211 static int prerecord_timeout; /* The tick count of the next prerecord data
212 store */
214 static unsigned long record_start_time; /* Value of current_tick when recording
215 was started */
216 static unsigned long pause_start_time; /* Value of current_tick when pause was
217 started */
218 static unsigned long last_rec_time;
219 static unsigned long num_rec_bytes;
220 static unsigned long last_rec_bytes;
221 static unsigned long frame_count_start;
222 static unsigned long frame_count_end;
223 static unsigned long saved_header = 0;
225 /* Shadow MAS registers */
226 unsigned long shadow_encoder_control = 0;
227 #endif /* CONFIG_CODEC == MAS3587F */
229 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
230 unsigned long shadow_io_control_main = 0;
231 unsigned long shadow_soft_mute = 0;
232 unsigned shadow_codec_reg0;
233 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
235 #ifdef HAVE_RECORDING
236 static const unsigned char empty_id3_header[] =
238 'I', 'D', '3', 0x03, 0x00, 0x00,
239 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
241 #endif /* HAVE_RECORDING */
244 static int get_unplayed_space(void);
245 static int get_playable_space(void);
246 static int get_unswapped_space(void);
247 #endif /* !SIMULATOR */
249 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
250 static void init_recording(void);
251 static void prepend_header(void);
252 static void update_header(void);
253 static void start_prerecording(void);
254 static void start_recording(void);
255 static void stop_recording(void);
256 static int get_unsaved_space(void);
257 static void pause_recording(void);
258 static void resume_recording(void);
259 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
262 #ifndef SIMULATOR
263 static int num_tracks_in_memory(void)
265 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
268 #ifdef DEBUG_TAGS
269 static void debug_tags(void)
271 int i;
273 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
275 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
277 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
278 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
280 #else /* !DEBUG_TAGS */
281 #define debug_tags()
282 #endif /* !DEBUG_TAGS */
284 static void remove_current_tag(void)
286 if(num_tracks_in_memory() > 0)
288 /* First move the index, so nobody tries to access the tag */
289 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
290 checked_for_cuesheet = false;
291 debug_tags();
293 else
295 DEBUGF("remove_current_tag: no tracks to remove\n");
299 static void remove_all_non_current_tags(void)
301 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
302 debug_tags();
305 static void remove_all_tags(void)
307 track_write_idx = track_read_idx;
309 debug_tags();
312 static struct trackdata *get_trackdata(int offset)
314 if(offset >= num_tracks_in_memory())
315 return NULL;
316 else
317 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
319 #endif /* !SIMULATOR */
321 /***********************************************************************/
322 /* audio event handling */
324 #define MAX_EVENT_HANDLERS 10
325 struct event_handlers_table
327 AUDIO_EVENT_HANDLER handler;
328 unsigned short mask;
330 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
331 static int event_handlers_count = 0;
333 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
335 if (event_handlers_count < MAX_EVENT_HANDLERS)
337 event_handlers[event_handlers_count].handler = handler;
338 event_handlers[event_handlers_count].mask = mask;
339 event_handlers_count++;
343 /* dispatch calls each handler in the order registered and returns after some
344 handler actually handles the event (the event is assumed to no longer be valid
345 after this, due to the handler changing some condition); returns true if someone
346 handled the event, which is expected to cause the caller to skip its own handling
347 of the event */
348 #ifndef SIMULATOR
349 static bool audio_dispatch_event(unsigned short event, unsigned long data)
351 int i = 0;
352 for(i=0; i < event_handlers_count; i++)
354 if ( event_handlers[i].mask & event )
356 int rc = event_handlers[i].handler(event, data);
357 if ( rc == AUDIO_EVENT_RC_HANDLED )
358 return true;
361 return false;
363 #endif
365 /***********************************************************************/
367 static void set_elapsed(struct mp3entry* id3)
369 if ( id3->vbr ) {
370 if ( id3->has_toc ) {
371 /* calculate elapsed time using TOC */
372 int i;
373 unsigned int remainder, plen, relpos, nextpos;
375 /* find wich percent we're at */
376 for (i=0; i<100; i++ )
378 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
380 break;
384 i--;
385 if (i < 0)
386 i = 0;
388 relpos = id3->toc[i];
390 if (i < 99)
392 nextpos = id3->toc[i+1];
394 else
396 nextpos = 256;
399 remainder = id3->offset - (relpos * (id3->filesize / 256));
401 /* set time for this percent (divide before multiply to prevent
402 overflow on long files. loss of precision is negligible on
403 short files) */
404 id3->elapsed = i * (id3->length / 100);
406 /* calculate remainder time */
407 plen = (nextpos - relpos) * (id3->filesize / 256);
408 id3->elapsed += (((remainder * 100) / plen) *
409 (id3->length / 10000));
411 else {
412 /* no TOC exists. set a rough estimate using average bitrate */
413 int tpk = id3->length / (id3->filesize / 1024);
414 id3->elapsed = id3->offset / 1024 * tpk;
417 else
418 /* constant bitrate, use exact calculation */
419 id3->elapsed = id3->offset / (id3->bitrate / 8);
422 int audio_get_file_pos(void)
424 int pos = -1;
425 struct mp3entry *id3 = audio_current_track();
427 if (id3->vbr)
429 if (id3->has_toc)
431 /* Use the TOC to find the new position */
432 unsigned int percent, remainder;
433 int curtoc, nexttoc, plen;
435 percent = (id3->elapsed*100)/id3->length;
436 if (percent > 99)
437 percent = 99;
439 curtoc = id3->toc[percent];
441 if (percent < 99)
442 nexttoc = id3->toc[percent+1];
443 else
444 nexttoc = 256;
446 pos = (id3->filesize/256)*curtoc;
448 /* Use the remainder to get a more accurate position */
449 remainder = (id3->elapsed*100)%id3->length;
450 remainder = (remainder*100)/id3->length;
451 plen = (nexttoc - curtoc)*(id3->filesize/256);
452 pos += (plen/100)*remainder;
454 else
456 /* No TOC exists, estimate the new position */
457 pos = (id3->filesize / (id3->length / 1000)) *
458 (id3->elapsed / 1000);
461 else if (id3->bitrate)
462 pos = id3->elapsed * (id3->bitrate / 8);
463 else
465 return -1;
468 if (pos >= (int)(id3->filesize - id3->id3v1len))
470 /* Don't seek right to the end of the file so that we can
471 transition properly to the next song */
472 pos = id3->filesize - id3->id3v1len - 1;
474 else if (pos < (int)id3->first_frame_offset)
476 /* skip past id3v2 tag and other leading garbage */
477 pos = id3->first_frame_offset;
479 return pos;
482 unsigned long mpeg_get_last_header(void)
484 #ifdef SIMULATOR
485 return 0;
486 #else /* !SIMULATOR */
487 unsigned long tmp[2];
489 /* Read the frame data from the MAS and reconstruct it with the
490 frame sync and all */
491 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
492 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
493 #endif /* !SIMULATOR */
496 static void do_stop(void)
498 DEBUGF("MPEG_STOP\n");
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 DEBUGF("%s()\n", __func__);
519 long offset = audio_current_track()->offset;
520 int status = audio_status();
521 /* TODO: Do it without stopping playback, if possible */
522 /* don't call audio_hard_stop() as it frees this handle */
523 if (thread_self() == audio_thread_id)
524 { /* inline case MPEG_STOP (audio_stop()) response
525 * if we're in the audio thread since audio_stop() otherwise deadlocks */
526 do_stop();
528 else
529 audio_stop();
530 talk_buffer_steal(); /* we obtain control over the buffer */
532 /* we should be free to change the buffer now */
533 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
534 ssize_t size = (ssize_t)old_size - wanted_size;
535 switch (hints & BUFLIB_SHRINK_POS_MASK)
537 case BUFLIB_SHRINK_POS_BACK:
538 core_shrink(handle, start, size);
539 audio_reset_buffer_noalloc(start, size);
540 break;
541 case BUFLIB_SHRINK_POS_FRONT:
542 core_shrink(handle, start + wanted_size, size);
543 audio_reset_buffer_noalloc(start + wanted_size, size);
544 break;
546 if (!(status & AUDIO_STATUS_PAUSE))
547 { /* safe to call even from the audio thread (due to queue_post()) */
548 audio_play(offset);
551 return BUFLIB_CB_OK;
554 static struct buflib_callbacks ops = {
555 .move_callback = NULL,
556 .shrink_callback = shrink_callback,
559 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
561 (void)talk_buf; /* always grab the voice buffer for now */
563 if (buffer_size) /* special case for talk_init() */
564 audio_hard_stop();
566 if (!audiobuf_handle)
568 size_t bufsize;
569 /* audio_hard_stop() frees audiobuf, so re-aquire */
570 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
571 audiobuflen = bufsize;
572 if (buffer_size)
573 *buffer_size = audiobuflen;
575 mpeg_audiobuf = core_get_data(audiobuf_handle);
577 if (!buffer_size) /* special case for talk_init() */
578 talkbuf_init(mpeg_audiobuf);
580 return mpeg_audiobuf;
584 #ifndef SIMULATOR
585 /* Send callback events to notify about removing old tracks. */
586 static void generate_unbuffer_events(void)
588 int i;
589 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
590 int cur_idx = track_write_idx;
592 for (i = 0; i < numentries; i++)
594 /* Send an event to notify that track has finished. */
595 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
596 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
600 /* Send callback events to notify about new tracks. */
601 static void generate_postbuffer_events(void)
603 int i;
604 int numentries = num_tracks_in_memory();
605 int cur_idx = track_read_idx;
607 for (i = 0; i < numentries; i++)
609 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
610 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
614 static void recalculate_watermark(int bitrate)
616 int bytes_per_sec;
617 int time = storage_spinup_time();
619 /* A bitrate of 0 probably means empty VBR header. We play safe
620 and set a high threshold */
621 if(bitrate == 0)
622 bitrate = 320;
624 bytes_per_sec = bitrate * 1000 / 8;
626 if(time)
628 /* No drive spins up faster than 3.5s */
629 if(time < 350)
630 time = 350;
632 time = time * 3;
633 low_watermark = ((low_watermark_margin * HZ + time) *
634 bytes_per_sec) / HZ;
636 else
638 low_watermark = MPEG_LOW_WATER;
642 #ifdef HAVE_DISK_STORAGE
643 void audio_set_buffer_margin(int setting)
645 low_watermark_margin = setting; /* in seconds */
647 #endif
649 void audio_get_debugdata(struct audio_debug *dbgdata)
651 dbgdata->audiobuflen = audiobuflen;
652 dbgdata->audiobuf_write = audiobuf_write;
653 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
654 dbgdata->audiobuf_read = audiobuf_read;
656 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
658 #if CONFIG_CPU == SH7034
659 dbgdata->dma_on = (SCR0 & 0x80) != 0;
660 #endif
661 dbgdata->playing = playing;
662 dbgdata->play_pending = play_pending;
663 dbgdata->is_playing = is_playing;
664 dbgdata->filling = filling;
665 dbgdata->dma_underrun = dma_underrun;
667 dbgdata->unplayed_space = get_unplayed_space();
668 dbgdata->playable_space = get_playable_space();
669 dbgdata->unswapped_space = get_unswapped_space();
671 dbgdata->low_watermark_level = low_watermark;
672 dbgdata->lowest_watermark_level = lowest_watermark_level;
675 #ifdef DEBUG
676 static void dbg_timer_start(void)
678 /* We are using timer 2 */
680 TSTR &= ~0x04; /* Stop the timer */
681 TSNC &= ~0x04; /* No synchronization */
682 TMDR &= ~0x44; /* Operate normally */
684 TCNT2 = 0; /* Start counting at 0 */
685 TCR2 = 0x03; /* Sysclock/8 */
687 TSTR |= 0x04; /* Start timer 2 */
690 static int dbg_cnt2us(unsigned int cnt)
692 return (cnt * 10000) / (FREQ/800);
694 #endif /* DEBUG */
696 static int get_unplayed_space(void)
698 int space = audiobuf_write - audiobuf_read;
699 if (space < 0)
700 space += audiobuflen;
701 return space;
704 static int get_playable_space(void)
706 int space = audiobuf_swapwrite - audiobuf_read;
707 if (space < 0)
708 space += audiobuflen;
709 return space;
712 static int get_unplayed_space_current_song(void)
714 int space;
716 if (num_tracks_in_memory() > 1)
718 space = get_trackdata(1)->mempos - audiobuf_read;
720 else
722 space = audiobuf_write - audiobuf_read;
725 if (space < 0)
726 space += audiobuflen;
728 return space;
731 static int get_unswapped_space(void)
733 int space = audiobuf_write - audiobuf_swapwrite;
734 if (space < 0)
735 space += audiobuflen;
736 return space;
739 #if CONFIG_CODEC == MAS3587F
740 static int get_unsaved_space(void)
742 int space = audiobuf_write - audiobuf_read;
743 if (space < 0)
744 space += audiobuflen;
745 return space;
748 static void drain_dma_buffer(void)
750 while (PBDRH & 0x40)
752 xor_b(0x08, &PADRH);
754 while (PBDRH & 0x80);
756 xor_b(0x08, &PADRH);
758 while (!(PBDRH & 0x80));
762 #ifdef DEBUG
763 static long timing_info_index = 0;
764 static long timing_info[1024];
765 #endif /* DEBUG */
767 void rec_tick (void) __attribute__ ((section (".icode")));
768 void rec_tick(void)
770 int i;
771 int delay;
772 char data;
774 if(is_recording && (PBDRH & 0x40))
776 #ifdef DEBUG
777 timing_info[timing_info_index++] = current_tick;
778 TCNT2 = 0;
779 #endif /* DEBUG */
780 /* Note: Although this loop is run in interrupt context, further
781 * optimisation will do no good. The MAS would then deliver bad
782 * frames occasionally, as observed in extended experiments. */
783 i = 0;
784 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
786 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
788 delay = 100;
789 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
791 if (--delay <= 0) /* Bail out if we have to wait too long */
792 { /* i.e. the MAS doesn't want to talk to us */
793 xor_b(0x08, &PADRH); /* Set PR inactive */
794 goto transfer_end; /* and get out of here */
798 data = *(unsigned char *)0x04000000; /* read data byte */
800 xor_b(0x08, &PADRH); /* Set PR inactive */
802 mpeg_audiobuf[audiobuf_write++] = data;
804 if (audiobuf_write >= audiobuflen)
805 audiobuf_write = 0;
807 i++;
809 transfer_end:
811 #ifdef DEBUG
812 timing_info[timing_info_index++] = TCNT2 + (i << 16);
813 timing_info_index &= 0x3ff;
814 #endif /* DEBUG */
816 num_rec_bytes += i;
818 if(is_prerecording)
820 if(TIME_AFTER(current_tick, prerecord_timeout))
822 prerecord_timeout = current_tick + HZ;
823 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
826 else
828 /* Signal to save the data if we are running out of buffer
829 space */
830 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
831 && saving_status == NOT_SAVING)
833 saving_status = BUFFER_FULL;
834 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
839 #endif /* CONFIG_CODEC == MAS3587F */
841 void playback_tick(void)
843 struct trackdata *ptd = get_trackdata(0);
844 if(ptd)
846 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
847 last_dma_tick = current_tick;
848 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
849 (unsigned long)ptd->id3.elapsed);
853 static void reset_mp3_buffer(void)
855 audiobuf_read = 0;
856 audiobuf_write = 0;
857 audiobuf_swapwrite = 0;
858 lowest_watermark_level = audiobuflen;
861 /* DMA transfer end interrupt callback */
862 static void transfer_end(unsigned char** ppbuf, size_t* psize)
864 if(playing && !paused)
866 int unplayed_space_left;
867 int space_until_end_of_buffer;
868 int track_offset = 1;
869 struct trackdata *track;
871 audiobuf_read += last_dma_chunk_size;
872 if(audiobuf_read >= audiobuflen)
873 audiobuf_read = 0;
875 /* First, check if we are on a track boundary */
876 if (num_tracks_in_memory() > 1)
878 if (audiobuf_read == get_trackdata(track_offset)->mempos)
880 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
882 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
883 track_offset++;
888 unplayed_space_left = get_unplayed_space();
890 space_until_end_of_buffer = audiobuflen - audiobuf_read;
892 if(!filling && unplayed_space_left < low_watermark)
894 filling = true;
895 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
898 if(unplayed_space_left)
900 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
901 last_dma_chunk_size = MIN(last_dma_chunk_size,
902 space_until_end_of_buffer);
904 /* several tracks loaded? */
905 track = get_trackdata(track_offset);
906 if(track)
908 /* will we move across the track boundary? */
909 if (( audiobuf_read < track->mempos ) &&
910 ((audiobuf_read+last_dma_chunk_size) >
911 track->mempos ))
913 /* Make sure that we end exactly on the boundary */
914 last_dma_chunk_size = track->mempos - audiobuf_read;
918 *psize = last_dma_chunk_size & 0xffff;
919 *ppbuf = mpeg_audiobuf + audiobuf_read;
920 track = get_trackdata(0);
921 if(track)
922 track->id3.offset += last_dma_chunk_size;
924 /* Update the watermark debug level */
925 if(unplayed_space_left < lowest_watermark_level)
926 lowest_watermark_level = unplayed_space_left;
928 else
930 /* Check if the end of data is because of a hard disk error.
931 If there is an open file handle, we are still playing music.
932 If not, the last file has been loaded, and the file handle is
933 closed. */
934 if(mpeg_file >= 0)
936 /* Update the watermark debug level */
937 if(unplayed_space_left < lowest_watermark_level)
938 lowest_watermark_level = unplayed_space_left;
940 DEBUGF("DMA underrun.\n");
941 dma_underrun = true;
943 else
945 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
947 DEBUGF("No more MP3 data. Stopping.\n");
948 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
949 playing = false;
952 *psize = 0; /* no more transfer */
957 static struct trackdata *add_track_to_tag_list(const char *filename)
959 struct trackdata *track;
960 bool send_nid3_event;
962 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
964 DEBUGF("Tag memory is full\n");
965 return NULL;
968 track = &trackdata[track_write_idx];
970 /* grab id3 tag of new file and
971 remember where in memory it starts */
972 if(mp3info(&track->id3, filename))
974 DEBUGF("Bad mp3\n");
975 return NULL;
977 track->mempos = audiobuf_write;
978 track->id3.elapsed = 0;
979 #ifdef HAVE_LCD_BITMAP
980 if (track->id3.title)
981 lcd_getstringsize(track->id3.title, NULL, NULL);
982 if (track->id3.artist)
983 lcd_getstringsize(track->id3.artist, NULL, NULL);
984 if (track->id3.album)
985 lcd_getstringsize(track->id3.album, NULL, NULL);
986 #endif
988 /* if this track is the next track then let the UI know it can get it */
989 send_nid3_event = (track_write_idx == track_read_idx + 1);
990 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
991 if (send_nid3_event)
992 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
993 debug_tags();
994 return track;
997 static int new_file(int steps)
999 int max_steps = playlist_amount();
1000 int start = 0;
1001 int i;
1002 struct trackdata *track;
1003 char name_buf[MAX_PATH+1];
1004 const char *trackname;
1006 /* Find out how many steps to advance. The load_ahead_index field tells
1007 us how many playlist entries it had to skip to get to a valid one.
1008 We add those together to find out where to start. */
1009 if(steps > 0 && num_tracks_in_memory() > 1)
1011 /* Begin with the song after the currently playing one */
1012 i = 1;
1013 while((track = get_trackdata(i++)))
1015 start += track->load_ahead_index;
1019 do {
1020 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
1021 if ( !trackname )
1022 return -1;
1024 DEBUGF("Loading %s\n", trackname);
1026 mpeg_file = open(trackname, O_RDONLY);
1027 if(mpeg_file < 0) {
1028 DEBUGF("Couldn't open file: %s\n",trackname);
1029 if(steps < 0)
1030 steps--;
1031 else
1032 steps++;
1034 else
1036 struct trackdata *track = add_track_to_tag_list(trackname);
1038 if(!track)
1040 /* Bad mp3 file */
1041 if(steps < 0)
1042 steps--;
1043 else
1044 steps++;
1045 close(mpeg_file);
1046 mpeg_file = -1;
1048 else
1050 /* skip past id3v2 tag */
1051 lseek(mpeg_file,
1052 track->id3.first_frame_offset,
1053 SEEK_SET);
1054 track->id3.index = steps;
1055 track->load_ahead_index = steps;
1056 track->id3.offset = 0;
1058 if(track->id3.vbr)
1059 /* Average bitrate * 1.5 */
1060 recalculate_watermark(
1061 (track->id3.bitrate * 3) / 2);
1062 else
1063 recalculate_watermark(
1064 track->id3.bitrate);
1069 /* Bail out if no file could be opened */
1070 if(abs(steps) > max_steps)
1071 return -1;
1072 } while ( mpeg_file < 0 );
1074 return 0;
1077 static void stop_playing(void)
1079 struct trackdata *track;
1081 /* Stop the current stream */
1082 mp3_play_stop();
1083 playing = false;
1084 filling = false;
1086 track = get_trackdata(0);
1087 if (track != NULL)
1088 prev_track_elapsed = track->id3.elapsed;
1090 if(mpeg_file >= 0)
1091 close(mpeg_file);
1092 mpeg_file = -1;
1093 remove_all_tags();
1094 generate_unbuffer_events();
1095 reset_mp3_buffer();
1098 static void end_current_track(void) {
1099 struct trackdata *track;
1101 play_pending = false;
1102 playing = false;
1103 mp3_play_pause(false);
1105 track = get_trackdata(0);
1106 if (track != NULL)
1107 prev_track_elapsed = track->id3.elapsed;
1109 reset_mp3_buffer();
1110 remove_all_tags();
1111 generate_unbuffer_events();
1113 if(mpeg_file >= 0)
1114 close(mpeg_file);
1117 /* Is this a really the end of playback or is a new playlist starting */
1118 static void check_playlist_end(int direction)
1120 /* Use the largest possible step size to account for skipped tracks */
1121 int steps = playlist_amount();
1123 if (direction < 0)
1124 steps = -steps;
1126 if (playlist_next(steps) < 0)
1127 is_playing = false;
1130 static void update_playlist(void)
1132 if (num_tracks_in_memory() > 0)
1134 struct trackdata *track = get_trackdata(0);
1135 track->id3.index = playlist_next(track->id3.index);
1137 else
1139 /* End of playlist? */
1140 check_playlist_end(1);
1143 playlist_update_resume_info(audio_current_track());
1146 static void track_change(void)
1148 DEBUGF("Track change\n");
1150 struct trackdata *track = get_trackdata(0);
1151 prev_track_elapsed = track->id3.elapsed;
1153 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1154 /* Reset the AVC */
1155 sound_set_avc(-1);
1156 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1158 if (num_tracks_in_memory() > 0)
1160 remove_current_tag();
1161 update_playlist();
1162 if (is_playing)
1163 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1166 current_track_counter++;
1169 unsigned long audio_prev_elapsed(void)
1171 return prev_track_elapsed;
1174 #ifdef DEBUG
1175 void hexdump(const unsigned char *buf, int len)
1177 int i;
1179 for(i = 0;i < len;i++)
1181 if(i && (i & 15) == 0)
1183 DEBUGF("\n");
1185 DEBUGF("%02x ", buf[i]);
1187 DEBUGF("\n");
1189 #endif /* DEBUG */
1191 static void start_playback_if_ready(void)
1193 int playable_space;
1195 playable_space = audiobuf_swapwrite - audiobuf_read;
1196 if(playable_space < 0)
1197 playable_space += audiobuflen;
1199 /* See if we have started playing yet. If not, do it. */
1200 if(play_pending || dma_underrun)
1202 /* If the filling has stopped, and we still haven't reached
1203 the watermark, the file must be smaller than the
1204 watermark. We must still play it. */
1205 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1206 !filling || dma_underrun)
1208 DEBUGF("P\n");
1209 if (play_pending) /* don't do this when recovering from DMA underrun */
1211 generate_postbuffer_events(); /* signal first track as buffered */
1212 if (play_pending_track_change)
1214 play_pending_track_change = false;
1215 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1217 play_pending = false;
1219 playing = true;
1221 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1222 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1223 dma_underrun = false;
1225 if (!paused)
1227 last_dma_tick = current_tick;
1228 mp3_play_pause(true);
1231 /* Tell ourselves that we need more data */
1232 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1237 static bool swap_one_chunk(void)
1239 int free_space_left;
1240 int amount_to_swap;
1242 free_space_left = get_unswapped_space();
1244 if(free_space_left == 0 && !play_pending)
1245 return false;
1247 /* Swap in larger chunks when the user is waiting for the playback
1248 to start, or when there is dangerously little playable data left */
1249 if(play_pending)
1250 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1251 else
1253 if(get_playable_space() < low_watermark)
1254 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1255 free_space_left);
1256 else
1257 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1260 if(audiobuf_write < audiobuf_swapwrite)
1261 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1262 amount_to_swap);
1263 else
1264 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1265 amount_to_swap);
1267 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1269 audiobuf_swapwrite += amount_to_swap;
1270 if(audiobuf_swapwrite >= audiobuflen)
1272 audiobuf_swapwrite = 0;
1275 return true;
1278 static void mpeg_thread(void)
1280 static int pause_tick = 0;
1281 static unsigned int pause_track = 0;
1282 struct queue_event ev;
1283 int len;
1284 int free_space_left;
1285 int unplayed_space_left;
1286 int amount_to_read;
1287 int t1, t2;
1288 int start_offset;
1289 #if CONFIG_CODEC == MAS3587F
1290 int amount_to_save;
1291 int save_endpos = 0;
1292 int rc;
1293 int level;
1294 long offset;
1295 #endif /* CONFIG_CODEC == MAS3587F */
1297 is_playing = false;
1298 play_pending = false;
1299 playing = false;
1300 mpeg_file = -1;
1302 while(1)
1304 #if CONFIG_CODEC == MAS3587F
1305 if(mpeg_mode == MPEG_DECODER)
1307 #endif /* CONFIG_CODEC == MAS3587F */
1308 yield();
1310 /* Swap if necessary, and don't block on the queue_wait() */
1311 if(swap_one_chunk())
1313 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1315 else if (playing)
1317 /* periodically update resume info */
1318 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1320 else
1322 DEBUGF("S R:%x W:%x SW:%x\n",
1323 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1324 queue_wait(&mpeg_queue, &ev);
1327 start_playback_if_ready();
1329 switch(ev.id)
1331 case MPEG_PLAY:
1332 DEBUGF("MPEG_PLAY\n");
1334 #if CONFIG_TUNER
1335 /* Silence the A/D input, it may be on because the radio
1336 may be playing */
1337 mas_codec_writereg(6, 0x0000);
1338 #endif /* CONFIG_TUNER */
1340 /* Stop the current stream */
1341 paused = false;
1342 end_current_track();
1344 if ( new_file(0) == -1 )
1346 is_playing = false;
1347 track_change();
1348 break;
1351 start_offset = (int)ev.data;
1353 /* mid-song resume? */
1354 if (start_offset) {
1355 struct mp3entry* id3 = &get_trackdata(0)->id3;
1356 lseek(mpeg_file, start_offset, SEEK_SET);
1357 id3->offset = start_offset;
1358 set_elapsed(id3);
1360 else {
1361 /* skip past id3v2 tag */
1362 lseek(mpeg_file,
1363 get_trackdata(0)->id3.first_frame_offset,
1364 SEEK_SET);
1368 /* Make it read more data */
1369 filling = true;
1370 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1372 /* Tell the file loading code that we want to start playing
1373 as soon as we have some data */
1374 play_pending = true;
1375 play_pending_track_change = true;
1377 update_playlist();
1378 current_track_counter++;
1379 break;
1381 case MPEG_STOP:
1382 do_stop();
1383 break;
1385 case MPEG_PAUSE:
1386 DEBUGF("MPEG_PAUSE\n");
1387 /* Stop the current stream */
1388 if (playing)
1389 playlist_update_resume_info(audio_current_track());
1390 paused = true;
1391 playing = false;
1392 pause_tick = current_tick;
1393 pause_track = current_track_counter;
1394 mp3_play_pause(false);
1395 break;
1397 case MPEG_RESUME:
1398 DEBUGF("MPEG_RESUME\n");
1399 /* Continue the current stream */
1400 paused = false;
1401 if (!play_pending)
1403 playing = true;
1404 if ( current_track_counter == pause_track )
1405 last_dma_tick += current_tick - pause_tick;
1406 else
1407 last_dma_tick = current_tick;
1408 pause_tick = 0;
1409 mp3_play_pause(true);
1411 break;
1413 case MPEG_NEXT:
1414 DEBUGF("MPEG_NEXT\n");
1415 /* is next track in ram? */
1416 if ( num_tracks_in_memory() > 1 ) {
1417 int unplayed_space_left, unswapped_space_left;
1419 /* stop the current stream */
1420 play_pending = false;
1421 playing = false;
1422 mp3_play_pause(false);
1424 track_change();
1425 audiobuf_read = get_trackdata(0)->mempos;
1426 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1427 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1428 dma_underrun = false;
1429 last_dma_tick = current_tick;
1431 unplayed_space_left = get_unplayed_space();
1432 unswapped_space_left = get_unswapped_space();
1434 /* should we start reading more data? */
1435 if(!filling && (unplayed_space_left < low_watermark)) {
1436 filling = true;
1437 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1438 play_pending = true;
1439 } else if(unswapped_space_left &&
1440 unswapped_space_left > unplayed_space_left) {
1441 /* Stop swapping the data from the previous file */
1442 audiobuf_swapwrite = audiobuf_read;
1443 play_pending = true;
1444 } else {
1445 playing = true;
1446 if (!paused)
1447 mp3_play_pause(true);
1450 else {
1451 if (!playlist_check(1))
1452 break;
1454 /* stop the current stream */
1455 end_current_track();
1457 if (new_file(1) < 0) {
1458 DEBUGF("No more files to play\n");
1459 filling = false;
1461 check_playlist_end(1);
1462 current_track_counter++;
1463 } else {
1464 /* Make it read more data */
1465 filling = true;
1466 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1468 /* Tell the file loading code that we want
1469 to start playing as soon as we have some data */
1470 play_pending = true;
1471 play_pending_track_change = true;
1473 update_playlist();
1474 current_track_counter++;
1477 break;
1479 case MPEG_PREV: {
1480 DEBUGF("MPEG_PREV\n");
1482 if (!playlist_check(-1))
1483 break;
1485 /* stop the current stream */
1486 end_current_track();
1488 /* Open the next file */
1489 if (new_file(-1) < 0) {
1490 DEBUGF("No more files to play\n");
1491 filling = false;
1493 check_playlist_end(-1);
1494 current_track_counter++;
1495 } else {
1496 /* Make it read more data */
1497 filling = true;
1498 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1500 /* Tell the file loading code that we want to
1501 start playing as soon as we have some data */
1502 play_pending = true;
1503 play_pending_track_change = true;
1505 update_playlist();
1506 current_track_counter++;
1508 break;
1511 case MPEG_FF_REWIND: {
1512 struct mp3entry *id3 = audio_current_track();
1513 unsigned int oldtime = id3->elapsed;
1514 unsigned int newtime = (unsigned int)ev.data;
1515 int curpos, newpos, diffpos;
1516 DEBUGF("MPEG_FF_REWIND\n");
1518 id3->elapsed = newtime;
1520 newpos = audio_get_file_pos();
1521 if(newpos < 0)
1523 id3->elapsed = oldtime;
1524 break;
1527 if (mpeg_file >= 0)
1528 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1529 else
1530 curpos = id3->filesize;
1532 if (num_tracks_in_memory() > 1)
1534 /* We have started loading other tracks that need to be
1535 accounted for */
1536 struct trackdata *track;
1537 int i = 0;
1539 while((track = get_trackdata(i++)))
1541 curpos += track->id3.filesize;
1545 diffpos = curpos - newpos;
1547 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1549 int unplayed_space_left, unswapped_space_left;
1551 /* We are changing to a position that's already in
1552 memory, so we just move the DMA read pointer. */
1553 audiobuf_read = audiobuf_write - diffpos;
1554 if (audiobuf_read < 0)
1556 audiobuf_read += audiobuflen;
1559 unplayed_space_left = get_unplayed_space();
1560 unswapped_space_left = get_unswapped_space();
1562 /* If unswapped_space_left is larger than
1563 unplayed_space_left, it means that the swapwrite pointer
1564 hasn't yet advanced up to the new location of the read
1565 pointer. We just move it, there is no need to swap
1566 data that won't be played anyway. */
1568 if (unswapped_space_left > unplayed_space_left)
1570 DEBUGF("Moved swapwrite\n");
1571 audiobuf_swapwrite = audiobuf_read;
1572 play_pending = true;
1575 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1577 /* We need to load more data before starting */
1578 filling = true;
1579 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1580 play_pending = true;
1582 else
1584 /* resume will start at new position */
1585 last_dma_chunk_size =
1586 MIN(0x2000, get_unplayed_space_current_song());
1587 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1588 last_dma_chunk_size, transfer_end);
1589 dma_underrun = false;
1592 else
1594 /* Move to the new position in the file and start
1595 loading data */
1596 reset_mp3_buffer();
1598 if (num_tracks_in_memory() > 1)
1600 /* We have to reload the current track */
1601 close(mpeg_file);
1602 remove_all_non_current_tags();
1603 generate_unbuffer_events();
1604 mpeg_file = -1;
1607 if (mpeg_file < 0)
1609 mpeg_file = open(id3->path, O_RDONLY);
1610 if (mpeg_file < 0)
1612 id3->elapsed = oldtime;
1613 break;
1617 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1619 id3->elapsed = oldtime;
1620 break;
1623 filling = true;
1624 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1626 /* Tell the file loading code that we want to start playing
1627 as soon as we have some data */
1628 play_pending = true;
1631 id3->offset = newpos;
1633 break;
1636 case MPEG_FLUSH_RELOAD: {
1637 int numtracks = num_tracks_in_memory();
1638 bool reload_track = false;
1640 if (numtracks > 1)
1642 /* Reset the buffer */
1643 audiobuf_write = get_trackdata(1)->mempos;
1645 /* Reset swapwrite unless we're still swapping current
1646 track */
1647 if (get_unplayed_space() <= get_playable_space())
1648 audiobuf_swapwrite = audiobuf_write;
1650 close(mpeg_file);
1651 remove_all_non_current_tags();
1652 generate_unbuffer_events();
1653 mpeg_file = -1;
1654 reload_track = true;
1656 else if (numtracks == 1 && mpeg_file < 0)
1658 reload_track = true;
1661 if(reload_track && new_file(1) >= 0)
1663 /* Tell ourselves that we want more data */
1664 filling = true;
1665 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1668 break;
1671 case MPEG_NEED_DATA:
1672 free_space_left = audiobuf_read - audiobuf_write;
1674 /* We interpret 0 as "empty buffer" */
1675 if(free_space_left <= 0)
1676 free_space_left += audiobuflen;
1678 unplayed_space_left = audiobuflen - free_space_left;
1680 /* Make sure that we don't fill the entire buffer */
1681 free_space_left -= MPEG_HIGH_WATER;
1683 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1684 generate_unbuffer_events();
1686 /* do we have any more buffer space to fill? */
1687 if(free_space_left <= 0)
1689 DEBUGF("0\n");
1690 filling = false;
1691 generate_postbuffer_events();
1692 storage_sleep();
1693 break;
1696 /* Read small chunks while we are below the low water mark */
1697 if(unplayed_space_left < low_watermark)
1698 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1699 free_space_left);
1700 else
1701 amount_to_read = free_space_left;
1703 /* Don't read more than until the end of the buffer */
1704 amount_to_read = MIN(audiobuflen - audiobuf_write,
1705 amount_to_read);
1706 #if (CONFIG_STORAGE & STORAGE_MMC)
1707 /* MMC is slow, so don't read too large chunks */
1708 amount_to_read = MIN(0x40000, amount_to_read);
1709 #elif MEMORYSIZE == 8
1710 amount_to_read = MIN(0x100000, amount_to_read);
1711 #endif
1713 /* Read as much mpeg data as we can fit in the buffer */
1714 if(mpeg_file >= 0)
1716 DEBUGF("R\n");
1717 t1 = current_tick;
1718 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1719 amount_to_read);
1720 if(len > 0)
1722 t2 = current_tick;
1723 DEBUGF("time: %d\n", t2 - t1);
1724 DEBUGF("R: %x\n", len);
1726 /* Now make sure that we don't feed the MAS with ID3V1
1727 data */
1728 if (len < amount_to_read)
1730 int i;
1731 static const unsigned char tag[] = "TAG";
1732 int taglen = 128;
1733 int tagptr = audiobuf_write + len - 128;
1735 /* Really rare case: entire potential tag wasn't
1736 read in this call AND audiobuf_write < 128 */
1737 if (tagptr < 0)
1738 tagptr += audiobuflen;
1740 for(i = 0;i < 3;i++)
1742 if(tagptr >= audiobuflen)
1743 tagptr -= audiobuflen;
1745 if(mpeg_audiobuf[tagptr] != tag[i])
1747 taglen = 0;
1748 break;
1751 tagptr++;
1754 if(taglen)
1756 /* Skip id3v1 tag */
1757 DEBUGF("Skipping ID3v1 tag\n");
1758 len -= taglen;
1760 /* In the very rare case when the entire tag
1761 wasn't read in this read() len will be < 0.
1762 Take care of this when changing the write
1763 pointer. */
1767 audiobuf_write += len;
1769 if (audiobuf_write < 0)
1770 audiobuf_write += audiobuflen;
1772 if(audiobuf_write >= audiobuflen)
1774 audiobuf_write = 0;
1775 DEBUGF("W\n");
1778 /* Tell ourselves that we want more data */
1779 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1781 else
1783 if(len < 0)
1785 DEBUGF("MPEG read error\n");
1788 close(mpeg_file);
1789 mpeg_file = -1;
1791 if(new_file(1) < 0)
1793 /* No more data to play */
1794 DEBUGF("No more files to play\n");
1795 filling = false;
1797 else
1799 /* Tell ourselves that we want more data */
1800 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1804 break;
1806 case MPEG_TRACK_CHANGE:
1807 track_change();
1808 break;
1810 #ifndef USB_NONE
1811 case SYS_USB_CONNECTED:
1812 is_playing = false;
1813 paused = false;
1814 stop_playing();
1816 /* Tell the USB thread that we are safe */
1817 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1818 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1820 /* Wait until the USB cable is extracted again */
1821 usb_wait_for_disconnect(&mpeg_queue);
1822 break;
1823 #endif /* !USB_NONE */
1825 #if CONFIG_CODEC == MAS3587F
1826 case MPEG_INIT_RECORDING:
1827 init_recording();
1828 init_recording_done = true;
1829 break;
1830 #endif /* CONFIG_CODEC == MAS3587F */
1832 case SYS_TIMEOUT:
1833 if (playing)
1834 playlist_update_resume_info(audio_current_track());
1835 break;
1837 #if CONFIG_CODEC == MAS3587F
1839 else
1841 queue_wait(&mpeg_queue, &ev);
1842 switch(ev.id)
1844 case MPEG_RECORD:
1845 if (is_prerecording)
1847 int startpos;
1849 /* Go back prerecord_count seconds in the buffer */
1850 startpos = prerecord_index - prerecord_count;
1851 if(startpos < 0)
1852 startpos += prerecording_max_seconds;
1854 /* Read the position data from the prerecord buffer */
1855 frame_count_start = prerecord_buffer[startpos].framecount;
1856 startpos = prerecord_buffer[startpos].mempos;
1858 DEBUGF("Start looking at address %x (%x)\n",
1859 mpeg_audiobuf+startpos, startpos);
1861 saved_header = mpeg_get_last_header();
1863 mem_find_next_frame(startpos, &offset, 1800,
1864 saved_header, mpeg_audiobuf,
1865 audiobuflen);
1867 audiobuf_read = startpos + offset;
1868 if(audiobuf_read >= audiobuflen)
1869 audiobuf_read -= audiobuflen;
1871 DEBUGF("New audiobuf_read address: %x (%x)\n",
1872 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1874 level = disable_irq_save();
1875 num_rec_bytes = get_unsaved_space();
1876 restore_irq(level);
1878 else
1880 frame_count_start = 0;
1881 num_rec_bytes = 0;
1882 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1883 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1886 prepend_header();
1887 DEBUGF("Recording...\n");
1888 start_recording();
1890 /* Wait until at least one frame is encoded and get the
1891 frame header, for later use by the Xing header
1892 generation */
1893 sleep(HZ/5);
1894 saved_header = mpeg_get_last_header();
1896 /* delayed until buffer is saved, don't open yet */
1897 strcpy(delayed_filename, recording_filename);
1898 mpeg_file = -1;
1900 break;
1902 case MPEG_STOP:
1903 DEBUGF("MPEG_STOP\n");
1905 stop_recording();
1907 /* Save the remaining data in the buffer */
1908 save_endpos = audiobuf_write;
1909 saving_status = STOP_RECORDING;
1910 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1911 break;
1913 case MPEG_STOP_DONE:
1914 DEBUGF("MPEG_STOP_DONE\n");
1916 if (mpeg_file >= 0)
1917 close(mpeg_file);
1918 mpeg_file = -1;
1920 update_header();
1921 #ifdef DEBUG1
1923 int i;
1924 for(i = 0;i < 512;i++)
1926 DEBUGF("%d - %d us (%d bytes)\n",
1927 timing_info[i*2],
1928 (timing_info[i*2+1] & 0xffff) *
1929 10000 / 13824,
1930 timing_info[i*2+1] >> 16);
1933 #endif /* DEBUG1 */
1935 if (prerecording)
1937 start_prerecording();
1939 mpeg_stop_done = true;
1940 break;
1942 case MPEG_NEW_FILE:
1943 /* Bail out when a more important save is happening */
1944 if (saving_status > NEW_FILE)
1945 break;
1947 /* Make sure we have at least one complete frame
1948 in the buffer. If we haven't recorded a single
1949 frame within 200ms, the MAS is probably not recording
1950 anything, and we bail out. */
1951 amount_to_save = get_unsaved_space();
1952 if (amount_to_save < 1800)
1954 sleep(HZ/5);
1955 amount_to_save = get_unsaved_space();
1958 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1959 &frame_count_end, 1);
1961 last_rec_time = current_tick - record_start_time;
1962 record_start_time = current_tick;
1963 if (paused)
1964 pause_start_time = record_start_time;
1966 /* capture all values at one point */
1967 level = disable_irq_save();
1968 save_endpos = audiobuf_write;
1969 last_rec_bytes = num_rec_bytes;
1970 num_rec_bytes = 0;
1971 restore_irq(level);
1973 if (amount_to_save >= 1800)
1975 /* Now find a frame boundary to split at */
1976 save_endpos -= 1800;
1977 if (save_endpos < 0)
1978 save_endpos += audiobuflen;
1980 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1981 saved_header, mpeg_audiobuf,
1982 audiobuflen);
1983 if (!rc) /* No header found, save whole buffer */
1984 offset = 1800;
1986 save_endpos += offset;
1987 if (save_endpos >= audiobuflen)
1988 save_endpos -= audiobuflen;
1990 last_rec_bytes += offset - 1800;
1991 level = disable_irq_save();
1992 num_rec_bytes += 1800 - offset;
1993 restore_irq(level);
1996 saving_status = NEW_FILE;
1997 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1998 break;
2000 case MPEG_SAVE_DATA:
2001 if (saving_status == BUFFER_FULL)
2002 save_endpos = audiobuf_write;
2004 if (mpeg_file < 0) /* delayed file open */
2006 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
2008 if (mpeg_file < 0)
2009 panicf("recfile: %d", mpeg_file);
2012 amount_to_save = save_endpos - audiobuf_read;
2013 if (amount_to_save < 0)
2014 amount_to_save += audiobuflen;
2016 amount_to_save = MIN(amount_to_save,
2017 audiobuflen - audiobuf_read);
2018 #if (CONFIG_STORAGE & STORAGE_MMC)
2019 /* MMC is slow, so don't save too large chunks at once */
2020 amount_to_save = MIN(0x40000, amount_to_save);
2021 #elif MEMORYSIZE == 8
2022 amount_to_save = MIN(0x100000, amount_to_save);
2023 #endif
2024 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
2025 amount_to_save);
2026 if (rc < 0)
2028 if (errno == ENOSPC)
2030 mpeg_errno = AUDIOERR_DISK_FULL;
2031 stop_recording();
2032 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2033 /* will close the file */
2034 break;
2036 else
2037 panicf("rec wrt: %d", rc);
2040 audiobuf_read += amount_to_save;
2041 if (audiobuf_read >= audiobuflen)
2042 audiobuf_read = 0;
2044 if (audiobuf_read == save_endpos) /* all saved */
2046 switch (saving_status)
2048 case BUFFER_FULL:
2049 rc = fsync(mpeg_file);
2050 if (rc < 0)
2051 panicf("rec fls: %d", rc);
2052 storage_sleep();
2053 break;
2055 case NEW_FILE:
2056 /* Close the current file */
2057 rc = close(mpeg_file);
2058 if (rc < 0)
2059 panicf("rec cls: %d", rc);
2060 mpeg_file = -1;
2061 update_header();
2062 storage_sleep();
2064 /* copy new filename */
2065 strcpy(delayed_filename, recording_filename);
2066 prepend_header();
2067 frame_count_start = frame_count_end;
2068 break;
2070 case STOP_RECORDING:
2071 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2072 /* will close the file */
2073 break;
2075 default:
2076 break;
2078 saving_status = NOT_SAVING;
2080 else /* tell ourselves to save the next chunk */
2081 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2083 break;
2085 case MPEG_PRERECORDING_TICK:
2086 if(!is_prerecording)
2087 break;
2089 /* Store the write pointer every second */
2090 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2091 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2092 &prerecord_buffer[prerecord_index].framecount, 1);
2094 /* Wrap if necessary */
2095 if(++prerecord_index == prerecording_max_seconds)
2096 prerecord_index = 0;
2098 /* Update the number of seconds recorded */
2099 if(prerecord_count < prerecording_max_seconds)
2100 prerecord_count++;
2101 break;
2103 case MPEG_INIT_PLAYBACK:
2104 /* Stop the prerecording */
2105 stop_recording();
2106 reset_mp3_buffer();
2107 mp3_play_init();
2108 init_playback_done = true;
2109 break;
2111 case MPEG_PAUSE_RECORDING:
2112 pause_recording();
2113 break;
2115 case MPEG_RESUME_RECORDING:
2116 resume_recording();
2117 break;
2119 case SYS_USB_CONNECTED:
2120 /* We can safely go to USB mode if no recording
2121 is taking place */
2122 if((!is_recording || is_prerecording) && mpeg_stop_done)
2124 /* Even if we aren't recording, we still call this
2125 function, to put the MAS in monitoring mode,
2126 to save power. */
2127 stop_recording();
2129 /* Tell the USB thread that we are safe */
2130 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2131 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2133 /* Wait until the USB cable is extracted again */
2134 usb_wait_for_disconnect(&mpeg_queue);
2136 break;
2139 #endif /* CONFIG_CODEC == MAS3587F */
2142 #endif /* !SIMULATOR */
2144 struct mp3entry* audio_current_track(void)
2146 #ifdef SIMULATOR
2147 struct mp3entry *id3 = &taginfo;
2148 #else /* !SIMULATOR */
2149 if(num_tracks_in_memory())
2151 struct mp3entry *id3 = &get_trackdata(0)->id3;
2152 #endif
2153 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2155 checked_for_cuesheet = true; /* only check once per track */
2156 char cuepath[MAX_PATH];
2158 if (look_for_cuesheet_file(id3->path, cuepath) &&
2159 parse_cuesheet(cuepath, curr_cuesheet))
2161 id3->cuesheet = curr_cuesheet;
2164 return id3;
2165 #ifndef SIMULATOR
2167 else
2168 return NULL;
2169 #endif /* !SIMULATOR */
2172 struct mp3entry* audio_next_track(void)
2174 #ifdef SIMULATOR
2175 return &taginfo;
2176 #else /* !SIMULATOR */
2177 if(num_tracks_in_memory() > 1)
2178 return &get_trackdata(1)->id3;
2179 else
2180 return NULL;
2181 #endif /* !SIMULATOR */
2184 #if CONFIG_CODEC == MAS3587F
2185 #ifndef SIMULATOR
2186 void audio_init_playback(void)
2188 init_playback_done = false;
2189 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2191 while(!init_playback_done)
2192 sleep(1);
2196 /****************************************************************************
2197 * Recording functions
2198 ***************************************************************************/
2199 void audio_init_recording(void)
2201 init_recording_done = false;
2202 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2204 while(!init_recording_done)
2205 sleep(1);
2208 static void init_recording(void)
2210 unsigned long val;
2211 int rc;
2213 /* Disable IRQ6 */
2214 IPRB &= 0xff0f;
2216 stop_playing();
2217 is_playing = false;
2218 paused = false;
2220 /* Init the recording variables */
2221 is_recording = false;
2222 is_prerecording = false;
2224 mpeg_stop_done = true;
2226 mas_reset();
2228 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2229 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2230 if(rc < 0)
2231 panicf("mas_ctrl_w: %d", rc);
2233 /* Stop the current application */
2234 val = 0;
2235 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2238 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2239 } while(val);
2241 /* Perform black magic as described by the data sheet */
2242 if((mas_version_code & 0x0fff) == 0x0102)
2244 DEBUGF("Performing MAS black magic for B2 version\n");
2245 mas_writereg(0xa3, 0x98);
2246 mas_writereg(0x94, 0xfffff);
2247 val = 0;
2248 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2249 mas_writereg(0xa3, 0x90);
2252 /* Enable A/D Converters */
2253 shadow_codec_reg0 = 0xcccd;
2254 mas_codec_writereg(0x0, shadow_codec_reg0);
2256 /* Copy left channel to right (mono mode) */
2257 mas_codec_writereg(8, 0x8000);
2259 /* ADC scale 0%, DSP scale 100%
2260 We use the DSP output for monitoring, because it works with all
2261 sources including S/PDIF */
2262 mas_codec_writereg(6, 0x0000);
2263 mas_codec_writereg(7, 0x4000);
2265 /* No mute */
2266 shadow_soft_mute = 0;
2267 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2269 #ifdef HAVE_SPDIF_OUT
2270 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2271 #else
2272 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2273 #endif
2274 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2276 /* Set Demand mode, monitoring OFF and validate all settings */
2277 shadow_io_control_main = 0x125;
2278 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2280 /* Start the encoder application */
2281 val = 0x40;
2282 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2285 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2286 } while(!(val & 0x40));
2288 /* We have started the recording application with monitoring OFF.
2289 This is because we want to record at least one frame to fill the DMA
2290 buffer, because the silly MAS will not negate EOD until at least one
2291 DMA transfer has taken place.
2292 Now let's wait for some data to be encoded. */
2293 sleep(HZ/5);
2295 /* Now set it to Monitoring mode as default, saves power */
2296 shadow_io_control_main = 0x525;
2297 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2299 /* Wait until the DSP has accepted the settings */
2302 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2303 } while(val & 1);
2305 drain_dma_buffer();
2306 mpeg_mode = MPEG_ENCODER;
2308 DEBUGF("MAS Recording application started\n");
2310 /* At this point, all settings are the reset MAS defaults, next thing is to
2311 call mpeg_set_recording_options(). */
2314 void audio_record(const char *filename)
2316 mpeg_errno = 0;
2318 strlcpy(recording_filename, filename, MAX_PATH);
2320 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2323 void audio_pause_recording(void)
2325 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2328 void audio_resume_recording(void)
2330 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2333 static void prepend_header(void)
2335 int startpos;
2336 unsigned i;
2338 /* Make room for header */
2339 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2340 if(audiobuf_read < 0)
2342 /* Clear the bottom half */
2343 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2345 /* And the top half */
2346 audiobuf_read += audiobuflen;
2347 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2349 else
2351 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2353 /* Copy the empty ID3 header */
2354 startpos = audiobuf_read;
2355 for(i = 0; i < sizeof(empty_id3_header); i++)
2357 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2358 if(startpos == audiobuflen)
2359 startpos = 0;
2363 static void update_header(void)
2365 int fd, framelen;
2366 unsigned long frames;
2368 if (last_rec_bytes > 0)
2370 /* Create the Xing header */
2371 fd = open(delayed_filename, O_RDWR);
2372 if (fd < 0)
2373 panicf("rec upd: %d (%s)", fd, recording_filename);
2375 frames = frame_count_end - frame_count_start;
2376 /* If the number of recorded frames has reached 0x7ffff,
2377 we can no longer trust it */
2378 if (frame_count_end == 0x7ffff)
2379 frames = 0;
2381 /* saved_header is saved right before stopping the MAS */
2382 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2383 frames, last_rec_time * (1000/HZ),
2384 saved_header, NULL, false,
2385 mpeg_audiobuf, audiobuflen);
2387 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2388 write(fd, xing_buffer, framelen);
2389 close(fd);
2393 static void start_prerecording(void)
2395 unsigned long val;
2397 DEBUGF("Starting prerecording\n");
2399 prerecord_index = 0;
2400 prerecord_count = 0;
2401 prerecord_timeout = current_tick + HZ;
2402 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2403 reset_mp3_buffer();
2405 is_prerecording = true;
2407 /* Stop monitoring and start the encoder */
2408 shadow_io_control_main &= ~(1 << 10);
2409 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2410 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2412 /* Wait until the DSP has accepted the settings */
2415 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2416 } while(val & 1);
2418 is_recording = true;
2419 saving_status = NOT_SAVING;
2421 demand_irq_enable(true);
2424 static void start_recording(void)
2426 unsigned long val;
2428 if(is_prerecording)
2430 /* This will make the IRQ handler start recording
2431 for real, i.e send MPEG_SAVE_DATA messages when
2432 the buffer is full */
2433 is_prerecording = false;
2435 else
2437 /* If prerecording is off, we need to stop the monitoring
2438 and start the encoder */
2439 shadow_io_control_main &= ~(1 << 10);
2440 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2441 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2443 /* Wait until the DSP has accepted the settings */
2446 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2447 } while(val & 1);
2450 is_recording = true;
2451 saving_status = NOT_SAVING;
2452 paused = false;
2454 /* Store the current time */
2455 if(prerecording)
2456 record_start_time = current_tick - prerecord_count * HZ;
2457 else
2458 record_start_time = current_tick;
2460 pause_start_time = 0;
2462 demand_irq_enable(true);
2465 static void pause_recording(void)
2467 pause_start_time = current_tick;
2469 /* Set the pause bit */
2470 shadow_soft_mute |= 2;
2471 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2473 paused = true;
2476 static void resume_recording(void)
2478 paused = false;
2480 /* Clear the pause bit */
2481 shadow_soft_mute &= ~2;
2482 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2484 /* Compensate for the time we have been paused */
2485 if(pause_start_time)
2487 record_start_time =
2488 current_tick - (pause_start_time - record_start_time);
2489 pause_start_time = 0;
2493 static void stop_recording(void)
2495 unsigned long val;
2497 /* Let it finish the last frame */
2498 if(!paused)
2499 pause_recording();
2500 sleep(HZ/5);
2502 demand_irq_enable(false);
2504 is_recording = false;
2505 is_prerecording = false;
2507 last_rec_bytes = num_rec_bytes;
2508 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2509 last_rec_time = current_tick - record_start_time;
2511 /* Start monitoring */
2512 shadow_io_control_main |= (1 << 10);
2513 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2514 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2516 /* Wait until the DSP has accepted the settings */
2519 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2520 } while(val & 1);
2522 resume_recording();
2525 void audio_set_recording_options(struct audio_recording_options *options)
2527 bool is_mpeg1;
2529 is_mpeg1 = (options->rec_frequency < 3);
2531 rec_version_index = is_mpeg1?3:2;
2532 rec_frequency_index = options->rec_frequency % 3;
2534 shadow_encoder_control = (options->rec_quality << 17) |
2535 (rec_frequency_index << 10) |
2536 ((is_mpeg1?1:0) << 9) |
2537 (((options->rec_channels * 2 + 1) & 3) << 6) |
2538 (1 << 5) /* MS-stereo */ |
2539 (1 << 2) /* Is an original */;
2540 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2542 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2544 #if CONFIG_TUNER & S1A0903X01
2545 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2546 interference with the Samsung tuner. */
2547 if (rec_frequency_index)
2548 mas_store_pllfreq(24576000);
2549 else
2550 mas_store_pllfreq(22579000);
2551 #endif
2553 shadow_soft_mute = options->rec_editable?4:0;
2554 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2556 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2558 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2559 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2560 (1 << 5) | /* SDO strobe invert */
2561 ((is_mpeg1?0:1) << 3) |
2562 (1 << 2) | /* Inverted SIBC clock signal */
2563 1; /* Validate */
2564 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2566 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2568 if(options->rec_source == AUDIO_SRC_MIC)
2570 /* Copy left channel to right (mono mode) */
2571 mas_codec_writereg(8, 0x8000);
2573 else
2575 /* Stereo input mode */
2576 mas_codec_writereg(8, 0);
2579 prerecording_max_seconds = options->rec_prerecord_time;
2580 if(prerecording_max_seconds)
2582 prerecording = true;
2583 start_prerecording();
2585 else
2587 prerecording = false;
2588 is_prerecording = false;
2589 is_recording = false;
2593 /* If use_mic is true, the left gain is used */
2594 void audio_set_recording_gain(int left, int right, int type)
2596 /* Enable both left and right A/D */
2597 shadow_codec_reg0 = (left << 12) |
2598 (right << 8) |
2599 (left << 4) |
2600 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2601 0x0007;
2602 mas_codec_writereg(0x0, shadow_codec_reg0);
2605 /* try to make some kind of beep, also in recording mode */
2606 void audio_beep(int duration)
2608 long starttick = current_tick;
2610 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2611 * While this is still audible even without an external signal,
2612 * it doesn't affect the (pre-)recording. */
2613 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2614 mas_codec_writereg(0, shadow_codec_reg0);
2615 yield();
2617 while (current_tick - starttick < duration);
2620 void audio_new_file(const char *filename)
2622 mpeg_errno = 0;
2624 strlcpy(recording_filename, filename, MAX_PATH);
2626 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2629 unsigned long audio_recorded_time(void)
2631 if(is_prerecording)
2632 return prerecord_count * HZ;
2634 if(is_recording)
2636 if(paused)
2637 return pause_start_time - record_start_time;
2638 else
2639 return current_tick - record_start_time;
2642 return 0;
2645 unsigned long audio_num_recorded_bytes(void)
2647 int num_bytes;
2648 int index;
2650 if(is_recording)
2652 if(is_prerecording)
2654 index = prerecord_index - prerecord_count;
2655 if(index < 0)
2656 index += prerecording_max_seconds;
2658 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2659 if(num_bytes < 0)
2660 num_bytes += audiobuflen;
2662 return num_bytes;
2664 else
2665 return num_rec_bytes;
2667 else
2668 return 0;
2671 #else /* SIMULATOR */
2673 /* dummies coming up */
2675 void audio_init_playback(void)
2677 /* a dummy */
2679 unsigned long audio_recorded_time(void)
2681 /* a dummy */
2682 return 0;
2684 void audio_beep(int duration)
2686 /* a dummy */
2687 (void)duration;
2689 void audio_pause_recording(void)
2691 /* a dummy */
2693 void audio_resume_recording(void)
2695 /* a dummy */
2697 unsigned long audio_num_recorded_bytes(void)
2699 /* a dummy */
2700 return 0;
2702 void audio_record(const char *filename)
2704 /* a dummy */
2705 (void)filename;
2707 void audio_new_file(const char *filename)
2709 /* a dummy */
2710 (void)filename;
2713 void audio_set_recording_gain(int left, int right, int type)
2715 /* a dummy */
2716 (void)left;
2717 (void)right;
2718 (void)type;
2720 void audio_init_recording(void)
2722 /* a dummy */
2724 void audio_set_recording_options(struct audio_recording_options *options)
2726 /* a dummy */
2727 (void)options;
2729 #endif /* SIMULATOR */
2730 #endif /* CONFIG_CODEC == MAS3587F */
2732 size_t audio_buffer_available(void)
2734 if (audiobuf_handle > 0)
2735 return audiobuflen;
2736 return core_available();
2739 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize)
2741 talk_buffer_steal(); /* will use the mp3 buffer */
2742 mpeg_audiobuf = buf;
2743 audiobuflen = bufsize;
2744 if (global_settings.cuesheet)
2745 { /* enable cuesheet support */
2746 curr_cuesheet = (struct cuesheet*)mpeg_audiobuf;
2747 mpeg_audiobuf = SKIPBYTES(mpeg_audiobuf, sizeof(struct cuesheet));
2748 audiobuflen -= sizeof(struct cuesheet);
2750 talkbuf_init(mpeg_audiobuf);
2753 static void audio_reset_buffer(void)
2755 size_t bufsize = audiobuflen;
2757 /* alloc buffer if it's was never allocated or freed by audio_hard_stop() */
2758 if (!audiobuf_handle)
2759 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
2761 audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize);
2764 void audio_play(long offset)
2766 audio_reset_buffer();
2767 #ifdef SIMULATOR
2768 char name_buf[MAX_PATH+1];
2769 const char* trackname;
2770 int steps=0;
2772 is_playing = true;
2774 do {
2775 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2776 if (!trackname)
2777 break;
2778 if(mp3info(&taginfo, trackname)) {
2779 /* bad mp3, move on */
2780 if(++steps > playlist_amount())
2781 break;
2782 continue;
2784 #ifdef HAVE_MPEG_PLAY
2785 real_mpeg_play(trackname);
2786 #endif
2787 playlist_next(steps);
2788 taginfo.offset = offset;
2789 set_elapsed(&taginfo);
2790 is_playing = true;
2791 playing = true;
2792 break;
2793 } while(1);
2794 #else /* !SIMULATOR */
2795 is_playing = true;
2796 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2797 #endif /* !SIMULATOR */
2799 mpeg_errno = 0;
2802 void audio_stop(void)
2804 #ifndef SIMULATOR
2805 if (playing)
2807 struct trackdata *track = get_trackdata(0);
2808 prev_track_elapsed = track->id3.elapsed;
2810 mpeg_stop_done = false;
2811 queue_post(&mpeg_queue, MPEG_STOP, 0);
2812 while(!mpeg_stop_done)
2813 yield();
2814 #else /* SIMULATOR */
2815 paused = false;
2816 is_playing = false;
2817 playing = false;
2818 #endif /* SIMULATOR */
2819 /* give voice our entire buffer */
2820 talkbuf_init(mpeg_audiobuf);
2823 /* dummy */
2824 void audio_stop_recording(void)
2826 audio_stop();
2829 void audio_hard_stop(void)
2831 audio_stop();
2832 /* tell voice we obtain the buffer before freeing */
2833 talk_buffer_steal();
2834 if (audiobuf_handle > 0)
2836 core_free(audiobuf_handle);
2837 audiobuf_handle = 0;
2838 mpeg_audiobuf = NULL;
2842 void audio_pause(void)
2844 #ifndef SIMULATOR
2845 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2846 #else /* SIMULATOR */
2847 is_playing = true;
2848 playing = false;
2849 paused = true;
2850 #endif /* SIMULATOR */
2853 void audio_resume(void)
2855 #ifndef SIMULATOR
2856 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2857 #else /* SIMULATOR */
2858 is_playing = true;
2859 playing = true;
2860 paused = false;
2861 #endif /* SIMULATOR */
2864 void audio_next(void)
2866 #ifndef SIMULATOR
2867 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2868 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2869 #else /* SIMULATOR */
2870 char name_buf[MAX_PATH+1];
2871 const char* file;
2872 int steps = 1;
2874 do {
2875 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2876 if(!file)
2877 break;
2878 if(mp3info(&taginfo, file)) {
2879 if(++steps > playlist_amount())
2880 break;
2881 continue;
2883 playlist_next(steps);
2884 current_track_counter++;
2885 is_playing = true;
2886 playing = true;
2887 break;
2888 } while(1);
2889 #endif /* SIMULATOR */
2892 void audio_prev(void)
2894 #ifndef SIMULATOR
2895 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2896 queue_post(&mpeg_queue, MPEG_PREV, 0);
2897 #else /* SIMULATOR */
2898 char name_buf[MAX_PATH+1];
2899 const char* file;
2900 int steps = -1;
2902 do {
2903 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2904 if(!file)
2905 break;
2906 if(mp3info(&taginfo, file)) {
2907 steps--;
2908 continue;
2910 playlist_next(steps);
2911 current_track_counter++;
2912 is_playing = true;
2913 playing = true;
2914 break;
2915 } while(1);
2916 #endif /* SIMULATOR */
2919 void audio_ff_rewind(long newpos)
2921 #ifndef SIMULATOR
2922 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2923 #else /* SIMULATOR */
2924 (void)newpos;
2925 #endif /* SIMULATOR */
2928 void audio_flush_and_reload_tracks(void)
2930 #ifndef SIMULATOR
2931 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2932 #endif /* !SIMULATOR*/
2935 int audio_status(void)
2937 int ret = 0;
2939 if(is_playing)
2940 ret |= AUDIO_STATUS_PLAY;
2942 if(paused)
2943 ret |= AUDIO_STATUS_PAUSE;
2945 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2946 if(is_recording && !is_prerecording)
2947 ret |= AUDIO_STATUS_RECORD;
2949 if(is_prerecording)
2950 ret |= AUDIO_STATUS_PRERECORD;
2951 #endif /* CONFIG_CODEC == MAS3587F */
2953 if(mpeg_errno)
2954 ret |= AUDIO_STATUS_ERROR;
2956 return ret;
2959 /* Unused function
2960 unsigned int audio_error(void)
2962 return mpeg_errno;
2966 void audio_error_clear(void)
2968 mpeg_errno = 0;
2971 #ifdef SIMULATOR
2972 static void mpeg_thread(void)
2974 struct mp3entry* id3;
2975 while ( 1 ) {
2976 if (is_playing) {
2977 id3 = audio_current_track();
2978 if (!paused)
2980 id3->elapsed+=1000;
2981 id3->offset+=1000;
2983 if (id3->elapsed>=id3->length)
2984 audio_next();
2986 sleep(HZ);
2989 #endif /* SIMULATOR */
2991 void audio_init(void)
2993 mpeg_errno = 0;
2995 talk_init();
2996 audio_reset_buffer();
2998 #ifndef SIMULATOR
2999 queue_init(&mpeg_queue, true);
3000 #endif /* !SIMULATOR */
3001 audio_thread_id = create_thread(mpeg_thread, mpeg_stack,
3002 sizeof(mpeg_stack), 0, mpeg_thread_name
3003 IF_PRIO(, PRIORITY_SYSTEM)
3004 IF_COP(, CPU));
3006 memset(trackdata, 0, sizeof(trackdata));
3008 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
3009 if (HW_MASK & PR_ACTIVE_HIGH)
3010 and_b(~0x08, &PADRH);
3011 else
3012 or_b(0x08, &PADRH);
3013 #endif /* CONFIG_CODEC == MAS3587F */
3015 #ifdef DEBUG
3016 #ifndef SIMULATOR
3017 dbg_timer_start();
3018 dbg_cnt2us(0);
3019 #endif /* !SIMULATOR */
3020 #endif /* DEBUG */
3023 #endif /* CONFIG_CODEC != SWCODEC */