GSoC/Buflib: Add buflib memory alocator to the core.
[maemo-rb.git] / apps / mpeg.c
blob595f943545f3931a305aabb15b437c435dd8c354
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 "bitswap.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 mpeg_errno;
145 static bool playing = false; /* We are playing an MP3 stream */
146 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
147 static bool paused; /* playback is paused */
148 static int audiobuf_handle; /* handle to the audio buffer */
149 static char* mpeg_audiobuf; /* poiunter to the audio buffer */
150 static long audiobuflen; /* length of the audio buffer */
152 #ifdef SIMULATOR
153 static char mpeg_stack[DEFAULT_STACK_SIZE];
154 static struct mp3entry taginfo;
155 #else /* !SIMULATOR */
156 static struct event_queue mpeg_queue SHAREDBSS_ATTR;
157 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
159 static int audiobuf_write;
160 static int audiobuf_swapwrite;
161 static long audiobuf_read;
163 static int mpeg_file;
165 static bool play_pending; /* We are about to start playing */
166 static bool play_pending_track_change; /* When starting play we're starting a new file */
167 static bool filling; /* We are filling the buffer with data from disk */
168 static bool dma_underrun; /* True when the DMA has stopped because of
169 slow disk reading (read error, shaking) */
170 static bool mpeg_stop_done;
172 static int last_dma_tick = 0;
173 static int last_dma_chunk_size;
175 static long low_watermark; /* Dynamic low watermark level */
176 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
177 static long lowest_watermark_level; /* Debug value to observe the buffer
178 usage */
179 #if CONFIG_CODEC == MAS3587F
180 static char recording_filename[MAX_PATH]; /* argument to thread */
181 static char delayed_filename[MAX_PATH]; /* internal copy of above */
183 static char xing_buffer[MAX_XING_HEADER_SIZE];
185 static bool init_recording_done;
186 static bool init_playback_done;
187 static bool prerecording; /* True if prerecording is enabled */
188 static bool is_prerecording; /* True if we are prerecording */
189 static bool is_recording; /* We are recording */
191 static enum {
192 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
193 BUFFER_FULL,
194 NEW_FILE,
195 STOP_RECORDING
196 } saving_status;
198 static int rec_frequency_index; /* For create_xing_header() calls */
199 static int rec_version_index; /* For create_xing_header() calls */
201 struct prerecord_info {
202 int mempos;
203 unsigned long framecount;
206 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
207 static int prerecord_index; /* Current index in the prerecord buffer */
208 static int prerecording_max_seconds; /* Max number of seconds to store */
209 static int prerecord_count; /* Number of seconds in the prerecord buffer */
210 static int prerecord_timeout; /* The tick count of the next prerecord data
211 store */
213 static unsigned long record_start_time; /* Value of current_tick when recording
214 was started */
215 static unsigned long pause_start_time; /* Value of current_tick when pause was
216 started */
217 static unsigned long last_rec_time;
218 static unsigned long num_rec_bytes;
219 static unsigned long last_rec_bytes;
220 static unsigned long frame_count_start;
221 static unsigned long frame_count_end;
222 static unsigned long saved_header = 0;
224 /* Shadow MAS registers */
225 unsigned long shadow_encoder_control = 0;
226 #endif /* CONFIG_CODEC == MAS3587F */
228 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
229 unsigned long shadow_io_control_main = 0;
230 unsigned long shadow_soft_mute = 0;
231 unsigned shadow_codec_reg0;
232 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
234 #ifdef HAVE_RECORDING
235 static const unsigned char empty_id3_header[] =
237 'I', 'D', '3', 0x03, 0x00, 0x00,
238 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
240 #endif /* HAVE_RECORDING */
243 static int get_unplayed_space(void);
244 static int get_playable_space(void);
245 static int get_unswapped_space(void);
246 #endif /* !SIMULATOR */
248 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
249 static void init_recording(void);
250 static void prepend_header(void);
251 static void update_header(void);
252 static void start_prerecording(void);
253 static void start_recording(void);
254 static void stop_recording(void);
255 static int get_unsaved_space(void);
256 static void pause_recording(void);
257 static void resume_recording(void);
258 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
261 #ifndef SIMULATOR
262 static int num_tracks_in_memory(void)
264 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
267 #ifdef DEBUG_TAGS
268 static void debug_tags(void)
270 int i;
272 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
274 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
276 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
277 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
279 #else /* !DEBUG_TAGS */
280 #define debug_tags()
281 #endif /* !DEBUG_TAGS */
283 static void remove_current_tag(void)
285 if(num_tracks_in_memory() > 0)
287 /* First move the index, so nobody tries to access the tag */
288 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
289 checked_for_cuesheet = false;
290 debug_tags();
292 else
294 DEBUGF("remove_current_tag: no tracks to remove\n");
298 static void remove_all_non_current_tags(void)
300 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
301 debug_tags();
304 static void remove_all_tags(void)
306 track_write_idx = track_read_idx;
308 debug_tags();
311 static struct trackdata *get_trackdata(int offset)
313 if(offset >= num_tracks_in_memory())
314 return NULL;
315 else
316 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
318 #endif /* !SIMULATOR */
320 /***********************************************************************/
321 /* audio event handling */
323 #define MAX_EVENT_HANDLERS 10
324 struct event_handlers_table
326 AUDIO_EVENT_HANDLER handler;
327 unsigned short mask;
329 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
330 static int event_handlers_count = 0;
332 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
334 if (event_handlers_count < MAX_EVENT_HANDLERS)
336 event_handlers[event_handlers_count].handler = handler;
337 event_handlers[event_handlers_count].mask = mask;
338 event_handlers_count++;
342 /* dispatch calls each handler in the order registered and returns after some
343 handler actually handles the event (the event is assumed to no longer be valid
344 after this, due to the handler changing some condition); returns true if someone
345 handled the event, which is expected to cause the caller to skip its own handling
346 of the event */
347 #ifndef SIMULATOR
348 static bool audio_dispatch_event(unsigned short event, unsigned long data)
350 int i = 0;
351 for(i=0; i < event_handlers_count; i++)
353 if ( event_handlers[i].mask & event )
355 int rc = event_handlers[i].handler(event, data);
356 if ( rc == AUDIO_EVENT_RC_HANDLED )
357 return true;
360 return false;
362 #endif
364 /***********************************************************************/
366 static void set_elapsed(struct mp3entry* id3)
368 if ( id3->vbr ) {
369 if ( id3->has_toc ) {
370 /* calculate elapsed time using TOC */
371 int i;
372 unsigned int remainder, plen, relpos, nextpos;
374 /* find wich percent we're at */
375 for (i=0; i<100; i++ )
377 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
379 break;
383 i--;
384 if (i < 0)
385 i = 0;
387 relpos = id3->toc[i];
389 if (i < 99)
391 nextpos = id3->toc[i+1];
393 else
395 nextpos = 256;
398 remainder = id3->offset - (relpos * (id3->filesize / 256));
400 /* set time for this percent (divide before multiply to prevent
401 overflow on long files. loss of precision is negligible on
402 short files) */
403 id3->elapsed = i * (id3->length / 100);
405 /* calculate remainder time */
406 plen = (nextpos - relpos) * (id3->filesize / 256);
407 id3->elapsed += (((remainder * 100) / plen) *
408 (id3->length / 10000));
410 else {
411 /* no TOC exists. set a rough estimate using average bitrate */
412 int tpk = id3->length / (id3->filesize / 1024);
413 id3->elapsed = id3->offset / 1024 * tpk;
416 else
417 /* constant bitrate, use exact calculation */
418 id3->elapsed = id3->offset / (id3->bitrate / 8);
421 int audio_get_file_pos(void)
423 int pos = -1;
424 struct mp3entry *id3 = audio_current_track();
426 if (id3->vbr)
428 if (id3->has_toc)
430 /* Use the TOC to find the new position */
431 unsigned int percent, remainder;
432 int curtoc, nexttoc, plen;
434 percent = (id3->elapsed*100)/id3->length;
435 if (percent > 99)
436 percent = 99;
438 curtoc = id3->toc[percent];
440 if (percent < 99)
441 nexttoc = id3->toc[percent+1];
442 else
443 nexttoc = 256;
445 pos = (id3->filesize/256)*curtoc;
447 /* Use the remainder to get a more accurate position */
448 remainder = (id3->elapsed*100)%id3->length;
449 remainder = (remainder*100)/id3->length;
450 plen = (nexttoc - curtoc)*(id3->filesize/256);
451 pos += (plen/100)*remainder;
453 else
455 /* No TOC exists, estimate the new position */
456 pos = (id3->filesize / (id3->length / 1000)) *
457 (id3->elapsed / 1000);
460 else if (id3->bitrate)
461 pos = id3->elapsed * (id3->bitrate / 8);
462 else
464 return -1;
467 if (pos >= (int)(id3->filesize - id3->id3v1len))
469 /* Don't seek right to the end of the file so that we can
470 transition properly to the next song */
471 pos = id3->filesize - id3->id3v1len - 1;
473 else if (pos < (int)id3->first_frame_offset)
475 /* skip past id3v2 tag and other leading garbage */
476 pos = id3->first_frame_offset;
478 return pos;
481 unsigned long mpeg_get_last_header(void)
483 #ifdef SIMULATOR
484 return 0;
485 #else /* !SIMULATOR */
486 unsigned long tmp[2];
488 /* Read the frame data from the MAS and reconstruct it with the
489 frame sync and all */
490 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
491 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
492 #endif /* !SIMULATOR */
495 /* Buffer must not move. And not shrink for now */
496 static struct buflib_callbacks ops = { NULL, NULL };
497 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
499 (void)talk_buf; /* always grab the voice buffer for now */
501 if (buffer_size) /* special case for talk_init() */
503 size_t bufsize;
504 audio_hard_stop();
505 /* audio_hard_stop() frees audiobuf, so re-aquire */
506 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
507 audiobuflen = bufsize;
508 *buffer_size = audiobuflen;
510 mpeg_audiobuf = core_get_data(audiobuf_handle);
512 if (!buffer_size) /* special case for talk_init() */
513 talkbuf_init(mpeg_audiobuf);
515 return mpeg_audiobuf;
519 #ifndef SIMULATOR
520 /* Send callback events to notify about removing old tracks. */
521 static void generate_unbuffer_events(void)
523 int i;
524 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
525 int cur_idx = track_write_idx;
527 for (i = 0; i < numentries; i++)
529 /* Send an event to notify that track has finished. */
530 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
531 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
535 /* Send callback events to notify about new tracks. */
536 static void generate_postbuffer_events(void)
538 int i;
539 int numentries = num_tracks_in_memory();
540 int cur_idx = track_read_idx;
542 for (i = 0; i < numentries; i++)
544 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
545 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
549 static void recalculate_watermark(int bitrate)
551 int bytes_per_sec;
552 int time = storage_spinup_time();
554 /* A bitrate of 0 probably means empty VBR header. We play safe
555 and set a high threshold */
556 if(bitrate == 0)
557 bitrate = 320;
559 bytes_per_sec = bitrate * 1000 / 8;
561 if(time)
563 /* No drive spins up faster than 3.5s */
564 if(time < 350)
565 time = 350;
567 time = time * 3;
568 low_watermark = ((low_watermark_margin * HZ + time) *
569 bytes_per_sec) / HZ;
571 else
573 low_watermark = MPEG_LOW_WATER;
577 #ifdef HAVE_DISK_STORAGE
578 void audio_set_buffer_margin(int setting)
580 low_watermark_margin = setting; /* in seconds */
582 #endif
584 void audio_get_debugdata(struct audio_debug *dbgdata)
586 dbgdata->audiobuflen = audiobuflen;
587 dbgdata->audiobuf_write = audiobuf_write;
588 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
589 dbgdata->audiobuf_read = audiobuf_read;
591 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
593 #if CONFIG_CPU == SH7034
594 dbgdata->dma_on = (SCR0 & 0x80) != 0;
595 #endif
596 dbgdata->playing = playing;
597 dbgdata->play_pending = play_pending;
598 dbgdata->is_playing = is_playing;
599 dbgdata->filling = filling;
600 dbgdata->dma_underrun = dma_underrun;
602 dbgdata->unplayed_space = get_unplayed_space();
603 dbgdata->playable_space = get_playable_space();
604 dbgdata->unswapped_space = get_unswapped_space();
606 dbgdata->low_watermark_level = low_watermark;
607 dbgdata->lowest_watermark_level = lowest_watermark_level;
610 #ifdef DEBUG
611 static void dbg_timer_start(void)
613 /* We are using timer 2 */
615 TSTR &= ~0x04; /* Stop the timer */
616 TSNC &= ~0x04; /* No synchronization */
617 TMDR &= ~0x44; /* Operate normally */
619 TCNT2 = 0; /* Start counting at 0 */
620 TCR2 = 0x03; /* Sysclock/8 */
622 TSTR |= 0x04; /* Start timer 2 */
625 static int dbg_cnt2us(unsigned int cnt)
627 return (cnt * 10000) / (FREQ/800);
629 #endif /* DEBUG */
631 static int get_unplayed_space(void)
633 int space = audiobuf_write - audiobuf_read;
634 if (space < 0)
635 space += audiobuflen;
636 return space;
639 static int get_playable_space(void)
641 int space = audiobuf_swapwrite - audiobuf_read;
642 if (space < 0)
643 space += audiobuflen;
644 return space;
647 static int get_unplayed_space_current_song(void)
649 int space;
651 if (num_tracks_in_memory() > 1)
653 space = get_trackdata(1)->mempos - audiobuf_read;
655 else
657 space = audiobuf_write - audiobuf_read;
660 if (space < 0)
661 space += audiobuflen;
663 return space;
666 static int get_unswapped_space(void)
668 int space = audiobuf_write - audiobuf_swapwrite;
669 if (space < 0)
670 space += audiobuflen;
671 return space;
674 #if CONFIG_CODEC == MAS3587F
675 static int get_unsaved_space(void)
677 int space = audiobuf_write - audiobuf_read;
678 if (space < 0)
679 space += audiobuflen;
680 return space;
683 static void drain_dma_buffer(void)
685 while (PBDRH & 0x40)
687 xor_b(0x08, &PADRH);
689 while (PBDRH & 0x80);
691 xor_b(0x08, &PADRH);
693 while (!(PBDRH & 0x80));
697 #ifdef DEBUG
698 static long timing_info_index = 0;
699 static long timing_info[1024];
700 #endif /* DEBUG */
702 void rec_tick (void) __attribute__ ((section (".icode")));
703 void rec_tick(void)
705 int i;
706 int delay;
707 char data;
709 if(is_recording && (PBDRH & 0x40))
711 #ifdef DEBUG
712 timing_info[timing_info_index++] = current_tick;
713 TCNT2 = 0;
714 #endif /* DEBUG */
715 /* Note: Although this loop is run in interrupt context, further
716 * optimisation will do no good. The MAS would then deliver bad
717 * frames occasionally, as observed in extended experiments. */
718 i = 0;
719 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
721 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
723 delay = 100;
724 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
726 if (--delay <= 0) /* Bail out if we have to wait too long */
727 { /* i.e. the MAS doesn't want to talk to us */
728 xor_b(0x08, &PADRH); /* Set PR inactive */
729 goto transfer_end; /* and get out of here */
733 data = *(unsigned char *)0x04000000; /* read data byte */
735 xor_b(0x08, &PADRH); /* Set PR inactive */
737 mpeg_audiobuf[audiobuf_write++] = data;
739 if (audiobuf_write >= audiobuflen)
740 audiobuf_write = 0;
742 i++;
744 transfer_end:
746 #ifdef DEBUG
747 timing_info[timing_info_index++] = TCNT2 + (i << 16);
748 timing_info_index &= 0x3ff;
749 #endif /* DEBUG */
751 num_rec_bytes += i;
753 if(is_prerecording)
755 if(TIME_AFTER(current_tick, prerecord_timeout))
757 prerecord_timeout = current_tick + HZ;
758 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
761 else
763 /* Signal to save the data if we are running out of buffer
764 space */
765 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
766 && saving_status == NOT_SAVING)
768 saving_status = BUFFER_FULL;
769 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
774 #endif /* CONFIG_CODEC == MAS3587F */
776 void playback_tick(void)
778 struct trackdata *ptd = get_trackdata(0);
779 if(ptd)
781 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
782 last_dma_tick = current_tick;
783 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
784 (unsigned long)ptd->id3.elapsed);
788 static void reset_mp3_buffer(void)
790 audiobuf_read = 0;
791 audiobuf_write = 0;
792 audiobuf_swapwrite = 0;
793 lowest_watermark_level = audiobuflen;
796 /* DMA transfer end interrupt callback */
797 static void transfer_end(unsigned char** ppbuf, size_t* psize)
799 if(playing && !paused)
801 int unplayed_space_left;
802 int space_until_end_of_buffer;
803 int track_offset = 1;
804 struct trackdata *track;
806 audiobuf_read += last_dma_chunk_size;
807 if(audiobuf_read >= audiobuflen)
808 audiobuf_read = 0;
810 /* First, check if we are on a track boundary */
811 if (num_tracks_in_memory() > 1)
813 if (audiobuf_read == get_trackdata(track_offset)->mempos)
815 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
817 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
818 track_offset++;
823 unplayed_space_left = get_unplayed_space();
825 space_until_end_of_buffer = audiobuflen - audiobuf_read;
827 if(!filling && unplayed_space_left < low_watermark)
829 filling = true;
830 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
833 if(unplayed_space_left)
835 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
836 last_dma_chunk_size = MIN(last_dma_chunk_size,
837 space_until_end_of_buffer);
839 /* several tracks loaded? */
840 track = get_trackdata(track_offset);
841 if(track)
843 /* will we move across the track boundary? */
844 if (( audiobuf_read < track->mempos ) &&
845 ((audiobuf_read+last_dma_chunk_size) >
846 track->mempos ))
848 /* Make sure that we end exactly on the boundary */
849 last_dma_chunk_size = track->mempos - audiobuf_read;
853 *psize = last_dma_chunk_size & 0xffff;
854 *ppbuf = mpeg_audiobuf + audiobuf_read;
855 track = get_trackdata(0);
856 if(track)
857 track->id3.offset += last_dma_chunk_size;
859 /* Update the watermark debug level */
860 if(unplayed_space_left < lowest_watermark_level)
861 lowest_watermark_level = unplayed_space_left;
863 else
865 /* Check if the end of data is because of a hard disk error.
866 If there is an open file handle, we are still playing music.
867 If not, the last file has been loaded, and the file handle is
868 closed. */
869 if(mpeg_file >= 0)
871 /* Update the watermark debug level */
872 if(unplayed_space_left < lowest_watermark_level)
873 lowest_watermark_level = unplayed_space_left;
875 DEBUGF("DMA underrun.\n");
876 dma_underrun = true;
878 else
880 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
882 DEBUGF("No more MP3 data. Stopping.\n");
883 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
884 playing = false;
887 *psize = 0; /* no more transfer */
892 static struct trackdata *add_track_to_tag_list(const char *filename)
894 struct trackdata *track;
895 bool send_nid3_event;
897 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
899 DEBUGF("Tag memory is full\n");
900 return NULL;
903 track = &trackdata[track_write_idx];
905 /* grab id3 tag of new file and
906 remember where in memory it starts */
907 if(mp3info(&track->id3, filename))
909 DEBUGF("Bad mp3\n");
910 return NULL;
912 track->mempos = audiobuf_write;
913 track->id3.elapsed = 0;
914 #ifdef HAVE_LCD_BITMAP
915 if (track->id3.title)
916 lcd_getstringsize(track->id3.title, NULL, NULL);
917 if (track->id3.artist)
918 lcd_getstringsize(track->id3.artist, NULL, NULL);
919 if (track->id3.album)
920 lcd_getstringsize(track->id3.album, NULL, NULL);
921 #endif
923 /* if this track is the next track then let the UI know it can get it */
924 send_nid3_event = (track_write_idx == track_read_idx + 1);
925 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
926 if (send_nid3_event)
927 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
928 debug_tags();
929 return track;
932 static int new_file(int steps)
934 int max_steps = playlist_amount();
935 int start = 0;
936 int i;
937 struct trackdata *track;
938 char name_buf[MAX_PATH+1];
939 const char *trackname;
941 /* Find out how many steps to advance. The load_ahead_index field tells
942 us how many playlist entries it had to skip to get to a valid one.
943 We add those together to find out where to start. */
944 if(steps > 0 && num_tracks_in_memory() > 1)
946 /* Begin with the song after the currently playing one */
947 i = 1;
948 while((track = get_trackdata(i++)))
950 start += track->load_ahead_index;
954 do {
955 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
956 if ( !trackname )
957 return -1;
959 DEBUGF("Loading %s\n", trackname);
961 mpeg_file = open(trackname, O_RDONLY);
962 if(mpeg_file < 0) {
963 DEBUGF("Couldn't open file: %s\n",trackname);
964 if(steps < 0)
965 steps--;
966 else
967 steps++;
969 else
971 struct trackdata *track = add_track_to_tag_list(trackname);
973 if(!track)
975 /* Bad mp3 file */
976 if(steps < 0)
977 steps--;
978 else
979 steps++;
980 close(mpeg_file);
981 mpeg_file = -1;
983 else
985 /* skip past id3v2 tag */
986 lseek(mpeg_file,
987 track->id3.first_frame_offset,
988 SEEK_SET);
989 track->id3.index = steps;
990 track->load_ahead_index = steps;
991 track->id3.offset = 0;
993 if(track->id3.vbr)
994 /* Average bitrate * 1.5 */
995 recalculate_watermark(
996 (track->id3.bitrate * 3) / 2);
997 else
998 recalculate_watermark(
999 track->id3.bitrate);
1004 /* Bail out if no file could be opened */
1005 if(abs(steps) > max_steps)
1006 return -1;
1007 } while ( mpeg_file < 0 );
1009 return 0;
1012 static void stop_playing(void)
1014 struct trackdata *track;
1016 /* Stop the current stream */
1017 mp3_play_stop();
1018 playing = false;
1019 filling = false;
1021 track = get_trackdata(0);
1022 if (track != NULL)
1023 prev_track_elapsed = track->id3.elapsed;
1025 if(mpeg_file >= 0)
1026 close(mpeg_file);
1027 mpeg_file = -1;
1028 remove_all_tags();
1029 generate_unbuffer_events();
1030 reset_mp3_buffer();
1033 static void end_current_track(void) {
1034 struct trackdata *track;
1036 play_pending = false;
1037 playing = false;
1038 mp3_play_pause(false);
1040 track = get_trackdata(0);
1041 if (track != NULL)
1042 prev_track_elapsed = track->id3.elapsed;
1044 reset_mp3_buffer();
1045 remove_all_tags();
1046 generate_unbuffer_events();
1048 if(mpeg_file >= 0)
1049 close(mpeg_file);
1052 /* Is this a really the end of playback or is a new playlist starting */
1053 static void check_playlist_end(int direction)
1055 /* Use the largest possible step size to account for skipped tracks */
1056 int steps = playlist_amount();
1058 if (direction < 0)
1059 steps = -steps;
1061 if (playlist_next(steps) < 0)
1062 is_playing = false;
1065 static void update_playlist(void)
1067 if (num_tracks_in_memory() > 0)
1069 struct trackdata *track = get_trackdata(0);
1070 track->id3.index = playlist_next(track->id3.index);
1072 else
1074 /* End of playlist? */
1075 check_playlist_end(1);
1078 playlist_update_resume_info(audio_current_track());
1081 static void track_change(void)
1083 DEBUGF("Track change\n");
1085 struct trackdata *track = get_trackdata(0);
1086 prev_track_elapsed = track->id3.elapsed;
1088 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1089 /* Reset the AVC */
1090 sound_set_avc(-1);
1091 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1093 if (num_tracks_in_memory() > 0)
1095 remove_current_tag();
1096 update_playlist();
1097 if (is_playing)
1098 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1101 current_track_counter++;
1104 unsigned long audio_prev_elapsed(void)
1106 return prev_track_elapsed;
1109 #ifdef DEBUG
1110 void hexdump(const unsigned char *buf, int len)
1112 int i;
1114 for(i = 0;i < len;i++)
1116 if(i && (i & 15) == 0)
1118 DEBUGF("\n");
1120 DEBUGF("%02x ", buf[i]);
1122 DEBUGF("\n");
1124 #endif /* DEBUG */
1126 static void start_playback_if_ready(void)
1128 int playable_space;
1130 playable_space = audiobuf_swapwrite - audiobuf_read;
1131 if(playable_space < 0)
1132 playable_space += audiobuflen;
1134 /* See if we have started playing yet. If not, do it. */
1135 if(play_pending || dma_underrun)
1137 /* If the filling has stopped, and we still haven't reached
1138 the watermark, the file must be smaller than the
1139 watermark. We must still play it. */
1140 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1141 !filling || dma_underrun)
1143 DEBUGF("P\n");
1144 if (play_pending) /* don't do this when recovering from DMA underrun */
1146 generate_postbuffer_events(); /* signal first track as buffered */
1147 if (play_pending_track_change)
1149 play_pending_track_change = false;
1150 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1152 play_pending = false;
1154 playing = true;
1156 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1157 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1158 dma_underrun = false;
1160 if (!paused)
1162 last_dma_tick = current_tick;
1163 mp3_play_pause(true);
1166 /* Tell ourselves that we need more data */
1167 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1172 static bool swap_one_chunk(void)
1174 int free_space_left;
1175 int amount_to_swap;
1177 free_space_left = get_unswapped_space();
1179 if(free_space_left == 0 && !play_pending)
1180 return false;
1182 /* Swap in larger chunks when the user is waiting for the playback
1183 to start, or when there is dangerously little playable data left */
1184 if(play_pending)
1185 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1186 else
1188 if(get_playable_space() < low_watermark)
1189 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1190 free_space_left);
1191 else
1192 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1195 if(audiobuf_write < audiobuf_swapwrite)
1196 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1197 amount_to_swap);
1198 else
1199 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1200 amount_to_swap);
1202 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1204 audiobuf_swapwrite += amount_to_swap;
1205 if(audiobuf_swapwrite >= audiobuflen)
1207 audiobuf_swapwrite = 0;
1210 return true;
1213 static void mpeg_thread(void)
1215 static int pause_tick = 0;
1216 static unsigned int pause_track = 0;
1217 struct queue_event ev;
1218 int len;
1219 int free_space_left;
1220 int unplayed_space_left;
1221 int amount_to_read;
1222 int t1, t2;
1223 int start_offset;
1224 #if CONFIG_CODEC == MAS3587F
1225 int amount_to_save;
1226 int save_endpos = 0;
1227 int rc;
1228 int level;
1229 long offset;
1230 #endif /* CONFIG_CODEC == MAS3587F */
1232 is_playing = false;
1233 play_pending = false;
1234 playing = false;
1235 mpeg_file = -1;
1237 while(1)
1239 #if CONFIG_CODEC == MAS3587F
1240 if(mpeg_mode == MPEG_DECODER)
1242 #endif /* CONFIG_CODEC == MAS3587F */
1243 yield();
1245 /* Swap if necessary, and don't block on the queue_wait() */
1246 if(swap_one_chunk())
1248 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1250 else if (playing)
1252 /* periodically update resume info */
1253 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1255 else
1257 DEBUGF("S R:%x W:%x SW:%x\n",
1258 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1259 queue_wait(&mpeg_queue, &ev);
1262 start_playback_if_ready();
1264 switch(ev.id)
1266 case MPEG_PLAY:
1267 DEBUGF("MPEG_PLAY\n");
1269 #if CONFIG_TUNER
1270 /* Silence the A/D input, it may be on because the radio
1271 may be playing */
1272 mas_codec_writereg(6, 0x0000);
1273 #endif /* CONFIG_TUNER */
1275 /* Stop the current stream */
1276 paused = false;
1277 end_current_track();
1279 if ( new_file(0) == -1 )
1281 is_playing = false;
1282 track_change();
1283 break;
1286 start_offset = (int)ev.data;
1288 /* mid-song resume? */
1289 if (start_offset) {
1290 struct mp3entry* id3 = &get_trackdata(0)->id3;
1291 lseek(mpeg_file, start_offset, SEEK_SET);
1292 id3->offset = start_offset;
1293 set_elapsed(id3);
1295 else {
1296 /* skip past id3v2 tag */
1297 lseek(mpeg_file,
1298 get_trackdata(0)->id3.first_frame_offset,
1299 SEEK_SET);
1303 /* Make it read more data */
1304 filling = true;
1305 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1307 /* Tell the file loading code that we want to start playing
1308 as soon as we have some data */
1309 play_pending = true;
1310 play_pending_track_change = true;
1312 update_playlist();
1313 current_track_counter++;
1314 break;
1316 case MPEG_STOP:
1317 DEBUGF("MPEG_STOP\n");
1318 is_playing = false;
1319 paused = false;
1321 if (playing)
1322 playlist_update_resume_info(audio_current_track());
1324 stop_playing();
1325 mpeg_stop_done = true;
1326 break;
1328 case MPEG_PAUSE:
1329 DEBUGF("MPEG_PAUSE\n");
1330 /* Stop the current stream */
1331 if (playing)
1332 playlist_update_resume_info(audio_current_track());
1333 paused = true;
1334 playing = false;
1335 pause_tick = current_tick;
1336 pause_track = current_track_counter;
1337 mp3_play_pause(false);
1338 break;
1340 case MPEG_RESUME:
1341 DEBUGF("MPEG_RESUME\n");
1342 /* Continue the current stream */
1343 paused = false;
1344 if (!play_pending)
1346 playing = true;
1347 if ( current_track_counter == pause_track )
1348 last_dma_tick += current_tick - pause_tick;
1349 else
1350 last_dma_tick = current_tick;
1351 pause_tick = 0;
1352 mp3_play_pause(true);
1354 break;
1356 case MPEG_NEXT:
1357 DEBUGF("MPEG_NEXT\n");
1358 /* is next track in ram? */
1359 if ( num_tracks_in_memory() > 1 ) {
1360 int unplayed_space_left, unswapped_space_left;
1362 /* stop the current stream */
1363 play_pending = false;
1364 playing = false;
1365 mp3_play_pause(false);
1367 track_change();
1368 audiobuf_read = get_trackdata(0)->mempos;
1369 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1370 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1371 dma_underrun = false;
1372 last_dma_tick = current_tick;
1374 unplayed_space_left = get_unplayed_space();
1375 unswapped_space_left = get_unswapped_space();
1377 /* should we start reading more data? */
1378 if(!filling && (unplayed_space_left < low_watermark)) {
1379 filling = true;
1380 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1381 play_pending = true;
1382 } else if(unswapped_space_left &&
1383 unswapped_space_left > unplayed_space_left) {
1384 /* Stop swapping the data from the previous file */
1385 audiobuf_swapwrite = audiobuf_read;
1386 play_pending = true;
1387 } else {
1388 playing = true;
1389 if (!paused)
1390 mp3_play_pause(true);
1393 else {
1394 if (!playlist_check(1))
1395 break;
1397 /* stop the current stream */
1398 end_current_track();
1400 if (new_file(1) < 0) {
1401 DEBUGF("No more files to play\n");
1402 filling = false;
1404 check_playlist_end(1);
1405 current_track_counter++;
1406 } else {
1407 /* Make it read more data */
1408 filling = true;
1409 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1411 /* Tell the file loading code that we want
1412 to start playing as soon as we have some data */
1413 play_pending = true;
1414 play_pending_track_change = true;
1416 update_playlist();
1417 current_track_counter++;
1420 break;
1422 case MPEG_PREV: {
1423 DEBUGF("MPEG_PREV\n");
1425 if (!playlist_check(-1))
1426 break;
1428 /* stop the current stream */
1429 end_current_track();
1431 /* Open the next file */
1432 if (new_file(-1) < 0) {
1433 DEBUGF("No more files to play\n");
1434 filling = false;
1436 check_playlist_end(-1);
1437 current_track_counter++;
1438 } else {
1439 /* Make it read more data */
1440 filling = true;
1441 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1443 /* Tell the file loading code that we want to
1444 start playing as soon as we have some data */
1445 play_pending = true;
1446 play_pending_track_change = true;
1448 update_playlist();
1449 current_track_counter++;
1451 break;
1454 case MPEG_FF_REWIND: {
1455 struct mp3entry *id3 = audio_current_track();
1456 unsigned int oldtime = id3->elapsed;
1457 unsigned int newtime = (unsigned int)ev.data;
1458 int curpos, newpos, diffpos;
1459 DEBUGF("MPEG_FF_REWIND\n");
1461 id3->elapsed = newtime;
1463 newpos = audio_get_file_pos();
1464 if(newpos < 0)
1466 id3->elapsed = oldtime;
1467 break;
1470 if (mpeg_file >= 0)
1471 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1472 else
1473 curpos = id3->filesize;
1475 if (num_tracks_in_memory() > 1)
1477 /* We have started loading other tracks that need to be
1478 accounted for */
1479 struct trackdata *track;
1480 int i = 0;
1482 while((track = get_trackdata(i++)))
1484 curpos += track->id3.filesize;
1488 diffpos = curpos - newpos;
1490 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1492 int unplayed_space_left, unswapped_space_left;
1494 /* We are changing to a position that's already in
1495 memory, so we just move the DMA read pointer. */
1496 audiobuf_read = audiobuf_write - diffpos;
1497 if (audiobuf_read < 0)
1499 audiobuf_read += audiobuflen;
1502 unplayed_space_left = get_unplayed_space();
1503 unswapped_space_left = get_unswapped_space();
1505 /* If unswapped_space_left is larger than
1506 unplayed_space_left, it means that the swapwrite pointer
1507 hasn't yet advanced up to the new location of the read
1508 pointer. We just move it, there is no need to swap
1509 data that won't be played anyway. */
1511 if (unswapped_space_left > unplayed_space_left)
1513 DEBUGF("Moved swapwrite\n");
1514 audiobuf_swapwrite = audiobuf_read;
1515 play_pending = true;
1518 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1520 /* We need to load more data before starting */
1521 filling = true;
1522 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1523 play_pending = true;
1525 else
1527 /* resume will start at new position */
1528 last_dma_chunk_size =
1529 MIN(0x2000, get_unplayed_space_current_song());
1530 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1531 last_dma_chunk_size, transfer_end);
1532 dma_underrun = false;
1535 else
1537 /* Move to the new position in the file and start
1538 loading data */
1539 reset_mp3_buffer();
1541 if (num_tracks_in_memory() > 1)
1543 /* We have to reload the current track */
1544 close(mpeg_file);
1545 remove_all_non_current_tags();
1546 generate_unbuffer_events();
1547 mpeg_file = -1;
1550 if (mpeg_file < 0)
1552 mpeg_file = open(id3->path, O_RDONLY);
1553 if (mpeg_file < 0)
1555 id3->elapsed = oldtime;
1556 break;
1560 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1562 id3->elapsed = oldtime;
1563 break;
1566 filling = true;
1567 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1569 /* Tell the file loading code that we want to start playing
1570 as soon as we have some data */
1571 play_pending = true;
1574 id3->offset = newpos;
1576 break;
1579 case MPEG_FLUSH_RELOAD: {
1580 int numtracks = num_tracks_in_memory();
1581 bool reload_track = false;
1583 if (numtracks > 1)
1585 /* Reset the buffer */
1586 audiobuf_write = get_trackdata(1)->mempos;
1588 /* Reset swapwrite unless we're still swapping current
1589 track */
1590 if (get_unplayed_space() <= get_playable_space())
1591 audiobuf_swapwrite = audiobuf_write;
1593 close(mpeg_file);
1594 remove_all_non_current_tags();
1595 generate_unbuffer_events();
1596 mpeg_file = -1;
1597 reload_track = true;
1599 else if (numtracks == 1 && mpeg_file < 0)
1601 reload_track = true;
1604 if(reload_track && new_file(1) >= 0)
1606 /* Tell ourselves that we want more data */
1607 filling = true;
1608 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1611 break;
1614 case MPEG_NEED_DATA:
1615 free_space_left = audiobuf_read - audiobuf_write;
1617 /* We interpret 0 as "empty buffer" */
1618 if(free_space_left <= 0)
1619 free_space_left += audiobuflen;
1621 unplayed_space_left = audiobuflen - free_space_left;
1623 /* Make sure that we don't fill the entire buffer */
1624 free_space_left -= MPEG_HIGH_WATER;
1626 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1627 generate_unbuffer_events();
1629 /* do we have any more buffer space to fill? */
1630 if(free_space_left <= 0)
1632 DEBUGF("0\n");
1633 filling = false;
1634 generate_postbuffer_events();
1635 storage_sleep();
1636 break;
1639 /* Read small chunks while we are below the low water mark */
1640 if(unplayed_space_left < low_watermark)
1641 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1642 free_space_left);
1643 else
1644 amount_to_read = free_space_left;
1646 /* Don't read more than until the end of the buffer */
1647 amount_to_read = MIN(audiobuflen - audiobuf_write,
1648 amount_to_read);
1649 #if (CONFIG_STORAGE & STORAGE_MMC)
1650 /* MMC is slow, so don't read too large chunks */
1651 amount_to_read = MIN(0x40000, amount_to_read);
1652 #elif MEMORYSIZE == 8
1653 amount_to_read = MIN(0x100000, amount_to_read);
1654 #endif
1656 /* Read as much mpeg data as we can fit in the buffer */
1657 if(mpeg_file >= 0)
1659 DEBUGF("R\n");
1660 t1 = current_tick;
1661 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1662 amount_to_read);
1663 if(len > 0)
1665 t2 = current_tick;
1666 DEBUGF("time: %d\n", t2 - t1);
1667 DEBUGF("R: %x\n", len);
1669 /* Now make sure that we don't feed the MAS with ID3V1
1670 data */
1671 if (len < amount_to_read)
1673 int i;
1674 static const unsigned char tag[] = "TAG";
1675 int taglen = 128;
1676 int tagptr = audiobuf_write + len - 128;
1678 /* Really rare case: entire potential tag wasn't
1679 read in this call AND audiobuf_write < 128 */
1680 if (tagptr < 0)
1681 tagptr += audiobuflen;
1683 for(i = 0;i < 3;i++)
1685 if(tagptr >= audiobuflen)
1686 tagptr -= audiobuflen;
1688 if(mpeg_audiobuf[tagptr] != tag[i])
1690 taglen = 0;
1691 break;
1694 tagptr++;
1697 if(taglen)
1699 /* Skip id3v1 tag */
1700 DEBUGF("Skipping ID3v1 tag\n");
1701 len -= taglen;
1703 /* In the very rare case when the entire tag
1704 wasn't read in this read() len will be < 0.
1705 Take care of this when changing the write
1706 pointer. */
1710 audiobuf_write += len;
1712 if (audiobuf_write < 0)
1713 audiobuf_write += audiobuflen;
1715 if(audiobuf_write >= audiobuflen)
1717 audiobuf_write = 0;
1718 DEBUGF("W\n");
1721 /* Tell ourselves that we want more data */
1722 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1724 else
1726 if(len < 0)
1728 DEBUGF("MPEG read error\n");
1731 close(mpeg_file);
1732 mpeg_file = -1;
1734 if(new_file(1) < 0)
1736 /* No more data to play */
1737 DEBUGF("No more files to play\n");
1738 filling = false;
1740 else
1742 /* Tell ourselves that we want more data */
1743 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1747 break;
1749 case MPEG_TRACK_CHANGE:
1750 track_change();
1751 break;
1753 #ifndef USB_NONE
1754 case SYS_USB_CONNECTED:
1755 is_playing = false;
1756 paused = false;
1757 stop_playing();
1759 /* Tell the USB thread that we are safe */
1760 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1761 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1763 /* Wait until the USB cable is extracted again */
1764 usb_wait_for_disconnect(&mpeg_queue);
1765 break;
1766 #endif /* !USB_NONE */
1768 #if CONFIG_CODEC == MAS3587F
1769 case MPEG_INIT_RECORDING:
1770 init_recording();
1771 init_recording_done = true;
1772 break;
1773 #endif /* CONFIG_CODEC == MAS3587F */
1775 case SYS_TIMEOUT:
1776 if (playing)
1777 playlist_update_resume_info(audio_current_track());
1778 break;
1780 #if CONFIG_CODEC == MAS3587F
1782 else
1784 queue_wait(&mpeg_queue, &ev);
1785 switch(ev.id)
1787 case MPEG_RECORD:
1788 if (is_prerecording)
1790 int startpos;
1792 /* Go back prerecord_count seconds in the buffer */
1793 startpos = prerecord_index - prerecord_count;
1794 if(startpos < 0)
1795 startpos += prerecording_max_seconds;
1797 /* Read the position data from the prerecord buffer */
1798 frame_count_start = prerecord_buffer[startpos].framecount;
1799 startpos = prerecord_buffer[startpos].mempos;
1801 DEBUGF("Start looking at address %x (%x)\n",
1802 mpeg_audiobuf+startpos, startpos);
1804 saved_header = mpeg_get_last_header();
1806 mem_find_next_frame(startpos, &offset, 1800,
1807 saved_header, mpeg_audiobuf,
1808 audiobuflen);
1810 audiobuf_read = startpos + offset;
1811 if(audiobuf_read >= audiobuflen)
1812 audiobuf_read -= audiobuflen;
1814 DEBUGF("New audiobuf_read address: %x (%x)\n",
1815 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1817 level = disable_irq_save();
1818 num_rec_bytes = get_unsaved_space();
1819 restore_irq(level);
1821 else
1823 frame_count_start = 0;
1824 num_rec_bytes = 0;
1825 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1826 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1829 prepend_header();
1830 DEBUGF("Recording...\n");
1831 start_recording();
1833 /* Wait until at least one frame is encoded and get the
1834 frame header, for later use by the Xing header
1835 generation */
1836 sleep(HZ/5);
1837 saved_header = mpeg_get_last_header();
1839 /* delayed until buffer is saved, don't open yet */
1840 strcpy(delayed_filename, recording_filename);
1841 mpeg_file = -1;
1843 break;
1845 case MPEG_STOP:
1846 DEBUGF("MPEG_STOP\n");
1848 stop_recording();
1850 /* Save the remaining data in the buffer */
1851 save_endpos = audiobuf_write;
1852 saving_status = STOP_RECORDING;
1853 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1854 break;
1856 case MPEG_STOP_DONE:
1857 DEBUGF("MPEG_STOP_DONE\n");
1859 if (mpeg_file >= 0)
1860 close(mpeg_file);
1861 mpeg_file = -1;
1863 update_header();
1864 #ifdef DEBUG1
1866 int i;
1867 for(i = 0;i < 512;i++)
1869 DEBUGF("%d - %d us (%d bytes)\n",
1870 timing_info[i*2],
1871 (timing_info[i*2+1] & 0xffff) *
1872 10000 / 13824,
1873 timing_info[i*2+1] >> 16);
1876 #endif /* DEBUG1 */
1878 if (prerecording)
1880 start_prerecording();
1882 mpeg_stop_done = true;
1883 break;
1885 case MPEG_NEW_FILE:
1886 /* Bail out when a more important save is happening */
1887 if (saving_status > NEW_FILE)
1888 break;
1890 /* Make sure we have at least one complete frame
1891 in the buffer. If we haven't recorded a single
1892 frame within 200ms, the MAS is probably not recording
1893 anything, and we bail out. */
1894 amount_to_save = get_unsaved_space();
1895 if (amount_to_save < 1800)
1897 sleep(HZ/5);
1898 amount_to_save = get_unsaved_space();
1901 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1902 &frame_count_end, 1);
1904 last_rec_time = current_tick - record_start_time;
1905 record_start_time = current_tick;
1906 if (paused)
1907 pause_start_time = record_start_time;
1909 /* capture all values at one point */
1910 level = disable_irq_save();
1911 save_endpos = audiobuf_write;
1912 last_rec_bytes = num_rec_bytes;
1913 num_rec_bytes = 0;
1914 restore_irq(level);
1916 if (amount_to_save >= 1800)
1918 /* Now find a frame boundary to split at */
1919 save_endpos -= 1800;
1920 if (save_endpos < 0)
1921 save_endpos += audiobuflen;
1923 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1924 saved_header, mpeg_audiobuf,
1925 audiobuflen);
1926 if (!rc) /* No header found, save whole buffer */
1927 offset = 1800;
1929 save_endpos += offset;
1930 if (save_endpos >= audiobuflen)
1931 save_endpos -= audiobuflen;
1933 last_rec_bytes += offset - 1800;
1934 level = disable_irq_save();
1935 num_rec_bytes += 1800 - offset;
1936 restore_irq(level);
1939 saving_status = NEW_FILE;
1940 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1941 break;
1943 case MPEG_SAVE_DATA:
1944 if (saving_status == BUFFER_FULL)
1945 save_endpos = audiobuf_write;
1947 if (mpeg_file < 0) /* delayed file open */
1949 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
1951 if (mpeg_file < 0)
1952 panicf("recfile: %d", mpeg_file);
1955 amount_to_save = save_endpos - audiobuf_read;
1956 if (amount_to_save < 0)
1957 amount_to_save += audiobuflen;
1959 amount_to_save = MIN(amount_to_save,
1960 audiobuflen - audiobuf_read);
1961 #if (CONFIG_STORAGE & STORAGE_MMC)
1962 /* MMC is slow, so don't save too large chunks at once */
1963 amount_to_save = MIN(0x40000, amount_to_save);
1964 #elif MEMORYSIZE == 8
1965 amount_to_save = MIN(0x100000, amount_to_save);
1966 #endif
1967 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
1968 amount_to_save);
1969 if (rc < 0)
1971 if (errno == ENOSPC)
1973 mpeg_errno = AUDIOERR_DISK_FULL;
1974 stop_recording();
1975 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1976 /* will close the file */
1977 break;
1979 else
1980 panicf("rec wrt: %d", rc);
1983 audiobuf_read += amount_to_save;
1984 if (audiobuf_read >= audiobuflen)
1985 audiobuf_read = 0;
1987 if (audiobuf_read == save_endpos) /* all saved */
1989 switch (saving_status)
1991 case BUFFER_FULL:
1992 rc = fsync(mpeg_file);
1993 if (rc < 0)
1994 panicf("rec fls: %d", rc);
1995 storage_sleep();
1996 break;
1998 case NEW_FILE:
1999 /* Close the current file */
2000 rc = close(mpeg_file);
2001 if (rc < 0)
2002 panicf("rec cls: %d", rc);
2003 mpeg_file = -1;
2004 update_header();
2005 storage_sleep();
2007 /* copy new filename */
2008 strcpy(delayed_filename, recording_filename);
2009 prepend_header();
2010 frame_count_start = frame_count_end;
2011 break;
2013 case STOP_RECORDING:
2014 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2015 /* will close the file */
2016 break;
2018 default:
2019 break;
2021 saving_status = NOT_SAVING;
2023 else /* tell ourselves to save the next chunk */
2024 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2026 break;
2028 case MPEG_PRERECORDING_TICK:
2029 if(!is_prerecording)
2030 break;
2032 /* Store the write pointer every second */
2033 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2034 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2035 &prerecord_buffer[prerecord_index].framecount, 1);
2037 /* Wrap if necessary */
2038 if(++prerecord_index == prerecording_max_seconds)
2039 prerecord_index = 0;
2041 /* Update the number of seconds recorded */
2042 if(prerecord_count < prerecording_max_seconds)
2043 prerecord_count++;
2044 break;
2046 case MPEG_INIT_PLAYBACK:
2047 /* Stop the prerecording */
2048 stop_recording();
2049 reset_mp3_buffer();
2050 mp3_play_init();
2051 init_playback_done = true;
2052 break;
2054 case MPEG_PAUSE_RECORDING:
2055 pause_recording();
2056 break;
2058 case MPEG_RESUME_RECORDING:
2059 resume_recording();
2060 break;
2062 case SYS_USB_CONNECTED:
2063 /* We can safely go to USB mode if no recording
2064 is taking place */
2065 if((!is_recording || is_prerecording) && mpeg_stop_done)
2067 /* Even if we aren't recording, we still call this
2068 function, to put the MAS in monitoring mode,
2069 to save power. */
2070 stop_recording();
2072 /* Tell the USB thread that we are safe */
2073 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2074 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2076 /* Wait until the USB cable is extracted again */
2077 usb_wait_for_disconnect(&mpeg_queue);
2079 break;
2082 #endif /* CONFIG_CODEC == MAS3587F */
2085 #endif /* !SIMULATOR */
2087 struct mp3entry* audio_current_track(void)
2089 #ifdef SIMULATOR
2090 struct mp3entry *id3 = &taginfo;
2091 #else /* !SIMULATOR */
2092 if(num_tracks_in_memory())
2094 struct mp3entry *id3 = &get_trackdata(0)->id3;
2095 #endif
2096 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2098 checked_for_cuesheet = true; /* only check once per track */
2099 char cuepath[MAX_PATH];
2101 if (look_for_cuesheet_file(id3->path, cuepath) &&
2102 parse_cuesheet(cuepath, curr_cuesheet))
2104 id3->cuesheet = curr_cuesheet;
2107 return id3;
2108 #ifndef SIMULATOR
2110 else
2111 return NULL;
2112 #endif /* !SIMULATOR */
2115 struct mp3entry* audio_next_track(void)
2117 #ifdef SIMULATOR
2118 return &taginfo;
2119 #else /* !SIMULATOR */
2120 if(num_tracks_in_memory() > 1)
2121 return &get_trackdata(1)->id3;
2122 else
2123 return NULL;
2124 #endif /* !SIMULATOR */
2127 #if CONFIG_CODEC == MAS3587F
2128 #ifndef SIMULATOR
2129 void audio_init_playback(void)
2131 init_playback_done = false;
2132 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2134 while(!init_playback_done)
2135 sleep(1);
2139 /****************************************************************************
2140 * Recording functions
2141 ***************************************************************************/
2142 void audio_init_recording(void)
2144 init_recording_done = false;
2145 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2147 while(!init_recording_done)
2148 sleep(1);
2151 static void init_recording(void)
2153 unsigned long val;
2154 int rc;
2156 /* Disable IRQ6 */
2157 IPRB &= 0xff0f;
2159 stop_playing();
2160 is_playing = false;
2161 paused = false;
2163 /* Init the recording variables */
2164 is_recording = false;
2165 is_prerecording = false;
2167 mpeg_stop_done = true;
2169 mas_reset();
2171 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2172 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2173 if(rc < 0)
2174 panicf("mas_ctrl_w: %d", rc);
2176 /* Stop the current application */
2177 val = 0;
2178 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2181 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2182 } while(val);
2184 /* Perform black magic as described by the data sheet */
2185 if((mas_version_code & 0x0fff) == 0x0102)
2187 DEBUGF("Performing MAS black magic for B2 version\n");
2188 mas_writereg(0xa3, 0x98);
2189 mas_writereg(0x94, 0xfffff);
2190 val = 0;
2191 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2192 mas_writereg(0xa3, 0x90);
2195 /* Enable A/D Converters */
2196 shadow_codec_reg0 = 0xcccd;
2197 mas_codec_writereg(0x0, shadow_codec_reg0);
2199 /* Copy left channel to right (mono mode) */
2200 mas_codec_writereg(8, 0x8000);
2202 /* ADC scale 0%, DSP scale 100%
2203 We use the DSP output for monitoring, because it works with all
2204 sources including S/PDIF */
2205 mas_codec_writereg(6, 0x0000);
2206 mas_codec_writereg(7, 0x4000);
2208 /* No mute */
2209 shadow_soft_mute = 0;
2210 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2212 #ifdef HAVE_SPDIF_OUT
2213 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2214 #else
2215 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2216 #endif
2217 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2219 /* Set Demand mode, monitoring OFF and validate all settings */
2220 shadow_io_control_main = 0x125;
2221 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2223 /* Start the encoder application */
2224 val = 0x40;
2225 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2228 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2229 } while(!(val & 0x40));
2231 /* We have started the recording application with monitoring OFF.
2232 This is because we want to record at least one frame to fill the DMA
2233 buffer, because the silly MAS will not negate EOD until at least one
2234 DMA transfer has taken place.
2235 Now let's wait for some data to be encoded. */
2236 sleep(HZ/5);
2238 /* Now set it to Monitoring mode as default, saves power */
2239 shadow_io_control_main = 0x525;
2240 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2242 /* Wait until the DSP has accepted the settings */
2245 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2246 } while(val & 1);
2248 drain_dma_buffer();
2249 mpeg_mode = MPEG_ENCODER;
2251 DEBUGF("MAS Recording application started\n");
2253 /* At this point, all settings are the reset MAS defaults, next thing is to
2254 call mpeg_set_recording_options(). */
2257 void audio_record(const char *filename)
2259 mpeg_errno = 0;
2261 strlcpy(recording_filename, filename, MAX_PATH);
2263 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2266 void audio_pause_recording(void)
2268 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2271 void audio_resume_recording(void)
2273 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2276 static void prepend_header(void)
2278 int startpos;
2279 unsigned i;
2281 /* Make room for header */
2282 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2283 if(audiobuf_read < 0)
2285 /* Clear the bottom half */
2286 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2288 /* And the top half */
2289 audiobuf_read += audiobuflen;
2290 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2292 else
2294 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2296 /* Copy the empty ID3 header */
2297 startpos = audiobuf_read;
2298 for(i = 0; i < sizeof(empty_id3_header); i++)
2300 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2301 if(startpos == audiobuflen)
2302 startpos = 0;
2306 static void update_header(void)
2308 int fd, framelen;
2309 unsigned long frames;
2311 if (last_rec_bytes > 0)
2313 /* Create the Xing header */
2314 fd = open(delayed_filename, O_RDWR);
2315 if (fd < 0)
2316 panicf("rec upd: %d (%s)", fd, recording_filename);
2318 frames = frame_count_end - frame_count_start;
2319 /* If the number of recorded frames has reached 0x7ffff,
2320 we can no longer trust it */
2321 if (frame_count_end == 0x7ffff)
2322 frames = 0;
2324 /* saved_header is saved right before stopping the MAS */
2325 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2326 frames, last_rec_time * (1000/HZ),
2327 saved_header, NULL, false,
2328 mpeg_audiobuf, audiobuflen);
2330 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2331 write(fd, xing_buffer, framelen);
2332 close(fd);
2336 static void start_prerecording(void)
2338 unsigned long val;
2340 DEBUGF("Starting prerecording\n");
2342 prerecord_index = 0;
2343 prerecord_count = 0;
2344 prerecord_timeout = current_tick + HZ;
2345 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2346 reset_mp3_buffer();
2348 is_prerecording = true;
2350 /* Stop monitoring and start the encoder */
2351 shadow_io_control_main &= ~(1 << 10);
2352 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2353 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2355 /* Wait until the DSP has accepted the settings */
2358 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2359 } while(val & 1);
2361 is_recording = true;
2362 saving_status = NOT_SAVING;
2364 demand_irq_enable(true);
2367 static void start_recording(void)
2369 unsigned long val;
2371 if(is_prerecording)
2373 /* This will make the IRQ handler start recording
2374 for real, i.e send MPEG_SAVE_DATA messages when
2375 the buffer is full */
2376 is_prerecording = false;
2378 else
2380 /* If prerecording is off, we need to stop the monitoring
2381 and start the encoder */
2382 shadow_io_control_main &= ~(1 << 10);
2383 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2384 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2386 /* Wait until the DSP has accepted the settings */
2389 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2390 } while(val & 1);
2393 is_recording = true;
2394 saving_status = NOT_SAVING;
2395 paused = false;
2397 /* Store the current time */
2398 if(prerecording)
2399 record_start_time = current_tick - prerecord_count * HZ;
2400 else
2401 record_start_time = current_tick;
2403 pause_start_time = 0;
2405 demand_irq_enable(true);
2408 static void pause_recording(void)
2410 pause_start_time = current_tick;
2412 /* Set the pause bit */
2413 shadow_soft_mute |= 2;
2414 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2416 paused = true;
2419 static void resume_recording(void)
2421 paused = false;
2423 /* Clear the pause bit */
2424 shadow_soft_mute &= ~2;
2425 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2427 /* Compensate for the time we have been paused */
2428 if(pause_start_time)
2430 record_start_time =
2431 current_tick - (pause_start_time - record_start_time);
2432 pause_start_time = 0;
2436 static void stop_recording(void)
2438 unsigned long val;
2440 /* Let it finish the last frame */
2441 if(!paused)
2442 pause_recording();
2443 sleep(HZ/5);
2445 demand_irq_enable(false);
2447 is_recording = false;
2448 is_prerecording = false;
2450 last_rec_bytes = num_rec_bytes;
2451 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2452 last_rec_time = current_tick - record_start_time;
2454 /* Start monitoring */
2455 shadow_io_control_main |= (1 << 10);
2456 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2457 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2459 /* Wait until the DSP has accepted the settings */
2462 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2463 } while(val & 1);
2465 resume_recording();
2468 void audio_set_recording_options(struct audio_recording_options *options)
2470 bool is_mpeg1;
2472 is_mpeg1 = (options->rec_frequency < 3);
2474 rec_version_index = is_mpeg1?3:2;
2475 rec_frequency_index = options->rec_frequency % 3;
2477 shadow_encoder_control = (options->rec_quality << 17) |
2478 (rec_frequency_index << 10) |
2479 ((is_mpeg1?1:0) << 9) |
2480 (((options->rec_channels * 2 + 1) & 3) << 6) |
2481 (1 << 5) /* MS-stereo */ |
2482 (1 << 2) /* Is an original */;
2483 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2485 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2487 #if CONFIG_TUNER & S1A0903X01
2488 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2489 interference with the Samsung tuner. */
2490 if (rec_frequency_index)
2491 mas_store_pllfreq(24576000);
2492 else
2493 mas_store_pllfreq(22579000);
2494 #endif
2496 shadow_soft_mute = options->rec_editable?4:0;
2497 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2499 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2501 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2502 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2503 (1 << 5) | /* SDO strobe invert */
2504 ((is_mpeg1?0:1) << 3) |
2505 (1 << 2) | /* Inverted SIBC clock signal */
2506 1; /* Validate */
2507 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2509 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2511 if(options->rec_source == AUDIO_SRC_MIC)
2513 /* Copy left channel to right (mono mode) */
2514 mas_codec_writereg(8, 0x8000);
2516 else
2518 /* Stereo input mode */
2519 mas_codec_writereg(8, 0);
2522 prerecording_max_seconds = options->rec_prerecord_time;
2523 if(prerecording_max_seconds)
2525 prerecording = true;
2526 start_prerecording();
2528 else
2530 prerecording = false;
2531 is_prerecording = false;
2532 is_recording = false;
2536 /* If use_mic is true, the left gain is used */
2537 void audio_set_recording_gain(int left, int right, int type)
2539 /* Enable both left and right A/D */
2540 shadow_codec_reg0 = (left << 12) |
2541 (right << 8) |
2542 (left << 4) |
2543 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2544 0x0007;
2545 mas_codec_writereg(0x0, shadow_codec_reg0);
2548 /* try to make some kind of beep, also in recording mode */
2549 void audio_beep(int duration)
2551 long starttick = current_tick;
2553 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2554 * While this is still audible even without an external signal,
2555 * it doesn't affect the (pre-)recording. */
2556 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2557 mas_codec_writereg(0, shadow_codec_reg0);
2558 yield();
2560 while (current_tick - starttick < duration);
2563 void audio_new_file(const char *filename)
2565 mpeg_errno = 0;
2567 strlcpy(recording_filename, filename, MAX_PATH);
2569 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2572 unsigned long audio_recorded_time(void)
2574 if(is_prerecording)
2575 return prerecord_count * HZ;
2577 if(is_recording)
2579 if(paused)
2580 return pause_start_time - record_start_time;
2581 else
2582 return current_tick - record_start_time;
2585 return 0;
2588 unsigned long audio_num_recorded_bytes(void)
2590 int num_bytes;
2591 int index;
2593 if(is_recording)
2595 if(is_prerecording)
2597 index = prerecord_index - prerecord_count;
2598 if(index < 0)
2599 index += prerecording_max_seconds;
2601 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2602 if(num_bytes < 0)
2603 num_bytes += audiobuflen;
2605 return num_bytes;
2607 else
2608 return num_rec_bytes;
2610 else
2611 return 0;
2614 #else /* SIMULATOR */
2616 /* dummies coming up */
2618 void audio_init_playback(void)
2620 /* a dummy */
2622 unsigned long audio_recorded_time(void)
2624 /* a dummy */
2625 return 0;
2627 void audio_beep(int duration)
2629 /* a dummy */
2630 (void)duration;
2632 void audio_pause_recording(void)
2634 /* a dummy */
2636 void audio_resume_recording(void)
2638 /* a dummy */
2640 unsigned long audio_num_recorded_bytes(void)
2642 /* a dummy */
2643 return 0;
2645 void audio_record(const char *filename)
2647 /* a dummy */
2648 (void)filename;
2650 void audio_new_file(const char *filename)
2652 /* a dummy */
2653 (void)filename;
2656 void audio_set_recording_gain(int left, int right, int type)
2658 /* a dummy */
2659 (void)left;
2660 (void)right;
2661 (void)type;
2663 void audio_init_recording(void)
2665 /* a dummy */
2667 void audio_set_recording_options(struct audio_recording_options *options)
2669 /* a dummy */
2670 (void)options;
2672 #endif /* SIMULATOR */
2673 #endif /* CONFIG_CODEC == MAS3587F */
2675 size_t audio_buffer_available(void)
2677 if (audiobuf_handle > 0)
2678 return audiobuflen;
2679 return core_available();
2682 static void audio_reset_buffer(void)
2684 talk_buffer_steal(); /* will use the mp3 buffer */
2686 /* alloc buffer if it's was never allocated or freed by audio_hard_stop() */
2687 if (!audiobuf_handle)
2689 size_t bufsize; /* dont break strict-aliasing */
2690 audiobuf_handle = core_alloc_maximum("audiobuf", &bufsize, &ops);
2691 mpeg_audiobuf = core_get_data(audiobuf_handle);
2692 audiobuflen = bufsize;
2694 talkbuf_init(mpeg_audiobuf);
2697 void audio_play(long offset)
2699 audio_reset_buffer();
2700 #ifdef SIMULATOR
2701 char name_buf[MAX_PATH+1];
2702 const char* trackname;
2703 int steps=0;
2705 is_playing = true;
2707 do {
2708 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2709 if (!trackname)
2710 break;
2711 if(mp3info(&taginfo, trackname)) {
2712 /* bad mp3, move on */
2713 if(++steps > playlist_amount())
2714 break;
2715 continue;
2717 #ifdef HAVE_MPEG_PLAY
2718 real_mpeg_play(trackname);
2719 #endif
2720 playlist_next(steps);
2721 taginfo.offset = offset;
2722 set_elapsed(&taginfo);
2723 is_playing = true;
2724 playing = true;
2725 break;
2726 } while(1);
2727 #else /* !SIMULATOR */
2728 is_playing = true;
2729 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2730 #endif /* !SIMULATOR */
2732 mpeg_errno = 0;
2735 void audio_stop(void)
2737 #ifndef SIMULATOR
2738 if (playing)
2740 struct trackdata *track = get_trackdata(0);
2741 prev_track_elapsed = track->id3.elapsed;
2743 mpeg_stop_done = false;
2744 queue_post(&mpeg_queue, MPEG_STOP, 0);
2745 while(!mpeg_stop_done)
2746 yield();
2747 #else /* SIMULATOR */
2748 paused = false;
2749 is_playing = false;
2750 playing = false;
2751 #endif /* SIMULATOR */
2752 /* give voice our entire buffer */
2753 talkbuf_init(mpeg_audiobuf);
2756 /* dummy */
2757 void audio_stop_recording(void)
2759 audio_stop();
2762 void audio_hard_stop(void)
2764 audio_stop();
2765 /* tell voice we obtain the buffer before freeing */
2766 talk_buffer_steal();
2767 if (audiobuf_handle > 0)
2769 audiobuf_handle = core_free(audiobuf_handle);
2770 mpeg_audiobuf = NULL;
2774 void audio_pause(void)
2776 #ifndef SIMULATOR
2777 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2778 #else /* SIMULATOR */
2779 is_playing = true;
2780 playing = false;
2781 paused = true;
2782 #endif /* SIMULATOR */
2785 void audio_resume(void)
2787 #ifndef SIMULATOR
2788 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2789 #else /* SIMULATOR */
2790 is_playing = true;
2791 playing = true;
2792 paused = false;
2793 #endif /* SIMULATOR */
2796 void audio_next(void)
2798 #ifndef SIMULATOR
2799 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2800 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2801 #else /* SIMULATOR */
2802 char name_buf[MAX_PATH+1];
2803 const char* file;
2804 int steps = 1;
2806 do {
2807 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2808 if(!file)
2809 break;
2810 if(mp3info(&taginfo, file)) {
2811 if(++steps > playlist_amount())
2812 break;
2813 continue;
2815 playlist_next(steps);
2816 current_track_counter++;
2817 is_playing = true;
2818 playing = true;
2819 break;
2820 } while(1);
2821 #endif /* SIMULATOR */
2824 void audio_prev(void)
2826 #ifndef SIMULATOR
2827 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2828 queue_post(&mpeg_queue, MPEG_PREV, 0);
2829 #else /* SIMULATOR */
2830 char name_buf[MAX_PATH+1];
2831 const char* file;
2832 int steps = -1;
2834 do {
2835 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2836 if(!file)
2837 break;
2838 if(mp3info(&taginfo, file)) {
2839 steps--;
2840 continue;
2842 playlist_next(steps);
2843 current_track_counter++;
2844 is_playing = true;
2845 playing = true;
2846 break;
2847 } while(1);
2848 #endif /* SIMULATOR */
2851 void audio_ff_rewind(long newpos)
2853 #ifndef SIMULATOR
2854 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2855 #else /* SIMULATOR */
2856 (void)newpos;
2857 #endif /* SIMULATOR */
2860 void audio_flush_and_reload_tracks(void)
2862 #ifndef SIMULATOR
2863 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2864 #endif /* !SIMULATOR*/
2867 int audio_status(void)
2869 int ret = 0;
2871 if(is_playing)
2872 ret |= AUDIO_STATUS_PLAY;
2874 if(paused)
2875 ret |= AUDIO_STATUS_PAUSE;
2877 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2878 if(is_recording && !is_prerecording)
2879 ret |= AUDIO_STATUS_RECORD;
2881 if(is_prerecording)
2882 ret |= AUDIO_STATUS_PRERECORD;
2883 #endif /* CONFIG_CODEC == MAS3587F */
2885 if(mpeg_errno)
2886 ret |= AUDIO_STATUS_ERROR;
2888 return ret;
2891 /* Unused function
2892 unsigned int audio_error(void)
2894 return mpeg_errno;
2898 void audio_error_clear(void)
2900 mpeg_errno = 0;
2903 #ifdef SIMULATOR
2904 static void mpeg_thread(void)
2906 struct mp3entry* id3;
2907 while ( 1 ) {
2908 if (is_playing) {
2909 id3 = audio_current_track();
2910 if (!paused)
2912 id3->elapsed+=1000;
2913 id3->offset+=1000;
2915 if (id3->elapsed>=id3->length)
2916 audio_next();
2918 sleep(HZ);
2921 #endif /* SIMULATOR */
2923 void audio_init(void)
2925 mpeg_errno = 0;
2926 /* cuesheet support */
2927 if (global_settings.cuesheet)
2929 int handle = core_alloc("cuesheet", sizeof(struct cuesheet));
2930 if (handle > 0)
2931 curr_cuesheet = core_get_data(handle);
2934 talk_init();
2935 audio_reset_buffer();
2937 #ifndef SIMULATOR
2938 queue_init(&mpeg_queue, true);
2939 #endif /* !SIMULATOR */
2940 create_thread(mpeg_thread, mpeg_stack,
2941 sizeof(mpeg_stack), 0, mpeg_thread_name
2942 IF_PRIO(, PRIORITY_SYSTEM)
2943 IF_COP(, CPU));
2945 memset(trackdata, 0, sizeof(trackdata));
2947 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2948 if (HW_MASK & PR_ACTIVE_HIGH)
2949 and_b(~0x08, &PADRH);
2950 else
2951 or_b(0x08, &PADRH);
2952 #endif /* CONFIG_CODEC == MAS3587F */
2954 #ifdef DEBUG
2955 #ifndef SIMULATOR
2956 dbg_timer_start();
2957 dbg_cnt2us(0);
2958 #endif /* !SIMULATOR */
2959 #endif /* DEBUG */
2962 #endif /* CONFIG_CODEC != SWCODEC */