Rework m4a seek/resume code. Seek/resume does now also work properly with files havin...
[kugel-rb.git] / apps / mpeg.c
blob583e4e2122cffbd6b3457c8fc9f70e6fc1b87a89
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 "sound.h"
41 #include "bitswap.h"
42 #include "appevents.h"
43 #include "playlist.h"
44 #include "cuesheet.h"
45 #include "settings.h"
46 #ifndef SIMULATOR
47 #include "i2c.h"
48 #include "mas35xx.h"
49 #include "system.h"
50 #include "usb.h"
51 #include "file.h"
52 #include "hwcompat.h"
53 #endif /* !SIMULATOR */
54 #ifdef HAVE_LCD_BITMAP
55 #include "lcd.h"
56 #endif /* CONFIG_CODEC != SWCODEC */
58 #define MPEG_SWAP_CHUNKSIZE 0x2000
59 #define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
60 wouldn't be able to see the difference between
61 an empty buffer and a full one. */
62 #define MPEG_LOW_WATER 0x60000
63 #define MPEG_RECORDING_LOW_WATER 0x80000
64 #define MPEG_LOW_WATER_CHUNKSIZE 0x40000
65 #define MPEG_LOW_WATER_SWAP_CHUNKSIZE 0x10000
66 #if (CONFIG_STORAGE & STORAGE_MMC)
67 #define MPEG_PLAY_PENDING_THRESHOLD 0x20000
68 #define MPEG_PLAY_PENDING_SWAPSIZE 0x20000
69 #else
70 #define MPEG_PLAY_PENDING_THRESHOLD 0x10000
71 #define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
72 #endif
74 #define MPEG_MAX_PRERECORD_SECONDS 30
76 /* For ID3 info and VBR header */
77 #define MPEG_RESERVED_HEADER_SPACE (4096 + 576)
79 #ifndef SIMULATOR
80 extern unsigned long mas_version_code;
81 #endif
83 #if CONFIG_CODEC == MAS3587F
84 extern enum /* from mp3_playback.c */
86 MPEG_DECODER,
87 MPEG_ENCODER
88 } mpeg_mode;
89 #endif /* CONFIG_CODEC == MAS3587F */
91 #define MPEG_PLAY 1
92 #define MPEG_STOP 2
93 #define MPEG_PAUSE 3
94 #define MPEG_RESUME 4
95 #define MPEG_NEXT 5
96 #define MPEG_PREV 6
97 #define MPEG_FF_REWIND 7
98 #define MPEG_FLUSH_RELOAD 8
99 #define MPEG_RECORD 9
100 #define MPEG_INIT_RECORDING 10
101 #define MPEG_INIT_PLAYBACK 11
102 #define MPEG_NEW_FILE 12
103 #define MPEG_PAUSE_RECORDING 13
104 #define MPEG_RESUME_RECORDING 14
105 #define MPEG_NEED_DATA 100
106 #define MPEG_TRACK_CHANGE 101
107 #define MPEG_SAVE_DATA 102
108 #define MPEG_STOP_DONE 103
109 #define MPEG_PRERECORDING_TICK 104
111 /* indicator for MPEG_NEED_DATA */
112 #define GENERATE_UNBUFFER_EVENTS 1
114 /* list of tracks in memory */
115 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
116 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
118 struct trackdata
120 struct mp3entry id3;
121 int mempos;
122 int load_ahead_index;
125 static struct trackdata trackdata[MAX_TRACK_ENTRIES];
127 static unsigned int current_track_counter = 0;
129 #ifndef SIMULATOR
130 /* Play time of the previous track */
131 static unsigned long prev_track_elapsed;
133 static int track_read_idx = 0;
134 static int track_write_idx = 0;
135 #endif /* !SIMULATOR */
137 /* Cuesheet support */
138 static struct cuesheet *curr_cuesheet = NULL;
139 static bool checked_for_cuesheet = false;
141 static const char mpeg_thread_name[] = "mpeg";
142 static unsigned int mpeg_errno;
144 static bool playing = false; /* We are playing an MP3 stream */
145 static bool is_playing = false; /* We are (attempting to) playing MP3 files */
146 static bool paused; /* playback is paused */
148 #ifdef SIMULATOR
149 static char mpeg_stack[DEFAULT_STACK_SIZE];
150 static struct mp3entry taginfo;
152 #else /* !SIMULATOR */
153 static struct event_queue mpeg_queue;
154 static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
156 static int audiobuflen;
157 static int audiobuf_write;
158 static int audiobuf_swapwrite;
159 static int audiobuf_read;
161 static int mpeg_file;
163 static bool play_pending; /* We are about to start playing */
164 static bool play_pending_track_change; /* When starting play we're starting a new file */
165 static bool filling; /* We are filling the buffer with data from disk */
166 static bool dma_underrun; /* True when the DMA has stopped because of
167 slow disk reading (read error, shaking) */
168 static bool mpeg_stop_done;
170 static int last_dma_tick = 0;
171 static int last_dma_chunk_size;
173 static long low_watermark; /* Dynamic low watermark level */
174 static long low_watermark_margin = 0; /* Extra time in seconds for watermark */
175 static long lowest_watermark_level; /* Debug value to observe the buffer
176 usage */
177 #if CONFIG_CODEC == MAS3587F
178 static char recording_filename[MAX_PATH]; /* argument to thread */
179 static char delayed_filename[MAX_PATH]; /* internal copy of above */
181 static char xing_buffer[MAX_XING_HEADER_SIZE];
183 static bool init_recording_done;
184 static bool init_playback_done;
185 static bool prerecording; /* True if prerecording is enabled */
186 static bool is_prerecording; /* True if we are prerecording */
187 static bool is_recording; /* We are recording */
189 static enum {
190 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
191 BUFFER_FULL,
192 NEW_FILE,
193 STOP_RECORDING
194 } saving_status;
196 static int rec_frequency_index; /* For create_xing_header() calls */
197 static int rec_version_index; /* For create_xing_header() calls */
199 struct prerecord_info {
200 int mempos;
201 unsigned long framecount;
204 static struct prerecord_info prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
205 static int prerecord_index; /* Current index in the prerecord buffer */
206 static int prerecording_max_seconds; /* Max number of seconds to store */
207 static int prerecord_count; /* Number of seconds in the prerecord buffer */
208 static int prerecord_timeout; /* The tick count of the next prerecord data
209 store */
211 static unsigned long record_start_time; /* Value of current_tick when recording
212 was started */
213 static unsigned long pause_start_time; /* Value of current_tick when pause was
214 started */
215 static unsigned long last_rec_time;
216 static unsigned long num_rec_bytes;
217 static unsigned long last_rec_bytes;
218 static unsigned long frame_count_start;
219 static unsigned long frame_count_end;
220 static unsigned long saved_header = 0;
222 /* Shadow MAS registers */
223 unsigned long shadow_encoder_control = 0;
224 #endif /* CONFIG_CODEC == MAS3587F */
226 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
227 unsigned long shadow_io_control_main = 0;
228 unsigned long shadow_soft_mute = 0;
229 unsigned shadow_codec_reg0;
230 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
232 #ifdef HAVE_RECORDING
233 static const unsigned char empty_id3_header[] =
235 'I', 'D', '3', 0x03, 0x00, 0x00,
236 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
238 #endif /* HAVE_RECORDING */
241 static int get_unplayed_space(void);
242 static int get_playable_space(void);
243 static int get_unswapped_space(void);
244 #endif /* !SIMULATOR */
246 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
247 static void init_recording(void);
248 static void prepend_header(void);
249 static void update_header(void);
250 static void start_prerecording(void);
251 static void start_recording(void);
252 static void stop_recording(void);
253 static int get_unsaved_space(void);
254 static void pause_recording(void);
255 static void resume_recording(void);
256 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
259 #ifndef SIMULATOR
260 static int num_tracks_in_memory(void)
262 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
265 #ifdef DEBUG_TAGS
266 static void debug_tags(void)
268 int i;
270 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
272 DEBUGF("%d - %s\n", i, trackdata[i].id3.path);
274 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
275 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
277 #else /* !DEBUG_TAGS */
278 #define debug_tags()
279 #endif /* !DEBUG_TAGS */
281 static void remove_current_tag(void)
283 if(num_tracks_in_memory() > 0)
285 /* First move the index, so nobody tries to access the tag */
286 track_read_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
287 checked_for_cuesheet = false;
288 debug_tags();
290 else
292 DEBUGF("remove_current_tag: no tracks to remove\n");
296 static void remove_all_non_current_tags(void)
298 track_write_idx = (track_read_idx+1) & MAX_TRACK_ENTRIES_MASK;
299 debug_tags();
302 static void remove_all_tags(void)
304 track_write_idx = track_read_idx;
306 debug_tags();
309 static struct trackdata *get_trackdata(int offset)
311 if(offset >= num_tracks_in_memory())
312 return NULL;
313 else
314 return &trackdata[(track_read_idx + offset) & MAX_TRACK_ENTRIES_MASK];
316 #endif /* !SIMULATOR */
318 /***********************************************************************/
319 /* audio event handling */
321 #define MAX_EVENT_HANDLERS 10
322 struct event_handlers_table
324 AUDIO_EVENT_HANDLER handler;
325 unsigned short mask;
327 static struct event_handlers_table event_handlers[MAX_EVENT_HANDLERS];
328 static int event_handlers_count = 0;
330 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler, unsigned short mask)
332 if (event_handlers_count < MAX_EVENT_HANDLERS)
334 event_handlers[event_handlers_count].handler = handler;
335 event_handlers[event_handlers_count].mask = mask;
336 event_handlers_count++;
340 /* dispatch calls each handler in the order registered and returns after some
341 handler actually handles the event (the event is assumed to no longer be valid
342 after this, due to the handler changing some condition); returns true if someone
343 handled the event, which is expected to cause the caller to skip its own handling
344 of the event */
345 #ifndef SIMULATOR
346 static bool audio_dispatch_event(unsigned short event, unsigned long data)
348 int i = 0;
349 for(i=0; i < event_handlers_count; i++)
351 if ( event_handlers[i].mask & event )
353 int rc = event_handlers[i].handler(event, data);
354 if ( rc == AUDIO_EVENT_RC_HANDLED )
355 return true;
358 return false;
360 #endif
362 /***********************************************************************/
364 static void set_elapsed(struct mp3entry* id3)
366 if ( id3->vbr ) {
367 if ( id3->has_toc ) {
368 /* calculate elapsed time using TOC */
369 int i;
370 unsigned int remainder, plen, relpos, nextpos;
372 /* find wich percent we're at */
373 for (i=0; i<100; i++ )
375 if ( id3->offset < id3->toc[i] * (id3->filesize / 256) )
377 break;
381 i--;
382 if (i < 0)
383 i = 0;
385 relpos = id3->toc[i];
387 if (i < 99)
389 nextpos = id3->toc[i+1];
391 else
393 nextpos = 256;
396 remainder = id3->offset - (relpos * (id3->filesize / 256));
398 /* set time for this percent (divide before multiply to prevent
399 overflow on long files. loss of precision is negligible on
400 short files) */
401 id3->elapsed = i * (id3->length / 100);
403 /* calculate remainder time */
404 plen = (nextpos - relpos) * (id3->filesize / 256);
405 id3->elapsed += (((remainder * 100) / plen) *
406 (id3->length / 10000));
408 else {
409 /* no TOC exists. set a rough estimate using average bitrate */
410 int tpk = id3->length / (id3->filesize / 1024);
411 id3->elapsed = id3->offset / 1024 * tpk;
414 else
415 /* constant bitrate, use exact calculation */
416 id3->elapsed = id3->offset / (id3->bitrate / 8);
419 int audio_get_file_pos(void)
421 int pos = -1;
422 struct mp3entry *id3 = audio_current_track();
424 if (id3->vbr)
426 if (id3->has_toc)
428 /* Use the TOC to find the new position */
429 unsigned int percent, remainder;
430 int curtoc, nexttoc, plen;
432 percent = (id3->elapsed*100)/id3->length;
433 if (percent > 99)
434 percent = 99;
436 curtoc = id3->toc[percent];
438 if (percent < 99)
439 nexttoc = id3->toc[percent+1];
440 else
441 nexttoc = 256;
443 pos = (id3->filesize/256)*curtoc;
445 /* Use the remainder to get a more accurate position */
446 remainder = (id3->elapsed*100)%id3->length;
447 remainder = (remainder*100)/id3->length;
448 plen = (nexttoc - curtoc)*(id3->filesize/256);
449 pos += (plen/100)*remainder;
451 else
453 /* No TOC exists, estimate the new position */
454 pos = (id3->filesize / (id3->length / 1000)) *
455 (id3->elapsed / 1000);
458 else if (id3->bitrate)
459 pos = id3->elapsed * (id3->bitrate / 8);
460 else
462 return -1;
465 if (pos >= (int)(id3->filesize - id3->id3v1len))
467 /* Don't seek right to the end of the file so that we can
468 transition properly to the next song */
469 pos = id3->filesize - id3->id3v1len - 1;
471 else if (pos < (int)id3->first_frame_offset)
473 /* skip past id3v2 tag and other leading garbage */
474 pos = id3->first_frame_offset;
476 return pos;
479 unsigned long mpeg_get_last_header(void)
481 #ifdef SIMULATOR
482 return 0;
483 #else /* !SIMULATOR */
484 unsigned long tmp[2];
486 /* Read the frame data from the MAS and reconstruct it with the
487 frame sync and all */
488 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
489 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
490 #endif /* !SIMULATOR */
493 #ifndef SIMULATOR
494 /* Send callback events to notify about removing old tracks. */
495 static void generate_unbuffer_events(void)
497 int i;
498 int numentries = MAX_TRACK_ENTRIES - num_tracks_in_memory();
499 int cur_idx = track_write_idx;
501 for (i = 0; i < numentries; i++)
503 /* Send an event to notify that track has finished. */
504 send_event(PLAYBACK_EVENT_TRACK_FINISH, &trackdata[cur_idx].id3);
505 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
509 /* Send callback events to notify about new tracks. */
510 static void generate_postbuffer_events(void)
512 int i;
513 int numentries = num_tracks_in_memory();
514 int cur_idx = track_read_idx;
516 for (i = 0; i < numentries; i++)
518 send_event(PLAYBACK_EVENT_TRACK_BUFFER, &trackdata[cur_idx].id3);
519 cur_idx = (cur_idx + 1) & MAX_TRACK_ENTRIES_MASK;
523 static void recalculate_watermark(int bitrate)
525 int bytes_per_sec;
526 int time = storage_spinup_time();
528 /* A bitrate of 0 probably means empty VBR header. We play safe
529 and set a high threshold */
530 if(bitrate == 0)
531 bitrate = 320;
533 bytes_per_sec = bitrate * 1000 / 8;
535 if(time)
537 /* No drive spins up faster than 3.5s */
538 if(time < 350)
539 time = 350;
541 time = time * 3;
542 low_watermark = ((low_watermark_margin * HZ + time) *
543 bytes_per_sec) / HZ;
545 else
547 low_watermark = MPEG_LOW_WATER;
551 #ifdef HAVE_DISK_STORAGE
552 void audio_set_buffer_margin(int setting)
554 low_watermark_margin = setting; /* in seconds */
556 #endif
558 void audio_get_debugdata(struct audio_debug *dbgdata)
560 dbgdata->audiobuflen = audiobuflen;
561 dbgdata->audiobuf_write = audiobuf_write;
562 dbgdata->audiobuf_swapwrite = audiobuf_swapwrite;
563 dbgdata->audiobuf_read = audiobuf_read;
565 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
567 #if CONFIG_CPU == SH7034
568 dbgdata->dma_on = (SCR0 & 0x80) != 0;
569 #endif
570 dbgdata->playing = playing;
571 dbgdata->play_pending = play_pending;
572 dbgdata->is_playing = is_playing;
573 dbgdata->filling = filling;
574 dbgdata->dma_underrun = dma_underrun;
576 dbgdata->unplayed_space = get_unplayed_space();
577 dbgdata->playable_space = get_playable_space();
578 dbgdata->unswapped_space = get_unswapped_space();
580 dbgdata->low_watermark_level = low_watermark;
581 dbgdata->lowest_watermark_level = lowest_watermark_level;
584 #ifdef DEBUG
585 static void dbg_timer_start(void)
587 /* We are using timer 2 */
589 TSTR &= ~0x04; /* Stop the timer */
590 TSNC &= ~0x04; /* No synchronization */
591 TMDR &= ~0x44; /* Operate normally */
593 TCNT2 = 0; /* Start counting at 0 */
594 TCR2 = 0x03; /* Sysclock/8 */
596 TSTR |= 0x04; /* Start timer 2 */
599 static int dbg_cnt2us(unsigned int cnt)
601 return (cnt * 10000) / (FREQ/800);
603 #endif /* DEBUG */
605 static int get_unplayed_space(void)
607 int space = audiobuf_write - audiobuf_read;
608 if (space < 0)
609 space += audiobuflen;
610 return space;
613 static int get_playable_space(void)
615 int space = audiobuf_swapwrite - audiobuf_read;
616 if (space < 0)
617 space += audiobuflen;
618 return space;
621 static int get_unplayed_space_current_song(void)
623 int space;
625 if (num_tracks_in_memory() > 1)
627 space = get_trackdata(1)->mempos - audiobuf_read;
629 else
631 space = audiobuf_write - audiobuf_read;
634 if (space < 0)
635 space += audiobuflen;
637 return space;
640 static int get_unswapped_space(void)
642 int space = audiobuf_write - audiobuf_swapwrite;
643 if (space < 0)
644 space += audiobuflen;
645 return space;
648 #if CONFIG_CODEC == MAS3587F
649 static int get_unsaved_space(void)
651 int space = audiobuf_write - audiobuf_read;
652 if (space < 0)
653 space += audiobuflen;
654 return space;
657 static void drain_dma_buffer(void)
659 while (PBDRH & 0x40)
661 xor_b(0x08, &PADRH);
663 while (PBDRH & 0x80);
665 xor_b(0x08, &PADRH);
667 while (!(PBDRH & 0x80));
671 #ifdef DEBUG
672 static long timing_info_index = 0;
673 static long timing_info[1024];
674 #endif /* DEBUG */
676 void rec_tick (void) __attribute__ ((section (".icode")));
677 void rec_tick(void)
679 int i;
680 int delay;
681 char data;
683 if(is_recording && (PBDRH & 0x40))
685 #ifdef DEBUG
686 timing_info[timing_info_index++] = current_tick;
687 TCNT2 = 0;
688 #endif /* DEBUG */
689 /* Note: Although this loop is run in interrupt context, further
690 * optimisation will do no good. The MAS would then deliver bad
691 * frames occasionally, as observed in extended experiments. */
692 i = 0;
693 while (PBDRH & 0x40) /* We try to read as long as EOD is high */
695 xor_b(0x08, &PADRH); /* Set PR active, independent of polarity */
697 delay = 100;
698 while (PBDRH & 0x80) /* Wait until /RTW becomes active */
700 if (--delay <= 0) /* Bail out if we have to wait too long */
701 { /* i.e. the MAS doesn't want to talk to us */
702 xor_b(0x08, &PADRH); /* Set PR inactive */
703 goto transfer_end; /* and get out of here */
707 data = *(unsigned char *)0x04000000; /* read data byte */
709 xor_b(0x08, &PADRH); /* Set PR inactive */
711 audiobuf[audiobuf_write++] = data;
713 if (audiobuf_write >= audiobuflen)
714 audiobuf_write = 0;
716 i++;
718 transfer_end:
720 #ifdef DEBUG
721 timing_info[timing_info_index++] = TCNT2 + (i << 16);
722 timing_info_index &= 0x3ff;
723 #endif /* DEBUG */
725 num_rec_bytes += i;
727 if(is_prerecording)
729 if(TIME_AFTER(current_tick, prerecord_timeout))
731 prerecord_timeout = current_tick + HZ;
732 queue_post(&mpeg_queue, MPEG_PRERECORDING_TICK, 0);
735 else
737 /* Signal to save the data if we are running out of buffer
738 space */
739 if (audiobuflen - get_unsaved_space() < MPEG_RECORDING_LOW_WATER
740 && saving_status == NOT_SAVING)
742 saving_status = BUFFER_FULL;
743 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
748 #endif /* CONFIG_CODEC == MAS3587F */
750 void playback_tick(void)
752 struct trackdata *ptd = get_trackdata(0);
753 if(ptd)
755 ptd->id3.elapsed += (current_tick - last_dma_tick) * 1000 / HZ;
756 last_dma_tick = current_tick;
757 audio_dispatch_event(AUDIO_EVENT_POS_REPORT,
758 (unsigned long)ptd->id3.elapsed);
762 static void reset_mp3_buffer(void)
764 audiobuf_read = 0;
765 audiobuf_write = 0;
766 audiobuf_swapwrite = 0;
767 lowest_watermark_level = audiobuflen;
770 /* DMA transfer end interrupt callback */
771 static void transfer_end(unsigned char** ppbuf, size_t* psize)
773 if(playing && !paused)
775 int unplayed_space_left;
776 int space_until_end_of_buffer;
777 int track_offset = 1;
778 struct trackdata *track;
780 audiobuf_read += last_dma_chunk_size;
781 if(audiobuf_read >= audiobuflen)
782 audiobuf_read = 0;
784 /* First, check if we are on a track boundary */
785 if (num_tracks_in_memory() > 1)
787 if (audiobuf_read == get_trackdata(track_offset)->mempos)
789 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
791 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
792 track_offset++;
797 unplayed_space_left = get_unplayed_space();
799 space_until_end_of_buffer = audiobuflen - audiobuf_read;
801 if(!filling && unplayed_space_left < low_watermark)
803 filling = true;
804 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
807 if(unplayed_space_left)
809 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
810 last_dma_chunk_size = MIN(last_dma_chunk_size,
811 space_until_end_of_buffer);
813 /* several tracks loaded? */
814 track = get_trackdata(track_offset);
815 if(track)
817 /* will we move across the track boundary? */
818 if (( audiobuf_read < track->mempos ) &&
819 ((audiobuf_read+last_dma_chunk_size) >
820 track->mempos ))
822 /* Make sure that we end exactly on the boundary */
823 last_dma_chunk_size = track->mempos - audiobuf_read;
827 *psize = last_dma_chunk_size & 0xffff;
828 *ppbuf = audiobuf + audiobuf_read;
829 track = get_trackdata(0);
830 if(track)
831 track->id3.offset += last_dma_chunk_size;
833 /* Update the watermark debug level */
834 if(unplayed_space_left < lowest_watermark_level)
835 lowest_watermark_level = unplayed_space_left;
837 else
839 /* Check if the end of data is because of a hard disk error.
840 If there is an open file handle, we are still playing music.
841 If not, the last file has been loaded, and the file handle is
842 closed. */
843 if(mpeg_file >= 0)
845 /* Update the watermark debug level */
846 if(unplayed_space_left < lowest_watermark_level)
847 lowest_watermark_level = unplayed_space_left;
849 DEBUGF("DMA underrun.\n");
850 dma_underrun = true;
852 else
854 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK, 0) )
856 DEBUGF("No more MP3 data. Stopping.\n");
857 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
858 playing = false;
861 *psize = 0; /* no more transfer */
866 static struct trackdata *add_track_to_tag_list(const char *filename)
868 struct trackdata *track;
869 bool send_nid3_event;
871 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES)
873 DEBUGF("Tag memory is full\n");
874 return NULL;
877 track = &trackdata[track_write_idx];
879 /* grab id3 tag of new file and
880 remember where in memory it starts */
881 if(mp3info(&track->id3, filename))
883 DEBUGF("Bad mp3\n");
884 return NULL;
886 track->mempos = audiobuf_write;
887 track->id3.elapsed = 0;
888 #ifdef HAVE_LCD_BITMAP
889 if (track->id3.title)
890 lcd_getstringsize(track->id3.title, NULL, NULL);
891 if (track->id3.artist)
892 lcd_getstringsize(track->id3.artist, NULL, NULL);
893 if (track->id3.album)
894 lcd_getstringsize(track->id3.album, NULL, NULL);
895 #endif
897 /* if this track is the next track then let the UI know it can get it */
898 send_nid3_event = (track_write_idx == track_read_idx + 1);
899 track_write_idx = (track_write_idx+1) & MAX_TRACK_ENTRIES_MASK;
900 if (send_nid3_event)
901 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, NULL);
902 debug_tags();
903 return track;
906 static int new_file(int steps)
908 int max_steps = playlist_amount();
909 int start = 0;
910 int i;
911 struct trackdata *track;
912 char name_buf[MAX_PATH+1];
913 const char *trackname;
915 /* Find out how many steps to advance. The load_ahead_index field tells
916 us how many playlist entries it had to skip to get to a valid one.
917 We add those together to find out where to start. */
918 if(steps > 0 && num_tracks_in_memory() > 1)
920 /* Begin with the song after the currently playing one */
921 i = 1;
922 while((track = get_trackdata(i++)))
924 start += track->load_ahead_index;
928 do {
929 trackname = playlist_peek(start + steps, name_buf, sizeof(name_buf));
930 if ( !trackname )
931 return -1;
933 DEBUGF("Loading %s\n", trackname);
935 mpeg_file = open(trackname, O_RDONLY);
936 if(mpeg_file < 0) {
937 DEBUGF("Couldn't open file: %s\n",trackname);
938 if(steps < 0)
939 steps--;
940 else
941 steps++;
943 else
945 struct trackdata *track = add_track_to_tag_list(trackname);
947 if(!track)
949 /* Bad mp3 file */
950 if(steps < 0)
951 steps--;
952 else
953 steps++;
954 close(mpeg_file);
955 mpeg_file = -1;
957 else
959 /* skip past id3v2 tag */
960 lseek(mpeg_file,
961 track->id3.first_frame_offset,
962 SEEK_SET);
963 track->id3.index = steps;
964 track->load_ahead_index = steps;
965 track->id3.offset = 0;
967 if(track->id3.vbr)
968 /* Average bitrate * 1.5 */
969 recalculate_watermark(
970 (track->id3.bitrate * 3) / 2);
971 else
972 recalculate_watermark(
973 track->id3.bitrate);
978 /* Bail out if no file could be opened */
979 if(abs(steps) > max_steps)
980 return -1;
981 } while ( mpeg_file < 0 );
983 return 0;
986 static void stop_playing(void)
988 struct trackdata *track;
990 /* Stop the current stream */
991 mp3_play_stop();
992 playing = false;
993 filling = false;
995 track = get_trackdata(0);
996 if (track != NULL)
997 prev_track_elapsed = track->id3.elapsed;
999 if(mpeg_file >= 0)
1000 close(mpeg_file);
1001 mpeg_file = -1;
1002 remove_all_tags();
1003 generate_unbuffer_events();
1004 reset_mp3_buffer();
1007 static void end_current_track(void) {
1008 struct trackdata *track;
1010 play_pending = false;
1011 playing = false;
1012 mp3_play_pause(false);
1014 track = get_trackdata(0);
1015 if (track != NULL)
1016 prev_track_elapsed = track->id3.elapsed;
1018 reset_mp3_buffer();
1019 remove_all_tags();
1020 generate_unbuffer_events();
1022 if(mpeg_file >= 0)
1023 close(mpeg_file);
1026 /* Is this a really the end of playback or is a new playlist starting */
1027 static void check_playlist_end(int direction)
1029 /* Use the largest possible step size to account for skipped tracks */
1030 int steps = playlist_amount();
1032 if (direction < 0)
1033 steps = -steps;
1035 if (playlist_next(steps) < 0)
1036 is_playing = false;
1039 static void update_playlist(void)
1041 if (num_tracks_in_memory() > 0)
1043 struct trackdata *track = get_trackdata(0);
1044 track->id3.index = playlist_next(track->id3.index);
1046 else
1048 /* End of playlist? */
1049 check_playlist_end(1);
1052 playlist_update_resume_info(audio_current_track());
1055 static void track_change(void)
1057 DEBUGF("Track change\n");
1059 struct trackdata *track = get_trackdata(0);
1060 prev_track_elapsed = track->id3.elapsed;
1062 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1063 /* Reset the AVC */
1064 sound_set_avc(-1);
1065 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1067 if (num_tracks_in_memory() > 0)
1069 remove_current_tag();
1070 update_playlist();
1071 if (is_playing)
1072 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1075 current_track_counter++;
1078 unsigned long audio_prev_elapsed(void)
1080 return prev_track_elapsed;
1083 #ifdef DEBUG
1084 void hexdump(const unsigned char *buf, int len)
1086 int i;
1088 for(i = 0;i < len;i++)
1090 if(i && (i & 15) == 0)
1092 DEBUGF("\n");
1094 DEBUGF("%02x ", buf[i]);
1096 DEBUGF("\n");
1098 #endif /* DEBUG */
1100 static void start_playback_if_ready(void)
1102 int playable_space;
1104 playable_space = audiobuf_swapwrite - audiobuf_read;
1105 if(playable_space < 0)
1106 playable_space += audiobuflen;
1108 /* See if we have started playing yet. If not, do it. */
1109 if(play_pending || dma_underrun)
1111 /* If the filling has stopped, and we still haven't reached
1112 the watermark, the file must be smaller than the
1113 watermark. We must still play it. */
1114 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
1115 !filling || dma_underrun)
1117 DEBUGF("P\n");
1118 if (play_pending) /* don't do this when recovering from DMA underrun */
1120 generate_postbuffer_events(); /* signal first track as buffered */
1121 if (play_pending_track_change)
1123 play_pending_track_change = false;
1124 send_event(PLAYBACK_EVENT_TRACK_CHANGE, audio_current_track());
1126 play_pending = false;
1128 playing = true;
1130 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1131 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1132 dma_underrun = false;
1134 if (!paused)
1136 last_dma_tick = current_tick;
1137 mp3_play_pause(true);
1140 /* Tell ourselves that we need more data */
1141 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1146 static bool swap_one_chunk(void)
1148 int free_space_left;
1149 int amount_to_swap;
1151 free_space_left = get_unswapped_space();
1153 if(free_space_left == 0 && !play_pending)
1154 return false;
1156 /* Swap in larger chunks when the user is waiting for the playback
1157 to start, or when there is dangerously little playable data left */
1158 if(play_pending)
1159 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1160 else
1162 if(get_playable_space() < low_watermark)
1163 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1164 free_space_left);
1165 else
1166 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1169 if(audiobuf_write < audiobuf_swapwrite)
1170 amount_to_swap = MIN(audiobuflen - audiobuf_swapwrite,
1171 amount_to_swap);
1172 else
1173 amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite,
1174 amount_to_swap);
1176 bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap);
1178 audiobuf_swapwrite += amount_to_swap;
1179 if(audiobuf_swapwrite >= audiobuflen)
1181 audiobuf_swapwrite = 0;
1184 return true;
1187 static void mpeg_thread(void)
1189 static int pause_tick = 0;
1190 static unsigned int pause_track = 0;
1191 struct queue_event ev;
1192 int len;
1193 int free_space_left;
1194 int unplayed_space_left;
1195 int amount_to_read;
1196 int t1, t2;
1197 int start_offset;
1198 #if CONFIG_CODEC == MAS3587F
1199 int amount_to_save;
1200 int save_endpos = 0;
1201 int rc;
1202 int level;
1203 long offset;
1204 #endif /* CONFIG_CODEC == MAS3587F */
1206 is_playing = false;
1207 play_pending = false;
1208 playing = false;
1209 mpeg_file = -1;
1211 while(1)
1213 #if CONFIG_CODEC == MAS3587F
1214 if(mpeg_mode == MPEG_DECODER)
1216 #endif /* CONFIG_CODEC == MAS3587F */
1217 yield();
1219 /* Swap if necessary, and don't block on the queue_wait() */
1220 if(swap_one_chunk())
1222 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1224 else if (playing)
1226 /* periodically update resume info */
1227 queue_wait_w_tmo(&mpeg_queue, &ev, HZ/2);
1229 else
1231 DEBUGF("S R:%x W:%x SW:%x\n",
1232 audiobuf_read, audiobuf_write, audiobuf_swapwrite);
1233 queue_wait(&mpeg_queue, &ev);
1236 start_playback_if_ready();
1238 switch(ev.id)
1240 case MPEG_PLAY:
1241 DEBUGF("MPEG_PLAY\n");
1243 #if CONFIG_TUNER
1244 /* Silence the A/D input, it may be on because the radio
1245 may be playing */
1246 mas_codec_writereg(6, 0x0000);
1247 #endif /* CONFIG_TUNER */
1249 /* Stop the current stream */
1250 paused = false;
1251 end_current_track();
1253 if ( new_file(0) == -1 )
1255 is_playing = false;
1256 track_change();
1257 break;
1260 start_offset = (int)ev.data;
1262 /* mid-song resume? */
1263 if (start_offset) {
1264 struct mp3entry* id3 = &get_trackdata(0)->id3;
1265 lseek(mpeg_file, start_offset, SEEK_SET);
1266 id3->offset = start_offset;
1267 set_elapsed(id3);
1269 else {
1270 /* skip past id3v2 tag */
1271 lseek(mpeg_file,
1272 get_trackdata(0)->id3.first_frame_offset,
1273 SEEK_SET);
1277 /* Make it read more data */
1278 filling = true;
1279 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1281 /* Tell the file loading code that we want to start playing
1282 as soon as we have some data */
1283 play_pending = true;
1284 play_pending_track_change = true;
1286 update_playlist();
1287 current_track_counter++;
1288 break;
1290 case MPEG_STOP:
1291 DEBUGF("MPEG_STOP\n");
1292 is_playing = false;
1293 paused = false;
1295 if (playing)
1296 playlist_update_resume_info(audio_current_track());
1298 stop_playing();
1299 mpeg_stop_done = true;
1300 break;
1302 case MPEG_PAUSE:
1303 DEBUGF("MPEG_PAUSE\n");
1304 /* Stop the current stream */
1305 if (playing)
1306 playlist_update_resume_info(audio_current_track());
1307 paused = true;
1308 playing = false;
1309 pause_tick = current_tick;
1310 pause_track = current_track_counter;
1311 mp3_play_pause(false);
1312 break;
1314 case MPEG_RESUME:
1315 DEBUGF("MPEG_RESUME\n");
1316 /* Continue the current stream */
1317 paused = false;
1318 if (!play_pending)
1320 playing = true;
1321 if ( current_track_counter == pause_track )
1322 last_dma_tick += current_tick - pause_tick;
1323 else
1324 last_dma_tick = current_tick;
1325 pause_tick = 0;
1326 mp3_play_pause(true);
1328 break;
1330 case MPEG_NEXT:
1331 DEBUGF("MPEG_NEXT\n");
1332 /* is next track in ram? */
1333 if ( num_tracks_in_memory() > 1 ) {
1334 int unplayed_space_left, unswapped_space_left;
1336 /* stop the current stream */
1337 play_pending = false;
1338 playing = false;
1339 mp3_play_pause(false);
1341 track_change();
1342 audiobuf_read = get_trackdata(0)->mempos;
1343 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1344 mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end);
1345 dma_underrun = false;
1346 last_dma_tick = current_tick;
1348 unplayed_space_left = get_unplayed_space();
1349 unswapped_space_left = get_unswapped_space();
1351 /* should we start reading more data? */
1352 if(!filling && (unplayed_space_left < low_watermark)) {
1353 filling = true;
1354 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1355 play_pending = true;
1356 } else if(unswapped_space_left &&
1357 unswapped_space_left > unplayed_space_left) {
1358 /* Stop swapping the data from the previous file */
1359 audiobuf_swapwrite = audiobuf_read;
1360 play_pending = true;
1361 } else {
1362 playing = true;
1363 if (!paused)
1364 mp3_play_pause(true);
1367 else {
1368 if (!playlist_check(1))
1369 break;
1371 /* stop the current stream */
1372 end_current_track();
1374 if (new_file(1) < 0) {
1375 DEBUGF("No more files to play\n");
1376 filling = false;
1378 check_playlist_end(1);
1379 current_track_counter++;
1380 } else {
1381 /* Make it read more data */
1382 filling = true;
1383 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1385 /* Tell the file loading code that we want
1386 to start playing as soon as we have some data */
1387 play_pending = true;
1388 play_pending_track_change = true;
1390 update_playlist();
1391 current_track_counter++;
1394 break;
1396 case MPEG_PREV: {
1397 DEBUGF("MPEG_PREV\n");
1399 if (!playlist_check(-1))
1400 break;
1402 /* stop the current stream */
1403 end_current_track();
1405 /* Open the next file */
1406 if (new_file(-1) < 0) {
1407 DEBUGF("No more files to play\n");
1408 filling = false;
1410 check_playlist_end(-1);
1411 current_track_counter++;
1412 } else {
1413 /* Make it read more data */
1414 filling = true;
1415 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1417 /* Tell the file loading code that we want to
1418 start playing as soon as we have some data */
1419 play_pending = true;
1420 play_pending_track_change = true;
1422 update_playlist();
1423 current_track_counter++;
1425 break;
1428 case MPEG_FF_REWIND: {
1429 struct mp3entry *id3 = audio_current_track();
1430 unsigned int oldtime = id3->elapsed;
1431 unsigned int newtime = (unsigned int)ev.data;
1432 int curpos, newpos, diffpos;
1433 DEBUGF("MPEG_FF_REWIND\n");
1435 id3->elapsed = newtime;
1437 newpos = audio_get_file_pos();
1438 if(newpos < 0)
1440 id3->elapsed = oldtime;
1441 break;
1444 if (mpeg_file >= 0)
1445 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1446 else
1447 curpos = id3->filesize;
1449 if (num_tracks_in_memory() > 1)
1451 /* We have started loading other tracks that need to be
1452 accounted for */
1453 struct trackdata *track;
1454 int i = 0;
1456 while((track = get_trackdata(i++)))
1458 curpos += track->id3.filesize;
1462 diffpos = curpos - newpos;
1464 if(!filling && diffpos >= 0 && diffpos < audiobuflen)
1466 int unplayed_space_left, unswapped_space_left;
1468 /* We are changing to a position that's already in
1469 memory, so we just move the DMA read pointer. */
1470 audiobuf_read = audiobuf_write - diffpos;
1471 if (audiobuf_read < 0)
1473 audiobuf_read += audiobuflen;
1476 unplayed_space_left = get_unplayed_space();
1477 unswapped_space_left = get_unswapped_space();
1479 /* If unswapped_space_left is larger than
1480 unplayed_space_left, it means that the swapwrite pointer
1481 hasn't yet advanced up to the new location of the read
1482 pointer. We just move it, there is no need to swap
1483 data that won't be played anyway. */
1485 if (unswapped_space_left > unplayed_space_left)
1487 DEBUGF("Moved swapwrite\n");
1488 audiobuf_swapwrite = audiobuf_read;
1489 play_pending = true;
1492 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1494 /* We need to load more data before starting */
1495 filling = true;
1496 queue_post(&mpeg_queue, MPEG_NEED_DATA, GENERATE_UNBUFFER_EVENTS);
1497 play_pending = true;
1499 else
1501 /* resume will start at new position */
1502 last_dma_chunk_size =
1503 MIN(0x2000, get_unplayed_space_current_song());
1504 mp3_play_data(audiobuf + audiobuf_read,
1505 last_dma_chunk_size, transfer_end);
1506 dma_underrun = false;
1509 else
1511 /* Move to the new position in the file and start
1512 loading data */
1513 reset_mp3_buffer();
1515 if (num_tracks_in_memory() > 1)
1517 /* We have to reload the current track */
1518 close(mpeg_file);
1519 remove_all_non_current_tags();
1520 generate_unbuffer_events();
1521 mpeg_file = -1;
1524 if (mpeg_file < 0)
1526 mpeg_file = open(id3->path, O_RDONLY);
1527 if (mpeg_file < 0)
1529 id3->elapsed = oldtime;
1530 break;
1534 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1536 id3->elapsed = oldtime;
1537 break;
1540 filling = true;
1541 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1543 /* Tell the file loading code that we want to start playing
1544 as soon as we have some data */
1545 play_pending = true;
1548 id3->offset = newpos;
1550 break;
1553 case MPEG_FLUSH_RELOAD: {
1554 int numtracks = num_tracks_in_memory();
1555 bool reload_track = false;
1557 if (numtracks > 1)
1559 /* Reset the buffer */
1560 audiobuf_write = get_trackdata(1)->mempos;
1562 /* Reset swapwrite unless we're still swapping current
1563 track */
1564 if (get_unplayed_space() <= get_playable_space())
1565 audiobuf_swapwrite = audiobuf_write;
1567 close(mpeg_file);
1568 remove_all_non_current_tags();
1569 generate_unbuffer_events();
1570 mpeg_file = -1;
1571 reload_track = true;
1573 else if (numtracks == 1 && mpeg_file < 0)
1575 reload_track = true;
1578 if(reload_track && new_file(1) >= 0)
1580 /* Tell ourselves that we want more data */
1581 filling = true;
1582 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1585 break;
1588 case MPEG_NEED_DATA:
1589 free_space_left = audiobuf_read - audiobuf_write;
1591 /* We interpret 0 as "empty buffer" */
1592 if(free_space_left <= 0)
1593 free_space_left += audiobuflen;
1595 unplayed_space_left = audiobuflen - free_space_left;
1597 /* Make sure that we don't fill the entire buffer */
1598 free_space_left -= MPEG_HIGH_WATER;
1600 if (ev.data == GENERATE_UNBUFFER_EVENTS)
1601 generate_unbuffer_events();
1603 /* do we have any more buffer space to fill? */
1604 if(free_space_left <= 0)
1606 DEBUGF("0\n");
1607 filling = false;
1608 generate_postbuffer_events();
1609 storage_sleep();
1610 break;
1613 /* Read small chunks while we are below the low water mark */
1614 if(unplayed_space_left < low_watermark)
1615 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1616 free_space_left);
1617 else
1618 amount_to_read = free_space_left;
1620 /* Don't read more than until the end of the buffer */
1621 amount_to_read = MIN(audiobuflen - audiobuf_write,
1622 amount_to_read);
1623 #if (CONFIG_STORAGE & STORAGE_MMC)
1624 /* MMC is slow, so don't read too large chunks */
1625 amount_to_read = MIN(0x40000, amount_to_read);
1626 #elif MEM == 8
1627 amount_to_read = MIN(0x100000, amount_to_read);
1628 #endif
1630 /* Read as much mpeg data as we can fit in the buffer */
1631 if(mpeg_file >= 0)
1633 DEBUGF("R\n");
1634 t1 = current_tick;
1635 len = read(mpeg_file, audiobuf + audiobuf_write,
1636 amount_to_read);
1637 if(len > 0)
1639 t2 = current_tick;
1640 DEBUGF("time: %d\n", t2 - t1);
1641 DEBUGF("R: %x\n", len);
1643 /* Now make sure that we don't feed the MAS with ID3V1
1644 data */
1645 if (len < amount_to_read)
1647 int i;
1648 static const unsigned char tag[] = "TAG";
1649 int taglen = 128;
1650 int tagptr = audiobuf_write + len - 128;
1652 /* Really rare case: entire potential tag wasn't
1653 read in this call AND audiobuf_write < 128 */
1654 if (tagptr < 0)
1655 tagptr += audiobuflen;
1657 for(i = 0;i < 3;i++)
1659 if(tagptr >= audiobuflen)
1660 tagptr -= audiobuflen;
1662 if(audiobuf[tagptr] != tag[i])
1664 taglen = 0;
1665 break;
1668 tagptr++;
1671 if(taglen)
1673 /* Skip id3v1 tag */
1674 DEBUGF("Skipping ID3v1 tag\n");
1675 len -= taglen;
1677 /* In the very rare case when the entire tag
1678 wasn't read in this read() len will be < 0.
1679 Take care of this when changing the write
1680 pointer. */
1684 audiobuf_write += len;
1686 if (audiobuf_write < 0)
1687 audiobuf_write += audiobuflen;
1689 if(audiobuf_write >= audiobuflen)
1691 audiobuf_write = 0;
1692 DEBUGF("W\n");
1695 /* Tell ourselves that we want more data */
1696 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1698 else
1700 if(len < 0)
1702 DEBUGF("MPEG read error\n");
1705 close(mpeg_file);
1706 mpeg_file = -1;
1708 if(new_file(1) < 0)
1710 /* No more data to play */
1711 DEBUGF("No more files to play\n");
1712 filling = false;
1714 else
1716 /* Tell ourselves that we want more data */
1717 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1721 break;
1723 case MPEG_TRACK_CHANGE:
1724 track_change();
1725 break;
1727 #ifndef USB_NONE
1728 case SYS_USB_CONNECTED:
1729 is_playing = false;
1730 paused = false;
1731 stop_playing();
1733 /* Tell the USB thread that we are safe */
1734 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1735 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1737 /* Wait until the USB cable is extracted again */
1738 usb_wait_for_disconnect(&mpeg_queue);
1739 break;
1740 #endif /* !USB_NONE */
1742 #if CONFIG_CODEC == MAS3587F
1743 case MPEG_INIT_RECORDING:
1744 init_recording();
1745 init_recording_done = true;
1746 break;
1747 #endif /* CONFIG_CODEC == MAS3587F */
1749 case SYS_TIMEOUT:
1750 if (playing)
1751 playlist_update_resume_info(audio_current_track());
1752 break;
1754 #if CONFIG_CODEC == MAS3587F
1756 else
1758 queue_wait(&mpeg_queue, &ev);
1759 switch(ev.id)
1761 case MPEG_RECORD:
1762 if (is_prerecording)
1764 int startpos;
1766 /* Go back prerecord_count seconds in the buffer */
1767 startpos = prerecord_index - prerecord_count;
1768 if(startpos < 0)
1769 startpos += prerecording_max_seconds;
1771 /* Read the position data from the prerecord buffer */
1772 frame_count_start = prerecord_buffer[startpos].framecount;
1773 startpos = prerecord_buffer[startpos].mempos;
1775 DEBUGF("Start looking at address %x (%x)\n",
1776 audiobuf+startpos, startpos);
1778 saved_header = mpeg_get_last_header();
1780 mem_find_next_frame(startpos, &offset, 1800,
1781 saved_header);
1783 audiobuf_read = startpos + offset;
1784 if(audiobuf_read >= audiobuflen)
1785 audiobuf_read -= audiobuflen;
1787 DEBUGF("New audiobuf_read address: %x (%x)\n",
1788 audiobuf+audiobuf_read, audiobuf_read);
1790 level = disable_irq_save();
1791 num_rec_bytes = get_unsaved_space();
1792 restore_irq(level);
1794 else
1796 frame_count_start = 0;
1797 num_rec_bytes = 0;
1798 audiobuf_read = MPEG_RESERVED_HEADER_SPACE;
1799 audiobuf_write = MPEG_RESERVED_HEADER_SPACE;
1802 prepend_header();
1803 DEBUGF("Recording...\n");
1804 start_recording();
1806 /* Wait until at least one frame is encoded and get the
1807 frame header, for later use by the Xing header
1808 generation */
1809 sleep(HZ/5);
1810 saved_header = mpeg_get_last_header();
1812 /* delayed until buffer is saved, don't open yet */
1813 strcpy(delayed_filename, recording_filename);
1814 mpeg_file = -1;
1816 break;
1818 case MPEG_STOP:
1819 DEBUGF("MPEG_STOP\n");
1821 stop_recording();
1823 /* Save the remaining data in the buffer */
1824 save_endpos = audiobuf_write;
1825 saving_status = STOP_RECORDING;
1826 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1827 break;
1829 case MPEG_STOP_DONE:
1830 DEBUGF("MPEG_STOP_DONE\n");
1832 if (mpeg_file >= 0)
1833 close(mpeg_file);
1834 mpeg_file = -1;
1836 update_header();
1837 #ifdef DEBUG1
1839 int i;
1840 for(i = 0;i < 512;i++)
1842 DEBUGF("%d - %d us (%d bytes)\n",
1843 timing_info[i*2],
1844 (timing_info[i*2+1] & 0xffff) *
1845 10000 / 13824,
1846 timing_info[i*2+1] >> 16);
1849 #endif /* DEBUG1 */
1851 if (prerecording)
1853 start_prerecording();
1855 mpeg_stop_done = true;
1856 break;
1858 case MPEG_NEW_FILE:
1859 /* Bail out when a more important save is happening */
1860 if (saving_status > NEW_FILE)
1861 break;
1863 /* Make sure we have at least one complete frame
1864 in the buffer. If we haven't recorded a single
1865 frame within 200ms, the MAS is probably not recording
1866 anything, and we bail out. */
1867 amount_to_save = get_unsaved_space();
1868 if (amount_to_save < 1800)
1870 sleep(HZ/5);
1871 amount_to_save = get_unsaved_space();
1874 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
1875 &frame_count_end, 1);
1877 last_rec_time = current_tick - record_start_time;
1878 record_start_time = current_tick;
1879 if (paused)
1880 pause_start_time = record_start_time;
1882 /* capture all values at one point */
1883 level = disable_irq_save();
1884 save_endpos = audiobuf_write;
1885 last_rec_bytes = num_rec_bytes;
1886 num_rec_bytes = 0;
1887 restore_irq(level);
1889 if (amount_to_save >= 1800)
1891 /* Now find a frame boundary to split at */
1892 save_endpos -= 1800;
1893 if (save_endpos < 0)
1894 save_endpos += audiobuflen;
1896 rc = mem_find_next_frame(save_endpos, &offset, 1800,
1897 saved_header);
1898 if (!rc) /* No header found, save whole buffer */
1899 offset = 1800;
1901 save_endpos += offset;
1902 if (save_endpos >= audiobuflen)
1903 save_endpos -= audiobuflen;
1905 last_rec_bytes += offset - 1800;
1906 level = disable_irq_save();
1907 num_rec_bytes += 1800 - offset;
1908 restore_irq(level);
1911 saving_status = NEW_FILE;
1912 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1913 break;
1915 case MPEG_SAVE_DATA:
1916 if (saving_status == BUFFER_FULL)
1917 save_endpos = audiobuf_write;
1919 if (mpeg_file < 0) /* delayed file open */
1921 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT, 0666);
1923 if (mpeg_file < 0)
1924 panicf("recfile: %d", mpeg_file);
1927 amount_to_save = save_endpos - audiobuf_read;
1928 if (amount_to_save < 0)
1929 amount_to_save += audiobuflen;
1931 amount_to_save = MIN(amount_to_save,
1932 audiobuflen - audiobuf_read);
1933 #if (CONFIG_STORAGE & STORAGE_MMC)
1934 /* MMC is slow, so don't save too large chunks at once */
1935 amount_to_save = MIN(0x40000, amount_to_save);
1936 #elif MEM == 8
1937 amount_to_save = MIN(0x100000, amount_to_save);
1938 #endif
1939 rc = write(mpeg_file, audiobuf + audiobuf_read,
1940 amount_to_save);
1941 if (rc < 0)
1943 if (errno == ENOSPC)
1945 mpeg_errno = AUDIOERR_DISK_FULL;
1946 stop_recording();
1947 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1948 /* will close the file */
1949 break;
1951 else
1952 panicf("rec wrt: %d", rc);
1955 audiobuf_read += amount_to_save;
1956 if (audiobuf_read >= audiobuflen)
1957 audiobuf_read = 0;
1959 if (audiobuf_read == save_endpos) /* all saved */
1961 switch (saving_status)
1963 case BUFFER_FULL:
1964 rc = fsync(mpeg_file);
1965 if (rc < 0)
1966 panicf("rec fls: %d", rc);
1967 storage_sleep();
1968 break;
1970 case NEW_FILE:
1971 /* Close the current file */
1972 rc = close(mpeg_file);
1973 if (rc < 0)
1974 panicf("rec cls: %d", rc);
1975 mpeg_file = -1;
1976 update_header();
1977 storage_sleep();
1979 /* copy new filename */
1980 strcpy(delayed_filename, recording_filename);
1981 prepend_header();
1982 frame_count_start = frame_count_end;
1983 break;
1985 case STOP_RECORDING:
1986 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1987 /* will close the file */
1988 break;
1990 default:
1991 break;
1993 saving_status = NOT_SAVING;
1995 else /* tell ourselves to save the next chunk */
1996 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1998 break;
2000 case MPEG_PRERECORDING_TICK:
2001 if(!is_prerecording)
2002 break;
2004 /* Store the write pointer every second */
2005 prerecord_buffer[prerecord_index].mempos = audiobuf_write;
2006 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT,
2007 &prerecord_buffer[prerecord_index].framecount, 1);
2009 /* Wrap if necessary */
2010 if(++prerecord_index == prerecording_max_seconds)
2011 prerecord_index = 0;
2013 /* Update the number of seconds recorded */
2014 if(prerecord_count < prerecording_max_seconds)
2015 prerecord_count++;
2016 break;
2018 case MPEG_INIT_PLAYBACK:
2019 /* Stop the prerecording */
2020 stop_recording();
2021 reset_mp3_buffer();
2022 mp3_play_init();
2023 init_playback_done = true;
2024 break;
2026 case MPEG_PAUSE_RECORDING:
2027 pause_recording();
2028 break;
2030 case MPEG_RESUME_RECORDING:
2031 resume_recording();
2032 break;
2034 case SYS_USB_CONNECTED:
2035 /* We can safely go to USB mode if no recording
2036 is taking place */
2037 if((!is_recording || is_prerecording) && mpeg_stop_done)
2039 /* Even if we aren't recording, we still call this
2040 function, to put the MAS in monitoring mode,
2041 to save power. */
2042 stop_recording();
2044 /* Tell the USB thread that we are safe */
2045 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2046 usb_acknowledge(SYS_USB_CONNECTED_ACK);
2048 /* Wait until the USB cable is extracted again */
2049 usb_wait_for_disconnect(&mpeg_queue);
2051 break;
2054 #endif /* CONFIG_CODEC == MAS3587F */
2057 #endif /* !SIMULATOR */
2059 struct mp3entry* audio_current_track(void)
2061 #ifdef SIMULATOR
2062 struct mp3entry *id3 = &taginfo;
2063 #else /* !SIMULATOR */
2064 if(num_tracks_in_memory())
2066 struct mp3entry *id3 = &get_trackdata(0)->id3;
2067 #endif
2068 if (!checked_for_cuesheet && curr_cuesheet && id3->cuesheet == NULL)
2070 checked_for_cuesheet = true; /* only check once per track */
2071 char cuepath[MAX_PATH];
2073 if (look_for_cuesheet_file(id3->path, cuepath) &&
2074 parse_cuesheet(cuepath, curr_cuesheet))
2076 id3->cuesheet = curr_cuesheet;
2079 return id3;
2080 #ifndef SIMULATOR
2082 else
2083 return NULL;
2084 #endif /* !SIMULATOR */
2087 struct mp3entry* audio_next_track(void)
2089 #ifdef SIMULATOR
2090 return &taginfo;
2091 #else /* !SIMULATOR */
2092 if(num_tracks_in_memory() > 1)
2093 return &get_trackdata(1)->id3;
2094 else
2095 return NULL;
2096 #endif /* !SIMULATOR */
2099 #if CONFIG_CODEC == MAS3587F
2100 #ifndef SIMULATOR
2101 void audio_init_playback(void)
2103 init_playback_done = false;
2104 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, 0);
2106 while(!init_playback_done)
2107 sleep(1);
2111 /****************************************************************************
2112 * Recording functions
2113 ***************************************************************************/
2114 void audio_init_recording(unsigned int buffer_offset)
2116 buffer_offset = buffer_offset;
2117 init_recording_done = false;
2118 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, 0);
2120 while(!init_recording_done)
2121 sleep(1);
2124 static void init_recording(void)
2126 unsigned long val;
2127 int rc;
2129 /* Disable IRQ6 */
2130 IPRB &= 0xff0f;
2132 stop_playing();
2133 is_playing = false;
2134 paused = false;
2136 /* Init the recording variables */
2137 is_recording = false;
2138 is_prerecording = false;
2140 mpeg_stop_done = true;
2142 mas_reset();
2144 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2145 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2146 if(rc < 0)
2147 panicf("mas_ctrl_w: %d", rc);
2149 /* Stop the current application */
2150 val = 0;
2151 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2154 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2155 } while(val);
2157 /* Perform black magic as described by the data sheet */
2158 if((mas_version_code & 0x0fff) == 0x0102)
2160 DEBUGF("Performing MAS black magic for B2 version\n");
2161 mas_writereg(0xa3, 0x98);
2162 mas_writereg(0x94, 0xfffff);
2163 val = 0;
2164 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2165 mas_writereg(0xa3, 0x90);
2168 /* Enable A/D Converters */
2169 shadow_codec_reg0 = 0xcccd;
2170 mas_codec_writereg(0x0, shadow_codec_reg0);
2172 /* Copy left channel to right (mono mode) */
2173 mas_codec_writereg(8, 0x8000);
2175 /* ADC scale 0%, DSP scale 100%
2176 We use the DSP output for monitoring, because it works with all
2177 sources including S/PDIF */
2178 mas_codec_writereg(6, 0x0000);
2179 mas_codec_writereg(7, 0x4000);
2181 /* No mute */
2182 shadow_soft_mute = 0;
2183 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2185 #ifdef HAVE_SPDIF_OUT
2186 val = 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2187 #else
2188 val = 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2189 #endif
2190 mas_writemem(MAS_BANK_D0, MAS_D0_INTERFACE_CONTROL, &val, 1);
2192 /* Set Demand mode, monitoring OFF and validate all settings */
2193 shadow_io_control_main = 0x125;
2194 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2196 /* Start the encoder application */
2197 val = 0x40;
2198 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2201 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2202 } while(!(val & 0x40));
2204 /* We have started the recording application with monitoring OFF.
2205 This is because we want to record at least one frame to fill the DMA
2206 buffer, because the silly MAS will not negate EOD until at least one
2207 DMA transfer has taken place.
2208 Now let's wait for some data to be encoded. */
2209 sleep(HZ/5);
2211 /* Now set it to Monitoring mode as default, saves power */
2212 shadow_io_control_main = 0x525;
2213 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2215 /* Wait until the DSP has accepted the settings */
2218 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2219 } while(val & 1);
2221 drain_dma_buffer();
2222 mpeg_mode = MPEG_ENCODER;
2224 DEBUGF("MAS Recording application started\n");
2226 /* At this point, all settings are the reset MAS defaults, next thing is to
2227 call mpeg_set_recording_options(). */
2230 void audio_record(const char *filename)
2232 mpeg_errno = 0;
2234 strlcpy(recording_filename, filename, MAX_PATH);
2236 queue_post(&mpeg_queue, MPEG_RECORD, 0);
2239 void audio_pause_recording(void)
2241 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, 0);
2244 void audio_resume_recording(void)
2246 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, 0);
2249 static void prepend_header(void)
2251 int startpos;
2252 unsigned i;
2254 /* Make room for header */
2255 audiobuf_read -= MPEG_RESERVED_HEADER_SPACE;
2256 if(audiobuf_read < 0)
2258 /* Clear the bottom half */
2259 memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE);
2261 /* And the top half */
2262 audiobuf_read += audiobuflen;
2263 memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read);
2265 else
2267 memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE);
2269 /* Copy the empty ID3 header */
2270 startpos = audiobuf_read;
2271 for(i = 0; i < sizeof(empty_id3_header); i++)
2273 audiobuf[startpos++] = empty_id3_header[i];
2274 if(startpos == audiobuflen)
2275 startpos = 0;
2279 static void update_header(void)
2281 int fd, framelen;
2282 unsigned long frames;
2284 if (last_rec_bytes > 0)
2286 /* Create the Xing header */
2287 fd = open(delayed_filename, O_RDWR);
2288 if (fd < 0)
2289 panicf("rec upd: %d (%s)", fd, recording_filename);
2291 frames = frame_count_end - frame_count_start;
2292 /* If the number of recorded frames has reached 0x7ffff,
2293 we can no longer trust it */
2294 if (frame_count_end == 0x7ffff)
2295 frames = 0;
2297 /* saved_header is saved right before stopping the MAS */
2298 framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer,
2299 frames, last_rec_time * (1000/HZ),
2300 saved_header, NULL, false);
2302 lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET);
2303 write(fd, xing_buffer, framelen);
2304 close(fd);
2308 static void start_prerecording(void)
2310 unsigned long val;
2312 DEBUGF("Starting prerecording\n");
2314 prerecord_index = 0;
2315 prerecord_count = 0;
2316 prerecord_timeout = current_tick + HZ;
2317 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2318 reset_mp3_buffer();
2320 is_prerecording = true;
2322 /* Stop monitoring and start the encoder */
2323 shadow_io_control_main &= ~(1 << 10);
2324 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2325 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2327 /* Wait until the DSP has accepted the settings */
2330 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2331 } while(val & 1);
2333 is_recording = true;
2334 saving_status = NOT_SAVING;
2336 demand_irq_enable(true);
2339 static void start_recording(void)
2341 unsigned long val;
2343 if(is_prerecording)
2345 /* This will make the IRQ handler start recording
2346 for real, i.e send MPEG_SAVE_DATA messages when
2347 the buffer is full */
2348 is_prerecording = false;
2350 else
2352 /* If prerecording is off, we need to stop the monitoring
2353 and start the encoder */
2354 shadow_io_control_main &= ~(1 << 10);
2355 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2356 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2358 /* Wait until the DSP has accepted the settings */
2361 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2362 } while(val & 1);
2365 is_recording = true;
2366 saving_status = NOT_SAVING;
2367 paused = false;
2369 /* Store the current time */
2370 if(prerecording)
2371 record_start_time = current_tick - prerecord_count * HZ;
2372 else
2373 record_start_time = current_tick;
2375 pause_start_time = 0;
2377 demand_irq_enable(true);
2380 static void pause_recording(void)
2382 pause_start_time = current_tick;
2384 /* Set the pause bit */
2385 shadow_soft_mute |= 2;
2386 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2388 paused = true;
2391 static void resume_recording(void)
2393 paused = false;
2395 /* Clear the pause bit */
2396 shadow_soft_mute &= ~2;
2397 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2399 /* Compensate for the time we have been paused */
2400 if(pause_start_time)
2402 record_start_time =
2403 current_tick - (pause_start_time - record_start_time);
2404 pause_start_time = 0;
2408 static void stop_recording(void)
2410 unsigned long val;
2412 /* Let it finish the last frame */
2413 if(!paused)
2414 pause_recording();
2415 sleep(HZ/5);
2417 demand_irq_enable(false);
2419 is_recording = false;
2420 is_prerecording = false;
2422 last_rec_bytes = num_rec_bytes;
2423 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1);
2424 last_rec_time = current_tick - record_start_time;
2426 /* Start monitoring */
2427 shadow_io_control_main |= (1 << 10);
2428 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2429 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2431 /* Wait until the DSP has accepted the settings */
2434 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2435 } while(val & 1);
2437 resume_recording();
2440 void audio_set_recording_options(struct audio_recording_options *options)
2442 bool is_mpeg1;
2444 is_mpeg1 = (options->rec_frequency < 3);
2446 rec_version_index = is_mpeg1?3:2;
2447 rec_frequency_index = options->rec_frequency % 3;
2449 shadow_encoder_control = (options->rec_quality << 17) |
2450 (rec_frequency_index << 10) |
2451 ((is_mpeg1?1:0) << 9) |
2452 (((options->rec_channels * 2 + 1) & 3) << 6) |
2453 (1 << 5) /* MS-stereo */ |
2454 (1 << 2) /* Is an original */;
2455 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2457 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2459 #if CONFIG_TUNER & S1A0903X01
2460 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2461 interference with the Samsung tuner. */
2462 if (rec_frequency_index)
2463 mas_store_pllfreq(24576000);
2464 else
2465 mas_store_pllfreq(22579000);
2466 #endif
2468 shadow_soft_mute = options->rec_editable?4:0;
2469 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2471 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2473 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2474 ((options->rec_source < 2)?1:2) << 8) | /* Input select */
2475 (1 << 5) | /* SDO strobe invert */
2476 ((is_mpeg1?0:1) << 3) |
2477 (1 << 2) | /* Inverted SIBC clock signal */
2478 1; /* Validate */
2479 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2481 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2483 if(options->rec_source == AUDIO_SRC_MIC)
2485 /* Copy left channel to right (mono mode) */
2486 mas_codec_writereg(8, 0x8000);
2488 else
2490 /* Stereo input mode */
2491 mas_codec_writereg(8, 0);
2494 prerecording_max_seconds = options->rec_prerecord_time;
2495 if(prerecording_max_seconds)
2497 prerecording = true;
2498 start_prerecording();
2500 else
2502 prerecording = false;
2503 is_prerecording = false;
2504 is_recording = false;
2508 /* If use_mic is true, the left gain is used */
2509 void audio_set_recording_gain(int left, int right, int type)
2511 /* Enable both left and right A/D */
2512 shadow_codec_reg0 = (left << 12) |
2513 (right << 8) |
2514 (left << 4) |
2515 (type==AUDIO_GAIN_MIC?0x0008:0) | /* Connect left A/D to mic */
2516 0x0007;
2517 mas_codec_writereg(0x0, shadow_codec_reg0);
2520 /* try to make some kind of beep, also in recording mode */
2521 void audio_beep(int duration)
2523 long starttick = current_tick;
2525 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2526 * While this is still audible even without an external signal,
2527 * it doesn't affect the (pre-)recording. */
2528 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2529 mas_codec_writereg(0, shadow_codec_reg0);
2530 yield();
2532 while (current_tick - starttick < duration);
2535 void audio_new_file(const char *filename)
2537 mpeg_errno = 0;
2539 strlcpy(recording_filename, filename, MAX_PATH);
2541 queue_post(&mpeg_queue, MPEG_NEW_FILE, 0);
2544 unsigned long audio_recorded_time(void)
2546 if(is_prerecording)
2547 return prerecord_count * HZ;
2549 if(is_recording)
2551 if(paused)
2552 return pause_start_time - record_start_time;
2553 else
2554 return current_tick - record_start_time;
2557 return 0;
2560 unsigned long audio_num_recorded_bytes(void)
2562 int num_bytes;
2563 int index;
2565 if(is_recording)
2567 if(is_prerecording)
2569 index = prerecord_index - prerecord_count;
2570 if(index < 0)
2571 index += prerecording_max_seconds;
2573 num_bytes = audiobuf_write - prerecord_buffer[index].mempos;
2574 if(num_bytes < 0)
2575 num_bytes += audiobuflen;
2577 return num_bytes;
2579 else
2580 return num_rec_bytes;
2582 else
2583 return 0;
2586 #else /* SIMULATOR */
2588 /* dummies coming up */
2590 void audio_init_playback(void)
2592 /* a dummy */
2594 unsigned long audio_recorded_time(void)
2596 /* a dummy */
2597 return 0;
2599 void audio_beep(int duration)
2601 /* a dummy */
2602 (void)duration;
2604 void audio_pause_recording(void)
2606 /* a dummy */
2608 void audio_resume_recording(void)
2610 /* a dummy */
2612 unsigned long audio_num_recorded_bytes(void)
2614 /* a dummy */
2615 return 0;
2617 void audio_record(const char *filename)
2619 /* a dummy */
2620 (void)filename;
2622 void audio_new_file(const char *filename)
2624 /* a dummy */
2625 (void)filename;
2628 void audio_set_recording_gain(int left, int right, int type)
2630 /* a dummy */
2631 (void)left;
2632 (void)right;
2633 (void)type;
2635 void audio_init_recording(unsigned int buffer_offset)
2637 /* a dummy */
2638 (void)buffer_offset;
2640 void audio_set_recording_options(struct audio_recording_options *options)
2642 /* a dummy */
2643 (void)options;
2645 #endif /* SIMULATOR */
2646 #endif /* CONFIG_CODEC == MAS3587F */
2648 void audio_play(long offset)
2650 #ifdef SIMULATOR
2651 char name_buf[MAX_PATH+1];
2652 const char* trackname;
2653 int steps=0;
2655 is_playing = true;
2657 do {
2658 trackname = playlist_peek(steps, name_buf, sizeof(name_buf));
2659 if (!trackname)
2660 break;
2661 if(mp3info(&taginfo, trackname)) {
2662 /* bad mp3, move on */
2663 if(++steps > playlist_amount())
2664 break;
2665 continue;
2667 #ifdef HAVE_MPEG_PLAY
2668 real_mpeg_play(trackname);
2669 #endif
2670 playlist_next(steps);
2671 taginfo.offset = offset;
2672 set_elapsed(&taginfo);
2673 is_playing = true;
2674 playing = true;
2675 break;
2676 } while(1);
2677 #else /* !SIMULATOR */
2678 is_playing = true;
2680 queue_post(&mpeg_queue, MPEG_PLAY, offset);
2681 #endif /* !SIMULATOR */
2683 mpeg_errno = 0;
2686 void audio_stop(void)
2688 #ifndef SIMULATOR
2689 if (playing)
2691 struct trackdata *track = get_trackdata(0);
2692 prev_track_elapsed = track->id3.elapsed;
2694 mpeg_stop_done = false;
2695 queue_post(&mpeg_queue, MPEG_STOP, 0);
2696 while(!mpeg_stop_done)
2697 yield();
2698 #else /* SIMULATOR */
2699 paused = false;
2700 is_playing = false;
2701 playing = false;
2702 #endif /* SIMULATOR */
2705 /* dummy */
2706 void audio_stop_recording(void)
2708 audio_stop();
2711 void audio_pause(void)
2713 #ifndef SIMULATOR
2714 queue_post(&mpeg_queue, MPEG_PAUSE, 0);
2715 #else /* SIMULATOR */
2716 is_playing = true;
2717 playing = false;
2718 paused = true;
2719 #endif /* SIMULATOR */
2722 void audio_resume(void)
2724 #ifndef SIMULATOR
2725 queue_post(&mpeg_queue, MPEG_RESUME, 0);
2726 #else /* SIMULATOR */
2727 is_playing = true;
2728 playing = true;
2729 paused = false;
2730 #endif /* SIMULATOR */
2733 void audio_next(void)
2735 #ifndef SIMULATOR
2736 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2737 queue_post(&mpeg_queue, MPEG_NEXT, 0);
2738 #else /* SIMULATOR */
2739 char name_buf[MAX_PATH+1];
2740 const char* file;
2741 int steps = 1;
2742 int index;
2744 do {
2745 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2746 if(!file)
2747 break;
2748 if(mp3info(&taginfo, file)) {
2749 if(++steps > playlist_amount())
2750 break;
2751 continue;
2753 index = playlist_next(steps);
2754 taginfo.index = index;
2755 current_track_counter++;
2756 is_playing = true;
2757 playing = true;
2758 break;
2759 } while(1);
2760 #endif /* SIMULATOR */
2763 void audio_prev(void)
2765 #ifndef SIMULATOR
2766 queue_remove_from_head(&mpeg_queue, MPEG_NEED_DATA);
2767 queue_post(&mpeg_queue, MPEG_PREV, 0);
2768 #else /* SIMULATOR */
2769 char name_buf[MAX_PATH+1];
2770 const char* file;
2771 int steps = -1;
2772 int index;
2774 do {
2775 file = playlist_peek(steps, name_buf, sizeof(name_buf));
2776 if(!file)
2777 break;
2778 if(mp3info(&taginfo, file)) {
2779 steps--;
2780 continue;
2782 index = playlist_next(steps);
2783 taginfo.index = index;
2784 current_track_counter++;
2785 is_playing = true;
2786 playing = true;
2787 break;
2788 } while(1);
2789 #endif /* SIMULATOR */
2792 void audio_ff_rewind(long newpos)
2794 #ifndef SIMULATOR
2795 queue_post(&mpeg_queue, MPEG_FF_REWIND, newpos);
2796 #else /* SIMULATOR */
2797 (void)newpos;
2798 #endif /* SIMULATOR */
2801 void audio_flush_and_reload_tracks(void)
2803 #ifndef SIMULATOR
2804 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, 0);
2805 #endif /* !SIMULATOR*/
2808 int audio_status(void)
2810 int ret = 0;
2812 if(is_playing)
2813 ret |= AUDIO_STATUS_PLAY;
2815 if(paused)
2816 ret |= AUDIO_STATUS_PAUSE;
2818 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2819 if(is_recording && !is_prerecording)
2820 ret |= AUDIO_STATUS_RECORD;
2822 if(is_prerecording)
2823 ret |= AUDIO_STATUS_PRERECORD;
2824 #endif /* CONFIG_CODEC == MAS3587F */
2826 if(mpeg_errno)
2827 ret |= AUDIO_STATUS_ERROR;
2829 return ret;
2832 /* Unused function
2833 unsigned int audio_error(void)
2835 return mpeg_errno;
2839 void audio_error_clear(void)
2841 mpeg_errno = 0;
2844 #ifdef SIMULATOR
2845 static void mpeg_thread(void)
2847 struct mp3entry* id3;
2848 while ( 1 ) {
2849 if (is_playing) {
2850 id3 = audio_current_track();
2851 if (!paused)
2853 id3->elapsed+=1000;
2854 id3->offset+=1000;
2856 if (id3->elapsed>=id3->length)
2857 audio_next();
2859 sleep(HZ);
2862 #endif /* SIMULATOR */
2864 void audio_init(void)
2866 mpeg_errno = 0;
2867 /* cuesheet support */
2868 if (global_settings.cuesheet)
2869 curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet));
2871 #ifndef SIMULATOR
2872 audiobuflen = audiobufend - audiobuf;
2873 queue_init(&mpeg_queue, true);
2874 #endif /* !SIMULATOR */
2875 create_thread(mpeg_thread, mpeg_stack,
2876 sizeof(mpeg_stack), 0, mpeg_thread_name
2877 IF_PRIO(, PRIORITY_SYSTEM)
2878 IF_COP(, CPU));
2880 memset(trackdata, 0, sizeof(trackdata));
2882 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2883 if (HW_MASK & PR_ACTIVE_HIGH)
2884 and_b(~0x08, &PADRH);
2885 else
2886 or_b(0x08, &PADRH);
2887 #endif /* CONFIG_CODEC == MAS3587F */
2889 #ifdef DEBUG
2890 #ifndef SIMULATOR
2891 dbg_timer_start();
2892 dbg_cnt2us(0);
2893 #endif /* !SIMULATOR */
2894 #endif /* DEBUG */
2897 #endif /* CONFIG_CODEC != SWCODEC */