Use full version string for voicefile version.
[maemo-rb.git] / apps / mpeg.c
blob0ecf68fc5329c870114107f912dc4149b483ffaf
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include "config.h"
25 #if CONFIG_CODEC != SWCODEC
27 #include "debug.h"
28 #include "panic.h"
29 #include "metadata.h"
30 #include "mpeg.h"
31 #include "audio.h"
32 #include "storage.h"
33 #include "string.h"
34 #include <kernel.h>
35 #include "thread.h"
36 #include "errno.h"
37 #include "mp3data.h"
38 #include "core_alloc.h"
39 #include "mp3_playback.h"
40 #include "talk.h"
41 #include "sound.h"
42 #include "system.h"
43 #include "appevents.h"
44 #include "playlist.h"
45 #include "cuesheet.h"
46 #include "settings.h"
47 #ifndef SIMULATOR
48 #include "i2c.h"
49 #include "mas35xx.h"
50 #include "system.h"
51 #include "usb.h"
52 #include "file.h"
53 #include "hwcompat.h"
54 #endif /* !SIMULATOR */
55 #ifdef HAVE_LCD_BITMAP
56 #include "lcd.h"
57 #endif /* CONFIG_CODEC != SWCODEC */
59 #define MPEG_SWAP_CHUNKSIZE 0x2000
60 #define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
61 wouldn't be able to see the difference between
62 an empty buffer and a full one. */
63 #define MPEG_LOW_WATER 0x60000
64 #define MPEG_RECORDING_LOW_WATER 0x80000
65 #define MPEG_LOW_WATER_CHUNKSIZE 0x40000
66 #define MPEG_LOW_WATER_SWAP_CHUNKSIZE 0x10000
67 #if (CONFIG_STORAGE & STORAGE_MMC)
68 #define MPEG_PLAY_PENDING_THRESHOLD 0x20000
69 #define MPEG_PLAY_PENDING_SWAPSIZE 0x20000
70 #else
71 #define MPEG_PLAY_PENDING_THRESHOLD 0x10000
72 #define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
73 #endif
75 #define MPEG_MAX_PRERECORD_SECONDS 30
77 /* For ID3 info and VBR header */
78 #define MPEG_RESERVED_HEADER_SPACE (4096 + 576)
80 #ifndef SIMULATOR
81 extern unsigned long mas_version_code;
82 #endif
84 #if CONFIG_CODEC == MAS3587F
85 extern enum /* from mp3_playback.c */
87 MPEG_DECODER,
88 MPEG_ENCODER
89 } mpeg_mode;
90 #endif /* CONFIG_CODEC == MAS3587F */
92 #define MPEG_PLAY 1
93 #define MPEG_STOP 2
94 #define MPEG_PAUSE 3
95 #define MPEG_RESUME 4
96 #define MPEG_NEXT 5
97 #define MPEG_PREV 6
98 #define MPEG_FF_REWIND 7
99 #define MPEG_FLUSH_RELOAD 8
100 #define MPEG_RECORD 9
101 #define MPEG_INIT_RECORDING 10
102 #define MPEG_INIT_PLAYBACK 11
103 #define MPEG_NEW_FILE 12
104 #define MPEG_PAUSE_RECORDING 13
105 #define MPEG_RESUME_RECORDING 14
106 #define MPEG_NEED_DATA 100
107 #define MPEG_TRACK_CHANGE 101
108 #define MPEG_SAVE_DATA 102
109 #define MPEG_STOP_DONE 103
110 #define MPEG_PRERECORDING_TICK 104
112 /* indicator for MPEG_NEED_DATA */
113 #define GENERATE_UNBUFFER_EVENTS 1
115 /* list of tracks in memory */
116 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
117 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
119 struct trackdata
121 struct mp3entry id3;
122 int mempos;
123 int load_ahead_index;
126 static struct trackdata trackdata[MAX_TRACK_ENTRIES];
128 static unsigned int current_track_counter = 0;
130 #ifndef SIMULATOR
131 static void stop_playing(void);
132 /* Play time of the previous track */
133 static unsigned long prev_track_elapsed;
135 static int track_read_idx = 0;
136 static int track_write_idx = 0;
137 #endif /* !SIMULATOR */
139 /* Cuesheet support */
140 static struct cuesheet *curr_cuesheet = NULL;
141 static bool checked_for_cuesheet = false;
143 static const char mpeg_thread_name[] = "mpeg";
144 static unsigned int audio_thread_id;
145 static bool audio_is_initialized;
146 static unsigned int mpeg_errno;
148 static bool playing = false; /* We are playing an MP3 stream */
149 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
150 static bool paused; /* playback is paused */
151 static int audiobuf_handle; /* handle to the audio buffer */
152 static char* mpeg_audiobuf; /* poiunter to the audio buffer */
153 static long audiobuflen; /* length of the audio buffer */
154 #define AUDIO_BUFFER_RESERVE (256*1024)
155 #ifdef SIMULATOR
156 static char mpeg_stack[DEFAULT_STACK_SIZE];
157 static struct mp3entry taginfo;
158 #else /* !SIMULATOR */
159 static struct event_queue mpeg_queue SHAREDBSS_ATTR;
160 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
162 static int audiobuf_write;
163 static int audiobuf_swapwrite;
164 static long audiobuf_read;
166 static int mpeg_file;
168 static bool play_pending; /* We are about to start playing */
169 static bool play_pending_track_change; /* When starting play we're starting a new file */
170 static bool filling; /* We are filling the buffer with data from disk */
171 static bool dma_underrun; /* True when the DMA has stopped because of
172 slow disk reading (read error, shaking) */
173 static bool mpeg_stop_done;
175 static int last_dma_tick = 0;
176 static int last_dma_chunk_size;
178 static long low_watermark; /* Dynamic low watermark level */
179 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
180 static long lowest_watermark_level; /* Debug value to observe the buffer
181 usage */
182 #if CONFIG_CODEC == MAS3587F
183 static char recording_filename[MAX_PATH]; /* argument to thread */
184 static char delayed_filename[MAX_PATH]; /* internal copy of above */
186 static char xing_buffer[MAX_XING_HEADER_SIZE];
188 static bool init_recording_done;
189 static bool init_playback_done;
190 static bool prerecording; /* True if prerecording is enabled */
191 static bool is_prerecording; /* True if we are prerecording */
192 static bool is_recording; /* We are recording */
194 static enum {
195 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
196 BUFFER_FULL,
197 NEW_FILE,
198 STOP_RECORDING
199 } saving_status;
201 static int rec_frequency_index; /* For create_xing_header() calls */
202 static int rec_version_index; /* For create_xing_header() calls */
204 struct prerecord_info {
205 int mempos;
206 unsigned long framecount;
209 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
210 static int prerecord_index; /* Current index in the prerecord buffer */
211 static int prerecording_max_seconds; /* Max number of seconds to store */
212 static int prerecord_count; /* Number of seconds in the prerecord buffer */
213 static int prerecord_timeout; /* The tick count of the next prerecord data
214 store */
216 static unsigned long record_start_time; /* Value of current_tick when recording
217 was started */
218 static unsigned long pause_start_time; /* Value of current_tick when pause was
219 started */
220 static unsigned long last_rec_time;
221 static unsigned long num_rec_bytes;
222 static unsigned long last_rec_bytes;
223 static unsigned long frame_count_start;
224 static unsigned long frame_count_end;
225 static unsigned long saved_header = 0;
227 /* Shadow MAS registers */
228 unsigned long shadow_encoder_control = 0;
229 #endif /* CONFIG_CODEC == MAS3587F */
231 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
232 unsigned long shadow_io_control_main = 0;
233 unsigned long shadow_soft_mute = 0;
234 unsigned shadow_codec_reg0;
235 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
237 #ifdef HAVE_RECORDING
238 static const unsigned char empty_id3_header[] =
240 'I', 'D', '3', 0x03, 0x00, 0x00,
241 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
243 #endif /* HAVE_RECORDING */
246 static int get_unplayed_space(void);
247 static int get_playable_space(void);
248 static int get_unswapped_space(void);
249 #endif /* !SIMULATOR */
251 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
252 static void init_recording(void);
253 static void prepend_header(void);
254 static void update_header(void);
255 static void start_prerecording(void);
256 static void start_recording(void);
257 static void stop_recording(void);
258 static int get_unsaved_space(void);
259 static void pause_recording(void);
260 static void resume_recording(void);
261 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
264 #ifndef SIMULATOR
265 static int num_tracks_in_memory(void)
267 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
270 #ifdef DEBUG_TAGS
271 static void debug_tags(void)
273 int i;
275 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
277 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
279 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
280 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
282 #else /* !DEBUG_TAGS */
283 #define debug_tags()
284 #endif /* !DEBUG_TAGS */
286 static void remove_current_tag(void)
288 if(num_tracks_in_memory() > 0)
290 /* First move the index, so nobody tries to access the tag */
291 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
292 checked_for_cuesheet = false;
293 debug_tags();
295 else
297 DEBUGF("remove_current_tag: no tracks to remove\n");
301 static void remove_all_non_current_tags(void)
303 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
304 debug_tags();
307 static void remove_all_tags(void)
309 track_write_idx = track_read_idx;
311 debug_tags();
314 static struct trackdata *get_trackdata(int offset)
316 if(offset >= num_tracks_in_memory())
317 return NULL;
318 else
319 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
321 #endif /* !SIMULATOR */
323 /***********************************************************************/
324 /* audio event handling */
326 #define MAX_EVENT_HANDLERS 10
327 struct event_handlers_table
329 AUDIO_EVENT_HANDLER handler;
330 unsigned short mask;
332 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
333 static int event_handlers_count = 0;
335 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
337 if (event_handlers_count < MAX_EVENT_HANDLERS)
339 event_handlers[event_handlers_count].handler = handler;
340 event_handlers[event_handlers_count].mask = mask;
341 event_handlers_count++;
345 /* dispatch calls each handler in the order registered and returns after some
346 handler actually handles the event (the event is assumed to no longer be valid
347 after this, due to the handler changing some condition); returns true if someone
348 handled the event, which is expected to cause the caller to skip its own handling
349 of the event */
350 #ifndef SIMULATOR
351 static bool audio_dispatch_event(unsigned short event, unsigned long data)
353 int i = 0;
354 for(i=0; i < event_handlers_count; i++)
356 if ( event_handlers[i].mask & event )
358 int rc = event_handlers[i].handler(event, data);
359 if ( rc == AUDIO_EVENT_RC_HANDLED )
360 return true;
363 return false;
365 #endif
367 /***********************************************************************/
369 static void set_elapsed(struct mp3entry* id3)
371 if ( id3->vbr ) {
372 if ( id3->has_toc ) {
373 /* calculate elapsed time using TOC */
374 int i;
375 unsigned int remainder, plen, relpos, nextpos;
377 /* find wich percent we're at */
378 for (i=0; i<100; i++ )
380 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
382 break;
386 i--;
387 if (i < 0)
388 i = 0;
390 relpos = id3->toc[i];
392 if (i < 99)
394 nextpos = id3->toc[i+1];
396 else
398 nextpos = 256;
401 remainder = id3->offset - (relpos * (id3->filesize / 256));
403 /* set time for this percent (divide before multiply to prevent
404 overflow on long files. loss of precision is negligible on
405 short files) */
406 id3->elapsed = i * (id3->length / 100);
408 /* calculate remainder time */
409 plen = (nextpos - relpos) * (id3->filesize / 256);
410 id3->elapsed += (((remainder * 100) / plen) *
411 (id3->length / 10000));
413 else {
414 /* no TOC exists. set a rough estimate using average bitrate */
415 int tpk = id3->length / (id3->filesize / 1024);
416 id3->elapsed = id3->offset / 1024 * tpk;
419 else
420 /* constant bitrate, use exact calculation */
421 id3->elapsed = id3->offset / (id3->bitrate / 8);
424 int audio_get_file_pos(void)
426 int pos = -1;
427 struct mp3entry *id3 = audio_current_track();
429 if (id3->vbr)
431 if (id3->has_toc)
433 /* Use the TOC to find the new position */
434 unsigned int percent, remainder;
435 int curtoc, nexttoc, plen;
437 percent = (id3->elapsed*100)/id3->length;
438 if (percent > 99)
439 percent = 99;
441 curtoc = id3->toc[percent];
443 if (percent < 99)
444 nexttoc = id3->toc[percent+1];
445 else
446 nexttoc = 256;
448 pos = (id3->filesize/256)*curtoc;
450 /* Use the remainder to get a more accurate position */
451 remainder = (id3->elapsed*100)%id3->length;
452 remainder = (remainder*100)/id3->length;
453 plen = (nexttoc - curtoc)*(id3->filesize/256);
454 pos += (plen/100)*remainder;
456 else
458 /* No TOC exists, estimate the new position */
459 pos = (id3->filesize / (id3->length / 1000)) *
460 (id3->elapsed / 1000);
463 else if (id3->bitrate)
464 pos = id3->elapsed * (id3->bitrate / 8);
465 else
467 return -1;
470 if (pos >= (int)(id3->filesize - id3->id3v1len))
472 /* Don't seek right to the end of the file so that we can
473 transition properly to the next song */
474 pos = id3->filesize - id3->id3v1len - 1;
476 else if (pos < (int)id3->first_frame_offset)
478 /* skip past id3v2 tag and other leading garbage */
479 pos = id3->first_frame_offset;
481 return pos;
484 unsigned long mpeg_get_last_header(void)
486 #ifdef SIMULATOR
487 return 0;
488 #else /* !SIMULATOR */
489 unsigned long tmp[2];
491 /* Read the frame data from the MAS and reconstruct it with the
492 frame sync and all */
493 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
494 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
495 #endif /* !SIMULATOR */
498 static void do_stop(void)
500 is_playing = false;
501 paused = false;
503 #ifndef SIMULATOR
504 if (playing)
505 playlist_update_resume_info(audio_current_track());
507 stop_playing();
508 mpeg_stop_done = true;
509 #else
510 playing = false;
511 #endif
514 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize);
515 /* Buffer must not move. */
516 static int shrink_callback(int handle, unsigned hints, void* start, size_t old_size)
518 ssize_t extradata_size = old_size - audiobuflen;
519 /* check what buflib requests */
520 size_t wanted_size = (hints & BUFLIB_SHRINK_SIZE_MASK);
521 ssize_t size = (ssize_t)old_size - wanted_size;
522 /* keep at least 256K for the buffering */
523 if ((size - extradata_size) < AUDIO_BUFFER_RESERVE)
524 return BUFLIB_CB_CANNOT_SHRINK;
525 /* TODO: Do it without stopping playback, if possible */
526 bool playing = (audio_status() & AUDIO_STATUS_PLAY) == AUDIO_STATUS_PLAY;
527 long offset = audio_current_track()->offset;
528 /* don't call audio_hard_stop() as it frees this handle */
529 if (thread_self() == audio_thread_id)
530 { /* inline case MPEG_STOP (audio_stop()) response
531 * if we're in the audio thread since audio_stop() otherwise deadlocks */
532 do_stop();
534 else
535 audio_stop();
536 talk_buffer_steal(); /* we obtain control over the buffer */
538 switch (hints & BUFLIB_SHRINK_POS_MASK)
540 case BUFLIB_SHRINK_POS_BACK:
541 core_shrink(handle, start, size);
542 audio_reset_buffer_noalloc(start, size);
543 break;
544 case BUFLIB_SHRINK_POS_FRONT:
545 core_shrink(handle, start + wanted_size, size);
546 audio_reset_buffer_noalloc(start + wanted_size, size);
547 break;
549 if (playing)
550 { /* safe to call even from the audio thread (due to queue_post()) */
551 audio_play(offset);
554 return BUFLIB_CB_OK;
557 static struct buflib_callbacks ops = {
558 .move_callback = NULL,
559 .shrink_callback = shrink_callback,
562 static size_t audio_talkbuf_init(char *bufstart)
564 size_t ret = talkbuf_init(bufstart);
565 if (ret > (size_t)audiobuflen) /* does the voice even fit? */
567 talk_buffer_steal();
568 return 0;
570 return ret;
573 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
575 (void)talk_buf; /* always grab the voice buffer for now */
577 if (audio_is_initialized)
578 audio_hard_stop();
580 if (!buffer_size) /* special case for talk_init() */
581 return NULL;
583 if (!audiobuf_handle)
585 size_t bufsize;
586 /* audio_hard_stop() frees audiobuf, so re-aquire */
587 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
588 audiobuflen = bufsize;
589 if (buffer_size)
590 *buffer_size = audiobuflen;
592 mpeg_audiobuf = core_get_data(audiobuf_handle);
593 /* tell talk about the new buffer, don't re-enable just yet because the
594 * buffer is stolen */
595 audio_talkbuf_init(mpeg_audiobuf);
597 return mpeg_audiobuf;
601 #ifndef SIMULATOR
602 /* Send callback events to notify about removing old tracks. */
603 static void generate_unbuffer_events(void)
605 int i;
606 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
607 int cur_idx = track_write_idx;
609 for (i = 0; i < numentries; i++)
611 /* Send an event to notify that track has finished. */
612 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
613 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
617 /* Send callback events to notify about new tracks. */
618 static void generate_postbuffer_events(void)
620 int i;
621 int numentries = num_tracks_in_memory();
622 int cur_idx = track_read_idx;
624 for (i = 0; i < numentries; i++)
626 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
627 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
631 static void recalculate_watermark(int bitrate)
633 int bytes_per_sec;
634 int time = storage_spinup_time();
636 /* A bitrate of 0 probably means empty VBR header. We play safe
637 and set a high threshold */
638 if(bitrate == 0)
639 bitrate = 320;
641 bytes_per_sec = bitrate * 1000 / 8;
643 if(time)
645 /* No drive spins up faster than 3.5s */
646 if(time < 350)
647 time = 350;
649 time = time * 3;
650 low_watermark = ((low_watermark_margin * HZ + time) *
651 bytes_per_sec) / HZ;
653 else
655 low_watermark = MPEG_LOW_WATER;
659 #ifdef HAVE_DISK_STORAGE
660 void audio_set_buffer_margin(int setting)
662 low_watermark_margin = setting; /* in seconds */
664 #endif
666 void audio_get_debugdata(struct audio_debug *dbgdata)
668 dbgdata->audiobuflen = audiobuflen;
669 dbgdata->audiobuf_write = audiobuf_write;
670 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
671 dbgdata->audiobuf_read = audiobuf_read;
673 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
675 #if CONFIG_CPU == SH7034
676 dbgdata->dma_on = (SCR0 & 0x80) != 0;
677 #endif
678 dbgdata->playing = playing;
679 dbgdata->play_pending = play_pending;
680 dbgdata->is_playing = is_playing;
681 dbgdata->filling = filling;
682 dbgdata->dma_underrun = dma_underrun;
684 dbgdata->unplayed_space = get_unplayed_space();
685 dbgdata->playable_space = get_playable_space();
686 dbgdata->unswapped_space = get_unswapped_space();
688 dbgdata->low_watermark_level = low_watermark;
689 dbgdata->lowest_watermark_level = lowest_watermark_level;
692 #ifdef DEBUG
693 static void dbg_timer_start(void)
695 /* We are using timer 2 */
697 TSTR &= ~0x04; /* Stop the timer */
698 TSNC &= ~0x04; /* No synchronization */
699 TMDR &= ~0x44; /* Operate normally */
701 TCNT2 = 0; /* Start counting at 0 */
702 TCR2 = 0x03; /* Sysclock/8 */
704 TSTR |= 0x04; /* Start timer 2 */
707 static int dbg_cnt2us(unsigned int cnt)
709 return (cnt * 10000) / (FREQ/800);
711 #endif /* DEBUG */
713 static int get_unplayed_space(void)
715 int space = audiobuf_write - audiobuf_read;
716 if (space < 0)
717 space += audiobuflen;
718 return space;
721 static int get_playable_space(void)
723 int space = audiobuf_swapwrite - audiobuf_read;
724 if (space < 0)
725 space += audiobuflen;
726 return space;
729 static int get_unplayed_space_current_song(void)
731 int space;
733 if (num_tracks_in_memory() > 1)
735 space = get_trackdata(1)->mempos - audiobuf_read;
737 else
739 space = audiobuf_write - audiobuf_read;
742 if (space < 0)
743 space += audiobuflen;
745 return space;
748 static int get_unswapped_space(void)
750 int space = audiobuf_write - audiobuf_swapwrite;
751 if (space < 0)
752 space += audiobuflen;
753 return space;
756 #if CONFIG_CODEC == MAS3587F
757 static int get_unsaved_space(void)
759 int space = audiobuf_write - audiobuf_read;
760 if (space < 0)
761 space += audiobuflen;
762 return space;
765 static void drain_dma_buffer(void)
767 while (PBDRH & 0x40)
769 xor_b(0x08, &PADRH);
771 while (PBDRH & 0x80);
773 xor_b(0x08, &PADRH);
775 while (!(PBDRH & 0x80));
779 #ifdef DEBUG
780 static long timing_info_index = 0;
781 static long timing_info[1024];
782 #endif /* DEBUG */
784 void rec_tick (void) __attribute__ ((section (".icode")));
785 void rec_tick(void)
787 int i;
788 int delay;
789 char data;
791 if(is_recording && (PBDRH & 0x40))
793 #ifdef DEBUG
794 timing_info[timing_info_index++] = current_tick;
795 TCNT2 = 0;
796 #endif /* DEBUG */
797 /* Note: Although this loop is run in interrupt context, further
798 * optimisation will do no good. The MAS would then deliver bad
799 * frames occasionally, as observed in extended experiments. */
800 i = 0;
801 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
803 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
805 delay = 100;
806 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
808 if (--delay <= 0) /* Bail out if we have to wait too long */
809 { /* i.e. the MAS doesn't want to talk to us */
810 xor_b(0x08, &PADRH); /* Set PR inactive */
811 goto transfer_end; /* and get out of here */
815 data = *(unsigned char *)0x04000000; /* read data byte */
817 xor_b(0x08, &PADRH); /* Set PR inactive */
819 mpeg_audiobuf[audiobuf_write++] = data;
821 if (audiobuf_write >= audiobuflen)
822 audiobuf_write = 0;
824 i++;
826 transfer_end:
828 #ifdef DEBUG
829 timing_info[timing_info_index++] = TCNT2 + (i << 16);
830 timing_info_index &= 0x3ff;
831 #endif /* DEBUG */
833 num_rec_bytes += i;
835 if(is_prerecording)
837 if(TIME_AFTER(current_tick, prerecord_timeout))
839 prerecord_timeout = current_tick + HZ;
840 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
843 else
845 /* Signal to save the data if we are running out of buffer
846 space */
847 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
848 && saving_status == NOT_SAVING)
850 saving_status = BUFFER_FULL;
851 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
856 #endif /* CONFIG_CODEC == MAS3587F */
858 void playback_tick(void)
860 struct trackdata *ptd = get_trackdata(0);
861 if(ptd)
863 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
864 last_dma_tick = current_tick;
865 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
866 (unsigned long)ptd->id3.elapsed);
870 static void reset_mp3_buffer(void)
872 audiobuf_read = 0;
873 audiobuf_write = 0;
874 audiobuf_swapwrite = 0;
875 lowest_watermark_level = audiobuflen;
878 /* DMA transfer end interrupt callback */
879 static void transfer_end(const void** ppbuf, size_t* psize)
881 if(playing && !paused)
883 int unplayed_space_left;
884 int space_until_end_of_buffer;
885 int track_offset = 1;
886 struct trackdata *track;
888 audiobuf_read += last_dma_chunk_size;
889 if(audiobuf_read >= audiobuflen)
890 audiobuf_read = 0;
892 /* First, check if we are on a track boundary */
893 if (num_tracks_in_memory() > 1)
895 if (audiobuf_read == get_trackdata(track_offset)->mempos)
897 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
899 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
900 track_offset++;
905 unplayed_space_left = get_unplayed_space();
907 space_until_end_of_buffer = audiobuflen - audiobuf_read;
909 if(!filling && unplayed_space_left < low_watermark)
911 filling = true;
912 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
915 if(unplayed_space_left)
917 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
918 last_dma_chunk_size = MIN(last_dma_chunk_size,
919 space_until_end_of_buffer);
921 /* several tracks loaded? */
922 track = get_trackdata(track_offset);
923 if(track)
925 /* will we move across the track boundary? */
926 if (( audiobuf_read < track->mempos ) &&
927 ((audiobuf_read+last_dma_chunk_size) >
928 track->mempos ))
930 /* Make sure that we end exactly on the boundary */
931 last_dma_chunk_size = track->mempos - audiobuf_read;
935 *psize = last_dma_chunk_size & 0xffff;
936 *ppbuf = mpeg_audiobuf + audiobuf_read;
937 track = get_trackdata(0);
938 if(track)
939 track->id3.offset += last_dma_chunk_size;
941 /* Update the watermark debug level */
942 if(unplayed_space_left < lowest_watermark_level)
943 lowest_watermark_level = unplayed_space_left;
945 else
947 /* Check if the end of data is because of a hard disk error.
948 If there is an open file handle, we are still playing music.
949 If not, the last file has been loaded, and the file handle is
950 closed. */
951 if(mpeg_file >= 0)
953 /* Update the watermark debug level */
954 if(unplayed_space_left < lowest_watermark_level)
955 lowest_watermark_level = unplayed_space_left;
957 DEBUGF("DMA underrun.\n");
958 dma_underrun = true;
960 else
962 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
964 DEBUGF("No more MP3 data. Stopping.\n");
965 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
966 playing = false;
969 *psize = 0; /* no more transfer */
974 static struct trackdata *add_track_to_tag_list(const char *filename)
976 struct trackdata *track;
977 bool send_nid3_event;
979 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
981 DEBUGF("Tag memory is full\n");
982 return NULL;
985 track = &trackdata[track_write_idx];
987 /* grab id3 tag of new file and
988 remember where in memory it starts */
989 if(mp3info(&track->id3, filename))
991 DEBUGF("Bad mp3\n");
992 return NULL;
994 track->mempos = audiobuf_write;
995 track->id3.elapsed = 0;
996 #ifdef HAVE_LCD_BITMAP
997 if (track->id3.title)
998 lcd_getstringsize(track->id3.title, NULL, NULL);
999 if (track->id3.artist)
1000 lcd_getstringsize(track->id3.artist, NULL, NULL);
1001 if (track->id3.album)
1002 lcd_getstringsize(track->id3.album, NULL, NULL);
1003 #endif
1005 /* if this track is the next track then let the UI know it can get it */
1006 send_nid3_event = (track_write_idx == track_read_idx + 1);
1007 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
1008 if (send_nid3_event)
1009 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
1010 debug_tags();
1011 return track;
1014 static int new_file(int steps)
1016 int max_steps = playlist_amount();
1017 int start = 0;
1018 int i;
1019 struct trackdata *track;
1020 char name_buf[MAX_PATH+1];
1021 const char *trackname;
1023 /* Find out how many steps to advance. The load_ahead_index field tells
1024 us how many playlist entries it had to skip to get to a valid one.
1025 We add those together to find out where to start. */
1026 if(steps > 0 && num_tracks_in_memory() > 1)
1028 /* Begin with the song after the currently playing one */
1029 i = 1;
1030 while((track = get_trackdata(i++)))
1032 start += track->load_ahead_index;
1036 do {
1037 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
1038 if ( !trackname )
1039 return -1;
1041 DEBUGF("Loading %s\n", trackname);
1043 mpeg_file = open(trackname, O_RDONLY);
1044 if(mpeg_file < 0) {
1045 DEBUGF("Couldn't open file: %s\n",trackname);
1046 if(steps < 0)
1047 steps--;
1048 else
1049 steps++;
1051 else
1053 struct trackdata *track = add_track_to_tag_list(trackname);
1055 if(!track)
1057 /* Bad mp3 file */
1058 if(steps < 0)
1059 steps--;
1060 else
1061 steps++;
1062 close(mpeg_file);
1063 mpeg_file = -1;
1065 else
1067 /* skip past id3v2 tag */
1068 lseek(mpeg_file,
1069 track->id3.first_frame_offset,
1070 SEEK_SET);
1071 track->id3.index = steps;
1072 track->load_ahead_index = steps;
1073 track->id3.offset = 0;
1075 if(track->id3.vbr)
1076 /* Average bitrate * 1.5 */
1077 recalculate_watermark(
1078 (track->id3.bitrate * 3) / 2);
1079 else
1080 recalculate_watermark(
1081 track->id3.bitrate);
1086 /* Bail out if no file could be opened */
1087 if(abs(steps) > max_steps)
1088 return -1;
1089 } while ( mpeg_file < 0 );
1091 return 0;
1094 static void stop_playing(void)
1096 struct trackdata *track;
1098 /* Stop the current stream */
1099 mp3_play_stop();
1100 playing = false;
1101 filling = false;
1103 track = get_trackdata(0);
1104 if (track != NULL)
1105 prev_track_elapsed = track->id3.elapsed;
1107 if(mpeg_file >= 0)
1108 close(mpeg_file);
1109 mpeg_file = -1;
1110 remove_all_tags();
1111 generate_unbuffer_events();
1112 reset_mp3_buffer();
1115 static void end_current_track(void) {
1116 struct trackdata *track;
1118 play_pending = false;
1119 playing = false;
1120 mp3_play_pause(false);
1122 track = get_trackdata(0);
1123 if (track != NULL)
1124 prev_track_elapsed = track->id3.elapsed;
1126 reset_mp3_buffer();
1127 remove_all_tags();
1128 generate_unbuffer_events();
1130 if(mpeg_file >= 0)
1131 close(mpeg_file);
1134 /* Is this a really the end of playback or is a new playlist starting */
1135 static void check_playlist_end(int direction)
1137 /* Use the largest possible step size to account for skipped tracks */
1138 int steps = playlist_amount();
1140 if (direction < 0)
1141 steps = -steps;
1143 if (playlist_next(steps) < 0)
1144 is_playing = false;
1147 static void update_playlist(void)
1149 if (num_tracks_in_memory() > 0)
1151 struct trackdata *track = get_trackdata(0);
1152 track->id3.index = playlist_next(track->id3.index);
1154 else
1156 /* End of playlist? */
1157 check_playlist_end(1);
1160 playlist_update_resume_info(audio_current_track());
1163 static void track_change(void)
1165 DEBUGF("Track change\n");
1167 struct trackdata *track = get_trackdata(0);
1168 prev_track_elapsed = track->id3.elapsed;
1170 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1171 /* Reset the AVC */
1172 sound_set_avc(-1);
1173 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1175 if (num_tracks_in_memory() > 0)
1177 remove_current_tag();
1178 update_playlist();
1179 if (is_playing)
1180 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1183 current_track_counter++;
1186 unsigned long audio_prev_elapsed(void)
1188 return prev_track_elapsed;
1191 #ifdef DEBUG
1192 void hexdump(const unsigned char *buf, int len)
1194 int i;
1196 for(i = 0;i < len;i++)
1198 if(i && (i & 15) == 0)
1200 DEBUGF("\n");
1202 DEBUGF("%02x ", buf[i]);
1204 DEBUGF("\n");
1206 #endif /* DEBUG */
1208 static void start_playback_if_ready(void)
1210 int playable_space;
1212 playable_space = audiobuf_swapwrite - audiobuf_read;
1213 if(playable_space < 0)
1214 playable_space += audiobuflen;
1216 /* See if we have started playing yet. If not, do it. */
1217 if(play_pending || dma_underrun)
1219 /* If the filling has stopped, and we still haven't reached
1220 the watermark, the file must be smaller than the
1221 watermark. We must still play it. */
1222 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1223 !filling || dma_underrun)
1225 DEBUGF("P\n");
1226 if (play_pending) /* don't do this when recovering from DMA underrun */
1228 generate_postbuffer_events(); /* signal first track as buffered */
1229 if (play_pending_track_change)
1231 play_pending_track_change = false;
1232 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1234 play_pending = false;
1236 playing = true;
1238 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1239 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1240 dma_underrun = false;
1242 if (!paused)
1244 last_dma_tick = current_tick;
1245 mp3_play_pause(true);
1248 /* Tell ourselves that we need more data */
1249 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1254 static bool swap_one_chunk(void)
1256 int free_space_left;
1257 int amount_to_swap;
1259 free_space_left = get_unswapped_space();
1261 if(free_space_left == 0 && !play_pending)
1262 return false;
1264 /* Swap in larger chunks when the user is waiting for the playback
1265 to start, or when there is dangerously little playable data left */
1266 if(play_pending)
1267 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1268 else
1270 if(get_playable_space() < low_watermark)
1271 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1272 free_space_left);
1273 else
1274 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1277 if(audiobuf_write < audiobuf_swapwrite)
1278 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1279 amount_to_swap);
1280 else
1281 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1282 amount_to_swap);
1284 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1286 audiobuf_swapwrite += amount_to_swap;
1287 if(audiobuf_swapwrite >= audiobuflen)
1289 audiobuf_swapwrite = 0;
1292 return true;
1295 static void mpeg_thread(void)
1297 static int pause_tick = 0;
1298 static unsigned int pause_track = 0;
1299 struct queue_event ev;
1300 int len;
1301 int free_space_left;
1302 int unplayed_space_left;
1303 int amount_to_read;
1304 int t1, t2;
1305 int start_offset;
1306 #if CONFIG_CODEC == MAS3587F
1307 int amount_to_save;
1308 int save_endpos = 0;
1309 int rc;
1310 int level;
1311 long offset;
1312 #endif /* CONFIG_CODEC == MAS3587F */
1314 is_playing = false;
1315 play_pending = false;
1316 playing = false;
1317 mpeg_file = -1;
1319 while(1)
1321 #if CONFIG_CODEC == MAS3587F
1322 if(mpeg_mode == MPEG_DECODER)
1324 #endif /* CONFIG_CODEC == MAS3587F */
1325 yield();
1327 /* Swap if necessary, and don't block on the queue_wait() */
1328 if(swap_one_chunk())
1330 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1332 else if (playing)
1334 /* periodically update resume info */
1335 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1337 else
1339 DEBUGF("S R:%x W:%x SW:%x\n",
1340 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1341 queue_wait(&mpeg_queue, &ev);
1344 start_playback_if_ready();
1346 switch(ev.id)
1348 case MPEG_PLAY:
1349 DEBUGF("MPEG_PLAY\n");
1351 #if CONFIG_TUNER
1352 /* Silence the A/D input, it may be on because the radio
1353 may be playing */
1354 mas_codec_writereg(6, 0x0000);
1355 #endif /* CONFIG_TUNER */
1357 /* Stop the current stream */
1358 paused = false;
1359 end_current_track();
1361 if ( new_file(0) == -1 )
1363 is_playing = false;
1364 track_change();
1365 break;
1368 start_offset = (int)ev.data;
1370 /* mid-song resume? */
1371 if (start_offset) {
1372 struct mp3entry* id3 = &get_trackdata(0)->id3;
1373 lseek(mpeg_file, start_offset, SEEK_SET);
1374 id3->offset = start_offset;
1375 set_elapsed(id3);
1377 else {
1378 /* skip past id3v2 tag */
1379 lseek(mpeg_file,
1380 get_trackdata(0)->id3.first_frame_offset,
1381 SEEK_SET);
1385 /* Make it read more data */
1386 filling = true;
1387 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1389 /* Tell the file loading code that we want to start playing
1390 as soon as we have some data */
1391 play_pending = true;
1392 play_pending_track_change = true;
1394 update_playlist();
1395 current_track_counter++;
1396 break;
1398 case MPEG_STOP:
1399 do_stop();
1400 break;
1402 case MPEG_PAUSE:
1403 DEBUGF("MPEG_PAUSE\n");
1404 /* Stop the current stream */
1405 if (playing)
1406 playlist_update_resume_info(audio_current_track());
1407 paused = true;
1408 playing = false;
1409 pause_tick = current_tick;
1410 pause_track = current_track_counter;
1411 mp3_play_pause(false);
1412 break;
1414 case MPEG_RESUME:
1415 DEBUGF("MPEG_RESUME\n");
1416 /* Continue the current stream */
1417 paused = false;
1418 if (!play_pending)
1420 playing = true;
1421 if ( current_track_counter == pause_track )
1422 last_dma_tick += current_tick - pause_tick;
1423 else
1424 last_dma_tick = current_tick;
1425 pause_tick = 0;
1426 mp3_play_pause(true);
1428 break;
1430 case MPEG_NEXT:
1431 DEBUGF("MPEG_NEXT\n");
1432 /* is next track in ram? */
1433 if ( num_tracks_in_memory() > 1 ) {
1434 int unplayed_space_left, unswapped_space_left;
1436 /* stop the current stream */
1437 play_pending = false;
1438 playing = false;
1439 mp3_play_pause(false);
1441 track_change();
1442 audiobuf_read = get_trackdata(0)->mempos;
1443 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1444 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1445 dma_underrun = false;
1446 last_dma_tick = current_tick;
1448 unplayed_space_left = get_unplayed_space();
1449 unswapped_space_left = get_unswapped_space();
1451 /* should we start reading more data? */
1452 if(!filling && (unplayed_space_left < low_watermark)) {
1453 filling = true;
1454 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1455 play_pending = true;
1456 } else if(unswapped_space_left &&
1457 unswapped_space_left > unplayed_space_left) {
1458 /* Stop swapping the data from the previous file */
1459 audiobuf_swapwrite = audiobuf_read;
1460 play_pending = true;
1461 } else {
1462 playing = true;
1463 if (!paused)
1464 mp3_play_pause(true);
1467 else {
1468 if (!playlist_check(1))
1469 break;
1471 /* stop the current stream */
1472 end_current_track();
1474 if (new_file(1) < 0) {
1475 DEBUGF("No more files to play\n");
1476 filling = false;
1478 check_playlist_end(1);
1479 current_track_counter++;
1480 } else {
1481 /* Make it read more data */
1482 filling = true;
1483 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1485 /* Tell the file loading code that we want
1486 to start playing as soon as we have some data */
1487 play_pending = true;
1488 play_pending_track_change = true;
1490 update_playlist();
1491 current_track_counter++;
1494 break;
1496 case MPEG_PREV: {
1497 DEBUGF("MPEG_PREV\n");
1499 if (!playlist_check(-1))
1500 break;
1502 /* stop the current stream */
1503 end_current_track();
1505 /* Open the next file */
1506 if (new_file(-1) < 0) {
1507 DEBUGF("No more files to play\n");
1508 filling = false;
1510 check_playlist_end(-1);
1511 current_track_counter++;
1512 } else {
1513 /* Make it read more data */
1514 filling = true;
1515 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1517 /* Tell the file loading code that we want to
1518 start playing as soon as we have some data */
1519 play_pending = true;
1520 play_pending_track_change = true;
1522 update_playlist();
1523 current_track_counter++;
1525 break;
1528 case MPEG_FF_REWIND: {
1529 struct mp3entry *id3 = audio_current_track();
1530 unsigned int oldtime = id3->elapsed;
1531 unsigned int newtime = (unsigned int)ev.data;
1532 int curpos, newpos, diffpos;
1533 DEBUGF("MPEG_FF_REWIND\n");
1535 id3->elapsed = newtime;
1537 newpos = audio_get_file_pos();
1538 if(newpos < 0)
1540 id3->elapsed = oldtime;
1541 break;
1544 if (mpeg_file >= 0)
1545 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1546 else
1547 curpos = id3->filesize;
1549 if (num_tracks_in_memory() > 1)
1551 /* We have started loading other tracks that need to be
1552 accounted for */
1553 struct trackdata *track;
1554 int i = 0;
1556 while((track = get_trackdata(i++)))
1558 curpos += track->id3.filesize;
1562 diffpos = curpos - newpos;
1564 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1566 int unplayed_space_left, unswapped_space_left;
1568 /* We are changing to a position that's already in
1569 memory, so we just move the DMA read pointer. */
1570 audiobuf_read = audiobuf_write - diffpos;
1571 if (audiobuf_read < 0)
1573 audiobuf_read += audiobuflen;
1576 unplayed_space_left = get_unplayed_space();
1577 unswapped_space_left = get_unswapped_space();
1579 /* If unswapped_space_left is larger than
1580 unplayed_space_left, it means that the swapwrite pointer
1581 hasn't yet advanced up to the new location of the read
1582 pointer. We just move it, there is no need to swap
1583 data that won't be played anyway. */
1585 if (unswapped_space_left > unplayed_space_left)
1587 DEBUGF("Moved swapwrite\n");
1588 audiobuf_swapwrite = audiobuf_read;
1589 play_pending = true;
1592 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1594 /* We need to load more data before starting */
1595 filling = true;
1596 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1597 play_pending = true;
1599 else
1601 /* resume will start at new position */
1602 last_dma_chunk_size =
1603 MIN(0x2000, get_unplayed_space_current_song());
1604 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1605 last_dma_chunk_size, transfer_end);
1606 dma_underrun = false;
1609 else
1611 /* Move to the new position in the file and start
1612 loading data */
1613 reset_mp3_buffer();
1615 if (num_tracks_in_memory() > 1)
1617 /* We have to reload the current track */
1618 close(mpeg_file);
1619 remove_all_non_current_tags();
1620 generate_unbuffer_events();
1621 mpeg_file = -1;
1624 if (mpeg_file < 0)
1626 mpeg_file = open(id3->path, O_RDONLY);
1627 if (mpeg_file < 0)
1629 id3->elapsed = oldtime;
1630 break;
1634 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1636 id3->elapsed = oldtime;
1637 break;
1640 filling = true;
1641 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1643 /* Tell the file loading code that we want to start playing
1644 as soon as we have some data */
1645 play_pending = true;
1648 id3->offset = newpos;
1650 break;
1653 case MPEG_FLUSH_RELOAD: {
1654 int numtracks = num_tracks_in_memory();
1655 bool reload_track = false;
1657 if (numtracks > 1)
1659 /* Reset the buffer */
1660 audiobuf_write = get_trackdata(1)->mempos;
1662 /* Reset swapwrite unless we're still swapping current
1663 track */
1664 if (get_unplayed_space() <= get_playable_space())
1665 audiobuf_swapwrite = audiobuf_write;
1667 close(mpeg_file);
1668 remove_all_non_current_tags();
1669 generate_unbuffer_events();
1670 mpeg_file = -1;
1671 reload_track = true;
1673 else if (numtracks == 1 && mpeg_file < 0)
1675 reload_track = true;
1678 if(reload_track && new_file(1) >= 0)
1680 /* Tell ourselves that we want more data */
1681 filling = true;
1682 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1685 break;
1688 case MPEG_NEED_DATA:
1689 free_space_left = audiobuf_read - audiobuf_write;
1691 /* We interpret 0 as "empty buffer" */
1692 if(free_space_left <= 0)
1693 free_space_left += audiobuflen;
1695 unplayed_space_left = audiobuflen - free_space_left;
1697 /* Make sure that we don't fill the entire buffer */
1698 free_space_left -= MPEG_HIGH_WATER;
1700 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1701 generate_unbuffer_events();
1703 /* do we have any more buffer space to fill? */
1704 if(free_space_left <= 0)
1706 DEBUGF("0\n");
1707 filling = false;
1708 generate_postbuffer_events();
1709 storage_sleep();
1710 break;
1713 /* Read small chunks while we are below the low water mark */
1714 if(unplayed_space_left < low_watermark)
1715 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1716 free_space_left);
1717 else
1718 amount_to_read = free_space_left;
1720 /* Don't read more than until the end of the buffer */
1721 amount_to_read = MIN(audiobuflen - audiobuf_write,
1722 amount_to_read);
1723 #if (CONFIG_STORAGE & STORAGE_MMC)
1724 /* MMC is slow, so don't read too large chunks */
1725 amount_to_read = MIN(0x40000, amount_to_read);
1726 #elif MEMORYSIZE == 8
1727 amount_to_read = MIN(0x100000, amount_to_read);
1728 #endif
1730 /* Read as much mpeg data as we can fit in the buffer */
1731 if(mpeg_file >= 0)
1733 DEBUGF("R\n");
1734 t1 = current_tick;
1735 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1736 amount_to_read);
1737 if(len > 0)
1739 t2 = current_tick;
1740 DEBUGF("time: %d\n", t2 - t1);
1741 DEBUGF("R: %x\n", len);
1743 /* Now make sure that we don't feed the MAS with ID3V1
1744 data */
1745 if (len < amount_to_read)
1747 int i;
1748 static const unsigned char tag[] = "TAG";
1749 int taglen = 128;
1750 int tagptr = audiobuf_write + len - 128;
1752 /* Really rare case: entire potential tag wasn't
1753 read in this call AND audiobuf_write < 128 */
1754 if (tagptr < 0)
1755 tagptr += audiobuflen;
1757 for(i = 0;i < 3;i++)
1759 if(tagptr >= audiobuflen)
1760 tagptr -= audiobuflen;
1762 if(mpeg_audiobuf[tagptr] != tag[i])
1764 taglen = 0;
1765 break;
1768 tagptr++;
1771 if(taglen)
1773 /* Skip id3v1 tag */
1774 DEBUGF("Skipping ID3v1 tag\n");
1775 len -= taglen;
1777 /* In the very rare case when the entire tag
1778 wasn't read in this read() len will be < 0.
1779 Take care of this when changing the write
1780 pointer. */
1784 audiobuf_write += len;
1786 if (audiobuf_write < 0)
1787 audiobuf_write += audiobuflen;
1789 if(audiobuf_write >= audiobuflen)
1791 audiobuf_write = 0;
1792 DEBUGF("W\n");
1795 /* Tell ourselves that we want more data */
1796 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1798 else
1800 if(len < 0)
1802 DEBUGF("MPEG read error\n");
1805 close(mpeg_file);
1806 mpeg_file = -1;
1808 if(new_file(1) < 0)
1810 /* No more data to play */
1811 DEBUGF("No more files to play\n");
1812 filling = false;
1814 else
1816 /* Tell ourselves that we want more data */
1817 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1821 break;
1823 case MPEG_TRACK_CHANGE:
1824 track_change();
1825 break;
1827 #ifndef USB_NONE
1828 case SYS_USB_CONNECTED:
1829 is_playing = false;
1830 paused = false;
1831 stop_playing();
1833 /* Tell the USB thread that we are safe */
1834 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1835 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1837 /* Wait until the USB cable is extracted again */
1838 usb_wait_for_disconnect(&mpeg_queue);
1839 break;
1840 #endif /* !USB_NONE */
1842 #if CONFIG_CODEC == MAS3587F
1843 case MPEG_INIT_RECORDING:
1844 init_recording();
1845 init_recording_done = true;
1846 break;
1847 #endif /* CONFIG_CODEC == MAS3587F */
1849 case SYS_TIMEOUT:
1850 if (playing)
1851 playlist_update_resume_info(audio_current_track());
1852 break;
1854 #if CONFIG_CODEC == MAS3587F
1856 else
1858 queue_wait(&mpeg_queue, &ev);
1859 switch(ev.id)
1861 case MPEG_RECORD:
1862 if (is_prerecording)
1864 int startpos;
1866 /* Go back prerecord_count seconds in the buffer */
1867 startpos = prerecord_index - prerecord_count;
1868 if(startpos < 0)
1869 startpos += prerecording_max_seconds;
1871 /* Read the position data from the prerecord buffer */
1872 frame_count_start = prerecord_buffer[startpos].framecount;
1873 startpos = prerecord_buffer[startpos].mempos;
1875 DEBUGF("Start looking at address %x (%x)\n",
1876 mpeg_audiobuf+startpos, startpos);
1878 saved_header = mpeg_get_last_header();
1880 mem_find_next_frame(startpos, &offset, 1800,
1881 saved_header, mpeg_audiobuf,
1882 audiobuflen);
1884 audiobuf_read = startpos + offset;
1885 if(audiobuf_read >= audiobuflen)
1886 audiobuf_read -= audiobuflen;
1888 DEBUGF("New audiobuf_read address: %x (%x)\n",
1889 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1891 level = disable_irq_save();
1892 num_rec_bytes = get_unsaved_space();
1893 restore_irq(level);
1895 else
1897 frame_count_start = 0;
1898 num_rec_bytes = 0;
1899 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1900 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1903 prepend_header();
1904 DEBUGF("Recording...\n");
1905 start_recording();
1907 /* Wait until at least one frame is encoded and get the
1908 frame header, for later use by the Xing header
1909 generation */
1910 sleep(HZ/5);
1911 saved_header = mpeg_get_last_header();
1913 /* delayed until buffer is saved, don't open yet */
1914 strcpy(delayed_filename, recording_filename);
1915 mpeg_file = -1;
1917 break;
1919 case MPEG_STOP:
1920 DEBUGF("MPEG_STOP\n");
1922 stop_recording();
1924 /* Save the remaining data in the buffer */
1925 save_endpos = audiobuf_write;
1926 saving_status = STOP_RECORDING;
1927 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1928 break;
1930 case MPEG_STOP_DONE:
1931 DEBUGF("MPEG_STOP_DONE\n");
1933 if (mpeg_file >= 0)
1934 close(mpeg_file);
1935 mpeg_file = -1;
1937 update_header();
1938 #ifdef DEBUG1
1940 int i;
1941 for(i = 0;i < 512;i++)
1943 DEBUGF("%d - %d us (%d bytes)\n",
1944 timing_info[i*2],
1945 (timing_info[i*2+1] & 0xffff) *
1946 10000 / 13824,
1947 timing_info[i*2+1] >> 16);
1950 #endif /* DEBUG1 */
1952 if (prerecording)
1954 start_prerecording();
1956 mpeg_stop_done = true;
1957 break;
1959 case MPEG_NEW_FILE:
1960 /* Bail out when a more important save is happening */
1961 if (saving_status > NEW_FILE)
1962 break;
1964 /* Make sure we have at least one complete frame
1965 in the buffer. If we haven't recorded a single
1966 frame within 200ms, the MAS is probably not recording
1967 anything, and we bail out. */
1968 amount_to_save = get_unsaved_space();
1969 if (amount_to_save < 1800)
1971 sleep(HZ/5);
1972 amount_to_save = get_unsaved_space();
1975 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1976 &frame_count_end, 1);
1978 last_rec_time = current_tick - record_start_time;
1979 record_start_time = current_tick;
1980 if (paused)
1981 pause_start_time = record_start_time;
1983 /* capture all values at one point */
1984 level = disable_irq_save();
1985 save_endpos = audiobuf_write;
1986 last_rec_bytes = num_rec_bytes;
1987 num_rec_bytes = 0;
1988 restore_irq(level);
1990 if (amount_to_save >= 1800)
1992 /* Now find a frame boundary to split at */
1993 save_endpos -= 1800;
1994 if (save_endpos < 0)
1995 save_endpos += audiobuflen;
1997 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1998 saved_header, mpeg_audiobuf,
1999 audiobuflen);
2000 if (!rc) /* No header found, save whole buffer */
2001 offset = 1800;
2003 save_endpos += offset;
2004 if (save_endpos >= audiobuflen)
2005 save_endpos -= audiobuflen;
2007 last_rec_bytes += offset - 1800;
2008 level = disable_irq_save();
2009 num_rec_bytes += 1800 - offset;
2010 restore_irq(level);
2013 saving_status = NEW_FILE;
2014 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2015 break;
2017 case MPEG_SAVE_DATA:
2018 if (saving_status == BUFFER_FULL)
2019 save_endpos = audiobuf_write;
2021 if (mpeg_file < 0) /* delayed file open */
2023 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
2025 if (mpeg_file < 0)
2026 panicf("recfile: %d", mpeg_file);
2029 amount_to_save = save_endpos - audiobuf_read;
2030 if (amount_to_save < 0)
2031 amount_to_save += audiobuflen;
2033 amount_to_save = MIN(amount_to_save,
2034 audiobuflen - audiobuf_read);
2035 #if (CONFIG_STORAGE & STORAGE_MMC)
2036 /* MMC is slow, so don't save too large chunks at once */
2037 amount_to_save = MIN(0x40000, amount_to_save);
2038 #elif MEMORYSIZE == 8
2039 amount_to_save = MIN(0x100000, amount_to_save);
2040 #endif
2041 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
2042 amount_to_save);
2043 if (rc < 0)
2045 if (errno == ENOSPC)
2047 mpeg_errno = AUDIOERR_DISK_FULL;
2048 stop_recording();
2049 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2050 /* will close the file */
2051 break;
2053 else
2054 panicf("rec wrt: %d", rc);
2057 audiobuf_read += amount_to_save;
2058 if (audiobuf_read >= audiobuflen)
2059 audiobuf_read = 0;
2061 if (audiobuf_read == save_endpos) /* all saved */
2063 switch (saving_status)
2065 case BUFFER_FULL:
2066 rc = fsync(mpeg_file);
2067 if (rc < 0)
2068 panicf("rec fls: %d", rc);
2069 storage_sleep();
2070 break;
2072 case NEW_FILE:
2073 /* Close the current file */
2074 rc = close(mpeg_file);
2075 if (rc < 0)
2076 panicf("rec cls: %d", rc);
2077 mpeg_file = -1;
2078 update_header();
2079 storage_sleep();
2081 /* copy new filename */
2082 strcpy(delayed_filename, recording_filename);
2083 prepend_header();
2084 frame_count_start = frame_count_end;
2085 break;
2087 case STOP_RECORDING:
2088 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2089 /* will close the file */
2090 break;
2092 default:
2093 break;
2095 saving_status = NOT_SAVING;
2097 else /* tell ourselves to save the next chunk */
2098 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2100 break;
2102 case MPEG_PRERECORDING_TICK:
2103 if(!is_prerecording)
2104 break;
2106 /* Store the write pointer every second */
2107 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2108 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2109 &prerecord_buffer[prerecord_index].framecount, 1);
2111 /* Wrap if necessary */
2112 if(++prerecord_index == prerecording_max_seconds)
2113 prerecord_index = 0;
2115 /* Update the number of seconds recorded */
2116 if(prerecord_count < prerecording_max_seconds)
2117 prerecord_count++;
2118 break;
2120 case MPEG_INIT_PLAYBACK:
2121 /* Stop the prerecording */
2122 stop_recording();
2123 reset_mp3_buffer();
2124 mp3_play_init();
2125 init_playback_done = true;
2126 break;
2128 case MPEG_PAUSE_RECORDING:
2129 pause_recording();
2130 break;
2132 case MPEG_RESUME_RECORDING:
2133 resume_recording();
2134 break;
2136 case SYS_USB_CONNECTED:
2137 /* We can safely go to USB mode if no recording
2138 is taking place */
2139 if((!is_recording || is_prerecording) && mpeg_stop_done)
2141 /* Even if we aren't recording, we still call this
2142 function, to put the MAS in monitoring mode,
2143 to save power. */
2144 stop_recording();
2146 /* Tell the USB thread that we are safe */
2147 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2148 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2150 /* Wait until the USB cable is extracted again */
2151 usb_wait_for_disconnect(&mpeg_queue);
2153 break;
2156 #endif /* CONFIG_CODEC == MAS3587F */
2159 #endif /* !SIMULATOR */
2161 struct mp3entry* audio_current_track(void)
2163 #ifdef SIMULATOR
2164 struct mp3entry *id3 = &taginfo;
2165 #else /* !SIMULATOR */
2166 if(num_tracks_in_memory())
2168 struct mp3entry *id3 = &get_trackdata(0)->id3;
2169 #endif
2170 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2172 checked_for_cuesheet = true; /* only check once per track */
2173 struct cuesheet_file cue_file;
2175 if (look_for_cuesheet_file(id3, &cue_file) &&
2176 parse_cuesheet(&cue_file, curr_cuesheet))
2178 id3->cuesheet = curr_cuesheet;
2181 return id3;
2182 #ifndef SIMULATOR
2184 else
2185 return NULL;
2186 #endif /* !SIMULATOR */
2189 struct mp3entry* audio_next_track(void)
2191 #ifdef SIMULATOR
2192 return &taginfo;
2193 #else /* !SIMULATOR */
2194 if(num_tracks_in_memory() > 1)
2195 return &get_trackdata(1)->id3;
2196 else
2197 return NULL;
2198 #endif /* !SIMULATOR */
2201 #if CONFIG_CODEC == MAS3587F
2202 #ifndef SIMULATOR
2203 void audio_init_playback(void)
2205 init_playback_done = false;
2206 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2208 while(!init_playback_done)
2209 sleep(1);
2213 /****************************************************************************
2214 * Recording functions
2215 ***************************************************************************/
2216 void audio_init_recording(void)
2218 init_recording_done = false;
2219 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2221 while(!init_recording_done)
2222 sleep(1);
2225 static void init_recording(void)
2227 unsigned long val;
2228 int rc;
2230 /* Disable IRQ6 */
2231 IPRB &= 0xff0f;
2233 stop_playing();
2234 is_playing = false;
2235 paused = false;
2237 /* Init the recording variables */
2238 is_recording = false;
2239 is_prerecording = false;
2241 mpeg_stop_done = true;
2243 mas_reset();
2245 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2246 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2247 if(rc < 0)
2248 panicf("mas_ctrl_w: %d", rc);
2250 /* Stop the current application */
2251 val = 0;
2252 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2255 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2256 } while(val);
2258 /* Perform black magic as described by the data sheet */
2259 if((mas_version_code & 0x0fff) == 0x0102)
2261 DEBUGF("Performing MAS black magic for B2 version\n");
2262 mas_writereg(0xa3, 0x98);
2263 mas_writereg(0x94, 0xfffff);
2264 val = 0;
2265 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2266 mas_writereg(0xa3, 0x90);
2269 /* Enable A/D Converters */
2270 shadow_codec_reg0 = 0xcccd;
2271 mas_codec_writereg(0x0, shadow_codec_reg0);
2273 /* Copy left channel to right (mono mode) */
2274 mas_codec_writereg(8, 0x8000);
2276 /* ADC scale 0%, DSP scale 100%
2277 We use the DSP output for monitoring, because it works with all
2278 sources including S/PDIF */
2279 mas_codec_writereg(6, 0x0000);
2280 mas_codec_writereg(7, 0x4000);
2282 /* No mute */
2283 shadow_soft_mute = 0;
2284 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2286 #ifdef HAVE_SPDIF_OUT
2287 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2288 #else
2289 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2290 #endif
2291 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2293 /* Set Demand mode, monitoring OFF and validate all settings */
2294 shadow_io_control_main = 0x125;
2295 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2297 /* Start the encoder application */
2298 val = 0x40;
2299 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2302 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2303 } while(!(val & 0x40));
2305 /* We have started the recording application with monitoring OFF.
2306 This is because we want to record at least one frame to fill the DMA
2307 buffer, because the silly MAS will not negate EOD until at least one
2308 DMA transfer has taken place.
2309 Now let's wait for some data to be encoded. */
2310 sleep(HZ/5);
2312 /* Now set it to Monitoring mode as default, saves power */
2313 shadow_io_control_main = 0x525;
2314 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2316 /* Wait until the DSP has accepted the settings */
2319 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2320 } while(val & 1);
2322 drain_dma_buffer();
2323 mpeg_mode = MPEG_ENCODER;
2325 DEBUGF("MAS Recording application started\n");
2327 /* At this point, all settings are the reset MAS defaults, next thing is to
2328 call mpeg_set_recording_options(). */
2331 void audio_record(const char *filename)
2333 mpeg_errno = 0;
2335 strlcpy(recording_filename, filename, MAX_PATH);
2337 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2340 void audio_pause_recording(void)
2342 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2345 void audio_resume_recording(void)
2347 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2350 static void prepend_header(void)
2352 int startpos;
2353 unsigned i;
2355 /* Make room for header */
2356 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2357 if(audiobuf_read < 0)
2359 /* Clear the bottom half */
2360 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2362 /* And the top half */
2363 audiobuf_read += audiobuflen;
2364 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2366 else
2368 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2370 /* Copy the empty ID3 header */
2371 startpos = audiobuf_read;
2372 for(i = 0; i < sizeof(empty_id3_header); i++)
2374 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2375 if(startpos == audiobuflen)
2376 startpos = 0;
2380 static void update_header(void)
2382 int fd, framelen;
2383 unsigned long frames;
2385 if (last_rec_bytes > 0)
2387 /* Create the Xing header */
2388 fd = open(delayed_filename, O_RDWR);
2389 if (fd < 0)
2390 panicf("rec upd: %d (%s)", fd, recording_filename);
2392 frames = frame_count_end - frame_count_start;
2393 /* If the number of recorded frames has reached 0x7ffff,
2394 we can no longer trust it */
2395 if (frame_count_end == 0x7ffff)
2396 frames = 0;
2398 /* saved_header is saved right before stopping the MAS */
2399 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2400 frames, last_rec_time * (1000/HZ),
2401 saved_header, NULL, false,
2402 mpeg_audiobuf, audiobuflen);
2404 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2405 write(fd, xing_buffer, framelen);
2406 close(fd);
2410 static void start_prerecording(void)
2412 unsigned long val;
2414 DEBUGF("Starting prerecording\n");
2416 prerecord_index = 0;
2417 prerecord_count = 0;
2418 prerecord_timeout = current_tick + HZ;
2419 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2420 reset_mp3_buffer();
2422 is_prerecording = true;
2424 /* Stop monitoring and start the encoder */
2425 shadow_io_control_main &= ~(1 << 10);
2426 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2427 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2429 /* Wait until the DSP has accepted the settings */
2432 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2433 } while(val & 1);
2435 is_recording = true;
2436 saving_status = NOT_SAVING;
2438 demand_irq_enable(true);
2441 static void start_recording(void)
2443 unsigned long val;
2445 if(is_prerecording)
2447 /* This will make the IRQ handler start recording
2448 for real, i.e send MPEG_SAVE_DATA messages when
2449 the buffer is full */
2450 is_prerecording = false;
2452 else
2454 /* If prerecording is off, we need to stop the monitoring
2455 and start the encoder */
2456 shadow_io_control_main &= ~(1 << 10);
2457 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2458 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2460 /* Wait until the DSP has accepted the settings */
2463 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2464 } while(val & 1);
2467 is_recording = true;
2468 saving_status = NOT_SAVING;
2469 paused = false;
2471 /* Store the current time */
2472 if(prerecording)
2473 record_start_time = current_tick - prerecord_count * HZ;
2474 else
2475 record_start_time = current_tick;
2477 pause_start_time = 0;
2479 demand_irq_enable(true);
2482 static void pause_recording(void)
2484 pause_start_time = current_tick;
2486 /* Set the pause bit */
2487 shadow_soft_mute |= 2;
2488 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2490 paused = true;
2493 static void resume_recording(void)
2495 paused = false;
2497 /* Clear the pause bit */
2498 shadow_soft_mute &= ~2;
2499 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2501 /* Compensate for the time we have been paused */
2502 if(pause_start_time)
2504 record_start_time =
2505 current_tick - (pause_start_time - record_start_time);
2506 pause_start_time = 0;
2510 static void stop_recording(void)
2512 unsigned long val;
2514 /* Let it finish the last frame */
2515 if(!paused)
2516 pause_recording();
2517 sleep(HZ/5);
2519 demand_irq_enable(false);
2521 is_recording = false;
2522 is_prerecording = false;
2524 last_rec_bytes = num_rec_bytes;
2525 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2526 last_rec_time = current_tick - record_start_time;
2528 /* Start monitoring */
2529 shadow_io_control_main |= (1 << 10);
2530 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2531 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2533 /* Wait until the DSP has accepted the settings */
2536 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2537 } while(val & 1);
2539 resume_recording();
2542 void audio_set_recording_options(struct audio_recording_options *options)
2544 bool is_mpeg1;
2546 is_mpeg1 = (options->rec_frequency < 3);
2548 rec_version_index = is_mpeg1?3:2;
2549 rec_frequency_index = options->rec_frequency % 3;
2551 shadow_encoder_control = (options->rec_quality << 17) |
2552 (rec_frequency_index << 10) |
2553 ((is_mpeg1?1:0) << 9) |
2554 (((options->rec_channels * 2 + 1) & 3) << 6) |
2555 (1 << 5) /* MS-stereo */ |
2556 (1 << 2) /* Is an original */;
2557 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2559 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2561 #if CONFIG_TUNER & S1A0903X01
2562 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2563 interference with the Samsung tuner. */
2564 if (rec_frequency_index)
2565 mas_store_pllfreq(24576000);
2566 else
2567 mas_store_pllfreq(22579000);
2568 #endif
2570 shadow_soft_mute = options->rec_editable?4:0;
2571 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2573 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2575 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2576 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2577 (1 << 5) | /* SDO strobe invert */
2578 ((is_mpeg1?0:1) << 3) |
2579 (1 << 2) | /* Inverted SIBC clock signal */
2580 1; /* Validate */
2581 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2583 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2585 if(options->rec_source == AUDIO_SRC_MIC)
2587 /* Copy left channel to right (mono mode) */
2588 mas_codec_writereg(8, 0x8000);
2590 else
2592 /* Stereo input mode */
2593 mas_codec_writereg(8, 0);
2596 prerecording_max_seconds = options->rec_prerecord_time;
2597 if(prerecording_max_seconds)
2599 prerecording = true;
2600 start_prerecording();
2602 else
2604 prerecording = false;
2605 is_prerecording = false;
2606 is_recording = false;
2610 /* If use_mic is true, the left gain is used */
2611 void audio_set_recording_gain(int left, int right, int type)
2613 /* Enable both left and right A/D */
2614 shadow_codec_reg0 = (left << 12) |
2615 (right << 8) |
2616 (left << 4) |
2617 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2618 0x0007;
2619 mas_codec_writereg(0x0, shadow_codec_reg0);
2622 /* try to make some kind of beep, also in recording mode */
2623 void audio_beep(int duration)
2625 long starttick = current_tick;
2627 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2628 * While this is still audible even without an external signal,
2629 * it doesn't affect the (pre-)recording. */
2630 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2631 mas_codec_writereg(0, shadow_codec_reg0);
2632 yield();
2634 while (current_tick - starttick < duration);
2637 void audio_new_file(const char *filename)
2639 mpeg_errno = 0;
2641 strlcpy(recording_filename, filename, MAX_PATH);
2643 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2646 unsigned long audio_recorded_time(void)
2648 if(is_prerecording)
2649 return prerecord_count * HZ;
2651 if(is_recording)
2653 if(paused)
2654 return pause_start_time - record_start_time;
2655 else
2656 return current_tick - record_start_time;
2659 return 0;
2662 unsigned long audio_num_recorded_bytes(void)
2664 int num_bytes;
2665 int index;
2667 if(is_recording)
2669 if(is_prerecording)
2671 index = prerecord_index - prerecord_count;
2672 if(index < 0)
2673 index += prerecording_max_seconds;
2675 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2676 if(num_bytes < 0)
2677 num_bytes += audiobuflen;
2679 return num_bytes;
2681 else
2682 return num_rec_bytes;
2684 else
2685 return 0;
2688 #else /* SIMULATOR */
2690 /* dummies coming up */
2692 void audio_init_playback(void)
2694 /* a dummy */
2696 unsigned long audio_recorded_time(void)
2698 /* a dummy */
2699 return 0;
2701 void audio_beep(int duration)
2703 /* a dummy */
2704 (void)duration;
2706 void audio_pause_recording(void)
2708 /* a dummy */
2710 void audio_resume_recording(void)
2712 /* a dummy */
2714 unsigned long audio_num_recorded_bytes(void)
2716 /* a dummy */
2717 return 0;
2719 void audio_record(const char *filename)
2721 /* a dummy */
2722 (void)filename;
2724 void audio_new_file(const char *filename)
2726 /* a dummy */
2727 (void)filename;
2730 void audio_set_recording_gain(int left, int right, int type)
2732 /* a dummy */
2733 (void)left;
2734 (void)right;
2735 (void)type;
2737 void audio_init_recording(void)
2739 /* a dummy */
2741 void audio_set_recording_options(struct audio_recording_options *options)
2743 /* a dummy */
2744 (void)options;
2746 #endif /* SIMULATOR */
2747 #endif /* CONFIG_CODEC == MAS3587F */
2749 size_t audio_buffer_size(void)
2751 if (audiobuf_handle > 0)
2752 return audiobuflen;
2753 return 0;
2756 size_t audio_buffer_available(void)
2758 size_t size = 0;
2759 size_t core_size = core_available();
2760 if (audiobuf_handle > 0)
2761 return audiobuflen - AUDIO_BUFFER_RESERVE - 128;
2762 return MAX(core_size, size);
2765 static void audio_reset_buffer_noalloc(void* buf, size_t bufsize)
2767 talk_buffer_steal(); /* will use the mp3 buffer */
2768 mpeg_audiobuf = buf;
2769 audiobuflen = bufsize;
2770 if (global_settings.cuesheet)
2771 { /* enable cuesheet support */
2772 curr_cuesheet = (struct cuesheet*)mpeg_audiobuf;
2773 mpeg_audiobuf = SKIPBYTES(mpeg_audiobuf, sizeof(struct cuesheet));
2774 audiobuflen -= sizeof(struct cuesheet);
2776 audio_talkbuf_init(mpeg_audiobuf);
2779 static void audio_reset_buffer(void)
2781 size_t bufsize = audiobuflen;
2783 /* alloc buffer if it's was never allocated or freed by audio_hard_stop() */
2784 if (!audiobuf_handle)
2785 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
2787 audio_reset_buffer_noalloc(core_get_data(audiobuf_handle), bufsize);
2790 void audio_play(long offset)
2792 audio_reset_buffer();
2793 #ifdef SIMULATOR
2794 char name_buf[MAX_PATH+1];
2795 const char* trackname;
2796 int steps=0;
2798 is_playing = true;
2800 do {
2801 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2802 if (!trackname)
2803 break;
2804 if(mp3info(&taginfo, trackname)) {
2805 /* bad mp3, move on */
2806 if(++steps > playlist_amount())
2807 break;
2808 continue;
2810 #ifdef HAVE_MPEG_PLAY
2811 real_mpeg_play(trackname);
2812 #endif
2813 playlist_next(steps);
2814 taginfo.offset = offset;
2815 set_elapsed(&taginfo);
2816 is_playing = true;
2817 playing = true;
2818 break;
2819 } while(1);
2820 #else /* !SIMULATOR */
2821 is_playing = true;
2822 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2823 #endif /* !SIMULATOR */
2825 mpeg_errno = 0;
2828 void audio_stop(void)
2830 #ifndef SIMULATOR
2831 if (playing)
2833 struct trackdata *track = get_trackdata(0);
2834 prev_track_elapsed = track->id3.elapsed;
2836 mpeg_stop_done = false;
2837 queue_post(&mpeg_queue, MPEG_STOP, 0);
2838 while(!mpeg_stop_done)
2839 yield();
2840 #else /* SIMULATOR */
2841 paused = false;
2842 is_playing = false;
2843 playing = false;
2844 #endif /* SIMULATOR */
2845 /* give voice our entire buffer */
2846 audio_talkbuf_init(mpeg_audiobuf);
2849 /* dummy */
2850 void audio_stop_recording(void)
2852 audio_stop();
2855 void audio_hard_stop(void)
2857 audio_stop();
2858 /* tell voice we obtain the buffer before freeing */
2859 talk_buffer_steal();
2860 if (audiobuf_handle > 0)
2862 audiobuf_handle = core_free(audiobuf_handle);
2863 mpeg_audiobuf = NULL;
2867 void audio_pause(void)
2869 #ifndef SIMULATOR
2870 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2871 #else /* SIMULATOR */
2872 is_playing = true;
2873 playing = false;
2874 paused = true;
2875 #endif /* SIMULATOR */
2878 void audio_resume(void)
2880 #ifndef SIMULATOR
2881 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2882 #else /* SIMULATOR */
2883 is_playing = true;
2884 playing = true;
2885 paused = false;
2886 #endif /* SIMULATOR */
2889 void audio_next(void)
2891 #ifndef SIMULATOR
2892 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2893 queue_post(&mpeg_queue, MPEG_NEXT, 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 if(++steps > playlist_amount())
2905 break;
2906 continue;
2908 playlist_next(steps);
2909 current_track_counter++;
2910 is_playing = true;
2911 playing = true;
2912 break;
2913 } while(1);
2914 #endif /* SIMULATOR */
2917 void audio_prev(void)
2919 #ifndef SIMULATOR
2920 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2921 queue_post(&mpeg_queue, MPEG_PREV, 0);
2922 #else /* SIMULATOR */
2923 char name_buf[MAX_PATH+1];
2924 const char* file;
2925 int steps = -1;
2927 do {
2928 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2929 if(!file)
2930 break;
2931 if(mp3info(&taginfo, file)) {
2932 steps--;
2933 continue;
2935 playlist_next(steps);
2936 current_track_counter++;
2937 is_playing = true;
2938 playing = true;
2939 break;
2940 } while(1);
2941 #endif /* SIMULATOR */
2944 void audio_ff_rewind(long newpos)
2946 #ifndef SIMULATOR
2947 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2948 #else /* SIMULATOR */
2949 (void)newpos;
2950 #endif /* SIMULATOR */
2953 void audio_flush_and_reload_tracks(void)
2955 #ifndef SIMULATOR
2956 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2957 #endif /* !SIMULATOR*/
2960 int audio_status(void)
2962 int ret = 0;
2964 if(is_playing)
2965 ret |= AUDIO_STATUS_PLAY;
2967 if(paused)
2968 ret |= AUDIO_STATUS_PAUSE;
2970 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2971 if(is_recording && !is_prerecording)
2972 ret |= AUDIO_STATUS_RECORD;
2974 if(is_prerecording)
2975 ret |= AUDIO_STATUS_PRERECORD;
2976 #endif /* CONFIG_CODEC == MAS3587F */
2978 if(mpeg_errno)
2979 ret |= AUDIO_STATUS_ERROR;
2981 return ret;
2984 /* Unused function
2985 unsigned int audio_error(void)
2987 return mpeg_errno;
2991 void audio_error_clear(void)
2993 mpeg_errno = 0;
2996 #ifdef SIMULATOR
2997 static void mpeg_thread(void)
2999 struct mp3entry* id3;
3000 while ( 1 ) {
3001 if (is_playing) {
3002 id3 = audio_current_track();
3003 if (!paused)
3005 id3->elapsed+=1000;
3006 id3->offset+=1000;
3008 if (id3->elapsed>=id3->length)
3009 audio_next();
3011 sleep(HZ);
3014 #endif /* SIMULATOR */
3016 void audio_init(void)
3018 mpeg_errno = 0;
3020 talk_init();
3021 audio_reset_buffer();
3023 #ifndef SIMULATOR
3024 queue_init(&mpeg_queue, true);
3025 #endif /* !SIMULATOR */
3026 audio_thread_id = create_thread(mpeg_thread, mpeg_stack,
3027 sizeof(mpeg_stack), 0, mpeg_thread_name
3028 IF_PRIO(, PRIORITY_SYSTEM)
3029 IF_COP(, CPU));
3031 memset(trackdata, 0, sizeof(trackdata));
3033 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
3034 if (HW_MASK & PR_ACTIVE_HIGH)
3035 and_b(~0x08, &PADRH);
3036 else
3037 or_b(0x08, &PADRH);
3038 #endif /* CONFIG_CODEC == MAS3587F */
3040 #ifdef DEBUG
3041 #ifndef SIMULATOR
3042 dbg_timer_start();
3043 dbg_cnt2us(0);
3044 #endif /* !SIMULATOR */
3045 #endif /* DEBUG */
3046 audio_is_initialized = true;
3049 #endif /* CONFIG_CODEC != SWCODEC */