Fix hwcodec sims
[kugel-rb.git] / apps / mpeg.c
blob2785107f222027052b80923226b7da5a83853874
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;
152 #else /* !SIMULATOR */
153 static struct event_queue mpeg_queue SHAREDBSS_ATTR;
154 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
156 static char* mpeg_audiobuf; /* the audio buffer */
157 static long audiobuflen; /* length of the audio buffer */
158 static int audiobuf_write;
159 static int audiobuf_swapwrite;
160 static long audiobuf_read;
162 static int mpeg_file;
164 static bool play_pending; /* We are about to start playing */
165 static bool play_pending_track_change; /* When starting play we're starting a new file */
166 static bool filling; /* We are filling the buffer with data from disk */
167 static bool dma_underrun; /* True when the DMA has stopped because of
168 slow disk reading (read error, shaking) */
169 static bool mpeg_stop_done;
171 static int last_dma_tick = 0;
172 static int last_dma_chunk_size;
174 static long low_watermark; /* Dynamic low watermark level */
175 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
176 static long lowest_watermark_level; /* Debug value to observe the buffer
177 usage */
178 #if CONFIG_CODEC == MAS3587F
179 static char recording_filename[MAX_PATH]; /* argument to thread */
180 static char delayed_filename[MAX_PATH]; /* internal copy of above */
182 static char xing_buffer[MAX_XING_HEADER_SIZE];
184 static bool init_recording_done;
185 static bool init_playback_done;
186 static bool prerecording; /* True if prerecording is enabled */
187 static bool is_prerecording; /* True if we are prerecording */
188 static bool is_recording; /* We are recording */
190 static enum {
191 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
192 BUFFER_FULL,
193 NEW_FILE,
194 STOP_RECORDING
195 } saving_status;
197 static int rec_frequency_index; /* For create_xing_header() calls */
198 static int rec_version_index; /* For create_xing_header() calls */
200 struct prerecord_info {
201 int mempos;
202 unsigned long framecount;
205 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
206 static int prerecord_index; /* Current index in the prerecord buffer */
207 static int prerecording_max_seconds; /* Max number of seconds to store */
208 static int prerecord_count; /* Number of seconds in the prerecord buffer */
209 static int prerecord_timeout; /* The tick count of the next prerecord data
210 store */
212 static unsigned long record_start_time; /* Value of current_tick when recording
213 was started */
214 static unsigned long pause_start_time; /* Value of current_tick when pause was
215 started */
216 static unsigned long last_rec_time;
217 static unsigned long num_rec_bytes;
218 static unsigned long last_rec_bytes;
219 static unsigned long frame_count_start;
220 static unsigned long frame_count_end;
221 static unsigned long saved_header = 0;
223 /* Shadow MAS registers */
224 unsigned long shadow_encoder_control = 0;
225 #endif /* CONFIG_CODEC == MAS3587F */
227 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
228 unsigned long shadow_io_control_main = 0;
229 unsigned long shadow_soft_mute = 0;
230 unsigned shadow_codec_reg0;
231 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
233 #ifdef HAVE_RECORDING
234 static const unsigned char empty_id3_header[] =
236 'I', 'D', '3', 0x03, 0x00, 0x00,
237 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
239 #endif /* HAVE_RECORDING */
242 static int get_unplayed_space(void);
243 static int get_playable_space(void);
244 static int get_unswapped_space(void);
245 #endif /* !SIMULATOR */
247 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
248 static void init_recording(void);
249 static void prepend_header(void);
250 static void update_header(void);
251 static void start_prerecording(void);
252 static void start_recording(void);
253 static void stop_recording(void);
254 static int get_unsaved_space(void);
255 static void pause_recording(void);
256 static void resume_recording(void);
257 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
260 #ifndef SIMULATOR
261 static int num_tracks_in_memory(void)
263 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
266 #ifdef DEBUG_TAGS
267 static void debug_tags(void)
269 int i;
271 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
273 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
275 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
276 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
278 #else /* !DEBUG_TAGS */
279 #define debug_tags()
280 #endif /* !DEBUG_TAGS */
282 static void remove_current_tag(void)
284 if(num_tracks_in_memory() > 0)
286 /* First move the index, so nobody tries to access the tag */
287 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
288 checked_for_cuesheet = false;
289 debug_tags();
291 else
293 DEBUGF("remove_current_tag: no tracks to remove\n");
297 static void remove_all_non_current_tags(void)
299 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
300 debug_tags();
303 static void remove_all_tags(void)
305 track_write_idx = track_read_idx;
307 debug_tags();
310 static struct trackdata *get_trackdata(int offset)
312 if(offset >= num_tracks_in_memory())
313 return NULL;
314 else
315 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
317 #endif /* !SIMULATOR */
319 /***********************************************************************/
320 /* audio event handling */
322 #define MAX_EVENT_HANDLERS 10
323 struct event_handlers_table
325 AUDIO_EVENT_HANDLER handler;
326 unsigned short mask;
328 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
329 static int event_handlers_count = 0;
331 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
333 if (event_handlers_count < MAX_EVENT_HANDLERS)
335 event_handlers[event_handlers_count].handler = handler;
336 event_handlers[event_handlers_count].mask = mask;
337 event_handlers_count++;
341 /* dispatch calls each handler in the order registered and returns after some
342 handler actually handles the event (the event is assumed to no longer be valid
343 after this, due to the handler changing some condition); returns true if someone
344 handled the event, which is expected to cause the caller to skip its own handling
345 of the event */
346 #ifndef SIMULATOR
347 static bool audio_dispatch_event(unsigned short event, unsigned long data)
349 int i = 0;
350 for(i=0; i < event_handlers_count; i++)
352 if ( event_handlers[i].mask & event )
354 int rc = event_handlers[i].handler(event, data);
355 if ( rc == AUDIO_EVENT_RC_HANDLED )
356 return true;
359 return false;
361 #endif
363 /***********************************************************************/
365 static void set_elapsed(struct mp3entry* id3)
367 if ( id3->vbr ) {
368 if ( id3->has_toc ) {
369 /* calculate elapsed time using TOC */
370 int i;
371 unsigned int remainder, plen, relpos, nextpos;
373 /* find wich percent we're at */
374 for (i=0; i<100; i++ )
376 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
378 break;
382 i--;
383 if (i < 0)
384 i = 0;
386 relpos = id3->toc[i];
388 if (i < 99)
390 nextpos = id3->toc[i+1];
392 else
394 nextpos = 256;
397 remainder = id3->offset - (relpos * (id3->filesize / 256));
399 /* set time for this percent (divide before multiply to prevent
400 overflow on long files. loss of precision is negligible on
401 short files) */
402 id3->elapsed = i * (id3->length / 100);
404 /* calculate remainder time */
405 plen = (nextpos - relpos) * (id3->filesize / 256);
406 id3->elapsed += (((remainder * 100) / plen) *
407 (id3->length / 10000));
409 else {
410 /* no TOC exists. set a rough estimate using average bitrate */
411 int tpk = id3->length / (id3->filesize / 1024);
412 id3->elapsed = id3->offset / 1024 * tpk;
415 else
416 /* constant bitrate, use exact calculation */
417 id3->elapsed = id3->offset / (id3->bitrate / 8);
420 int audio_get_file_pos(void)
422 int pos = -1;
423 struct mp3entry *id3 = audio_current_track();
425 if (id3->vbr)
427 if (id3->has_toc)
429 /* Use the TOC to find the new position */
430 unsigned int percent, remainder;
431 int curtoc, nexttoc, plen;
433 percent = (id3->elapsed*100)/id3->length;
434 if (percent > 99)
435 percent = 99;
437 curtoc = id3->toc[percent];
439 if (percent < 99)
440 nexttoc = id3->toc[percent+1];
441 else
442 nexttoc = 256;
444 pos = (id3->filesize/256)*curtoc;
446 /* Use the remainder to get a more accurate position */
447 remainder = (id3->elapsed*100)%id3->length;
448 remainder = (remainder*100)/id3->length;
449 plen = (nexttoc - curtoc)*(id3->filesize/256);
450 pos += (plen/100)*remainder;
452 else
454 /* No TOC exists, estimate the new position */
455 pos = (id3->filesize / (id3->length / 1000)) *
456 (id3->elapsed / 1000);
459 else if (id3->bitrate)
460 pos = id3->elapsed * (id3->bitrate / 8);
461 else
463 return -1;
466 if (pos >= (int)(id3->filesize - id3->id3v1len))
468 /* Don't seek right to the end of the file so that we can
469 transition properly to the next song */
470 pos = id3->filesize - id3->id3v1len - 1;
472 else if (pos < (int)id3->first_frame_offset)
474 /* skip past id3v2 tag and other leading garbage */
475 pos = id3->first_frame_offset;
477 return pos;
480 unsigned long mpeg_get_last_header(void)
482 #ifdef SIMULATOR
483 return 0;
484 #else /* !SIMULATOR */
485 unsigned long tmp[2];
487 /* Read the frame data from the MAS and reconstruct it with the
488 frame sync and all */
489 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
490 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
491 #endif /* !SIMULATOR */
495 unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
497 (void)talk_buf; /* always grab the voice buffer for now */
498 talk_buffer_steal(); /* need to tell */
500 if (buffer_size) /* special case for talk_init() */
501 return buffer_get_buffer(buffer_size);
502 return NULL;
506 #ifndef SIMULATOR
507 /* Send callback events to notify about removing old tracks. */
508 static void generate_unbuffer_events(void)
510 int i;
511 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
512 int cur_idx = track_write_idx;
514 for (i = 0; i < numentries; i++)
516 /* Send an event to notify that track has finished. */
517 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
518 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
522 /* Send callback events to notify about new tracks. */
523 static void generate_postbuffer_events(void)
525 int i;
526 int numentries = num_tracks_in_memory();
527 int cur_idx = track_read_idx;
529 for (i = 0; i < numentries; i++)
531 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
532 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
536 static void recalculate_watermark(int bitrate)
538 int bytes_per_sec;
539 int time = storage_spinup_time();
541 /* A bitrate of 0 probably means empty VBR header. We play safe
542 and set a high threshold */
543 if(bitrate == 0)
544 bitrate = 320;
546 bytes_per_sec = bitrate * 1000 / 8;
548 if(time)
550 /* No drive spins up faster than 3.5s */
551 if(time < 350)
552 time = 350;
554 time = time * 3;
555 low_watermark = ((low_watermark_margin * HZ + time) *
556 bytes_per_sec) / HZ;
558 else
560 low_watermark = MPEG_LOW_WATER;
564 #ifdef HAVE_DISK_STORAGE
565 void audio_set_buffer_margin(int setting)
567 low_watermark_margin = setting; /* in seconds */
569 #endif
571 void audio_get_debugdata(struct audio_debug *dbgdata)
573 dbgdata->audiobuflen = audiobuflen;
574 dbgdata->audiobuf_write = audiobuf_write;
575 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
576 dbgdata->audiobuf_read = audiobuf_read;
578 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
580 #if CONFIG_CPU == SH7034
581 dbgdata->dma_on = (SCR0 & 0x80) != 0;
582 #endif
583 dbgdata->playing = playing;
584 dbgdata->play_pending = play_pending;
585 dbgdata->is_playing = is_playing;
586 dbgdata->filling = filling;
587 dbgdata->dma_underrun = dma_underrun;
589 dbgdata->unplayed_space = get_unplayed_space();
590 dbgdata->playable_space = get_playable_space();
591 dbgdata->unswapped_space = get_unswapped_space();
593 dbgdata->low_watermark_level = low_watermark;
594 dbgdata->lowest_watermark_level = lowest_watermark_level;
597 #ifdef DEBUG
598 static void dbg_timer_start(void)
600 /* We are using timer 2 */
602 TSTR &= ~0x04; /* Stop the timer */
603 TSNC &= ~0x04; /* No synchronization */
604 TMDR &= ~0x44; /* Operate normally */
606 TCNT2 = 0; /* Start counting at 0 */
607 TCR2 = 0x03; /* Sysclock/8 */
609 TSTR |= 0x04; /* Start timer 2 */
612 static int dbg_cnt2us(unsigned int cnt)
614 return (cnt * 10000) / (FREQ/800);
616 #endif /* DEBUG */
618 static int get_unplayed_space(void)
620 int space = audiobuf_write - audiobuf_read;
621 if (space < 0)
622 space += audiobuflen;
623 return space;
626 static int get_playable_space(void)
628 int space = audiobuf_swapwrite - audiobuf_read;
629 if (space < 0)
630 space += audiobuflen;
631 return space;
634 static int get_unplayed_space_current_song(void)
636 int space;
638 if (num_tracks_in_memory() > 1)
640 space = get_trackdata(1)->mempos - audiobuf_read;
642 else
644 space = audiobuf_write - audiobuf_read;
647 if (space < 0)
648 space += audiobuflen;
650 return space;
653 static int get_unswapped_space(void)
655 int space = audiobuf_write - audiobuf_swapwrite;
656 if (space < 0)
657 space += audiobuflen;
658 return space;
661 #if CONFIG_CODEC == MAS3587F
662 static int get_unsaved_space(void)
664 int space = audiobuf_write - audiobuf_read;
665 if (space < 0)
666 space += audiobuflen;
667 return space;
670 static void drain_dma_buffer(void)
672 while (PBDRH & 0x40)
674 xor_b(0x08, &PADRH);
676 while (PBDRH & 0x80);
678 xor_b(0x08, &PADRH);
680 while (!(PBDRH & 0x80));
684 #ifdef DEBUG
685 static long timing_info_index = 0;
686 static long timing_info[1024];
687 #endif /* DEBUG */
689 void rec_tick (void) __attribute__ ((section (".icode")));
690 void rec_tick(void)
692 int i;
693 int delay;
694 char data;
696 if(is_recording && (PBDRH & 0x40))
698 #ifdef DEBUG
699 timing_info[timing_info_index++] = current_tick;
700 TCNT2 = 0;
701 #endif /* DEBUG */
702 /* Note: Although this loop is run in interrupt context, further
703 * optimisation will do no good. The MAS would then deliver bad
704 * frames occasionally, as observed in extended experiments. */
705 i = 0;
706 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
708 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
710 delay = 100;
711 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
713 if (--delay <= 0) /* Bail out if we have to wait too long */
714 { /* i.e. the MAS doesn't want to talk to us */
715 xor_b(0x08, &PADRH); /* Set PR inactive */
716 goto transfer_end; /* and get out of here */
720 data = *(unsigned char *)0x04000000; /* read data byte */
722 xor_b(0x08, &PADRH); /* Set PR inactive */
724 mpeg_audiobuf[audiobuf_write++] = data;
726 if (audiobuf_write >= audiobuflen)
727 audiobuf_write = 0;
729 i++;
731 transfer_end:
733 #ifdef DEBUG
734 timing_info[timing_info_index++] = TCNT2 + (i << 16);
735 timing_info_index &= 0x3ff;
736 #endif /* DEBUG */
738 num_rec_bytes += i;
740 if(is_prerecording)
742 if(TIME_AFTER(current_tick, prerecord_timeout))
744 prerecord_timeout = current_tick + HZ;
745 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
748 else
750 /* Signal to save the data if we are running out of buffer
751 space */
752 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
753 && saving_status == NOT_SAVING)
755 saving_status = BUFFER_FULL;
756 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
761 #endif /* CONFIG_CODEC == MAS3587F */
763 void playback_tick(void)
765 struct trackdata *ptd = get_trackdata(0);
766 if(ptd)
768 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
769 last_dma_tick = current_tick;
770 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
771 (unsigned long)ptd->id3.elapsed);
775 static void reset_mp3_buffer(void)
777 audiobuf_read = 0;
778 audiobuf_write = 0;
779 audiobuf_swapwrite = 0;
780 lowest_watermark_level = audiobuflen;
783 /* DMA transfer end interrupt callback */
784 static void transfer_end(unsigned char** ppbuf, size_t* psize)
786 if(playing && !paused)
788 int unplayed_space_left;
789 int space_until_end_of_buffer;
790 int track_offset = 1;
791 struct trackdata *track;
793 audiobuf_read += last_dma_chunk_size;
794 if(audiobuf_read >= audiobuflen)
795 audiobuf_read = 0;
797 /* First, check if we are on a track boundary */
798 if (num_tracks_in_memory() > 1)
800 if (audiobuf_read == get_trackdata(track_offset)->mempos)
802 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
804 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
805 track_offset++;
810 unplayed_space_left = get_unplayed_space();
812 space_until_end_of_buffer = audiobuflen - audiobuf_read;
814 if(!filling && unplayed_space_left < low_watermark)
816 filling = true;
817 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
820 if(unplayed_space_left)
822 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
823 last_dma_chunk_size = MIN(last_dma_chunk_size,
824 space_until_end_of_buffer);
826 /* several tracks loaded? */
827 track = get_trackdata(track_offset);
828 if(track)
830 /* will we move across the track boundary? */
831 if (( audiobuf_read < track->mempos ) &&
832 ((audiobuf_read+last_dma_chunk_size) >
833 track->mempos ))
835 /* Make sure that we end exactly on the boundary */
836 last_dma_chunk_size = track->mempos - audiobuf_read;
840 *psize = last_dma_chunk_size & 0xffff;
841 *ppbuf = mpeg_audiobuf + audiobuf_read;
842 track = get_trackdata(0);
843 if(track)
844 track->id3.offset += last_dma_chunk_size;
846 /* Update the watermark debug level */
847 if(unplayed_space_left < lowest_watermark_level)
848 lowest_watermark_level = unplayed_space_left;
850 else
852 /* Check if the end of data is because of a hard disk error.
853 If there is an open file handle, we are still playing music.
854 If not, the last file has been loaded, and the file handle is
855 closed. */
856 if(mpeg_file >= 0)
858 /* Update the watermark debug level */
859 if(unplayed_space_left < lowest_watermark_level)
860 lowest_watermark_level = unplayed_space_left;
862 DEBUGF("DMA underrun.\n");
863 dma_underrun = true;
865 else
867 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
869 DEBUGF("No more MP3 data. Stopping.\n");
870 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
871 playing = false;
874 *psize = 0; /* no more transfer */
879 static struct trackdata *add_track_to_tag_list(const char *filename)
881 struct trackdata *track;
882 bool send_nid3_event;
884 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
886 DEBUGF("Tag memory is full\n");
887 return NULL;
890 track = &trackdata[track_write_idx];
892 /* grab id3 tag of new file and
893 remember where in memory it starts */
894 if(mp3info(&track->id3, filename))
896 DEBUGF("Bad mp3\n");
897 return NULL;
899 track->mempos = audiobuf_write;
900 track->id3.elapsed = 0;
901 #ifdef HAVE_LCD_BITMAP
902 if (track->id3.title)
903 lcd_getstringsize(track->id3.title, NULL, NULL);
904 if (track->id3.artist)
905 lcd_getstringsize(track->id3.artist, NULL, NULL);
906 if (track->id3.album)
907 lcd_getstringsize(track->id3.album, NULL, NULL);
908 #endif
910 /* if this track is the next track then let the UI know it can get it */
911 send_nid3_event = (track_write_idx == track_read_idx + 1);
912 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
913 if (send_nid3_event)
914 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
915 debug_tags();
916 return track;
919 static int new_file(int steps)
921 int max_steps = playlist_amount();
922 int start = 0;
923 int i;
924 struct trackdata *track;
925 char name_buf[MAX_PATH+1];
926 const char *trackname;
928 /* Find out how many steps to advance. The load_ahead_index field tells
929 us how many playlist entries it had to skip to get to a valid one.
930 We add those together to find out where to start. */
931 if(steps > 0 && num_tracks_in_memory() > 1)
933 /* Begin with the song after the currently playing one */
934 i = 1;
935 while((track = get_trackdata(i++)))
937 start += track->load_ahead_index;
941 do {
942 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
943 if ( !trackname )
944 return -1;
946 DEBUGF("Loading %s\n", trackname);
948 mpeg_file = open(trackname, O_RDONLY);
949 if(mpeg_file < 0) {
950 DEBUGF("Couldn't open file: %s\n",trackname);
951 if(steps < 0)
952 steps--;
953 else
954 steps++;
956 else
958 struct trackdata *track = add_track_to_tag_list(trackname);
960 if(!track)
962 /* Bad mp3 file */
963 if(steps < 0)
964 steps--;
965 else
966 steps++;
967 close(mpeg_file);
968 mpeg_file = -1;
970 else
972 /* skip past id3v2 tag */
973 lseek(mpeg_file,
974 track->id3.first_frame_offset,
975 SEEK_SET);
976 track->id3.index = steps;
977 track->load_ahead_index = steps;
978 track->id3.offset = 0;
980 if(track->id3.vbr)
981 /* Average bitrate * 1.5 */
982 recalculate_watermark(
983 (track->id3.bitrate * 3) / 2);
984 else
985 recalculate_watermark(
986 track->id3.bitrate);
991 /* Bail out if no file could be opened */
992 if(abs(steps) > max_steps)
993 return -1;
994 } while ( mpeg_file < 0 );
996 return 0;
999 static void stop_playing(void)
1001 struct trackdata *track;
1003 /* Stop the current stream */
1004 mp3_play_stop();
1005 playing = false;
1006 filling = false;
1008 track = get_trackdata(0);
1009 if (track != NULL)
1010 prev_track_elapsed = track->id3.elapsed;
1012 if(mpeg_file >= 0)
1013 close(mpeg_file);
1014 mpeg_file = -1;
1015 remove_all_tags();
1016 generate_unbuffer_events();
1017 reset_mp3_buffer();
1020 static void end_current_track(void) {
1021 struct trackdata *track;
1023 play_pending = false;
1024 playing = false;
1025 mp3_play_pause(false);
1027 track = get_trackdata(0);
1028 if (track != NULL)
1029 prev_track_elapsed = track->id3.elapsed;
1031 reset_mp3_buffer();
1032 remove_all_tags();
1033 generate_unbuffer_events();
1035 if(mpeg_file >= 0)
1036 close(mpeg_file);
1039 /* Is this a really the end of playback or is a new playlist starting */
1040 static void check_playlist_end(int direction)
1042 /* Use the largest possible step size to account for skipped tracks */
1043 int steps = playlist_amount();
1045 if (direction < 0)
1046 steps = -steps;
1048 if (playlist_next(steps) < 0)
1049 is_playing = false;
1052 static void update_playlist(void)
1054 if (num_tracks_in_memory() > 0)
1056 struct trackdata *track = get_trackdata(0);
1057 track->id3.index = playlist_next(track->id3.index);
1059 else
1061 /* End of playlist? */
1062 check_playlist_end(1);
1065 playlist_update_resume_info(audio_current_track());
1068 static void track_change(void)
1070 DEBUGF("Track change\n");
1072 struct trackdata *track = get_trackdata(0);
1073 prev_track_elapsed = track->id3.elapsed;
1075 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1076 /* Reset the AVC */
1077 sound_set_avc(-1);
1078 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1080 if (num_tracks_in_memory() > 0)
1082 remove_current_tag();
1083 update_playlist();
1084 if (is_playing)
1085 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1088 current_track_counter++;
1091 unsigned long audio_prev_elapsed(void)
1093 return prev_track_elapsed;
1096 #ifdef DEBUG
1097 void hexdump(const unsigned char *buf, int len)
1099 int i;
1101 for(i = 0;i < len;i++)
1103 if(i && (i & 15) == 0)
1105 DEBUGF("\n");
1107 DEBUGF("%02x ", buf[i]);
1109 DEBUGF("\n");
1111 #endif /* DEBUG */
1113 static void start_playback_if_ready(void)
1115 int playable_space;
1117 playable_space = audiobuf_swapwrite - audiobuf_read;
1118 if(playable_space < 0)
1119 playable_space += audiobuflen;
1121 /* See if we have started playing yet. If not, do it. */
1122 if(play_pending || dma_underrun)
1124 /* If the filling has stopped, and we still haven't reached
1125 the watermark, the file must be smaller than the
1126 watermark. We must still play it. */
1127 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1128 !filling || dma_underrun)
1130 DEBUGF("P\n");
1131 if (play_pending) /* don't do this when recovering from DMA underrun */
1133 generate_postbuffer_events(); /* signal first track as buffered */
1134 if (play_pending_track_change)
1136 play_pending_track_change = false;
1137 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1139 play_pending = false;
1141 playing = true;
1143 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1144 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1145 dma_underrun = false;
1147 if (!paused)
1149 last_dma_tick = current_tick;
1150 mp3_play_pause(true);
1153 /* Tell ourselves that we need more data */
1154 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1159 static bool swap_one_chunk(void)
1161 int free_space_left;
1162 int amount_to_swap;
1164 free_space_left = get_unswapped_space();
1166 if(free_space_left == 0 && !play_pending)
1167 return false;
1169 /* Swap in larger chunks when the user is waiting for the playback
1170 to start, or when there is dangerously little playable data left */
1171 if(play_pending)
1172 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1173 else
1175 if(get_playable_space() < low_watermark)
1176 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1177 free_space_left);
1178 else
1179 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1182 if(audiobuf_write < audiobuf_swapwrite)
1183 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1184 amount_to_swap);
1185 else
1186 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1187 amount_to_swap);
1189 bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap);
1191 audiobuf_swapwrite += amount_to_swap;
1192 if(audiobuf_swapwrite >= audiobuflen)
1194 audiobuf_swapwrite = 0;
1197 return true;
1200 static void mpeg_thread(void)
1202 static int pause_tick = 0;
1203 static unsigned int pause_track = 0;
1204 struct queue_event ev;
1205 int len;
1206 int free_space_left;
1207 int unplayed_space_left;
1208 int amount_to_read;
1209 int t1, t2;
1210 int start_offset;
1211 #if CONFIG_CODEC == MAS3587F
1212 int amount_to_save;
1213 int save_endpos = 0;
1214 int rc;
1215 int level;
1216 long offset;
1217 #endif /* CONFIG_CODEC == MAS3587F */
1219 is_playing = false;
1220 play_pending = false;
1221 playing = false;
1222 mpeg_file = -1;
1224 while(1)
1226 #if CONFIG_CODEC == MAS3587F
1227 if(mpeg_mode == MPEG_DECODER)
1229 #endif /* CONFIG_CODEC == MAS3587F */
1230 yield();
1232 /* Swap if necessary, and don't block on the queue_wait() */
1233 if(swap_one_chunk())
1235 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1237 else if (playing)
1239 /* periodically update resume info */
1240 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1242 else
1244 DEBUGF("S R:%x W:%x SW:%x\n",
1245 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1246 queue_wait(&mpeg_queue, &ev);
1249 start_playback_if_ready();
1251 switch(ev.id)
1253 case MPEG_PLAY:
1254 DEBUGF("MPEG_PLAY\n");
1256 #if CONFIG_TUNER
1257 /* Silence the A/D input, it may be on because the radio
1258 may be playing */
1259 mas_codec_writereg(6, 0x0000);
1260 #endif /* CONFIG_TUNER */
1262 /* Stop the current stream */
1263 paused = false;
1264 end_current_track();
1266 if ( new_file(0) == -1 )
1268 is_playing = false;
1269 track_change();
1270 break;
1273 start_offset = (int)ev.data;
1275 /* mid-song resume? */
1276 if (start_offset) {
1277 struct mp3entry* id3 = &get_trackdata(0)->id3;
1278 lseek(mpeg_file, start_offset, SEEK_SET);
1279 id3->offset = start_offset;
1280 set_elapsed(id3);
1282 else {
1283 /* skip past id3v2 tag */
1284 lseek(mpeg_file,
1285 get_trackdata(0)->id3.first_frame_offset,
1286 SEEK_SET);
1290 /* Make it read more data */
1291 filling = true;
1292 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1294 /* Tell the file loading code that we want to start playing
1295 as soon as we have some data */
1296 play_pending = true;
1297 play_pending_track_change = true;
1299 update_playlist();
1300 current_track_counter++;
1301 break;
1303 case MPEG_STOP:
1304 DEBUGF("MPEG_STOP\n");
1305 is_playing = false;
1306 paused = false;
1308 if (playing)
1309 playlist_update_resume_info(audio_current_track());
1311 stop_playing();
1312 mpeg_stop_done = true;
1313 break;
1315 case MPEG_PAUSE:
1316 DEBUGF("MPEG_PAUSE\n");
1317 /* Stop the current stream */
1318 if (playing)
1319 playlist_update_resume_info(audio_current_track());
1320 paused = true;
1321 playing = false;
1322 pause_tick = current_tick;
1323 pause_track = current_track_counter;
1324 mp3_play_pause(false);
1325 break;
1327 case MPEG_RESUME:
1328 DEBUGF("MPEG_RESUME\n");
1329 /* Continue the current stream */
1330 paused = false;
1331 if (!play_pending)
1333 playing = true;
1334 if ( current_track_counter == pause_track )
1335 last_dma_tick += current_tick - pause_tick;
1336 else
1337 last_dma_tick = current_tick;
1338 pause_tick = 0;
1339 mp3_play_pause(true);
1341 break;
1343 case MPEG_NEXT:
1344 DEBUGF("MPEG_NEXT\n");
1345 /* is next track in ram? */
1346 if ( num_tracks_in_memory() > 1 ) {
1347 int unplayed_space_left, unswapped_space_left;
1349 /* stop the current stream */
1350 play_pending = false;
1351 playing = false;
1352 mp3_play_pause(false);
1354 track_change();
1355 audiobuf_read = get_trackdata(0)->mempos;
1356 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1357 mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1358 dma_underrun = false;
1359 last_dma_tick = current_tick;
1361 unplayed_space_left = get_unplayed_space();
1362 unswapped_space_left = get_unswapped_space();
1364 /* should we start reading more data? */
1365 if(!filling && (unplayed_space_left < low_watermark)) {
1366 filling = true;
1367 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1368 play_pending = true;
1369 } else if(unswapped_space_left &&
1370 unswapped_space_left > unplayed_space_left) {
1371 /* Stop swapping the data from the previous file */
1372 audiobuf_swapwrite = audiobuf_read;
1373 play_pending = true;
1374 } else {
1375 playing = true;
1376 if (!paused)
1377 mp3_play_pause(true);
1380 else {
1381 if (!playlist_check(1))
1382 break;
1384 /* stop the current stream */
1385 end_current_track();
1387 if (new_file(1) < 0) {
1388 DEBUGF("No more files to play\n");
1389 filling = false;
1391 check_playlist_end(1);
1392 current_track_counter++;
1393 } else {
1394 /* Make it read more data */
1395 filling = true;
1396 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1398 /* Tell the file loading code that we want
1399 to start playing as soon as we have some data */
1400 play_pending = true;
1401 play_pending_track_change = true;
1403 update_playlist();
1404 current_track_counter++;
1407 break;
1409 case MPEG_PREV: {
1410 DEBUGF("MPEG_PREV\n");
1412 if (!playlist_check(-1))
1413 break;
1415 /* stop the current stream */
1416 end_current_track();
1418 /* Open the next file */
1419 if (new_file(-1) < 0) {
1420 DEBUGF("No more files to play\n");
1421 filling = false;
1423 check_playlist_end(-1);
1424 current_track_counter++;
1425 } else {
1426 /* Make it read more data */
1427 filling = true;
1428 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1430 /* Tell the file loading code that we want to
1431 start playing as soon as we have some data */
1432 play_pending = true;
1433 play_pending_track_change = true;
1435 update_playlist();
1436 current_track_counter++;
1438 break;
1441 case MPEG_FF_REWIND: {
1442 struct mp3entry *id3 = audio_current_track();
1443 unsigned int oldtime = id3->elapsed;
1444 unsigned int newtime = (unsigned int)ev.data;
1445 int curpos, newpos, diffpos;
1446 DEBUGF("MPEG_FF_REWIND\n");
1448 id3->elapsed = newtime;
1450 newpos = audio_get_file_pos();
1451 if(newpos < 0)
1453 id3->elapsed = oldtime;
1454 break;
1457 if (mpeg_file >= 0)
1458 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1459 else
1460 curpos = id3->filesize;
1462 if (num_tracks_in_memory() > 1)
1464 /* We have started loading other tracks that need to be
1465 accounted for */
1466 struct trackdata *track;
1467 int i = 0;
1469 while((track = get_trackdata(i++)))
1471 curpos += track->id3.filesize;
1475 diffpos = curpos - newpos;
1477 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1479 int unplayed_space_left, unswapped_space_left;
1481 /* We are changing to a position that's already in
1482 memory, so we just move the DMA read pointer. */
1483 audiobuf_read = audiobuf_write - diffpos;
1484 if (audiobuf_read < 0)
1486 audiobuf_read += audiobuflen;
1489 unplayed_space_left = get_unplayed_space();
1490 unswapped_space_left = get_unswapped_space();
1492 /* If unswapped_space_left is larger than
1493 unplayed_space_left, it means that the swapwrite pointer
1494 hasn't yet advanced up to the new location of the read
1495 pointer. We just move it, there is no need to swap
1496 data that won't be played anyway. */
1498 if (unswapped_space_left > unplayed_space_left)
1500 DEBUGF("Moved swapwrite\n");
1501 audiobuf_swapwrite = audiobuf_read;
1502 play_pending = true;
1505 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1507 /* We need to load more data before starting */
1508 filling = true;
1509 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1510 play_pending = true;
1512 else
1514 /* resume will start at new position */
1515 last_dma_chunk_size =
1516 MIN(0x2000, get_unplayed_space_current_song());
1517 mp3_play_data(mpeg_audiobuf + audiobuf_read,
1518 last_dma_chunk_size, transfer_end);
1519 dma_underrun = false;
1522 else
1524 /* Move to the new position in the file and start
1525 loading data */
1526 reset_mp3_buffer();
1528 if (num_tracks_in_memory() > 1)
1530 /* We have to reload the current track */
1531 close(mpeg_file);
1532 remove_all_non_current_tags();
1533 generate_unbuffer_events();
1534 mpeg_file = -1;
1537 if (mpeg_file < 0)
1539 mpeg_file = open(id3->path, O_RDONLY);
1540 if (mpeg_file < 0)
1542 id3->elapsed = oldtime;
1543 break;
1547 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1549 id3->elapsed = oldtime;
1550 break;
1553 filling = true;
1554 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1556 /* Tell the file loading code that we want to start playing
1557 as soon as we have some data */
1558 play_pending = true;
1561 id3->offset = newpos;
1563 break;
1566 case MPEG_FLUSH_RELOAD: {
1567 int numtracks = num_tracks_in_memory();
1568 bool reload_track = false;
1570 if (numtracks > 1)
1572 /* Reset the buffer */
1573 audiobuf_write = get_trackdata(1)->mempos;
1575 /* Reset swapwrite unless we're still swapping current
1576 track */
1577 if (get_unplayed_space() <= get_playable_space())
1578 audiobuf_swapwrite = audiobuf_write;
1580 close(mpeg_file);
1581 remove_all_non_current_tags();
1582 generate_unbuffer_events();
1583 mpeg_file = -1;
1584 reload_track = true;
1586 else if (numtracks == 1 && mpeg_file < 0)
1588 reload_track = true;
1591 if(reload_track && new_file(1) >= 0)
1593 /* Tell ourselves that we want more data */
1594 filling = true;
1595 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1598 break;
1601 case MPEG_NEED_DATA:
1602 free_space_left = audiobuf_read - audiobuf_write;
1604 /* We interpret 0 as "empty buffer" */
1605 if(free_space_left <= 0)
1606 free_space_left += audiobuflen;
1608 unplayed_space_left = audiobuflen - free_space_left;
1610 /* Make sure that we don't fill the entire buffer */
1611 free_space_left -= MPEG_HIGH_WATER;
1613 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1614 generate_unbuffer_events();
1616 /* do we have any more buffer space to fill? */
1617 if(free_space_left <= 0)
1619 DEBUGF("0\n");
1620 filling = false;
1621 generate_postbuffer_events();
1622 storage_sleep();
1623 break;
1626 /* Read small chunks while we are below the low water mark */
1627 if(unplayed_space_left < low_watermark)
1628 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1629 free_space_left);
1630 else
1631 amount_to_read = free_space_left;
1633 /* Don't read more than until the end of the buffer */
1634 amount_to_read = MIN(audiobuflen - audiobuf_write,
1635 amount_to_read);
1636 #if (CONFIG_STORAGE & STORAGE_MMC)
1637 /* MMC is slow, so don't read too large chunks */
1638 amount_to_read = MIN(0x40000, amount_to_read);
1639 #elif MEMORYSIZE == 8
1640 amount_to_read = MIN(0x100000, amount_to_read);
1641 #endif
1643 /* Read as much mpeg data as we can fit in the buffer */
1644 if(mpeg_file >= 0)
1646 DEBUGF("R\n");
1647 t1 = current_tick;
1648 len = read(mpeg_file, mpeg_audiobuf + audiobuf_write,
1649 amount_to_read);
1650 if(len > 0)
1652 t2 = current_tick;
1653 DEBUGF("time: %d\n", t2 - t1);
1654 DEBUGF("R: %x\n", len);
1656 /* Now make sure that we don't feed the MAS with ID3V1
1657 data */
1658 if (len < amount_to_read)
1660 int i;
1661 static const unsigned char tag[] = "TAG";
1662 int taglen = 128;
1663 int tagptr = audiobuf_write + len - 128;
1665 /* Really rare case: entire potential tag wasn't
1666 read in this call AND audiobuf_write < 128 */
1667 if (tagptr < 0)
1668 tagptr += audiobuflen;
1670 for(i = 0;i < 3;i++)
1672 if(tagptr >= audiobuflen)
1673 tagptr -= audiobuflen;
1675 if(mpeg_audiobuf[tagptr] != tag[i])
1677 taglen = 0;
1678 break;
1681 tagptr++;
1684 if(taglen)
1686 /* Skip id3v1 tag */
1687 DEBUGF("Skipping ID3v1 tag\n");
1688 len -= taglen;
1690 /* In the very rare case when the entire tag
1691 wasn't read in this read() len will be < 0.
1692 Take care of this when changing the write
1693 pointer. */
1697 audiobuf_write += len;
1699 if (audiobuf_write < 0)
1700 audiobuf_write += audiobuflen;
1702 if(audiobuf_write >= audiobuflen)
1704 audiobuf_write = 0;
1705 DEBUGF("W\n");
1708 /* Tell ourselves that we want more data */
1709 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1711 else
1713 if(len < 0)
1715 DEBUGF("MPEG read error\n");
1718 close(mpeg_file);
1719 mpeg_file = -1;
1721 if(new_file(1) < 0)
1723 /* No more data to play */
1724 DEBUGF("No more files to play\n");
1725 filling = false;
1727 else
1729 /* Tell ourselves that we want more data */
1730 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1734 break;
1736 case MPEG_TRACK_CHANGE:
1737 track_change();
1738 break;
1740 #ifndef USB_NONE
1741 case SYS_USB_CONNECTED:
1742 is_playing = false;
1743 paused = false;
1744 stop_playing();
1746 /* Tell the USB thread that we are safe */
1747 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1748 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1750 /* Wait until the USB cable is extracted again */
1751 usb_wait_for_disconnect(&mpeg_queue);
1752 break;
1753 #endif /* !USB_NONE */
1755 #if CONFIG_CODEC == MAS3587F
1756 case MPEG_INIT_RECORDING:
1757 init_recording();
1758 init_recording_done = true;
1759 break;
1760 #endif /* CONFIG_CODEC == MAS3587F */
1762 case SYS_TIMEOUT:
1763 if (playing)
1764 playlist_update_resume_info(audio_current_track());
1765 break;
1767 #if CONFIG_CODEC == MAS3587F
1769 else
1771 queue_wait(&mpeg_queue, &ev);
1772 switch(ev.id)
1774 case MPEG_RECORD:
1775 if (is_prerecording)
1777 int startpos;
1779 /* Go back prerecord_count seconds in the buffer */
1780 startpos = prerecord_index - prerecord_count;
1781 if(startpos < 0)
1782 startpos += prerecording_max_seconds;
1784 /* Read the position data from the prerecord buffer */
1785 frame_count_start = prerecord_buffer[startpos].framecount;
1786 startpos = prerecord_buffer[startpos].mempos;
1788 DEBUGF("Start looking at address %x (%x)\n",
1789 mpeg_audiobuf+startpos, startpos);
1791 saved_header = mpeg_get_last_header();
1793 mem_find_next_frame(startpos, &offset, 1800,
1794 saved_header, mpeg_audiobuf,
1795 audiobuflen);
1797 audiobuf_read = startpos + offset;
1798 if(audiobuf_read >= audiobuflen)
1799 audiobuf_read -= audiobuflen;
1801 DEBUGF("New audiobuf_read address: %x (%x)\n",
1802 mpeg_audiobuf+audiobuf_read, audiobuf_read);
1804 level = disable_irq_save();
1805 num_rec_bytes = get_unsaved_space();
1806 restore_irq(level);
1808 else
1810 frame_count_start = 0;
1811 num_rec_bytes = 0;
1812 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1813 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1816 prepend_header();
1817 DEBUGF("Recording...\n");
1818 start_recording();
1820 /* Wait until at least one frame is encoded and get the
1821 frame header, for later use by the Xing header
1822 generation */
1823 sleep(HZ/5);
1824 saved_header = mpeg_get_last_header();
1826 /* delayed until buffer is saved, don't open yet */
1827 strcpy(delayed_filename, recording_filename);
1828 mpeg_file = -1;
1830 break;
1832 case MPEG_STOP:
1833 DEBUGF("MPEG_STOP\n");
1835 stop_recording();
1837 /* Save the remaining data in the buffer */
1838 save_endpos = audiobuf_write;
1839 saving_status = STOP_RECORDING;
1840 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1841 break;
1843 case MPEG_STOP_DONE:
1844 DEBUGF("MPEG_STOP_DONE\n");
1846 if (mpeg_file >= 0)
1847 close(mpeg_file);
1848 mpeg_file = -1;
1850 update_header();
1851 #ifdef DEBUG1
1853 int i;
1854 for(i = 0;i < 512;i++)
1856 DEBUGF("%d - %d us (%d bytes)\n",
1857 timing_info[i*2],
1858 (timing_info[i*2+1] & 0xffff) *
1859 10000 / 13824,
1860 timing_info[i*2+1] >> 16);
1863 #endif /* DEBUG1 */
1865 if (prerecording)
1867 start_prerecording();
1869 mpeg_stop_done = true;
1870 break;
1872 case MPEG_NEW_FILE:
1873 /* Bail out when a more important save is happening */
1874 if (saving_status > NEW_FILE)
1875 break;
1877 /* Make sure we have at least one complete frame
1878 in the buffer. If we haven't recorded a single
1879 frame within 200ms, the MAS is probably not recording
1880 anything, and we bail out. */
1881 amount_to_save = get_unsaved_space();
1882 if (amount_to_save < 1800)
1884 sleep(HZ/5);
1885 amount_to_save = get_unsaved_space();
1888 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1889 &frame_count_end, 1);
1891 last_rec_time = current_tick - record_start_time;
1892 record_start_time = current_tick;
1893 if (paused)
1894 pause_start_time = record_start_time;
1896 /* capture all values at one point */
1897 level = disable_irq_save();
1898 save_endpos = audiobuf_write;
1899 last_rec_bytes = num_rec_bytes;
1900 num_rec_bytes = 0;
1901 restore_irq(level);
1903 if (amount_to_save >= 1800)
1905 /* Now find a frame boundary to split at */
1906 save_endpos -= 1800;
1907 if (save_endpos < 0)
1908 save_endpos += audiobuflen;
1910 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1911 saved_header, mpeg_audiobuf,
1912 audiobuflen);
1913 if (!rc) /* No header found, save whole buffer */
1914 offset = 1800;
1916 save_endpos += offset;
1917 if (save_endpos >= audiobuflen)
1918 save_endpos -= audiobuflen;
1920 last_rec_bytes += offset - 1800;
1921 level = disable_irq_save();
1922 num_rec_bytes += 1800 - offset;
1923 restore_irq(level);
1926 saving_status = NEW_FILE;
1927 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1928 break;
1930 case MPEG_SAVE_DATA:
1931 if (saving_status == BUFFER_FULL)
1932 save_endpos = audiobuf_write;
1934 if (mpeg_file < 0) /* delayed file open */
1936 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
1938 if (mpeg_file < 0)
1939 panicf("recfile: %d", mpeg_file);
1942 amount_to_save = save_endpos - audiobuf_read;
1943 if (amount_to_save < 0)
1944 amount_to_save += audiobuflen;
1946 amount_to_save = MIN(amount_to_save,
1947 audiobuflen - audiobuf_read);
1948 #if (CONFIG_STORAGE & STORAGE_MMC)
1949 /* MMC is slow, so don't save too large chunks at once */
1950 amount_to_save = MIN(0x40000, amount_to_save);
1951 #elif MEMORYSIZE == 8
1952 amount_to_save = MIN(0x100000, amount_to_save);
1953 #endif
1954 rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read,
1955 amount_to_save);
1956 if (rc < 0)
1958 if (errno == ENOSPC)
1960 mpeg_errno = AUDIOERR_DISK_FULL;
1961 stop_recording();
1962 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1963 /* will close the file */
1964 break;
1966 else
1967 panicf("rec wrt: %d", rc);
1970 audiobuf_read += amount_to_save;
1971 if (audiobuf_read >= audiobuflen)
1972 audiobuf_read = 0;
1974 if (audiobuf_read == save_endpos) /* all saved */
1976 switch (saving_status)
1978 case BUFFER_FULL:
1979 rc = fsync(mpeg_file);
1980 if (rc < 0)
1981 panicf("rec fls: %d", rc);
1982 storage_sleep();
1983 break;
1985 case NEW_FILE:
1986 /* Close the current file */
1987 rc = close(mpeg_file);
1988 if (rc < 0)
1989 panicf("rec cls: %d", rc);
1990 mpeg_file = -1;
1991 update_header();
1992 storage_sleep();
1994 /* copy new filename */
1995 strcpy(delayed_filename, recording_filename);
1996 prepend_header();
1997 frame_count_start = frame_count_end;
1998 break;
2000 case STOP_RECORDING:
2001 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
2002 /* will close the file */
2003 break;
2005 default:
2006 break;
2008 saving_status = NOT_SAVING;
2010 else /* tell ourselves to save the next chunk */
2011 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
2013 break;
2015 case MPEG_PRERECORDING_TICK:
2016 if(!is_prerecording)
2017 break;
2019 /* Store the write pointer every second */
2020 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2021 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2022 &prerecord_buffer[prerecord_index].framecount, 1);
2024 /* Wrap if necessary */
2025 if(++prerecord_index == prerecording_max_seconds)
2026 prerecord_index = 0;
2028 /* Update the number of seconds recorded */
2029 if(prerecord_count < prerecording_max_seconds)
2030 prerecord_count++;
2031 break;
2033 case MPEG_INIT_PLAYBACK:
2034 /* Stop the prerecording */
2035 stop_recording();
2036 reset_mp3_buffer();
2037 mp3_play_init();
2038 init_playback_done = true;
2039 break;
2041 case MPEG_PAUSE_RECORDING:
2042 pause_recording();
2043 break;
2045 case MPEG_RESUME_RECORDING:
2046 resume_recording();
2047 break;
2049 case SYS_USB_CONNECTED:
2050 /* We can safely go to USB mode if no recording
2051 is taking place */
2052 if((!is_recording || is_prerecording) && mpeg_stop_done)
2054 /* Even if we aren't recording, we still call this
2055 function, to put the MAS in monitoring mode,
2056 to save power. */
2057 stop_recording();
2059 /* Tell the USB thread that we are safe */
2060 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2061 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2063 /* Wait until the USB cable is extracted again */
2064 usb_wait_for_disconnect(&mpeg_queue);
2066 break;
2069 #endif /* CONFIG_CODEC == MAS3587F */
2072 #endif /* !SIMULATOR */
2074 struct mp3entry* audio_current_track(void)
2076 #ifdef SIMULATOR
2077 struct mp3entry *id3 = &taginfo;
2078 #else /* !SIMULATOR */
2079 if(num_tracks_in_memory())
2081 struct mp3entry *id3 = &get_trackdata(0)->id3;
2082 #endif
2083 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2085 checked_for_cuesheet = true; /* only check once per track */
2086 char cuepath[MAX_PATH];
2088 if (look_for_cuesheet_file(id3->path, cuepath) &&
2089 parse_cuesheet(cuepath, curr_cuesheet))
2091 id3->cuesheet = curr_cuesheet;
2094 return id3;
2095 #ifndef SIMULATOR
2097 else
2098 return NULL;
2099 #endif /* !SIMULATOR */
2102 struct mp3entry* audio_next_track(void)
2104 #ifdef SIMULATOR
2105 return &taginfo;
2106 #else /* !SIMULATOR */
2107 if(num_tracks_in_memory() > 1)
2108 return &get_trackdata(1)->id3;
2109 else
2110 return NULL;
2111 #endif /* !SIMULATOR */
2114 #if CONFIG_CODEC == MAS3587F
2115 #ifndef SIMULATOR
2116 void audio_init_playback(void)
2118 init_playback_done = false;
2119 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2121 while(!init_playback_done)
2122 sleep(1);
2126 /****************************************************************************
2127 * Recording functions
2128 ***************************************************************************/
2129 void audio_init_recording(unsigned int buffer_offset)
2131 buffer_offset = buffer_offset;
2132 init_recording_done = false;
2133 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2135 while(!init_recording_done)
2136 sleep(1);
2139 static void init_recording(void)
2141 unsigned long val;
2142 int rc;
2144 /* Disable IRQ6 */
2145 IPRB &= 0xff0f;
2147 stop_playing();
2148 is_playing = false;
2149 paused = false;
2151 /* Init the recording variables */
2152 is_recording = false;
2153 is_prerecording = false;
2155 mpeg_stop_done = true;
2157 mas_reset();
2159 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2160 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2161 if(rc < 0)
2162 panicf("mas_ctrl_w: %d", rc);
2164 /* Stop the current application */
2165 val = 0;
2166 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2169 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2170 } while(val);
2172 /* Perform black magic as described by the data sheet */
2173 if((mas_version_code & 0x0fff) == 0x0102)
2175 DEBUGF("Performing MAS black magic for B2 version\n");
2176 mas_writereg(0xa3, 0x98);
2177 mas_writereg(0x94, 0xfffff);
2178 val = 0;
2179 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2180 mas_writereg(0xa3, 0x90);
2183 /* Enable A/D Converters */
2184 shadow_codec_reg0 = 0xcccd;
2185 mas_codec_writereg(0x0, shadow_codec_reg0);
2187 /* Copy left channel to right (mono mode) */
2188 mas_codec_writereg(8, 0x8000);
2190 /* ADC scale 0%, DSP scale 100%
2191 We use the DSP output for monitoring, because it works with all
2192 sources including S/PDIF */
2193 mas_codec_writereg(6, 0x0000);
2194 mas_codec_writereg(7, 0x4000);
2196 /* No mute */
2197 shadow_soft_mute = 0;
2198 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2200 #ifdef HAVE_SPDIF_OUT
2201 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2202 #else
2203 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2204 #endif
2205 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2207 /* Set Demand mode, monitoring OFF and validate all settings */
2208 shadow_io_control_main = 0x125;
2209 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2211 /* Start the encoder application */
2212 val = 0x40;
2213 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2216 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2217 } while(!(val & 0x40));
2219 /* We have started the recording application with monitoring OFF.
2220 This is because we want to record at least one frame to fill the DMA
2221 buffer, because the silly MAS will not negate EOD until at least one
2222 DMA transfer has taken place.
2223 Now let's wait for some data to be encoded. */
2224 sleep(HZ/5);
2226 /* Now set it to Monitoring mode as default, saves power */
2227 shadow_io_control_main = 0x525;
2228 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2230 /* Wait until the DSP has accepted the settings */
2233 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2234 } while(val & 1);
2236 drain_dma_buffer();
2237 mpeg_mode = MPEG_ENCODER;
2239 DEBUGF("MAS Recording application started\n");
2241 /* At this point, all settings are the reset MAS defaults, next thing is to
2242 call mpeg_set_recording_options(). */
2245 void audio_record(const char *filename)
2247 mpeg_errno = 0;
2249 strlcpy(recording_filename, filename, MAX_PATH);
2251 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2254 void audio_pause_recording(void)
2256 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2259 void audio_resume_recording(void)
2261 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2264 static void prepend_header(void)
2266 int startpos;
2267 unsigned i;
2269 /* Make room for header */
2270 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2271 if(audiobuf_read < 0)
2273 /* Clear the bottom half */
2274 memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2276 /* And the top half */
2277 audiobuf_read += audiobuflen;
2278 memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2280 else
2282 memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2284 /* Copy the empty ID3 header */
2285 startpos = audiobuf_read;
2286 for(i = 0; i < sizeof(empty_id3_header); i++)
2288 mpeg_audiobuf[startpos++] = empty_id3_header[i];
2289 if(startpos == audiobuflen)
2290 startpos = 0;
2294 static void update_header(void)
2296 int fd, framelen;
2297 unsigned long frames;
2299 if (last_rec_bytes > 0)
2301 /* Create the Xing header */
2302 fd = open(delayed_filename, O_RDWR);
2303 if (fd < 0)
2304 panicf("rec upd: %d (%s)", fd, recording_filename);
2306 frames = frame_count_end - frame_count_start;
2307 /* If the number of recorded frames has reached 0x7ffff,
2308 we can no longer trust it */
2309 if (frame_count_end == 0x7ffff)
2310 frames = 0;
2312 /* saved_header is saved right before stopping the MAS */
2313 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2314 frames, last_rec_time * (1000/HZ),
2315 saved_header, NULL, false,
2316 mpeg_audiobuf, audiobuflen);
2318 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2319 write(fd, xing_buffer, framelen);
2320 close(fd);
2324 static void start_prerecording(void)
2326 unsigned long val;
2328 DEBUGF("Starting prerecording\n");
2330 prerecord_index = 0;
2331 prerecord_count = 0;
2332 prerecord_timeout = current_tick + HZ;
2333 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2334 reset_mp3_buffer();
2336 is_prerecording = true;
2338 /* Stop monitoring and start the encoder */
2339 shadow_io_control_main &= ~(1 << 10);
2340 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2341 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2343 /* Wait until the DSP has accepted the settings */
2346 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2347 } while(val & 1);
2349 is_recording = true;
2350 saving_status = NOT_SAVING;
2352 demand_irq_enable(true);
2355 static void start_recording(void)
2357 unsigned long val;
2359 if(is_prerecording)
2361 /* This will make the IRQ handler start recording
2362 for real, i.e send MPEG_SAVE_DATA messages when
2363 the buffer is full */
2364 is_prerecording = false;
2366 else
2368 /* If prerecording is off, we need to stop the monitoring
2369 and start the encoder */
2370 shadow_io_control_main &= ~(1 << 10);
2371 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2372 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2374 /* Wait until the DSP has accepted the settings */
2377 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2378 } while(val & 1);
2381 is_recording = true;
2382 saving_status = NOT_SAVING;
2383 paused = false;
2385 /* Store the current time */
2386 if(prerecording)
2387 record_start_time = current_tick - prerecord_count * HZ;
2388 else
2389 record_start_time = current_tick;
2391 pause_start_time = 0;
2393 demand_irq_enable(true);
2396 static void pause_recording(void)
2398 pause_start_time = current_tick;
2400 /* Set the pause bit */
2401 shadow_soft_mute |= 2;
2402 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2404 paused = true;
2407 static void resume_recording(void)
2409 paused = false;
2411 /* Clear the pause bit */
2412 shadow_soft_mute &= ~2;
2413 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2415 /* Compensate for the time we have been paused */
2416 if(pause_start_time)
2418 record_start_time =
2419 current_tick - (pause_start_time - record_start_time);
2420 pause_start_time = 0;
2424 static void stop_recording(void)
2426 unsigned long val;
2428 /* Let it finish the last frame */
2429 if(!paused)
2430 pause_recording();
2431 sleep(HZ/5);
2433 demand_irq_enable(false);
2435 is_recording = false;
2436 is_prerecording = false;
2438 last_rec_bytes = num_rec_bytes;
2439 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2440 last_rec_time = current_tick - record_start_time;
2442 /* Start monitoring */
2443 shadow_io_control_main |= (1 << 10);
2444 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2445 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2447 /* Wait until the DSP has accepted the settings */
2450 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2451 } while(val & 1);
2453 resume_recording();
2456 void audio_set_recording_options(struct audio_recording_options *options)
2458 bool is_mpeg1;
2460 is_mpeg1 = (options->rec_frequency < 3);
2462 rec_version_index = is_mpeg1?3:2;
2463 rec_frequency_index = options->rec_frequency % 3;
2465 shadow_encoder_control = (options->rec_quality << 17) |
2466 (rec_frequency_index << 10) |
2467 ((is_mpeg1?1:0) << 9) |
2468 (((options->rec_channels * 2 + 1) & 3) << 6) |
2469 (1 << 5) /* MS-stereo */ |
2470 (1 << 2) /* Is an original */;
2471 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2473 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2475 #if CONFIG_TUNER & S1A0903X01
2476 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2477 interference with the Samsung tuner. */
2478 if (rec_frequency_index)
2479 mas_store_pllfreq(24576000);
2480 else
2481 mas_store_pllfreq(22579000);
2482 #endif
2484 shadow_soft_mute = options->rec_editable?4:0;
2485 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2487 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2489 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2490 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2491 (1 << 5) | /* SDO strobe invert */
2492 ((is_mpeg1?0:1) << 3) |
2493 (1 << 2) | /* Inverted SIBC clock signal */
2494 1; /* Validate */
2495 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2497 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2499 if(options->rec_source == AUDIO_SRC_MIC)
2501 /* Copy left channel to right (mono mode) */
2502 mas_codec_writereg(8, 0x8000);
2504 else
2506 /* Stereo input mode */
2507 mas_codec_writereg(8, 0);
2510 prerecording_max_seconds = options->rec_prerecord_time;
2511 if(prerecording_max_seconds)
2513 prerecording = true;
2514 start_prerecording();
2516 else
2518 prerecording = false;
2519 is_prerecording = false;
2520 is_recording = false;
2524 /* If use_mic is true, the left gain is used */
2525 void audio_set_recording_gain(int left, int right, int type)
2527 /* Enable both left and right A/D */
2528 shadow_codec_reg0 = (left << 12) |
2529 (right << 8) |
2530 (left << 4) |
2531 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2532 0x0007;
2533 mas_codec_writereg(0x0, shadow_codec_reg0);
2536 /* try to make some kind of beep, also in recording mode */
2537 void audio_beep(int duration)
2539 long starttick = current_tick;
2541 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2542 * While this is still audible even without an external signal,
2543 * it doesn't affect the (pre-)recording. */
2544 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2545 mas_codec_writereg(0, shadow_codec_reg0);
2546 yield();
2548 while (current_tick - starttick < duration);
2551 void audio_new_file(const char *filename)
2553 mpeg_errno = 0;
2555 strlcpy(recording_filename, filename, MAX_PATH);
2557 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2560 unsigned long audio_recorded_time(void)
2562 if(is_prerecording)
2563 return prerecord_count * HZ;
2565 if(is_recording)
2567 if(paused)
2568 return pause_start_time - record_start_time;
2569 else
2570 return current_tick - record_start_time;
2573 return 0;
2576 unsigned long audio_num_recorded_bytes(void)
2578 int num_bytes;
2579 int index;
2581 if(is_recording)
2583 if(is_prerecording)
2585 index = prerecord_index - prerecord_count;
2586 if(index < 0)
2587 index += prerecording_max_seconds;
2589 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2590 if(num_bytes < 0)
2591 num_bytes += audiobuflen;
2593 return num_bytes;
2595 else
2596 return num_rec_bytes;
2598 else
2599 return 0;
2602 #else /* SIMULATOR */
2604 /* dummies coming up */
2606 void audio_init_playback(void)
2608 /* a dummy */
2610 unsigned long audio_recorded_time(void)
2612 /* a dummy */
2613 return 0;
2615 void audio_beep(int duration)
2617 /* a dummy */
2618 (void)duration;
2620 void audio_pause_recording(void)
2622 /* a dummy */
2624 void audio_resume_recording(void)
2626 /* a dummy */
2628 unsigned long audio_num_recorded_bytes(void)
2630 /* a dummy */
2631 return 0;
2633 void audio_record(const char *filename)
2635 /* a dummy */
2636 (void)filename;
2638 void audio_new_file(const char *filename)
2640 /* a dummy */
2641 (void)filename;
2644 void audio_set_recording_gain(int left, int right, int type)
2646 /* a dummy */
2647 (void)left;
2648 (void)right;
2649 (void)type;
2651 void audio_init_recording(unsigned int buffer_offset)
2653 /* a dummy */
2654 (void)buffer_offset;
2656 void audio_set_recording_options(struct audio_recording_options *options)
2658 /* a dummy */
2659 (void)options;
2661 #endif /* SIMULATOR */
2662 #endif /* CONFIG_CODEC == MAS3587F */
2664 #ifndef SIMULATOR
2665 static void audio_reset_buffer(void)
2667 size_t bufsize; /* dont break strict-aliasing */
2668 talk_buffer_steal(); /* will use the mp3 buffer */
2670 /* release buffer on behalf of any audio_get_buffer() caller,
2671 * non-fatal if there was none */
2672 buffer_release_buffer(0);
2673 /* re-aquire */
2674 mpeg_audiobuf = buffer_get_buffer(&bufsize);
2675 audiobuflen = bufsize;
2677 #endif
2679 void audio_play(long offset)
2681 #ifdef SIMULATOR
2682 char name_buf[MAX_PATH+1];
2683 const char* trackname;
2684 int steps=0;
2686 is_playing = true;
2688 do {
2689 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2690 if (!trackname)
2691 break;
2692 if(mp3info(&taginfo, trackname)) {
2693 /* bad mp3, move on */
2694 if(++steps > playlist_amount())
2695 break;
2696 continue;
2698 #ifdef HAVE_MPEG_PLAY
2699 real_mpeg_play(trackname);
2700 #endif
2701 playlist_next(steps);
2702 taginfo.offset = offset;
2703 set_elapsed(&taginfo);
2704 is_playing = true;
2705 playing = true;
2706 break;
2707 } while(1);
2708 #else /* !SIMULATOR */
2709 is_playing = true;
2711 audio_reset_buffer();
2712 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2713 #endif /* !SIMULATOR */
2715 mpeg_errno = 0;
2718 void audio_stop(void)
2720 #ifndef SIMULATOR
2721 if (playing)
2723 struct trackdata *track = get_trackdata(0);
2724 prev_track_elapsed = track->id3.elapsed;
2726 mpeg_stop_done = false;
2727 queue_post(&mpeg_queue, MPEG_STOP, 0);
2728 while(!mpeg_stop_done)
2729 yield();
2730 #else /* SIMULATOR */
2731 paused = false;
2732 is_playing = false;
2733 playing = false;
2734 #endif /* SIMULATOR */
2737 /* dummy */
2738 void audio_stop_recording(void)
2740 audio_stop();
2743 void audio_pause(void)
2745 #ifndef SIMULATOR
2746 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2747 #else /* SIMULATOR */
2748 is_playing = true;
2749 playing = false;
2750 paused = true;
2751 #endif /* SIMULATOR */
2754 void audio_resume(void)
2756 #ifndef SIMULATOR
2757 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2758 #else /* SIMULATOR */
2759 is_playing = true;
2760 playing = true;
2761 paused = false;
2762 #endif /* SIMULATOR */
2765 void audio_next(void)
2767 #ifndef SIMULATOR
2768 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2769 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2770 #else /* SIMULATOR */
2771 char name_buf[MAX_PATH+1];
2772 const char* file;
2773 int steps = 1;
2775 do {
2776 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2777 if(!file)
2778 break;
2779 if(mp3info(&taginfo, file)) {
2780 if(++steps > playlist_amount())
2781 break;
2782 continue;
2784 playlist_next(steps);
2785 current_track_counter++;
2786 is_playing = true;
2787 playing = true;
2788 break;
2789 } while(1);
2790 #endif /* SIMULATOR */
2793 void audio_prev(void)
2795 #ifndef SIMULATOR
2796 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2797 queue_post(&mpeg_queue, MPEG_PREV, 0);
2798 #else /* SIMULATOR */
2799 char name_buf[MAX_PATH+1];
2800 const char* file;
2801 int steps = -1;
2803 do {
2804 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2805 if(!file)
2806 break;
2807 if(mp3info(&taginfo, file)) {
2808 steps--;
2809 continue;
2811 playlist_next(steps);
2812 current_track_counter++;
2813 is_playing = true;
2814 playing = true;
2815 break;
2816 } while(1);
2817 #endif /* SIMULATOR */
2820 void audio_ff_rewind(long newpos)
2822 #ifndef SIMULATOR
2823 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2824 #else /* SIMULATOR */
2825 (void)newpos;
2826 #endif /* SIMULATOR */
2829 void audio_flush_and_reload_tracks(void)
2831 #ifndef SIMULATOR
2832 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2833 #endif /* !SIMULATOR*/
2836 int audio_status(void)
2838 int ret = 0;
2840 if(is_playing)
2841 ret |= AUDIO_STATUS_PLAY;
2843 if(paused)
2844 ret |= AUDIO_STATUS_PAUSE;
2846 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2847 if(is_recording && !is_prerecording)
2848 ret |= AUDIO_STATUS_RECORD;
2850 if(is_prerecording)
2851 ret |= AUDIO_STATUS_PRERECORD;
2852 #endif /* CONFIG_CODEC == MAS3587F */
2854 if(mpeg_errno)
2855 ret |= AUDIO_STATUS_ERROR;
2857 return ret;
2860 /* Unused function
2861 unsigned int audio_error(void)
2863 return mpeg_errno;
2867 void audio_error_clear(void)
2869 mpeg_errno = 0;
2872 #ifdef SIMULATOR
2873 static void mpeg_thread(void)
2875 struct mp3entry* id3;
2876 while ( 1 ) {
2877 if (is_playing) {
2878 id3 = audio_current_track();
2879 if (!paused)
2881 id3->elapsed+=1000;
2882 id3->offset+=1000;
2884 if (id3->elapsed>=id3->length)
2885 audio_next();
2887 sleep(HZ);
2890 #endif /* SIMULATOR */
2892 void audio_init(void)
2894 mpeg_errno = 0;
2895 /* cuesheet support */
2896 if (global_settings.cuesheet)
2897 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2899 #ifndef SIMULATOR
2900 size_t bufsize; /* don't break strict-aliasing */
2901 mpeg_audiobuf = buffer_get_buffer(&bufsize);
2902 audiobuflen = bufsize;
2903 queue_init(&mpeg_queue, true);
2904 #endif /* !SIMULATOR */
2905 create_thread(mpeg_thread, mpeg_stack,
2906 sizeof(mpeg_stack), 0, mpeg_thread_name
2907 IF_PRIO(, PRIORITY_SYSTEM)
2908 IF_COP(, CPU));
2910 memset(trackdata, 0, sizeof(trackdata));
2912 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2913 if (HW_MASK & PR_ACTIVE_HIGH)
2914 and_b(~0x08, &PADRH);
2915 else
2916 or_b(0x08, &PADRH);
2917 #endif /* CONFIG_CODEC == MAS3587F */
2919 #ifdef DEBUG
2920 #ifndef SIMULATOR
2921 dbg_timer_start();
2922 dbg_cnt2us(0);
2923 #endif /* !SIMULATOR */
2924 #endif /* DEBUG */
2927 #endif /* CONFIG_CODEC != SWCODEC */