Few more fixes, notably make audiobufend static.
[kugel-rb.git] / apps / mpeg.c
blobb79a0a1065a5b64fccc90e4122abaf87dd0fdc53
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 "buffer.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 */
149 #ifdef SIMULATOR
150 static char mpeg_stack[DEFAULT_STACK_SIZE];
151 static struct mp3entry taginfo;
153 #else /* !SIMULATOR */
154 static struct event_queue mpeg_queue SHAREDBSS_ATTR;
155 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
157 static char* mpeg_audiobuf;
158 static long audiobuflen;
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 #ifndef SIMULATOR
496 /* Send callback events to notify about removing old tracks. */
497 static void generate_unbuffer_events(void)
499 int i;
500 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
501 int cur_idx = track_write_idx;
503 for (i = 0; i < numentries; i++)
505 /* Send an event to notify that track has finished. */
506 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
507 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
511 /* Send callback events to notify about new tracks. */
512 static void generate_postbuffer_events(void)
514 int i;
515 int numentries = num_tracks_in_memory();
516 int cur_idx = track_read_idx;
518 for (i = 0; i < numentries; i++)
520 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
521 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
525 static void recalculate_watermark(int bitrate)
527 int bytes_per_sec;
528 int time = storage_spinup_time();
530 /* A bitrate of 0 probably means empty VBR header. We play safe
531 and set a high threshold */
532 if(bitrate == 0)
533 bitrate = 320;
535 bytes_per_sec = bitrate * 1000 / 8;
537 if(time)
539 /* No drive spins up faster than 3.5s */
540 if(time < 350)
541 time = 350;
543 time = time * 3;
544 low_watermark = ((low_watermark_margin * HZ + time) *
545 bytes_per_sec) / HZ;
547 else
549 low_watermark = MPEG_LOW_WATER;
553 #ifdef HAVE_DISK_STORAGE
554 void audio_set_buffer_margin(int setting)
556 low_watermark_margin = setting; /* in seconds */
558 #endif
560 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
562 (void)talk_buf; /* always grab the voice buffer for now */
563 talk_buffer_steal(); /* need to tell */
565 if (buffer_size) /* special case for talk_init() */
566 return buffer_get_buffer(buffer_size);
567 return NULL;
570 void audio_get_debugdata(struct audio_debug *dbgdata)
572 dbgdata->audiobuflen = audiobuflen;
573 dbgdata->audiobuf_write = audiobuf_write;
574 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
575 dbgdata->audiobuf_read = audiobuf_read;
577 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
579 #if CONFIG_CPU == SH7034
580 dbgdata->dma_on = (SCR0 & 0x80) != 0;
581 #endif
582 dbgdata->playing = playing;
583 dbgdata->play_pending = play_pending;
584 dbgdata->is_playing = is_playing;
585 dbgdata->filling = filling;
586 dbgdata->dma_underrun = dma_underrun;
588 dbgdata->unplayed_space = get_unplayed_space();
589 dbgdata->playable_space = get_playable_space();
590 dbgdata->unswapped_space = get_unswapped_space();
592 dbgdata->low_watermark_level = low_watermark;
593 dbgdata->lowest_watermark_level = lowest_watermark_level;
596 #ifdef DEBUG
597 static void dbg_timer_start(void)
599 /* We are using timer 2 */
601 TSTR &= ~0x04; /* Stop the timer */
602 TSNC &= ~0x04; /* No synchronization */
603 TMDR &= ~0x44; /* Operate normally */
605 TCNT2 = 0; /* Start counting at 0 */
606 TCR2 = 0x03; /* Sysclock/8 */
608 TSTR |= 0x04; /* Start timer 2 */
611 static int dbg_cnt2us(unsigned int cnt)
613 return (cnt * 10000) / (FREQ/800);
615 #endif /* DEBUG */
617 static int get_unplayed_space(void)
619 int space = audiobuf_write - audiobuf_read;
620 if (space < 0)
621 space += audiobuflen;
622 return space;
625 static int get_playable_space(void)
627 int space = audiobuf_swapwrite - audiobuf_read;
628 if (space < 0)
629 space += audiobuflen;
630 return space;
633 static int get_unplayed_space_current_song(void)
635 int space;
637 if (num_tracks_in_memory() > 1)
639 space = get_trackdata(1)->mempos - audiobuf_read;
641 else
643 space = audiobuf_write - audiobuf_read;
646 if (space < 0)
647 space += audiobuflen;
649 return space;
652 static int get_unswapped_space(void)
654 int space = audiobuf_write - audiobuf_swapwrite;
655 if (space < 0)
656 space += audiobuflen;
657 return space;
660 #if CONFIG_CODEC == MAS3587F
661 static int get_unsaved_space(void)
663 int space = audiobuf_write - audiobuf_read;
664 if (space < 0)
665 space += audiobuflen;
666 return space;
669 static void drain_dma_buffer(void)
671 while (PBDRH & 0x40)
673 xor_b(0x08, &PADRH);
675 while (PBDRH & 0x80);
677 xor_b(0x08, &PADRH);
679 while (!(PBDRH & 0x80));
683 #ifdef DEBUG
684 static long timing_info_index = 0;
685 static long timing_info[1024];
686 #endif /* DEBUG */
688 void rec_tick (void) __attribute__ ((section (".icode")));
689 void rec_tick(void)
691 int i;
692 int delay;
693 char data;
695 if(is_recording && (PBDRH & 0x40))
697 #ifdef DEBUG
698 timing_info[timing_info_index++] = current_tick;
699 TCNT2 = 0;
700 #endif /* DEBUG */
701 /* Note: Although this loop is run in interrupt context, further
702 * optimisation will do no good. The MAS would then deliver bad
703 * frames occasionally, as observed in extended experiments. */
704 i = 0;
705 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
707 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
709 delay = 100;
710 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
712 if (--delay <= 0) /* Bail out if we have to wait too long */
713 { /* i.e. the MAS doesn't want to talk to us */
714 xor_b(0x08, &PADRH); /* Set PR inactive */
715 goto transfer_end; /* and get out of here */
719 data = *(unsigned char *)0x04000000; /* read data byte */
721 xor_b(0x08, &PADRH); /* Set PR inactive */
723 mpeg_audiobuf[audiobuf_write++] = data;
725 if (audiobuf_write >= audiobuflen)
726 audiobuf_write = 0;
728 i++;
730 transfer_end:
732 #ifdef DEBUG
733 timing_info[timing_info_index++] = TCNT2 + (i << 16);
734 timing_info_index &= 0x3ff;
735 #endif /* DEBUG */
737 num_rec_bytes += i;
739 if(is_prerecording)
741 if(TIME_AFTER(current_tick, prerecord_timeout))
743 prerecord_timeout = current_tick + HZ;
744 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
747 else
749 /* Signal to save the data if we are running out of buffer
750 space */
751 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
752 && saving_status == NOT_SAVING)
754 saving_status = BUFFER_FULL;
755 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
760 #endif /* CONFIG_CODEC == MAS3587F */
762 void playback_tick(void)
764 struct trackdata *ptd = get_trackdata(0);
765 if(ptd)
767 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
768 last_dma_tick = current_tick;
769 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
770 (unsigned long)ptd->id3.elapsed);
774 static void reset_mp3_buffer(void)
776 audiobuf_read = 0;
777 audiobuf_write = 0;
778 audiobuf_swapwrite = 0;
779 lowest_watermark_level = audiobuflen;
782 /* DMA transfer end interrupt callback */
783 static void transfer_end(unsigned char** ppbuf, size_t* psize)
785 if(playing && !paused)
787 int unplayed_space_left;
788 int space_until_end_of_buffer;
789 int track_offset = 1;
790 struct trackdata *track;
792 audiobuf_read += last_dma_chunk_size;
793 if(audiobuf_read >= audiobuflen)
794 audiobuf_read = 0;
796 /* First, check if we are on a track boundary */
797 if (num_tracks_in_memory() > 1)
799 if (audiobuf_read == get_trackdata(track_offset)->mempos)
801 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
803 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
804 track_offset++;
809 unplayed_space_left = get_unplayed_space();
811 space_until_end_of_buffer = audiobuflen - audiobuf_read;
813 if(!filling && unplayed_space_left < low_watermark)
815 filling = true;
816 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
819 if(unplayed_space_left)
821 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
822 last_dma_chunk_size = MIN(last_dma_chunk_size,
823 space_until_end_of_buffer);
825 /* several tracks loaded? */
826 track = get_trackdata(track_offset);
827 if(track)
829 /* will we move across the track boundary? */
830 if (( audiobuf_read < track->mempos ) &&
831 ((audiobuf_read+last_dma_chunk_size) >
832 track->mempos ))
834 /* Make sure that we end exactly on the boundary */
835 last_dma_chunk_size = track->mempos - audiobuf_read;
839 *psize = last_dma_chunk_size & 0xffff;
840 *ppbuf = mpeg_audiobuf + audiobuf_read;
841 track = get_trackdata(0);
842 if(track)
843 track->id3.offset += last_dma_chunk_size;
845 /* Update the watermark debug level */
846 if(unplayed_space_left < lowest_watermark_level)
847 lowest_watermark_level = unplayed_space_left;
849 else
851 /* Check if the end of data is because of a hard disk error.
852 If there is an open file handle, we are still playing music.
853 If not, the last file has been loaded, and the file handle is
854 closed. */
855 if(mpeg_file >= 0)
857 /* Update the watermark debug level */
858 if(unplayed_space_left < lowest_watermark_level)
859 lowest_watermark_level = unplayed_space_left;
861 DEBUGF("DMA underrun.\n");
862 dma_underrun = true;
864 else
866 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
868 DEBUGF("No more MP3 data. Stopping.\n");
869 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
870 playing = false;
873 *psize = 0; /* no more transfer */
878 static struct trackdata *add_track_to_tag_list(const char *filename)
880 struct trackdata *track;
881 bool send_nid3_event;
883 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
885 DEBUGF("Tag memory is full\n");
886 return NULL;
889 track = &trackdata[track_write_idx];
891 /* grab id3 tag of new file and
892 remember where in memory it starts */
893 if(mp3info(&track->id3, filename))
895 DEBUGF("Bad mp3\n");
896 return NULL;
898 track->mempos = audiobuf_write;
899 track->id3.elapsed = 0;
900 #ifdef HAVE_LCD_BITMAP
901 if (track->id3.title)
902 lcd_getstringsize(track->id3.title, NULL, NULL);
903 if (track->id3.artist)
904 lcd_getstringsize(track->id3.artist, NULL, NULL);
905 if (track->id3.album)
906 lcd_getstringsize(track->id3.album, NULL, NULL);
907 #endif
909 /* if this track is the next track then let the UI know it can get it */
910 send_nid3_event = (track_write_idx == track_read_idx + 1);
911 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
912 if (send_nid3_event)
913 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
914 debug_tags();
915 return track;
918 static int new_file(int steps)
920 int max_steps = playlist_amount();
921 int start = 0;
922 int i;
923 struct trackdata *track;
924 char name_buf[MAX_PATH+1];
925 const char *trackname;
927 /* Find out how many steps to advance. The load_ahead_index field tells
928 us how many playlist entries it had to skip to get to a valid one.
929 We add those together to find out where to start. */
930 if(steps > 0 && num_tracks_in_memory() > 1)
932 /* Begin with the song after the currently playing one */
933 i = 1;
934 while((track = get_trackdata(i++)))
936 start += track->load_ahead_index;
940 do {
941 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
942 if ( !trackname )
943 return -1;
945 DEBUGF("Loading %s\n", trackname);
947 mpeg_file = open(trackname, O_RDONLY);
948 if(mpeg_file < 0) {
949 DEBUGF("Couldn't open file: %s\n",trackname);
950 if(steps < 0)
951 steps--;
952 else
953 steps++;
955 else
957 struct trackdata *track = add_track_to_tag_list(trackname);
959 if(!track)
961 /* Bad mp3 file */
962 if(steps < 0)
963 steps--;
964 else
965 steps++;
966 close(mpeg_file);
967 mpeg_file = -1;
969 else
971 /* skip past id3v2 tag */
972 lseek(mpeg_file,
973 track->id3.first_frame_offset,
974 SEEK_SET);
975 track->id3.index = steps;
976 track->load_ahead_index = steps;
977 track->id3.offset = 0;
979 if(track->id3.vbr)
980 /* Average bitrate * 1.5 */
981 recalculate_watermark(
982 (track->id3.bitrate * 3) / 2);
983 else
984 recalculate_watermark(
985 track->id3.bitrate);
990 /* Bail out if no file could be opened */
991 if(abs(steps) > max_steps)
992 return -1;
993 } while ( mpeg_file < 0 );
995 return 0;
998 static void stop_playing(void)
1000 struct trackdata *track;
1002 /* Stop the current stream */
1003 mp3_play_stop();
1004 playing = false;
1005 filling = false;
1007 track = get_trackdata(0);
1008 if (track != NULL)
1009 prev_track_elapsed = track->id3.elapsed;
1011 if(mpeg_file >= 0)
1012 close(mpeg_file);
1013 mpeg_file = -1;
1014 remove_all_tags();
1015 generate_unbuffer_events();
1016 reset_mp3_buffer();
1019 static void end_current_track(void) {
1020 struct trackdata *track;
1022 play_pending = false;
1023 playing = false;
1024 mp3_play_pause(false);
1026 track = get_trackdata(0);
1027 if (track != NULL)
1028 prev_track_elapsed = track->id3.elapsed;
1030 reset_mp3_buffer();
1031 remove_all_tags();
1032 generate_unbuffer_events();
1034 if(mpeg_file >= 0)
1035 close(mpeg_file);
1038 /* Is this a really the end of playback or is a new playlist starting */
1039 static void check_playlist_end(int direction)
1041 /* Use the largest possible step size to account for skipped tracks */
1042 int steps = playlist_amount();
1044 if (direction < 0)
1045 steps = -steps;
1047 if (playlist_next(steps) < 0)
1048 is_playing = false;
1051 static void update_playlist(void)
1053 if (num_tracks_in_memory() > 0)
1055 struct trackdata *track = get_trackdata(0);
1056 track->id3.index = playlist_next(track->id3.index);
1058 else
1060 /* End of playlist? */
1061 check_playlist_end(1);
1064 playlist_update_resume_info(audio_current_track());
1067 static void track_change(void)
1069 DEBUGF("Track change\n");
1071 struct trackdata *track = get_trackdata(0);
1072 prev_track_elapsed = track->id3.elapsed;
1074 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1075 /* Reset the AVC */
1076 sound_set_avc(-1);
1077 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1079 if (num_tracks_in_memory() > 0)
1081 remove_current_tag();
1082 update_playlist();
1083 if (is_playing)
1084 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1087 current_track_counter++;
1090 unsigned long audio_prev_elapsed(void)
1092 return prev_track_elapsed;
1095 #ifdef DEBUG
1096 void hexdump(const unsigned char *buf, int len)
1098 int i;
1100 for(i = 0;i < len;i++)
1102 if(i && (i & 15) == 0)
1104 DEBUGF("\n");
1106 DEBUGF("%02x ", buf[i]);
1108 DEBUGF("\n");
1110 #endif /* DEBUG */
1112 static void start_playback_if_ready(void)
1114 int playable_space;
1116 playable_space = audiobuf_swapwrite - audiobuf_read;
1117 if(playable_space < 0)
1118 playable_space += audiobuflen;
1120 /* See if we have started playing yet. If not, do it. */
1121 if(play_pending || dma_underrun)
1123 /* If the filling has stopped, and we still haven't reached
1124 the watermark, the file must be smaller than the
1125 watermark. We must still play it. */
1126 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1127 !filling || dma_underrun)
1129 DEBUGF("P\n");
1130 if (play_pending) /* don't do this when recovering from DMA underrun */
1132 generate_postbuffer_events(); /* signal first track as buffered */
1133 if (play_pending_track_change)
1135 play_pending_track_change = false;
1136 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1138 play_pending = false;
1140 playing = true;
1142 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1143 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1144 dma_underrun = false;
1146 if (!paused)
1148 last_dma_tick = current_tick;
1149 mp3_play_pause(true);
1152 /* Tell ourselves that we need more data */
1153 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1158 static bool swap_one_chunk(void)
1160 int free_space_left;
1161 int amount_to_swap;
1163 free_space_left = get_unswapped_space();
1165 if(free_space_left == 0 && !play_pending)
1166 return false;
1168 /* Swap in larger chunks when the user is waiting for the playback
1169 to start, or when there is dangerously little playable data left */
1170 if(play_pending)
1171 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1172 else
1174 if(get_playable_space() < low_watermark)
1175 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1176 free_space_left);
1177 else
1178 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1181 if(audiobuf_write < audiobuf_swapwrite)
1182 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1183 amount_to_swap);
1184 else
1185 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1186 amount_to_swap);
1188 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1190 audiobuf_swapwrite += amount_to_swap;
1191 if(audiobuf_swapwrite >= audiobuflen)
1193 audiobuf_swapwrite = 0;
1196 return true;
1199 static void mpeg_thread(void)
1201 static int pause_tick = 0;
1202 static unsigned int pause_track = 0;
1203 struct queue_event ev;
1204 int len;
1205 int free_space_left;
1206 int unplayed_space_left;
1207 int amount_to_read;
1208 int t1, t2;
1209 int start_offset;
1210 #if CONFIG_CODEC == MAS3587F
1211 int amount_to_save;
1212 int save_endpos = 0;
1213 int rc;
1214 int level;
1215 long offset;
1216 #endif /* CONFIG_CODEC == MAS3587F */
1218 is_playing = false;
1219 play_pending = false;
1220 playing = false;
1221 mpeg_file = -1;
1223 while(1)
1225 #if CONFIG_CODEC == MAS3587F
1226 if(mpeg_mode == MPEG_DECODER)
1228 #endif /* CONFIG_CODEC == MAS3587F */
1229 yield();
1231 /* Swap if necessary, and don't block on the queue_wait() */
1232 if(swap_one_chunk())
1234 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1236 else if (playing)
1238 /* periodically update resume info */
1239 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1241 else
1243 DEBUGF("S R:%x W:%x SW:%x\n",
1244 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1245 queue_wait(&mpeg_queue, &ev);
1248 start_playback_if_ready();
1250 switch(ev.id)
1252 case MPEG_PLAY:
1253 DEBUGF("MPEG_PLAY\n");
1255 #if CONFIG_TUNER
1256 /* Silence the A/D input, it may be on because the radio
1257 may be playing */
1258 mas_codec_writereg(6, 0x0000);
1259 #endif /* CONFIG_TUNER */
1261 /* Stop the current stream */
1262 paused = false;
1263 end_current_track();
1265 if ( new_file(0) == -1 )
1267 is_playing = false;
1268 track_change();
1269 break;
1272 start_offset = (int)ev.data;
1274 /* mid-song resume? */
1275 if (start_offset) {
1276 struct mp3entry* id3 = &get_trackdata(0)->id3;
1277 lseek(mpeg_file, start_offset, SEEK_SET);
1278 id3->offset = start_offset;
1279 set_elapsed(id3);
1281 else {
1282 /* skip past id3v2 tag */
1283 lseek(mpeg_file,
1284 get_trackdata(0)->id3.first_frame_offset,
1285 SEEK_SET);
1289 /* Make it read more data */
1290 filling = true;
1291 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1293 /* Tell the file loading code that we want to start playing
1294 as soon as we have some data */
1295 play_pending = true;
1296 play_pending_track_change = true;
1298 update_playlist();
1299 current_track_counter++;
1300 break;
1302 case MPEG_STOP:
1303 DEBUGF("MPEG_STOP\n");
1304 is_playing = false;
1305 paused = false;
1307 if (playing)
1308 playlist_update_resume_info(audio_current_track());
1310 stop_playing();
1311 mpeg_stop_done = true;
1312 break;
1314 case MPEG_PAUSE:
1315 DEBUGF("MPEG_PAUSE\n");
1316 /* Stop the current stream */
1317 if (playing)
1318 playlist_update_resume_info(audio_current_track());
1319 paused = true;
1320 playing = false;
1321 pause_tick = current_tick;
1322 pause_track = current_track_counter;
1323 mp3_play_pause(false);
1324 break;
1326 case MPEG_RESUME:
1327 DEBUGF("MPEG_RESUME\n");
1328 /* Continue the current stream */
1329 paused = false;
1330 if (!play_pending)
1332 playing = true;
1333 if ( current_track_counter == pause_track )
1334 last_dma_tick += current_tick - pause_tick;
1335 else
1336 last_dma_tick = current_tick;
1337 pause_tick = 0;
1338 mp3_play_pause(true);
1340 break;
1342 case MPEG_NEXT:
1343 DEBUGF("MPEG_NEXT\n");
1344 /* is next track in ram? */
1345 if ( num_tracks_in_memory() > 1 ) {
1346 int unplayed_space_left, unswapped_space_left;
1348 /* stop the current stream */
1349 play_pending = false;
1350 playing = false;
1351 mp3_play_pause(false);
1353 track_change();
1354 audiobuf_read = get_trackdata(0)->mempos;
1355 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1356 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1357 dma_underrun = false;
1358 last_dma_tick = current_tick;
1360 unplayed_space_left = get_unplayed_space();
1361 unswapped_space_left = get_unswapped_space();
1363 /* should we start reading more data? */
1364 if(!filling && (unplayed_space_left < low_watermark)) {
1365 filling = true;
1366 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1367 play_pending = true;
1368 } else if(unswapped_space_left &&
1369 unswapped_space_left > unplayed_space_left) {
1370 /* Stop swapping the data from the previous file */
1371 audiobuf_swapwrite = audiobuf_read;
1372 play_pending = true;
1373 } else {
1374 playing = true;
1375 if (!paused)
1376 mp3_play_pause(true);
1379 else {
1380 if (!playlist_check(1))
1381 break;
1383 /* stop the current stream */
1384 end_current_track();
1386 if (new_file(1) < 0) {
1387 DEBUGF("No more files to play\n");
1388 filling = false;
1390 check_playlist_end(1);
1391 current_track_counter++;
1392 } else {
1393 /* Make it read more data */
1394 filling = true;
1395 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1397 /* Tell the file loading code that we want
1398 to start playing as soon as we have some data */
1399 play_pending = true;
1400 play_pending_track_change = true;
1402 update_playlist();
1403 current_track_counter++;
1406 break;
1408 case MPEG_PREV: {
1409 DEBUGF("MPEG_PREV\n");
1411 if (!playlist_check(-1))
1412 break;
1414 /* stop the current stream */
1415 end_current_track();
1417 /* Open the next file */
1418 if (new_file(-1) < 0) {
1419 DEBUGF("No more files to play\n");
1420 filling = false;
1422 check_playlist_end(-1);
1423 current_track_counter++;
1424 } else {
1425 /* Make it read more data */
1426 filling = true;
1427 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1429 /* Tell the file loading code that we want to
1430 start playing as soon as we have some data */
1431 play_pending = true;
1432 play_pending_track_change = true;
1434 update_playlist();
1435 current_track_counter++;
1437 break;
1440 case MPEG_FF_REWIND: {
1441 struct mp3entry *id3 = audio_current_track();
1442 unsigned int oldtime = id3->elapsed;
1443 unsigned int newtime = (unsigned int)ev.data;
1444 int curpos, newpos, diffpos;
1445 DEBUGF("MPEG_FF_REWIND\n");
1447 id3->elapsed = newtime;
1449 newpos = audio_get_file_pos();
1450 if(newpos < 0)
1452 id3->elapsed = oldtime;
1453 break;
1456 if (mpeg_file >= 0)
1457 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1458 else
1459 curpos = id3->filesize;
1461 if (num_tracks_in_memory() > 1)
1463 /* We have started loading other tracks that need to be
1464 accounted for */
1465 struct trackdata *track;
1466 int i = 0;
1468 while((track = get_trackdata(i++)))
1470 curpos += track->id3.filesize;
1474 diffpos = curpos - newpos;
1476 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1478 int unplayed_space_left, unswapped_space_left;
1480 /* We are changing to a position that's already in
1481 memory, so we just move the DMA read pointer. */
1482 audiobuf_read = audiobuf_write - diffpos;
1483 if (audiobuf_read < 0)
1485 audiobuf_read += audiobuflen;
1488 unplayed_space_left = get_unplayed_space();
1489 unswapped_space_left = get_unswapped_space();
1491 /* If unswapped_space_left is larger than
1492 unplayed_space_left, it means that the swapwrite pointer
1493 hasn't yet advanced up to the new location of the read
1494 pointer. We just move it, there is no need to swap
1495 data that won't be played anyway. */
1497 if (unswapped_space_left > unplayed_space_left)
1499 DEBUGF("Moved swapwrite\n");
1500 audiobuf_swapwrite = audiobuf_read;
1501 play_pending = true;
1504 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1506 /* We need to load more data before starting */
1507 filling = true;
1508 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1509 play_pending = true;
1511 else
1513 /* resume will start at new position */
1514 last_dma_chunk_size =
1515 MIN(0x2000, get_unplayed_space_current_song());
1516 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1517 last_dma_chunk_size, transfer_end);
1518 dma_underrun = false;
1521 else
1523 /* Move to the new position in the file and start
1524 loading data */
1525 reset_mp3_buffer();
1527 if (num_tracks_in_memory() > 1)
1529 /* We have to reload the current track */
1530 close(mpeg_file);
1531 remove_all_non_current_tags();
1532 generate_unbuffer_events();
1533 mpeg_file = -1;
1536 if (mpeg_file < 0)
1538 mpeg_file = open(id3->path, O_RDONLY);
1539 if (mpeg_file < 0)
1541 id3->elapsed = oldtime;
1542 break;
1546 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1548 id3->elapsed = oldtime;
1549 break;
1552 filling = true;
1553 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1555 /* Tell the file loading code that we want to start playing
1556 as soon as we have some data */
1557 play_pending = true;
1560 id3->offset = newpos;
1562 break;
1565 case MPEG_FLUSH_RELOAD: {
1566 int numtracks = num_tracks_in_memory();
1567 bool reload_track = false;
1569 if (numtracks > 1)
1571 /* Reset the buffer */
1572 audiobuf_write = get_trackdata(1)->mempos;
1574 /* Reset swapwrite unless we're still swapping current
1575 track */
1576 if (get_unplayed_space() <= get_playable_space())
1577 audiobuf_swapwrite = audiobuf_write;
1579 close(mpeg_file);
1580 remove_all_non_current_tags();
1581 generate_unbuffer_events();
1582 mpeg_file = -1;
1583 reload_track = true;
1585 else if (numtracks == 1 && mpeg_file < 0)
1587 reload_track = true;
1590 if(reload_track && new_file(1) >= 0)
1592 /* Tell ourselves that we want more data */
1593 filling = true;
1594 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1597 break;
1600 case MPEG_NEED_DATA:
1601 free_space_left = audiobuf_read - audiobuf_write;
1603 /* We interpret 0 as "empty buffer" */
1604 if(free_space_left <= 0)
1605 free_space_left += audiobuflen;
1607 unplayed_space_left = audiobuflen - free_space_left;
1609 /* Make sure that we don't fill the entire buffer */
1610 free_space_left -= MPEG_HIGH_WATER;
1612 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1613 generate_unbuffer_events();
1615 /* do we have any more buffer space to fill? */
1616 if(free_space_left <= 0)
1618 DEBUGF("0\n");
1619 filling = false;
1620 generate_postbuffer_events();
1621 storage_sleep();
1622 break;
1625 /* Read small chunks while we are below the low water mark */
1626 if(unplayed_space_left < low_watermark)
1627 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1628 free_space_left);
1629 else
1630 amount_to_read = free_space_left;
1632 /* Don't read more than until the end of the buffer */
1633 amount_to_read = MIN(audiobuflen - audiobuf_write,
1634 amount_to_read);
1635 #if (CONFIG_STORAGE & STORAGE_MMC)
1636 /* MMC is slow, so don't read too large chunks */
1637 amount_to_read = MIN(0x40000, amount_to_read);
1638 #elif MEMORYSIZE == 8
1639 amount_to_read = MIN(0x100000, amount_to_read);
1640 #endif
1642 /* Read as much mpeg data as we can fit in the buffer */
1643 if(mpeg_file >= 0)
1645 DEBUGF("R\n");
1646 t1 = current_tick;
1647 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1648 amount_to_read);
1649 if(len > 0)
1651 t2 = current_tick;
1652 DEBUGF("time: %d\n", t2 - t1);
1653 DEBUGF("R: %x\n", len);
1655 /* Now make sure that we don't feed the MAS with ID3V1
1656 data */
1657 if (len < amount_to_read)
1659 int i;
1660 static const unsigned char tag[] = "TAG";
1661 int taglen = 128;
1662 int tagptr = audiobuf_write + len - 128;
1664 /* Really rare case: entire potential tag wasn't
1665 read in this call AND audiobuf_write < 128 */
1666 if (tagptr < 0)
1667 tagptr += audiobuflen;
1669 for(i = 0;i < 3;i++)
1671 if(tagptr >= audiobuflen)
1672 tagptr -= audiobuflen;
1674 if(mpeg_audiobuf[tagptr] != tag[i])
1676 taglen = 0;
1677 break;
1680 tagptr++;
1683 if(taglen)
1685 /* Skip id3v1 tag */
1686 DEBUGF("Skipping ID3v1 tag\n");
1687 len -= taglen;
1689 /* In the very rare case when the entire tag
1690 wasn't read in this read() len will be < 0.
1691 Take care of this when changing the write
1692 pointer. */
1696 audiobuf_write += len;
1698 if (audiobuf_write < 0)
1699 audiobuf_write += audiobuflen;
1701 if(audiobuf_write >= audiobuflen)
1703 audiobuf_write = 0;
1704 DEBUGF("W\n");
1707 /* Tell ourselves that we want more data */
1708 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1710 else
1712 if(len < 0)
1714 DEBUGF("MPEG read error\n");
1717 close(mpeg_file);
1718 mpeg_file = -1;
1720 if(new_file(1) < 0)
1722 /* No more data to play */
1723 DEBUGF("No more files to play\n");
1724 filling = false;
1726 else
1728 /* Tell ourselves that we want more data */
1729 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1733 break;
1735 case MPEG_TRACK_CHANGE:
1736 track_change();
1737 break;
1739 #ifndef USB_NONE
1740 case SYS_USB_CONNECTED:
1741 is_playing = false;
1742 paused = false;
1743 stop_playing();
1745 /* Tell the USB thread that we are safe */
1746 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1747 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1749 /* Wait until the USB cable is extracted again */
1750 usb_wait_for_disconnect(&mpeg_queue);
1751 break;
1752 #endif /* !USB_NONE */
1754 #if CONFIG_CODEC == MAS3587F
1755 case MPEG_INIT_RECORDING:
1756 init_recording();
1757 init_recording_done = true;
1758 break;
1759 #endif /* CONFIG_CODEC == MAS3587F */
1761 case SYS_TIMEOUT:
1762 if (playing)
1763 playlist_update_resume_info(audio_current_track());
1764 break;
1766 #if CONFIG_CODEC == MAS3587F
1768 else
1770 queue_wait(&mpeg_queue, &ev);
1771 switch(ev.id)
1773 case MPEG_RECORD:
1774 if (is_prerecording)
1776 int startpos;
1778 /* Go back prerecord_count seconds in the buffer */
1779 startpos = prerecord_index - prerecord_count;
1780 if(startpos < 0)
1781 startpos += prerecording_max_seconds;
1783 /* Read the position data from the prerecord buffer */
1784 frame_count_start = prerecord_buffer[startpos].framecount;
1785 startpos = prerecord_buffer[startpos].mempos;
1787 DEBUGF("Start looking at address %x (%x)\n",
1788 mpeg_audiobuf+startpos, startpos);
1790 saved_header = mpeg_get_last_header();
1792 mem_find_next_frame(startpos, &offset, 1800,
1793 saved_header, mpeg_audiobuf,
1794 audiobuflen);
1796 audiobuf_read = startpos + offset;
1797 if(audiobuf_read >= audiobuflen)
1798 audiobuf_read -= audiobuflen;
1800 DEBUGF("New audiobuf_read address: %x (%x)\n",
1801 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1803 level = disable_irq_save();
1804 num_rec_bytes = get_unsaved_space();
1805 restore_irq(level);
1807 else
1809 frame_count_start = 0;
1810 num_rec_bytes = 0;
1811 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1812 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1815 prepend_header();
1816 DEBUGF("Recording...\n");
1817 start_recording();
1819 /* Wait until at least one frame is encoded and get the
1820 frame header, for later use by the Xing header
1821 generation */
1822 sleep(HZ/5);
1823 saved_header = mpeg_get_last_header();
1825 /* delayed until buffer is saved, don't open yet */
1826 strcpy(delayed_filename, recording_filename);
1827 mpeg_file = -1;
1829 break;
1831 case MPEG_STOP:
1832 DEBUGF("MPEG_STOP\n");
1834 stop_recording();
1836 /* Save the remaining data in the buffer */
1837 save_endpos = audiobuf_write;
1838 saving_status = STOP_RECORDING;
1839 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1840 break;
1842 case MPEG_STOP_DONE:
1843 DEBUGF("MPEG_STOP_DONE\n");
1845 if (mpeg_file >= 0)
1846 close(mpeg_file);
1847 mpeg_file = -1;
1849 update_header();
1850 #ifdef DEBUG1
1852 int i;
1853 for(i = 0;i < 512;i++)
1855 DEBUGF("%d - %d us (%d bytes)\n",
1856 timing_info[i*2],
1857 (timing_info[i*2+1] & 0xffff) *
1858 10000 / 13824,
1859 timing_info[i*2+1] >> 16);
1862 #endif /* DEBUG1 */
1864 if (prerecording)
1866 start_prerecording();
1868 mpeg_stop_done = true;
1869 break;
1871 case MPEG_NEW_FILE:
1872 /* Bail out when a more important save is happening */
1873 if (saving_status > NEW_FILE)
1874 break;
1876 /* Make sure we have at least one complete frame
1877 in the buffer. If we haven't recorded a single
1878 frame within 200ms, the MAS is probably not recording
1879 anything, and we bail out. */
1880 amount_to_save = get_unsaved_space();
1881 if (amount_to_save < 1800)
1883 sleep(HZ/5);
1884 amount_to_save = get_unsaved_space();
1887 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1888 &frame_count_end, 1);
1890 last_rec_time = current_tick - record_start_time;
1891 record_start_time = current_tick;
1892 if (paused)
1893 pause_start_time = record_start_time;
1895 /* capture all values at one point */
1896 level = disable_irq_save();
1897 save_endpos = audiobuf_write;
1898 last_rec_bytes = num_rec_bytes;
1899 num_rec_bytes = 0;
1900 restore_irq(level);
1902 if (amount_to_save >= 1800)
1904 /* Now find a frame boundary to split at */
1905 save_endpos -= 1800;
1906 if (save_endpos < 0)
1907 save_endpos += audiobuflen;
1909 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1910 saved_header, mpeg_audiobuf,
1911 audiobuflen);
1912 if (!rc) /* No header found, save whole buffer */
1913 offset = 1800;
1915 save_endpos += offset;
1916 if (save_endpos >= audiobuflen)
1917 save_endpos -= audiobuflen;
1919 last_rec_bytes += offset - 1800;
1920 level = disable_irq_save();
1921 num_rec_bytes += 1800 - offset;
1922 restore_irq(level);
1925 saving_status = NEW_FILE;
1926 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1927 break;
1929 case MPEG_SAVE_DATA:
1930 if (saving_status == BUFFER_FULL)
1931 save_endpos = audiobuf_write;
1933 if (mpeg_file < 0) /* delayed file open */
1935 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
1937 if (mpeg_file < 0)
1938 panicf("recfile: %d", mpeg_file);
1941 amount_to_save = save_endpos - audiobuf_read;
1942 if (amount_to_save < 0)
1943 amount_to_save += audiobuflen;
1945 amount_to_save = MIN(amount_to_save,
1946 audiobuflen - audiobuf_read);
1947 #if (CONFIG_STORAGE & STORAGE_MMC)
1948 /* MMC is slow, so don't save too large chunks at once */
1949 amount_to_save = MIN(0x40000, amount_to_save);
1950 #elif MEMORYSIZE == 8
1951 amount_to_save = MIN(0x100000, amount_to_save);
1952 #endif
1953 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
1954 amount_to_save);
1955 if (rc < 0)
1957 if (errno == ENOSPC)
1959 mpeg_errno = AUDIOERR_DISK_FULL;
1960 stop_recording();
1961 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1962 /* will close the file */
1963 break;
1965 else
1966 panicf("rec wrt: %d", rc);
1969 audiobuf_read += amount_to_save;
1970 if (audiobuf_read >= audiobuflen)
1971 audiobuf_read = 0;
1973 if (audiobuf_read == save_endpos) /* all saved */
1975 switch (saving_status)
1977 case BUFFER_FULL:
1978 rc = fsync(mpeg_file);
1979 if (rc < 0)
1980 panicf("rec fls: %d", rc);
1981 storage_sleep();
1982 break;
1984 case NEW_FILE:
1985 /* Close the current file */
1986 rc = close(mpeg_file);
1987 if (rc < 0)
1988 panicf("rec cls: %d", rc);
1989 mpeg_file = -1;
1990 update_header();
1991 storage_sleep();
1993 /* copy new filename */
1994 strcpy(delayed_filename, recording_filename);
1995 prepend_header();
1996 frame_count_start = frame_count_end;
1997 break;
1999 case STOP_RECORDING:
2000 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2001 /* will close the file */
2002 break;
2004 default:
2005 break;
2007 saving_status = NOT_SAVING;
2009 else /* tell ourselves to save the next chunk */
2010 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2012 break;
2014 case MPEG_PRERECORDING_TICK:
2015 if(!is_prerecording)
2016 break;
2018 /* Store the write pointer every second */
2019 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2020 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2021 &prerecord_buffer[prerecord_index].framecount, 1);
2023 /* Wrap if necessary */
2024 if(++prerecord_index == prerecording_max_seconds)
2025 prerecord_index = 0;
2027 /* Update the number of seconds recorded */
2028 if(prerecord_count < prerecording_max_seconds)
2029 prerecord_count++;
2030 break;
2032 case MPEG_INIT_PLAYBACK:
2033 /* Stop the prerecording */
2034 stop_recording();
2035 reset_mp3_buffer();
2036 mp3_play_init();
2037 init_playback_done = true;
2038 break;
2040 case MPEG_PAUSE_RECORDING:
2041 pause_recording();
2042 break;
2044 case MPEG_RESUME_RECORDING:
2045 resume_recording();
2046 break;
2048 case SYS_USB_CONNECTED:
2049 /* We can safely go to USB mode if no recording
2050 is taking place */
2051 if((!is_recording || is_prerecording) && mpeg_stop_done)
2053 /* Even if we aren't recording, we still call this
2054 function, to put the MAS in monitoring mode,
2055 to save power. */
2056 stop_recording();
2058 /* Tell the USB thread that we are safe */
2059 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2060 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2062 /* Wait until the USB cable is extracted again */
2063 usb_wait_for_disconnect(&mpeg_queue);
2065 break;
2068 #endif /* CONFIG_CODEC == MAS3587F */
2071 #endif /* !SIMULATOR */
2073 struct mp3entry* audio_current_track(void)
2075 #ifdef SIMULATOR
2076 struct mp3entry *id3 = &taginfo;
2077 #else /* !SIMULATOR */
2078 if(num_tracks_in_memory())
2080 struct mp3entry *id3 = &get_trackdata(0)->id3;
2081 #endif
2082 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2084 checked_for_cuesheet = true; /* only check once per track */
2085 char cuepath[MAX_PATH];
2087 if (look_for_cuesheet_file(id3->path, cuepath) &&
2088 parse_cuesheet(cuepath, curr_cuesheet))
2090 id3->cuesheet = curr_cuesheet;
2093 return id3;
2094 #ifndef SIMULATOR
2096 else
2097 return NULL;
2098 #endif /* !SIMULATOR */
2101 struct mp3entry* audio_next_track(void)
2103 #ifdef SIMULATOR
2104 return &taginfo;
2105 #else /* !SIMULATOR */
2106 if(num_tracks_in_memory() > 1)
2107 return &get_trackdata(1)->id3;
2108 else
2109 return NULL;
2110 #endif /* !SIMULATOR */
2113 #if CONFIG_CODEC == MAS3587F
2114 #ifndef SIMULATOR
2115 void audio_init_playback(void)
2117 init_playback_done = false;
2118 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2120 while(!init_playback_done)
2121 sleep(1);
2125 /****************************************************************************
2126 * Recording functions
2127 ***************************************************************************/
2128 void audio_init_recording(unsigned int buffer_offset)
2130 buffer_offset = buffer_offset;
2131 init_recording_done = false;
2132 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2134 while(!init_recording_done)
2135 sleep(1);
2138 static void init_recording(void)
2140 unsigned long val;
2141 int rc;
2143 /* Disable IRQ6 */
2144 IPRB &= 0xff0f;
2146 stop_playing();
2147 is_playing = false;
2148 paused = false;
2150 /* Init the recording variables */
2151 is_recording = false;
2152 is_prerecording = false;
2154 mpeg_stop_done = true;
2156 mas_reset();
2158 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2159 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2160 if(rc < 0)
2161 panicf("mas_ctrl_w: %d", rc);
2163 /* Stop the current application */
2164 val = 0;
2165 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2168 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2169 } while(val);
2171 /* Perform black magic as described by the data sheet */
2172 if((mas_version_code & 0x0fff) == 0x0102)
2174 DEBUGF("Performing MAS black magic for B2 version\n");
2175 mas_writereg(0xa3, 0x98);
2176 mas_writereg(0x94, 0xfffff);
2177 val = 0;
2178 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2179 mas_writereg(0xa3, 0x90);
2182 /* Enable A/D Converters */
2183 shadow_codec_reg0 = 0xcccd;
2184 mas_codec_writereg(0x0, shadow_codec_reg0);
2186 /* Copy left channel to right (mono mode) */
2187 mas_codec_writereg(8, 0x8000);
2189 /* ADC scale 0%, DSP scale 100%
2190 We use the DSP output for monitoring, because it works with all
2191 sources including S/PDIF */
2192 mas_codec_writereg(6, 0x0000);
2193 mas_codec_writereg(7, 0x4000);
2195 /* No mute */
2196 shadow_soft_mute = 0;
2197 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2199 #ifdef HAVE_SPDIF_OUT
2200 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2201 #else
2202 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2203 #endif
2204 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2206 /* Set Demand mode, monitoring OFF and validate all settings */
2207 shadow_io_control_main = 0x125;
2208 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2210 /* Start the encoder application */
2211 val = 0x40;
2212 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2215 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2216 } while(!(val & 0x40));
2218 /* We have started the recording application with monitoring OFF.
2219 This is because we want to record at least one frame to fill the DMA
2220 buffer, because the silly MAS will not negate EOD until at least one
2221 DMA transfer has taken place.
2222 Now let's wait for some data to be encoded. */
2223 sleep(HZ/5);
2225 /* Now set it to Monitoring mode as default, saves power */
2226 shadow_io_control_main = 0x525;
2227 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2229 /* Wait until the DSP has accepted the settings */
2232 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2233 } while(val & 1);
2235 drain_dma_buffer();
2236 mpeg_mode = MPEG_ENCODER;
2238 DEBUGF("MAS Recording application started\n");
2240 /* At this point, all settings are the reset MAS defaults, next thing is to
2241 call mpeg_set_recording_options(). */
2244 void audio_record(const char *filename)
2246 mpeg_errno = 0;
2248 strlcpy(recording_filename, filename, MAX_PATH);
2250 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2253 void audio_pause_recording(void)
2255 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2258 void audio_resume_recording(void)
2260 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2263 static void prepend_header(void)
2265 int startpos;
2266 unsigned i;
2268 /* Make room for header */
2269 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2270 if(audiobuf_read < 0)
2272 /* Clear the bottom half */
2273 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2275 /* And the top half */
2276 audiobuf_read += audiobuflen;
2277 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2279 else
2281 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2283 /* Copy the empty ID3 header */
2284 startpos = audiobuf_read;
2285 for(i = 0; i < sizeof(empty_id3_header); i++)
2287 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2288 if(startpos == audiobuflen)
2289 startpos = 0;
2293 static void update_header(void)
2295 int fd, framelen;
2296 unsigned long frames;
2298 if (last_rec_bytes > 0)
2300 /* Create the Xing header */
2301 fd = open(delayed_filename, O_RDWR);
2302 if (fd < 0)
2303 panicf("rec upd: %d (%s)", fd, recording_filename);
2305 frames = frame_count_end - frame_count_start;
2306 /* If the number of recorded frames has reached 0x7ffff,
2307 we can no longer trust it */
2308 if (frame_count_end == 0x7ffff)
2309 frames = 0;
2311 /* saved_header is saved right before stopping the MAS */
2312 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2313 frames, last_rec_time * (1000/HZ),
2314 saved_header, NULL, false,
2315 mpeg_audiobuf, audiobuflen);
2317 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2318 write(fd, xing_buffer, framelen);
2319 close(fd);
2323 static void start_prerecording(void)
2325 unsigned long val;
2327 DEBUGF("Starting prerecording\n");
2329 prerecord_index = 0;
2330 prerecord_count = 0;
2331 prerecord_timeout = current_tick + HZ;
2332 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2333 reset_mp3_buffer();
2335 is_prerecording = true;
2337 /* Stop monitoring and start the encoder */
2338 shadow_io_control_main &= ~(1 << 10);
2339 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2340 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2342 /* Wait until the DSP has accepted the settings */
2345 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2346 } while(val & 1);
2348 is_recording = true;
2349 saving_status = NOT_SAVING;
2351 demand_irq_enable(true);
2354 static void start_recording(void)
2356 unsigned long val;
2358 if(is_prerecording)
2360 /* This will make the IRQ handler start recording
2361 for real, i.e send MPEG_SAVE_DATA messages when
2362 the buffer is full */
2363 is_prerecording = false;
2365 else
2367 /* If prerecording is off, we need to stop the monitoring
2368 and start the encoder */
2369 shadow_io_control_main &= ~(1 << 10);
2370 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2371 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2373 /* Wait until the DSP has accepted the settings */
2376 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2377 } while(val & 1);
2380 is_recording = true;
2381 saving_status = NOT_SAVING;
2382 paused = false;
2384 /* Store the current time */
2385 if(prerecording)
2386 record_start_time = current_tick - prerecord_count * HZ;
2387 else
2388 record_start_time = current_tick;
2390 pause_start_time = 0;
2392 demand_irq_enable(true);
2395 static void pause_recording(void)
2397 pause_start_time = current_tick;
2399 /* Set the pause bit */
2400 shadow_soft_mute |= 2;
2401 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2403 paused = true;
2406 static void resume_recording(void)
2408 paused = false;
2410 /* Clear the pause bit */
2411 shadow_soft_mute &= ~2;
2412 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2414 /* Compensate for the time we have been paused */
2415 if(pause_start_time)
2417 record_start_time =
2418 current_tick - (pause_start_time - record_start_time);
2419 pause_start_time = 0;
2423 static void stop_recording(void)
2425 unsigned long val;
2427 /* Let it finish the last frame */
2428 if(!paused)
2429 pause_recording();
2430 sleep(HZ/5);
2432 demand_irq_enable(false);
2434 is_recording = false;
2435 is_prerecording = false;
2437 last_rec_bytes = num_rec_bytes;
2438 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2439 last_rec_time = current_tick - record_start_time;
2441 /* Start monitoring */
2442 shadow_io_control_main |= (1 << 10);
2443 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2444 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2446 /* Wait until the DSP has accepted the settings */
2449 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2450 } while(val & 1);
2452 resume_recording();
2455 void audio_set_recording_options(struct audio_recording_options *options)
2457 bool is_mpeg1;
2459 is_mpeg1 = (options->rec_frequency < 3);
2461 rec_version_index = is_mpeg1?3:2;
2462 rec_frequency_index = options->rec_frequency % 3;
2464 shadow_encoder_control = (options->rec_quality << 17) |
2465 (rec_frequency_index << 10) |
2466 ((is_mpeg1?1:0) << 9) |
2467 (((options->rec_channels * 2 + 1) & 3) << 6) |
2468 (1 << 5) /* MS-stereo */ |
2469 (1 << 2) /* Is an original */;
2470 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2472 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2474 #if CONFIG_TUNER & S1A0903X01
2475 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2476 interference with the Samsung tuner. */
2477 if (rec_frequency_index)
2478 mas_store_pllfreq(24576000);
2479 else
2480 mas_store_pllfreq(22579000);
2481 #endif
2483 shadow_soft_mute = options->rec_editable?4:0;
2484 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2486 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2488 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2489 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2490 (1 << 5) | /* SDO strobe invert */
2491 ((is_mpeg1?0:1) << 3) |
2492 (1 << 2) | /* Inverted SIBC clock signal */
2493 1; /* Validate */
2494 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2496 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2498 if(options->rec_source == AUDIO_SRC_MIC)
2500 /* Copy left channel to right (mono mode) */
2501 mas_codec_writereg(8, 0x8000);
2503 else
2505 /* Stereo input mode */
2506 mas_codec_writereg(8, 0);
2509 prerecording_max_seconds = options->rec_prerecord_time;
2510 if(prerecording_max_seconds)
2512 prerecording = true;
2513 start_prerecording();
2515 else
2517 prerecording = false;
2518 is_prerecording = false;
2519 is_recording = false;
2523 /* If use_mic is true, the left gain is used */
2524 void audio_set_recording_gain(int left, int right, int type)
2526 /* Enable both left and right A/D */
2527 shadow_codec_reg0 = (left << 12) |
2528 (right << 8) |
2529 (left << 4) |
2530 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2531 0x0007;
2532 mas_codec_writereg(0x0, shadow_codec_reg0);
2535 /* try to make some kind of beep, also in recording mode */
2536 void audio_beep(int duration)
2538 long starttick = current_tick;
2540 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2541 * While this is still audible even without an external signal,
2542 * it doesn't affect the (pre-)recording. */
2543 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2544 mas_codec_writereg(0, shadow_codec_reg0);
2545 yield();
2547 while (current_tick - starttick < duration);
2550 void audio_new_file(const char *filename)
2552 mpeg_errno = 0;
2554 strlcpy(recording_filename, filename, MAX_PATH);
2556 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2559 unsigned long audio_recorded_time(void)
2561 if(is_prerecording)
2562 return prerecord_count * HZ;
2564 if(is_recording)
2566 if(paused)
2567 return pause_start_time - record_start_time;
2568 else
2569 return current_tick - record_start_time;
2572 return 0;
2575 unsigned long audio_num_recorded_bytes(void)
2577 int num_bytes;
2578 int index;
2580 if(is_recording)
2582 if(is_prerecording)
2584 index = prerecord_index - prerecord_count;
2585 if(index < 0)
2586 index += prerecording_max_seconds;
2588 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2589 if(num_bytes < 0)
2590 num_bytes += audiobuflen;
2592 return num_bytes;
2594 else
2595 return num_rec_bytes;
2597 else
2598 return 0;
2601 #else /* SIMULATOR */
2603 /* dummies coming up */
2605 void audio_init_playback(void)
2607 /* a dummy */
2609 unsigned long audio_recorded_time(void)
2611 /* a dummy */
2612 return 0;
2614 void audio_beep(int duration)
2616 /* a dummy */
2617 (void)duration;
2619 void audio_pause_recording(void)
2621 /* a dummy */
2623 void audio_resume_recording(void)
2625 /* a dummy */
2627 unsigned long audio_num_recorded_bytes(void)
2629 /* a dummy */
2630 return 0;
2632 void audio_record(const char *filename)
2634 /* a dummy */
2635 (void)filename;
2637 void audio_new_file(const char *filename)
2639 /* a dummy */
2640 (void)filename;
2643 void audio_set_recording_gain(int left, int right, int type)
2645 /* a dummy */
2646 (void)left;
2647 (void)right;
2648 (void)type;
2650 void audio_init_recording(unsigned int buffer_offset)
2652 /* a dummy */
2653 (void)buffer_offset;
2655 void audio_set_recording_options(struct audio_recording_options *options)
2657 /* a dummy */
2658 (void)options;
2660 #endif /* SIMULATOR */
2661 #endif /* CONFIG_CODEC == MAS3587F */
2663 static void audio_reset_buffer(void)
2665 size_t bufsize; /* dont break strict-aliasing */
2666 talk_buffer_steal(); /* will use the mp3 buffer */
2668 /* release buffer on behalf of any audio_get_buffer() caller,
2669 * non-fatal if there was none */
2670 buffer_release_buffer(0);
2671 /* re-aquire */
2672 mpeg_audiobuf = buffer_get_buffer(&bufsize);
2673 audiobuflen = bufsize;
2676 void audio_play(long offset)
2678 #ifdef SIMULATOR
2679 char name_buf[MAX_PATH+1];
2680 const char* trackname;
2681 int steps=0;
2683 is_playing = true;
2685 do {
2686 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2687 if (!trackname)
2688 break;
2689 if(mp3info(&taginfo, trackname)) {
2690 /* bad mp3, move on */
2691 if(++steps > playlist_amount())
2692 break;
2693 continue;
2695 #ifdef HAVE_MPEG_PLAY
2696 real_mpeg_play(trackname);
2697 #endif
2698 playlist_next(steps);
2699 taginfo.offset = offset;
2700 set_elapsed(&taginfo);
2701 is_playing = true;
2702 playing = true;
2703 break;
2704 } while(1);
2705 #else /* !SIMULATOR */
2706 is_playing = true;
2708 audio_reset_buffer();
2709 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2710 #endif /* !SIMULATOR */
2712 mpeg_errno = 0;
2715 void audio_stop(void)
2717 #ifndef SIMULATOR
2718 if (playing)
2720 struct trackdata *track = get_trackdata(0);
2721 prev_track_elapsed = track->id3.elapsed;
2723 mpeg_stop_done = false;
2724 queue_post(&mpeg_queue, MPEG_STOP, 0);
2725 while(!mpeg_stop_done)
2726 yield();
2727 #else /* SIMULATOR */
2728 paused = false;
2729 is_playing = false;
2730 playing = false;
2731 #endif /* SIMULATOR */
2734 /* dummy */
2735 void audio_stop_recording(void)
2737 audio_stop();
2740 void audio_pause(void)
2742 #ifndef SIMULATOR
2743 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2744 #else /* SIMULATOR */
2745 is_playing = true;
2746 playing = false;
2747 paused = true;
2748 #endif /* SIMULATOR */
2751 void audio_resume(void)
2753 #ifndef SIMULATOR
2754 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2755 #else /* SIMULATOR */
2756 is_playing = true;
2757 playing = true;
2758 paused = false;
2759 #endif /* SIMULATOR */
2762 void audio_next(void)
2764 #ifndef SIMULATOR
2765 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2766 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2767 #else /* SIMULATOR */
2768 char name_buf[MAX_PATH+1];
2769 const char* file;
2770 int steps = 1;
2772 do {
2773 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2774 if(!file)
2775 break;
2776 if(mp3info(&taginfo, file)) {
2777 if(++steps > playlist_amount())
2778 break;
2779 continue;
2781 playlist_next(steps);
2782 current_track_counter++;
2783 is_playing = true;
2784 playing = true;
2785 break;
2786 } while(1);
2787 #endif /* SIMULATOR */
2790 void audio_prev(void)
2792 #ifndef SIMULATOR
2793 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2794 queue_post(&mpeg_queue, MPEG_PREV, 0);
2795 #else /* SIMULATOR */
2796 char name_buf[MAX_PATH+1];
2797 const char* file;
2798 int steps = -1;
2800 do {
2801 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2802 if(!file)
2803 break;
2804 if(mp3info(&taginfo, file)) {
2805 steps--;
2806 continue;
2808 playlist_next(steps);
2809 current_track_counter++;
2810 is_playing = true;
2811 playing = true;
2812 break;
2813 } while(1);
2814 #endif /* SIMULATOR */
2817 void audio_ff_rewind(long newpos)
2819 #ifndef SIMULATOR
2820 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2821 #else /* SIMULATOR */
2822 (void)newpos;
2823 #endif /* SIMULATOR */
2826 void audio_flush_and_reload_tracks(void)
2828 #ifndef SIMULATOR
2829 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2830 #endif /* !SIMULATOR*/
2833 int audio_status(void)
2835 int ret = 0;
2837 if(is_playing)
2838 ret |= AUDIO_STATUS_PLAY;
2840 if(paused)
2841 ret |= AUDIO_STATUS_PAUSE;
2843 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2844 if(is_recording && !is_prerecording)
2845 ret |= AUDIO_STATUS_RECORD;
2847 if(is_prerecording)
2848 ret |= AUDIO_STATUS_PRERECORD;
2849 #endif /* CONFIG_CODEC == MAS3587F */
2851 if(mpeg_errno)
2852 ret |= AUDIO_STATUS_ERROR;
2854 return ret;
2857 /* Unused function
2858 unsigned int audio_error(void)
2860 return mpeg_errno;
2864 void audio_error_clear(void)
2866 mpeg_errno = 0;
2869 #ifdef SIMULATOR
2870 static void mpeg_thread(void)
2872 struct mp3entry* id3;
2873 while ( 1 ) {
2874 if (is_playing) {
2875 id3 = audio_current_track();
2876 if (!paused)
2878 id3->elapsed+=1000;
2879 id3->offset+=1000;
2881 if (id3->elapsed>=id3->length)
2882 audio_next();
2884 sleep(HZ);
2887 #endif /* SIMULATOR */
2889 void audio_init(void)
2891 mpeg_errno = 0;
2892 /* cuesheet support */
2893 if (global_settings.cuesheet)
2894 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2896 #ifndef SIMULATOR
2897 size_t bufsize; /* don't break strict-aliasing */
2898 mpeg_audiobuf = buffer_get_buffer(&bufsize);
2899 audiobuflen = bufsize;
2900 queue_init(&mpeg_queue, true);
2901 #endif /* !SIMULATOR */
2902 create_thread(mpeg_thread, mpeg_stack,
2903 sizeof(mpeg_stack), 0, mpeg_thread_name
2904 IF_PRIO(, PRIORITY_SYSTEM)
2905 IF_COP(, CPU));
2907 memset(trackdata, 0, sizeof(trackdata));
2909 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2910 if (HW_MASK & PR_ACTIVE_HIGH)
2911 and_b(~0x08, &PADRH);
2912 else
2913 or_b(0x08, &PADRH);
2914 #endif /* CONFIG_CODEC == MAS3587F */
2916 #ifdef DEBUG
2917 #ifndef SIMULATOR
2918 dbg_timer_start();
2919 dbg_cnt2us(0);
2920 #endif /* !SIMULATOR */
2921 #endif /* DEBUG */
2924 #endif /* CONFIG_CODEC != SWCODEC */