Fixed red build...
[kugel-rb.git] / firmware / mpeg.c
blob5b5faceeb18fb0a7e5dcdfbcb9a34a973daa3800
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdbool.h>
20 #include <stdlib.h>
21 #include "config.h"
22 #include "debug.h"
23 #include "panic.h"
24 #include "id3.h"
25 #include "mpeg.h"
26 #include "ata.h"
27 #include "string.h"
28 #include <kernel.h>
29 #include "thread.h"
30 #include "errno.h"
31 #include "mp3data.h"
32 #include "buffer.h"
33 #include "mp3_playback.h"
34 #ifndef SIMULATOR
35 #include "i2c.h"
36 #include "mas.h"
37 #include "dac.h"
38 #include "system.h"
39 #include "usb.h"
40 #include "file.h"
41 #include "hwcompat.h"
42 #else
43 #include "mpegplay.h"
44 #endif /* #ifndef SIMULATOR */
46 #include "bitswap.h"
48 #if CONFIG_HWCODEC == MAS3587F
49 static void init_recording(void);
50 static void start_prerecording(void);
51 static void start_recording(void);
52 static void stop_recording(void);
53 static int get_unsaved_space(void);
54 static void pause_recording(void);
55 static void resume_recording(void);
56 #endif /* #if CONFIG_HWCODEC == MAS3587F */
58 #ifndef SIMULATOR
59 static int get_unplayed_space(void);
60 static int get_playable_space(void);
61 static int get_unswapped_space(void);
62 #endif /* #ifndef SIMULATOR */
64 #define MPEG_PLAY 1
65 #define MPEG_STOP 2
66 #define MPEG_PAUSE 3
67 #define MPEG_RESUME 4
68 #define MPEG_NEXT 5
69 #define MPEG_PREV 6
70 #define MPEG_FF_REWIND 7
71 #define MPEG_FLUSH_RELOAD 8
72 #define MPEG_RECORD 9
73 #define MPEG_INIT_RECORDING 10
74 #define MPEG_INIT_PLAYBACK 11
75 #define MPEG_NEW_FILE 12
76 #define MPEG_PAUSE_RECORDING 13
77 #define MPEG_RESUME_RECORDING 14
78 #define MPEG_NEED_DATA 100
79 #define MPEG_TRACK_CHANGE 101
80 #define MPEG_SAVE_DATA 102
81 #define MPEG_STOP_DONE 103
83 #if CONFIG_HWCODEC == MAS3587F
84 extern enum /* from mp3_playback.c */
86 MPEG_DECODER,
87 MPEG_ENCODER
88 } mpeg_mode;
89 #endif /* #if CONFIG_HWCODEC == MAS3587F */
91 extern char* playlist_peek(int steps);
92 extern bool playlist_check(int steps);
93 extern int playlist_next(int steps);
94 extern int playlist_amount(void);
95 extern void update_file_pos( int id, int pos );
97 /* list of tracks in memory */
98 #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
99 #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
101 struct id3tag
103 struct mp3entry id3;
104 int mempos;
105 int load_ahead_index;
108 static struct id3tag id3tags[MAX_ID3_TAGS];
110 static bool v1first = false;
112 static unsigned int current_track_counter = 0;
113 static unsigned int last_track_counter = 0;
115 #ifndef SIMULATOR
117 static int tag_read_idx = 0;
118 static int tag_write_idx = 0;
120 static int num_tracks_in_memory(void)
122 return (tag_write_idx - tag_read_idx) & MAX_ID3_TAGS_MASK;
124 #endif /* #ifndef SIMULATOR */
126 #ifndef SIMULATOR
127 static void debug_tags(void)
129 #ifdef DEBUG_TAGS
130 int i;
132 for(i = 0;i < MAX_ID3_TAGS;i++)
134 DEBUGF("%d - %s\n", i, id3tags[i].id3.path);
136 DEBUGF("read: %d, write :%d\n", tag_read_idx, tag_write_idx);
137 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
138 #endif /* #ifdef DEBUG_TAGS */
141 static void remove_current_tag(void)
143 if(num_tracks_in_memory() > 0)
145 /* First move the index, so nobody tries to access the tag */
146 tag_read_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
147 debug_tags();
149 else
151 DEBUGF("remove_current_tag: no tracks to remove\n");
155 static void remove_all_non_current_tags(void)
157 tag_write_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
158 debug_tags();
161 static void remove_all_tags(void)
163 tag_write_idx = tag_read_idx;
165 debug_tags();
167 #endif /* #ifndef SIMULATOR */
169 static void set_elapsed(struct mp3entry* id3)
171 if ( id3->vbr ) {
172 if ( id3->has_toc ) {
173 /* calculate elapsed time using TOC */
174 int i;
175 unsigned int remainder, plen, relpos, nextpos;
177 /* find wich percent we're at */
178 for (i=0; i<100; i++ )
180 if ( id3->offset < (int)(id3->toc[i] * (id3->filesize / 256)) )
182 break;
186 i--;
187 if (i < 0)
188 i = 0;
190 relpos = id3->toc[i];
192 if (i < 99)
194 nextpos = id3->toc[i+1];
196 else
198 nextpos = 256;
201 remainder = id3->offset - (relpos * (id3->filesize / 256));
203 /* set time for this percent (divide before multiply to prevent
204 overflow on long files. loss of precision is negligible on
205 short files) */
206 id3->elapsed = i * (id3->length / 100);
208 /* calculate remainder time */
209 plen = (nextpos - relpos) * (id3->filesize / 256);
210 id3->elapsed += (((remainder * 100) / plen) *
211 (id3->length / 10000));
213 else {
214 /* no TOC exists. set a rough estimate using average bitrate */
215 int tpk = id3->length / (id3->filesize / 1024);
216 id3->elapsed = id3->offset / 1024 * tpk;
219 else
220 /* constant bitrate == simple frame calculation */
221 id3->elapsed = id3->offset / id3->bpf * id3->tpf;
224 int mpeg_get_file_pos(void)
226 int pos = -1;
227 struct mp3entry *id3 = mpeg_current_track();
229 if (id3->vbr)
231 if (id3->has_toc)
233 /* Use the TOC to find the new position */
234 unsigned int percent, remainder;
235 int curtoc, nexttoc, plen;
237 percent = (id3->elapsed*100)/id3->length;
238 if (percent > 99)
239 percent = 99;
241 curtoc = id3->toc[percent];
243 if (percent < 99)
244 nexttoc = id3->toc[percent+1];
245 else
246 nexttoc = 256;
248 pos = (id3->filesize/256)*curtoc;
250 /* Use the remainder to get a more accurate position */
251 remainder = (id3->elapsed*100)%id3->length;
252 remainder = (remainder*100)/id3->length;
253 plen = (nexttoc - curtoc)*(id3->filesize/256);
254 pos += (plen/100)*remainder;
256 else
258 /* No TOC exists, estimate the new position */
259 pos = (id3->filesize / (id3->length / 1000)) *
260 (id3->elapsed / 1000);
263 else if (id3->bpf && id3->tpf)
264 pos = (id3->elapsed/id3->tpf)*id3->bpf;
265 else
267 return -1;
270 if (pos >= (int)(id3->filesize - id3->id3v1len))
272 /* Don't seek right to the end of the file so that we can
273 transition properly to the next song */
274 pos = id3->filesize - id3->id3v1len - 1;
276 else if (pos < (int)id3->first_frame_offset)
278 /* skip past id3v2 tag and other leading garbage */
279 pos = id3->first_frame_offset;
281 return pos;
284 unsigned long mpeg_get_last_header(void)
286 #ifdef SIMULATOR
287 return 0;
288 #else
289 unsigned long tmp[2];
291 /* Read the frame data from the MAS and reconstruct it with the
292 frame sync and all */
293 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
294 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
295 #endif
298 static bool paused; /* playback is paused */
300 static unsigned int mpeg_errno;
302 #ifdef SIMULATOR
303 static bool is_playing = false;
304 static bool playing = false;
305 #else
306 static int last_dma_tick = 0;
308 extern unsigned long mas_version_code;
310 static struct event_queue mpeg_queue;
311 static char mpeg_stack[DEFAULT_STACK_SIZE + 0x1000];
312 static const char mpeg_thread_name[] = "mpeg";
314 static int mp3buflen;
315 static int mp3buf_write;
316 static int mp3buf_swapwrite;
317 static int mp3buf_read;
319 static int last_dma_chunk_size;
321 static bool playing; /* We are playing an MP3 stream */
322 static bool play_pending; /* We are about to start playing */
323 static bool is_playing; /* We are (attempting to) playing MP3 files */
324 static bool filling; /* We are filling the buffer with data from disk */
325 static bool dma_underrun; /* True when the DMA has stopped because of
326 slow disk reading (read error, shaking) */
327 static int low_watermark; /* Dynamic low watermark level */
328 static int low_watermark_margin; /* Extra time in seconds for watermark */
329 static int lowest_watermark_level; /* Debug value to observe the buffer
330 usage */
331 #if CONFIG_HWCODEC == MAS3587F
332 static bool is_recording; /* We are recording */
333 static bool stop_pending;
334 unsigned long record_start_time; /* Value of current_tick when recording
335 was started */
336 unsigned long pause_start_time; /* Value of current_tick when pause was
337 started */
338 static bool saving; /* We are saving the buffer to disk */
339 static char recording_filename[MAX_PATH]; /* argument to thread */
340 static char delayed_filename[MAX_PATH]; /* internal copy of above */
341 static int rec_frequency_index; /* For create_xing_header() calls */
342 static int rec_version_index; /* For create_xing_header() calls */
343 static bool disable_xing_header; /* When splitting files */
345 static bool prerecording; /* True if prerecording is enabled */
346 static bool is_prerecording; /* True if we are prerecording */
347 static int prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS]; /* Array of buffer
348 indexes for each
349 prerecorded
350 second */
351 static int prerecord_index; /* Current index in the prerecord buffer */
352 static int prerecording_max_seconds; /* Max number of seconds to store */
353 static int prerecord_count; /* Number of seconds in the prerecord buffer */
354 static int prerecord_timeout; /* The tick count of the next prerecord data store */
356 /* Shadow MAS registers */
357 unsigned long shadow_encoder_control = 0;
358 #endif /* #if CONFIG_HWCODEC == MAS3587F */
360 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
361 unsigned long shadow_io_control_main = 0;
362 unsigned long shadow_app_select = 0;
363 unsigned long shadow_soft_mute = 0;
364 unsigned shadow_codec_reg0;
365 #endif
367 static int mpeg_file;
369 /* Synchronization variables */
370 #if CONFIG_HWCODEC == MAS3587F
371 static bool init_recording_done;
372 static bool init_playback_done;
373 #endif /* #if CONFIG_HWCODEC == MAS3587F */
374 static bool mpeg_stop_done;
376 static void recalculate_watermark(int bitrate)
378 int bytes_per_sec;
379 int time = ata_spinup_time;
381 /* A bitrate of 0 probably means empty VBR header. We play safe
382 and set a high threshold */
383 if(bitrate == 0)
384 bitrate = 320;
386 bytes_per_sec = bitrate * 1000 / 8;
388 if(time)
390 /* No drive spins up faster than 3.5s */
391 if(time < 350)
392 time = 350;
394 time = time * 3;
395 low_watermark = ((low_watermark_margin * HZ + time) *
396 bytes_per_sec) / HZ;
398 else
400 low_watermark = MPEG_LOW_WATER;
404 void mpeg_set_buffer_margin(int seconds)
406 low_watermark_margin = seconds;
409 void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
411 dbgdata->mp3buflen = mp3buflen;
412 dbgdata->mp3buf_write = mp3buf_write;
413 dbgdata->mp3buf_swapwrite = mp3buf_swapwrite;
414 dbgdata->mp3buf_read = mp3buf_read;
416 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
418 dbgdata->dma_on = (SCR0 & 0x80) != 0;
419 dbgdata->playing = playing;
420 dbgdata->play_pending = play_pending;
421 dbgdata->is_playing = is_playing;
422 dbgdata->filling = filling;
423 dbgdata->dma_underrun = dma_underrun;
425 dbgdata->unplayed_space = get_unplayed_space();
426 dbgdata->playable_space = get_playable_space();
427 dbgdata->unswapped_space = get_unswapped_space();
429 dbgdata->low_watermark_level = low_watermark;
430 dbgdata->lowest_watermark_level = lowest_watermark_level;
433 #ifdef DEBUG
434 static void dbg_timer_start(void)
436 /* We are using timer 2 */
438 TSTR &= ~0x04; /* Stop the timer */
439 TSNC &= ~0x04; /* No synchronization */
440 TMDR &= ~0x44; /* Operate normally */
442 TCNT2 = 0; /* Start counting at 0 */
443 TCR2 = 0x03; /* Sysclock/8 */
445 TSTR |= 0x04; /* Start timer 2 */
448 static int dbg_cnt2us(unsigned int cnt)
450 return (cnt * 10000) / (FREQ/800);
452 #endif /* #ifdef DEBUG */
454 static int get_unplayed_space(void)
456 int space = mp3buf_write - mp3buf_read;
457 if (space < 0)
458 space += mp3buflen;
459 return space;
462 static int get_playable_space(void)
464 int space = mp3buf_swapwrite - mp3buf_read;
465 if (space < 0)
466 space += mp3buflen;
467 return space;
470 static int get_unplayed_space_current_song(void)
472 int space;
474 if (num_tracks_in_memory() > 1)
476 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
478 space = id3tags[track_offset].mempos - mp3buf_read;
480 else
482 space = mp3buf_write - mp3buf_read;
485 if (space < 0)
486 space += mp3buflen;
488 return space;
491 static int get_unswapped_space(void)
493 int space = mp3buf_write - mp3buf_swapwrite;
494 if (space < 0)
495 space += mp3buflen;
496 return space;
499 #if CONFIG_HWCODEC == MAS3587F
500 static int get_unsaved_space(void)
502 int space = mp3buf_write - mp3buf_read;
503 if (space < 0)
504 space += mp3buflen;
505 return space;
507 #endif /* #if CONFIG_HWCODEC == MAS3587F */
509 #if CONFIG_HWCODEC == MAS3587F
510 #ifdef DEBUG
511 static long timing_info_index = 0;
512 static long timing_info[1024];
513 #endif /* #ifdef DEBUG */
514 static unsigned long num_rec_bytes;
515 static unsigned long num_recorded_frames;
517 static void drain_dma_buffer(void)
519 asm (
520 "mov #0x40,r2 \n" /* mask for EOD check */
521 "bra .d_start \n"
522 "mov.b @%0,r1 \n" /* read PBDR (first time) */
524 ".d_loop: \n"
525 "xor.b #0x08,@(r0,gbr) \n" /* set PR active */
526 ".d_wait1: \n"
527 "mov.b @%0,r1 \n" /* read PBDR */
528 "cmp/pz r1 \n" /* and wait for PRTW */
529 "bf .d_wait1 \n"
531 "xor.b #0x08,@(r0,gbr) \n" /* reset PR to inactive */
532 ".d_wait2: \n"
533 "mov.b @%0,r1 \n" /* read PBDR */
534 "cmp/pz r1 \n" /* and wait for /PRTW */
535 "bt .d_wait2 \n"
537 ".d_start: \n"
538 "tst r1,r2 \n" /* EOD low? */
539 "bf .d_loop \n" /* no: next pass */
541 : /* outputs */
542 : /* inputs */
543 /* %0 */ "r"(PBDR_ADDR),
544 /* %1 = r0 */ "z"(&PADRH)
545 : /* clobbers */
546 "r1","r2"
550 #endif /* #if CONFIG_HWCODEC == MAS3587F */
552 void rec_tick (void) __attribute__ ((section (".icode")));
553 void rec_tick(void)
555 #if CONFIG_HWCODEC == MAS3587F
556 int i;
557 int num_bytes;
558 if(is_recording && (PBDR & 0x4000))
560 #ifdef DEBUG
561 timing_info[timing_info_index++] = current_tick;
562 TCNT2 = 0;
563 #endif /* #ifdef DEBUG */
564 /* We read as long as EOD is high, but max 30 bytes. */
565 asm (
566 "mov #30,r3 \n" /* i_max = 30 */
567 "mov #0x40,r2 \n" /* mask for EOD check */
568 "mov #0,%0 \n" /* i = 0; */
569 "add %2,%1 \n" /* mp3buf_write -> cur_addr */
570 "add %2,%3 \n" /* mp3buflen -> end_addr */
571 "bra .r_start \n"
572 "mov.b @%4,r1 \n" /* read PBDR (first time) */
574 ".align 2 \n"
576 ".r_loop: \n"
577 "xor.b #0x08,@(r0,gbr) \n" /* set PR active */
578 ".r_wait1: \n"
579 "mov.b @%4,r1 \n" /* read PBDR */
580 "cmp/pz r1 \n" /* and wait for PRTW */
581 "bf .r_wait1 \n"
583 "mov.b @%6,r1 \n" /* read byte from mas */
584 "add #1,%0 \n" /* i++; */
585 "mov.b r1,@%1 \n" /* store byte */
586 "add #1,%1 \n" /* increment current address */
588 "cmp/hi %1,%3 \n" /* end address reached? */
589 "bt .r_nowrap \n" /* no: do nothing */
590 "mov %2,%1 \n" /* yes: reset to start address */
591 ".r_nowrap: \n"
593 "xor.b #0x08,@(r0,gbr) \n" /* set PR inactive again */
594 ".r_wait2: \n"
595 "mov.b @%4,r1 \n" /* read PBDR */
596 "cmp/pz r1 \n" /* and wait for /PRTW */
597 "bt .r_wait2 \n"
599 ".r_start: \n"
600 "tst r2,r1 \n" /* EOD low? */
601 "bt .r_end \n" /* yes: end of transfer */
602 "cmp/hi %0,r3 \n" /* i < i_max? */
603 "bt .r_loop \n" /* yes: next pass */
605 ".r_end: \n"
606 "sub %2,%1 \n" /* cur_addr -> mp3buf_write */
607 : /* outputs */
608 /* %0 */ "=&r"(i),
609 /* %1, in & out */ "+r"(mp3buf_write)
610 : /* inputs */
611 /* %2 */ "r"(mp3buf),
612 /* %3 */ "r"(mp3buflen),
613 /* %4 */ "r"(PBDR_ADDR),
614 /* %5 = r0 */ "z"(&PADRH),
615 /* %6 */ "r"(0x4000000)
616 : /* clobbers */
617 "r1","r2","r3"
619 #ifdef DEBUG
620 timing_info[timing_info_index++] = TCNT2 + (i << 16);
621 timing_info_index &= 0x3ff;
622 #endif /* #ifdef DEBUG */
624 num_rec_bytes += i;
626 if(is_prerecording)
628 if(TIME_AFTER(current_tick, prerecord_timeout))
630 prerecord_timeout = current_tick + HZ;
632 /* Store the write pointer every second */
633 prerecord_buffer[prerecord_index++] = mp3buf_write;
635 /* Wrap if necessary */
636 if(prerecord_index == prerecording_max_seconds)
637 prerecord_index = 0;
639 /* Update the number of seconds recorded */
640 if(prerecord_count < prerecording_max_seconds)
641 prerecord_count++;
644 else
646 /* Signal to save the data if we are running out of buffer
647 space */
648 num_bytes = mp3buf_write - mp3buf_read;
649 if(num_bytes < 0)
650 num_bytes += mp3buflen;
652 if(mp3buflen - num_bytes < MPEG_RECORDING_LOW_WATER && !saving)
654 saving = true;
655 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
656 wake_up_thread();
660 #endif /* #if CONFIG_HWCODEC == MAS3587F */
663 void playback_tick(void)
665 id3tags[tag_read_idx].id3.elapsed +=
666 (current_tick - last_dma_tick) * 1000 / HZ;
667 last_dma_tick = current_tick;
670 static void reset_mp3_buffer(void)
672 mp3buf_read = 0;
673 mp3buf_write = 0;
674 mp3buf_swapwrite = 0;
675 lowest_watermark_level = mp3buflen;
678 /* DMA transfer end interrupt callback */
679 static void transfer_end(unsigned char** ppbuf, int* psize)
681 if(playing && !paused)
683 int unplayed_space_left;
684 int space_until_end_of_buffer;
685 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
687 mp3buf_read += last_dma_chunk_size;
688 if(mp3buf_read >= mp3buflen)
689 mp3buf_read = 0;
691 /* First, check if we are on a track boundary */
692 if (num_tracks_in_memory() > 1)
694 if (mp3buf_read == id3tags[track_offset].mempos)
696 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
697 track_offset = (track_offset+1) & MAX_ID3_TAGS_MASK;
701 unplayed_space_left = get_unplayed_space();
703 space_until_end_of_buffer = mp3buflen - mp3buf_read;
705 if(!filling && unplayed_space_left < low_watermark)
707 filling = true;
708 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
711 if(unplayed_space_left)
713 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
714 last_dma_chunk_size = MIN(last_dma_chunk_size,
715 space_until_end_of_buffer);
717 /* several tracks loaded? */
718 if (num_tracks_in_memory() > 1)
720 /* will we move across the track boundary? */
721 if (( mp3buf_read < id3tags[track_offset].mempos ) &&
722 ((mp3buf_read+last_dma_chunk_size) >
723 id3tags[track_offset].mempos ))
725 /* Make sure that we end exactly on the boundary */
726 last_dma_chunk_size = id3tags[track_offset].mempos
727 - mp3buf_read;
731 *psize = last_dma_chunk_size & 0xffff;
732 *ppbuf = mp3buf + mp3buf_read;
733 id3tags[tag_read_idx].id3.offset += last_dma_chunk_size;
735 /* Update the watermark debug level */
736 if(unplayed_space_left < lowest_watermark_level)
737 lowest_watermark_level = unplayed_space_left;
739 else
741 /* Check if the end of data is because of a hard disk error.
742 If there is an open file handle, we are still playing music.
743 If not, the last file has been loaded, and the file handle is
744 closed. */
745 if(mpeg_file >= 0)
747 /* Update the watermark debug level */
748 if(unplayed_space_left < lowest_watermark_level)
749 lowest_watermark_level = unplayed_space_left;
751 DEBUGF("DMA underrun.\n");
752 dma_underrun = true;
754 else
756 DEBUGF("No more MP3 data. Stopping.\n");
758 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
759 playing = false;
760 is_playing = false;
762 *psize = 0; /* no more transfer */
766 wake_up_thread();
769 static int add_track_to_tag_list(const char *filename)
771 if(num_tracks_in_memory() >= MAX_ID3_TAGS)
773 DEBUGF("Tag memory is full\n");
774 return -1;
777 /* grab id3 tag of new file and
778 remember where in memory it starts */
779 if(mp3info(&id3tags[tag_write_idx].id3, filename, v1first))
781 DEBUGF("Bad mp3\n");
782 return -1;
784 id3tags[tag_write_idx].mempos = mp3buf_write;
785 id3tags[tag_write_idx].id3.elapsed = 0;
787 tag_write_idx = (tag_write_idx+1) & MAX_ID3_TAGS_MASK;
788 debug_tags();
789 return 0;
792 static int new_file(int steps)
794 int max_steps = playlist_amount();
795 int start = 0;
796 int i;
798 /* Find out how many steps to advance. The load_ahead_index field tells
799 us how many playlist entries it had to skip to get to a valid one.
800 We add those together to find out where to start. */
801 if(steps > 0 && num_tracks_in_memory() > 1)
803 /* Begin with the song after the currently playing one */
804 i = (tag_read_idx + 1) & MAX_ID3_TAGS_MASK;
805 while(i != tag_write_idx)
807 start += id3tags[i].load_ahead_index;
808 i = (i+1) & MAX_ID3_TAGS_MASK;
812 do {
813 char *trackname;
815 trackname = playlist_peek( start + steps );
816 if ( !trackname )
817 return -1;
819 DEBUGF("Loading %s\n", trackname);
821 mpeg_file = open(trackname, O_RDONLY);
822 if(mpeg_file < 0) {
823 DEBUGF("Couldn't open file: %s\n",trackname);
824 if(steps < 0)
825 steps--;
826 else
827 steps++;
829 else
831 int new_tag_idx = tag_write_idx;
833 if(add_track_to_tag_list(trackname))
835 /* Bad mp3 file */
836 if(steps < 0)
837 steps--;
838 else
839 steps++;
840 close(mpeg_file);
841 mpeg_file = -1;
843 else
845 /* skip past id3v2 tag */
846 lseek(mpeg_file,
847 id3tags[new_tag_idx].id3.first_frame_offset,
848 SEEK_SET);
849 id3tags[new_tag_idx].id3.index = steps;
850 id3tags[new_tag_idx].load_ahead_index = steps;
851 id3tags[new_tag_idx].id3.offset = 0;
853 if(id3tags[new_tag_idx].id3.vbr)
854 /* Average bitrate * 1.5 */
855 recalculate_watermark(
856 (id3tags[new_tag_idx].id3.bitrate * 3) / 2);
857 else
858 recalculate_watermark(
859 id3tags[new_tag_idx].id3.bitrate);
864 /* Bail out if no file could be opened */
865 if(abs(steps) > max_steps)
866 return -1;
867 } while ( mpeg_file < 0 );
869 return 0;
872 static void stop_playing(void)
874 /* Stop the current stream */
875 mp3_play_stop();
876 playing = false;
877 filling = false;
878 if(mpeg_file >= 0)
879 close(mpeg_file);
880 mpeg_file = -1;
881 remove_all_tags();
882 reset_mp3_buffer();
885 static void update_playlist(void)
887 int index;
889 if (num_tracks_in_memory() > 0)
891 index = playlist_next(id3tags[tag_read_idx].id3.index);
892 id3tags[tag_read_idx].id3.index = index;
896 static void track_change(void)
898 DEBUGF("Track change\n");
900 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
901 /* Reset the AVC */
902 mpeg_sound_set(SOUND_AVC, -1);
903 #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
904 remove_current_tag();
906 update_playlist();
907 current_track_counter++;
910 #ifdef DEBUG
911 void hexdump(const unsigned char *buf, int len)
913 int i;
915 for(i = 0;i < len;i++)
917 if(i && (i & 15) == 0)
919 DEBUGF("\n");
921 DEBUGF("%02x ", buf[i]);
923 DEBUGF("\n");
925 #endif /* #ifdef DEBUG */
927 static void start_playback_if_ready(void)
929 int playable_space;
931 playable_space = mp3buf_swapwrite - mp3buf_read;
932 if(playable_space < 0)
933 playable_space += mp3buflen;
935 /* See if we have started playing yet. If not, do it. */
936 if(play_pending || dma_underrun)
938 /* If the filling has stopped, and we still haven't reached
939 the watermark, the file must be smaller than the
940 watermark. We must still play it. */
941 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
942 !filling || dma_underrun)
944 DEBUGF("P\n");
945 play_pending = false;
946 playing = true;
948 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
949 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
950 dma_underrun = false;
952 if (!paused)
954 last_dma_tick = current_tick;
955 mp3_play_pause(true);
958 /* Tell ourselves that we need more data */
959 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
964 static bool swap_one_chunk(void)
966 int free_space_left;
967 int amount_to_swap;
969 free_space_left = get_unswapped_space();
971 if(free_space_left == 0 && !play_pending)
972 return false;
974 /* Swap in larger chunks when the user is waiting for the playback
975 to start, or when there is dangerously little playable data left */
976 if(play_pending)
977 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
978 else
980 if(get_playable_space() < low_watermark)
981 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
982 free_space_left);
983 else
984 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
987 if(mp3buf_write < mp3buf_swapwrite)
988 amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
989 amount_to_swap);
990 else
991 amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite,
992 amount_to_swap);
994 bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap);
996 mp3buf_swapwrite += amount_to_swap;
997 if(mp3buf_swapwrite >= mp3buflen)
999 mp3buf_swapwrite = 0;
1002 return true;
1005 static const unsigned char empty_id3_header[] =
1007 'I', 'D', '3', 0x03, 0x00, 0x00,
1008 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
1011 static void mpeg_thread(void)
1013 static int pause_tick = 0;
1014 static unsigned int pause_track = 0;
1015 struct event ev;
1016 int len;
1017 int free_space_left;
1018 int unplayed_space_left;
1019 int amount_to_read;
1020 int t1, t2;
1021 int start_offset;
1022 #if CONFIG_HWCODEC == MAS3587F
1023 int amount_to_save;
1024 int writelen;
1025 int framelen;
1026 unsigned long saved_header = 0;
1027 int startpos;
1028 int rc;
1029 int offset;
1030 int countdown;
1031 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1033 is_playing = false;
1034 play_pending = false;
1035 playing = false;
1036 mpeg_file = -1;
1038 while(1)
1040 #if CONFIG_HWCODEC == MAS3587F
1041 if(mpeg_mode == MPEG_DECODER)
1043 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1044 yield();
1046 /* Swap if necessary, and don't block on the queue_wait() */
1047 if(swap_one_chunk())
1049 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1051 else
1053 DEBUGF("S R:%x W:%x SW:%x\n",
1054 mp3buf_read, mp3buf_write, mp3buf_swapwrite);
1055 queue_wait(&mpeg_queue, &ev);
1058 start_playback_if_ready();
1060 switch(ev.id)
1062 case MPEG_PLAY:
1063 DEBUGF("MPEG_PLAY\n");
1065 #ifdef CONFIG_TUNER
1066 /* Silence the A/D input, it may be on because the radio
1067 may be playing */
1068 mas_codec_writereg(6, 0x0000);
1069 #endif /* #ifdef CONFIG_TUNER */
1071 /* Stop the current stream */
1072 play_pending = false;
1073 playing = false;
1074 paused = false;
1075 mp3_play_pause(false);
1077 reset_mp3_buffer();
1078 remove_all_tags();
1080 if(mpeg_file >= 0)
1081 close(mpeg_file);
1083 if ( new_file(0) == -1 )
1085 is_playing = false;
1086 track_change();
1087 break;
1090 start_offset = (int)ev.data;
1092 /* mid-song resume? */
1093 if (start_offset) {
1094 struct mp3entry* id3 = &id3tags[tag_read_idx].id3;
1095 lseek(mpeg_file, start_offset, SEEK_SET);
1096 id3->offset = start_offset;
1097 set_elapsed(id3);
1099 else {
1100 /* skip past id3v2 tag */
1101 lseek(mpeg_file,
1102 id3tags[tag_read_idx].id3.first_frame_offset,
1103 SEEK_SET);
1107 /* Make it read more data */
1108 filling = true;
1109 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1111 /* Tell the file loading code that we want to start playing
1112 as soon as we have some data */
1113 play_pending = true;
1115 update_playlist();
1116 current_track_counter++;
1117 break;
1119 case MPEG_STOP:
1120 DEBUGF("MPEG_STOP\n");
1121 is_playing = false;
1122 paused = false;
1123 stop_playing();
1124 mpeg_stop_done = true;
1125 break;
1127 case MPEG_PAUSE:
1128 DEBUGF("MPEG_PAUSE\n");
1129 /* Stop the current stream */
1130 paused = true;
1131 playing = false;
1132 pause_tick = current_tick;
1133 pause_track = current_track_counter;
1134 mp3_play_pause(false);
1135 break;
1137 case MPEG_RESUME:
1138 DEBUGF("MPEG_RESUME\n");
1139 /* Continue the current stream */
1140 paused = false;
1141 if (!play_pending)
1143 playing = true;
1144 if ( current_track_counter == pause_track )
1145 last_dma_tick += current_tick - pause_tick;
1146 else
1147 last_dma_tick = current_tick;
1148 pause_tick = 0;
1149 mp3_play_pause(true);
1151 break;
1153 case MPEG_NEXT:
1154 DEBUGF("MPEG_NEXT\n");
1155 /* is next track in ram? */
1156 if ( num_tracks_in_memory() > 1 ) {
1157 int unplayed_space_left, unswapped_space_left;
1159 /* stop the current stream */
1160 play_pending = false;
1161 playing = false;
1162 mp3_play_pause(false);
1164 track_change();
1165 mp3buf_read = id3tags[tag_read_idx].mempos;
1166 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1167 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
1168 dma_underrun = false;
1169 last_dma_tick = current_tick;
1171 unplayed_space_left = get_unplayed_space();
1172 unswapped_space_left = get_unswapped_space();
1174 /* should we start reading more data? */
1175 if(!filling && (unplayed_space_left < low_watermark)) {
1176 filling = true;
1177 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1178 play_pending = true;
1179 } else if(unswapped_space_left &&
1180 unswapped_space_left > unplayed_space_left) {
1181 /* Stop swapping the data from the previous file */
1182 mp3buf_swapwrite = mp3buf_read;
1183 play_pending = true;
1184 } else {
1185 playing = true;
1186 if (!paused)
1187 mp3_play_pause(true);
1190 else {
1191 if (!playlist_check(1))
1192 break;
1194 /* stop the current stream */
1195 play_pending = false;
1196 playing = false;
1197 mp3_play_pause(false);
1199 reset_mp3_buffer();
1200 remove_all_tags();
1202 /* Open the next file */
1203 if (mpeg_file >= 0)
1204 close(mpeg_file);
1206 if (new_file(1) < 0) {
1207 DEBUGF("No more files to play\n");
1208 filling = false;
1209 } else {
1210 /* Make it read more data */
1211 filling = true;
1212 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1214 /* Tell the file loading code that we want
1215 to start playing as soon as we have some data */
1216 play_pending = true;
1218 update_playlist();
1219 current_track_counter++;
1222 break;
1224 case MPEG_PREV: {
1225 DEBUGF("MPEG_PREV\n");
1227 if (!playlist_check(-1))
1228 break;
1230 /* stop the current stream */
1231 play_pending = false;
1232 playing = false;
1233 mp3_play_pause(false);
1235 reset_mp3_buffer();
1236 remove_all_tags();
1238 /* Open the next file */
1239 if (mpeg_file >= 0)
1240 close(mpeg_file);
1242 if (new_file(-1) < 0) {
1243 DEBUGF("No more files to play\n");
1244 filling = false;
1245 } else {
1246 /* Make it read more data */
1247 filling = true;
1248 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1250 /* Tell the file loading code that we want to
1251 start playing as soon as we have some data */
1252 play_pending = true;
1254 update_playlist();
1255 current_track_counter++;
1257 break;
1260 case MPEG_FF_REWIND: {
1261 struct mp3entry *id3 = mpeg_current_track();
1262 unsigned int oldtime = id3->elapsed;
1263 unsigned int newtime = (unsigned int)ev.data;
1264 int curpos, newpos, diffpos;
1265 DEBUGF("MPEG_FF_REWIND\n");
1267 id3->elapsed = newtime;
1269 newpos = mpeg_get_file_pos();
1270 if(newpos < 0)
1272 id3->elapsed = oldtime;
1273 break;
1276 if (mpeg_file >= 0)
1277 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1278 else
1279 curpos = id3->filesize;
1281 if (num_tracks_in_memory() > 1)
1283 /* We have started loading other tracks that need to be
1284 accounted for */
1285 int i = tag_read_idx;
1286 int j = tag_write_idx - 1;
1288 if (j < 0)
1289 j = MAX_ID3_TAGS - 1;
1291 while (i != j)
1293 curpos += id3tags[i].id3.filesize;
1294 i = (i+1) & MAX_ID3_TAGS_MASK;
1298 diffpos = curpos - newpos;
1300 if(!filling && diffpos >= 0 && diffpos < mp3buflen)
1302 int unplayed_space_left, unswapped_space_left;
1304 /* We are changing to a position that's already in
1305 memory, so we just move the DMA read pointer. */
1306 mp3buf_read = mp3buf_write - diffpos;
1307 if (mp3buf_read < 0)
1309 mp3buf_read += mp3buflen;
1312 unplayed_space_left = get_unplayed_space();
1313 unswapped_space_left = get_unswapped_space();
1315 /* If unswapped_space_left is larger than
1316 unplayed_space_left, it means that the swapwrite pointer
1317 hasn't yet advanced up to the new location of the read
1318 pointer. We just move it, there is no need to swap
1319 data that won't be played anyway. */
1321 if (unswapped_space_left > unplayed_space_left)
1323 DEBUGF("Moved swapwrite\n");
1324 mp3buf_swapwrite = mp3buf_read;
1325 play_pending = true;
1328 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1330 /* We need to load more data before starting */
1331 filling = true;
1332 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1333 play_pending = true;
1335 else
1337 /* resume will start at new position */
1338 last_dma_chunk_size =
1339 MIN(0x2000, get_unplayed_space_current_song());
1340 mp3_play_data(mp3buf + mp3buf_read,
1341 last_dma_chunk_size, transfer_end);
1342 dma_underrun = false;
1345 else
1347 /* Move to the new position in the file and start
1348 loading data */
1349 reset_mp3_buffer();
1351 if (num_tracks_in_memory() > 1)
1353 /* We have to reload the current track */
1354 close(mpeg_file);
1355 remove_all_non_current_tags();
1356 mpeg_file = -1;
1359 if (mpeg_file < 0)
1361 mpeg_file = open(id3->path, O_RDONLY);
1362 if (mpeg_file < 0)
1364 id3->elapsed = oldtime;
1365 break;
1369 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1371 id3->elapsed = oldtime;
1372 break;
1375 filling = true;
1376 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1378 /* Tell the file loading code that we want to start playing
1379 as soon as we have some data */
1380 play_pending = true;
1383 id3->offset = newpos;
1385 break;
1388 case MPEG_FLUSH_RELOAD: {
1389 int numtracks = num_tracks_in_memory();
1390 bool reload_track = false;
1392 if (numtracks > 1)
1394 /* Reload songs */
1395 int next = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
1397 /* Reset the buffer */
1398 mp3buf_write = id3tags[next].mempos;
1400 /* Reset swapwrite unless we're still swapping current
1401 track */
1402 if (get_unplayed_space() <= get_playable_space())
1403 mp3buf_swapwrite = mp3buf_write;
1405 close(mpeg_file);
1406 remove_all_non_current_tags();
1407 mpeg_file = -1;
1408 reload_track = true;
1410 else if (numtracks == 1 && mpeg_file < 0)
1412 reload_track = true;
1415 if(reload_track && new_file(1) >= 0)
1417 /* Tell ourselves that we want more data */
1418 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1419 filling = true;
1422 break;
1425 case MPEG_NEED_DATA:
1426 free_space_left = mp3buf_read - mp3buf_write;
1428 /* We interpret 0 as "empty buffer" */
1429 if(free_space_left <= 0)
1430 free_space_left = mp3buflen + free_space_left;
1432 unplayed_space_left = mp3buflen - free_space_left;
1434 /* Make sure that we don't fill the entire buffer */
1435 free_space_left -= MPEG_HIGH_WATER;
1437 /* do we have any more buffer space to fill? */
1438 if(free_space_left <= MPEG_HIGH_WATER)
1440 DEBUGF("0\n");
1441 filling = false;
1442 ata_sleep();
1443 break;
1446 /* Read small chunks while we are below the low water mark */
1447 if(unplayed_space_left < low_watermark)
1448 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1449 free_space_left);
1450 else
1451 amount_to_read = free_space_left;
1453 /* Don't read more than until the end of the buffer */
1454 amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
1455 #if MEM == 8
1456 amount_to_read = MIN(0x100000, amount_to_read);
1457 #endif /* #if MEM == 8 */
1458 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1459 amount_to_read = MIN(0x40000, amount_to_read);
1460 #endif
1462 /* Read as much mpeg data as we can fit in the buffer */
1463 if(mpeg_file >= 0)
1465 DEBUGF("R\n");
1466 t1 = current_tick;
1467 len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
1468 if(len > 0)
1470 t2 = current_tick;
1471 DEBUGF("time: %d\n", t2 - t1);
1472 DEBUGF("R: %x\n", len);
1474 /* Now make sure that we don't feed the MAS with ID3V1
1475 data */
1476 if (len < amount_to_read)
1478 int tagptr = mp3buf_write + len - 128;
1479 int i;
1480 char *tag = "TAG";
1481 int taglen = 128;
1483 for(i = 0;i < 3;i++)
1485 if(tagptr >= mp3buflen)
1486 tagptr -= mp3buflen;
1488 if(mp3buf[tagptr] != tag[i])
1489 taglen = 0;
1491 tagptr++;
1494 if(taglen)
1496 /* Skip id3v1 tag */
1497 DEBUGF("Skipping ID3v1 tag\n");
1498 len -= taglen;
1500 /* The very rare case when the entire tag
1501 wasn't read in this read() call must be
1502 taken care of */
1503 if(len < 0)
1504 len = 0;
1508 mp3buf_write += len;
1510 if(mp3buf_write >= mp3buflen)
1512 mp3buf_write = 0;
1513 DEBUGF("W\n");
1516 /* Tell ourselves that we want more data */
1517 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1519 else
1521 if(len < 0)
1523 DEBUGF("MPEG read error\n");
1526 close(mpeg_file);
1527 mpeg_file = -1;
1529 if(new_file(1) < 0)
1531 /* No more data to play */
1532 DEBUGF("No more files to play\n");
1533 filling = false;
1535 else
1537 /* Tell ourselves that we want more data */
1538 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1542 break;
1544 case MPEG_TRACK_CHANGE:
1545 track_change();
1546 break;
1548 #ifndef USB_NONE
1549 case SYS_USB_CONNECTED:
1550 is_playing = false;
1551 paused = false;
1552 stop_playing();
1553 #ifndef SIMULATOR
1555 /* Tell the USB thread that we are safe */
1556 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1557 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1559 /* Wait until the USB cable is extracted again */
1560 usb_wait_for_disconnect(&mpeg_queue);
1561 #endif /* #ifndef SIMULATOR */
1562 break;
1563 #endif /* #ifndef USB_NONE */
1565 #if CONFIG_HWCODEC == MAS3587F
1566 case MPEG_INIT_RECORDING:
1567 init_recording();
1568 init_recording_done = true;
1569 break;
1570 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1572 #if CONFIG_HWCODEC == MAS3587F
1574 else
1576 queue_wait(&mpeg_queue, &ev);
1577 switch(ev.id)
1579 case MPEG_RECORD:
1580 if(is_prerecording)
1582 int startpos, i;
1584 /* Go back prerecord_count seconds in the buffer */
1585 startpos = prerecord_index - prerecord_count;
1586 if(startpos < 0)
1587 startpos += prerecording_max_seconds;
1589 /* Read the mp3 buffer pointer from the prerecord buffer */
1590 startpos = prerecord_buffer[startpos];
1592 DEBUGF("Start looking at address %x (%x)\n",
1593 mp3buf+startpos, startpos);
1595 saved_header = mpeg_get_last_header();
1597 mem_find_next_frame(startpos, &offset, 5000,
1598 saved_header);
1600 mp3buf_read = startpos + offset;
1602 DEBUGF("New mp3buf_read address: %x (%x)\n",
1603 mp3buf+mp3buf_read, mp3buf_read);
1605 /* Make room for headers */
1606 mp3buf_read -= MPEG_RESERVED_HEADER_SPACE;
1607 if(mp3buf_read < 0)
1609 /* Clear the bottom half */
1610 memset(mp3buf, 0,
1611 mp3buf_read + MPEG_RESERVED_HEADER_SPACE);
1613 /* And the top half */
1614 mp3buf_read += mp3buflen;
1615 memset(mp3buf + mp3buf_read, 0,
1616 mp3buflen - mp3buf_read);
1618 else
1620 memset(mp3buf + mp3buf_read, 0,
1621 MPEG_RESERVED_HEADER_SPACE);
1624 /* Copy the empty ID3 header */
1625 startpos = mp3buf_read;
1626 for(i = 0;i < (int)sizeof(empty_id3_header);i++)
1628 mp3buf[startpos++] = empty_id3_header[i];
1629 if(startpos == mp3buflen)
1630 startpos = 0;
1633 DEBUGF("New mp3buf_read address (reservation): %x\n",
1634 mp3buf+mp3buf_read);
1636 DEBUGF("Prerecording...\n");
1638 else
1640 reset_mp3_buffer();
1642 num_rec_bytes = 0;
1644 /* Advance the write pointer to make
1645 room for an ID3 tag plus a VBR header */
1646 mp3buf_write = MPEG_RESERVED_HEADER_SPACE;
1647 memset(mp3buf, 0, MPEG_RESERVED_HEADER_SPACE);
1649 /* Insert the ID3 header */
1650 memcpy(mp3buf, empty_id3_header,
1651 sizeof(empty_id3_header));
1653 DEBUGF("Recording...\n");
1656 start_recording();
1658 /* Wait until at least one frame is encoded and get the
1659 frame header, for later use by the Xing header
1660 generation */
1661 sleep(HZ/10);
1662 saved_header = mpeg_get_last_header();
1664 /* delayed until buffer is saved, don't open yet */
1665 strcpy(delayed_filename, recording_filename);
1666 mpeg_file = -1;
1668 break;
1670 case MPEG_STOP:
1671 DEBUGF("MPEG_STOP\n");
1673 stop_recording();
1675 /* Save the remaining data in the buffer */
1676 stop_pending = true;
1677 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1678 break;
1680 case MPEG_STOP_DONE:
1681 DEBUGF("MPEG_STOP_DONE\n");
1683 if(mpeg_file >= 0)
1684 close(mpeg_file);
1686 if(!disable_xing_header && num_rec_bytes > 0)
1688 /* Create the Xing header */
1689 mpeg_file = open(recording_filename, O_RDWR);
1690 if(mpeg_file < 0)
1691 panicf("rec upd: %d (%s)", mpeg_file,
1692 recording_filename);
1694 /* If the number of recorded frames have
1695 reached 0x7ffff, we can no longer trust it */
1696 if(num_recorded_frames == 0x7ffff)
1697 num_recorded_frames = 0;
1699 /* Also, if we have been prerecording, the frame count
1700 will be wrong */
1701 if(prerecording)
1702 num_recorded_frames = 0;
1704 /* saved_header is saved right before stopping
1705 the MAS */
1706 framelen = create_xing_header(mpeg_file, 0,
1707 num_rec_bytes, mp3buf,
1708 num_recorded_frames,
1709 saved_header, NULL,
1710 false);
1712 lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE-framelen,
1713 SEEK_SET);
1714 write(mpeg_file, mp3buf, framelen);
1715 close(mpeg_file);
1717 mpeg_file = -1;
1719 #ifdef DEBUG1
1721 int i;
1722 for(i = 0;i < 512;i++)
1724 DEBUGF("%d - %d us (%d bytes)\n",
1725 timing_info[i*2],
1726 (timing_info[i*2+1] & 0xffff) *
1727 10000 / 13824,
1728 timing_info[i*2+1] >> 16);
1731 #endif /* #ifdef DEBUG1 */
1733 if(prerecording)
1735 start_prerecording();
1737 mpeg_stop_done = true;
1738 break;
1740 case MPEG_NEW_FILE:
1741 /* Make sure we have at least one complete frame
1742 in the buffer. If we haven't recorded a single
1743 frame within 200ms, the MAS is probably not recording
1744 anything, and we bail out. */
1745 countdown = 20;
1746 amount_to_save = get_unsaved_space();
1747 while(countdown-- && amount_to_save < 1800)
1749 sleep(HZ/10);
1750 amount_to_save = get_unsaved_space();
1753 if(amount_to_save >= 1800)
1755 /* Now find a frame boundary to split at */
1756 startpos = mp3buf_write - 1800;
1757 if(startpos < 0)
1758 startpos += mp3buflen;
1760 rc = mem_find_next_frame(startpos, &offset, 1800,
1761 saved_header);
1762 if(rc) /* Header found? */
1764 /* offset will now contain the number of bytes to
1765 add to startpos to find the frame boundary */
1766 startpos += offset;
1767 if(startpos >= mp3buflen)
1768 startpos -= mp3buflen;
1770 else
1772 /* No header found. Let's save the whole buffer. */
1773 startpos = mp3buf_write;
1776 else
1778 /* Too few bytes recorded, timeout */
1779 startpos = mp3buf_write;
1782 amount_to_save = startpos - mp3buf_read;
1783 if(amount_to_save < 0)
1784 amount_to_save += mp3buflen;
1786 /* First save up to the end of the buffer */
1787 writelen = MIN(amount_to_save,
1788 mp3buflen - mp3buf_read);
1790 if (mpeg_file < 0) /* delayed file opening */
1792 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT);
1794 if(mpeg_file < 0)
1795 panicf("recfile: %d", mpeg_file);
1798 if(writelen)
1800 rc = write(mpeg_file, mp3buf + mp3buf_read, writelen);
1801 if(rc < 0)
1803 if(errno == ENOSPC)
1805 mpeg_errno = MPEGERR_DISK_FULL;
1806 demand_irq_enable(false);
1807 stop_recording();
1808 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1809 break;
1811 else
1813 panicf("spt wrt: %d", rc);
1818 /* Then save the rest */
1819 writelen = amount_to_save - writelen;
1820 if(writelen)
1822 rc = write(mpeg_file, mp3buf, writelen);
1823 if(rc < 0)
1825 if(errno == ENOSPC)
1827 mpeg_errno = MPEGERR_DISK_FULL;
1828 demand_irq_enable(false);
1829 stop_recording();
1830 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1831 break;
1833 else
1835 panicf("spt wrt: %d", rc);
1840 /* Advance the buffer pointers */
1841 mp3buf_read += amount_to_save;
1842 if(mp3buf_read >= mp3buflen)
1843 mp3buf_read -= mp3buflen;
1845 /* Close the current file */
1846 rc = close(mpeg_file);
1847 if(rc < 0)
1848 panicf("spt cls: %d", rc);
1850 /* Open the new file */
1851 mpeg_file = open(recording_filename, O_WRONLY|O_CREAT);
1852 if(mpeg_file < 0)
1853 panicf("sptfile: %d", mpeg_file);
1854 break;
1856 case MPEG_SAVE_DATA:
1857 amount_to_save = get_unsaved_space();
1859 /* If the result is negative, the write index has
1860 wrapped */
1861 if(amount_to_save < 0)
1863 amount_to_save += mp3buflen;
1866 DEBUGF("r: %x w: %x\n", mp3buf_read, mp3buf_write);
1867 DEBUGF("ats: %x\n", amount_to_save);
1869 /* Save data only if the buffer is getting full,
1870 or if we should stop recording */
1871 if(amount_to_save)
1873 if(mp3buflen -
1874 amount_to_save < MPEG_RECORDING_LOW_WATER ||
1875 stop_pending)
1877 /* Only save up to the end of the buffer */
1878 writelen = MIN(amount_to_save,
1879 mp3buflen - mp3buf_read);
1881 DEBUGF("wrl: %x\n", writelen);
1883 if (mpeg_file < 0) /* delayed file opening */
1885 mpeg_file = open(delayed_filename,
1886 O_WRONLY|O_CREAT);
1888 if(mpeg_file < 0)
1889 panicf("recfile: %d", mpeg_file);
1892 rc = write(mpeg_file, mp3buf + mp3buf_read,
1893 writelen);
1895 if(rc < 0)
1897 if(errno == ENOSPC)
1899 mpeg_errno = MPEGERR_DISK_FULL;
1900 stop_recording();
1901 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1902 break;
1904 else
1906 panicf("rec wrt: %d", rc);
1910 mp3buf_read += amount_to_save;
1911 if(mp3buf_read >= mp3buflen)
1912 mp3buf_read = 0;
1914 rc = fsync(mpeg_file);
1915 if(rc < 0)
1916 panicf("rec fls: %d", rc);
1918 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1920 else
1922 saving = false;
1923 ata_sleep();
1926 else
1928 /* We have saved all data,
1929 time to stop for real */
1930 if(stop_pending)
1931 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1932 saving = false;
1933 ata_sleep();
1935 break;
1937 case MPEG_INIT_PLAYBACK:
1938 /* Stop the prerecording */
1939 stop_recording();
1940 mp3_play_init();
1941 init_playback_done = true;
1942 break;
1944 case MPEG_PAUSE_RECORDING:
1945 pause_recording();
1946 break;
1948 case MPEG_RESUME_RECORDING:
1949 resume_recording();
1950 break;
1952 case SYS_USB_CONNECTED:
1953 /* We can safely go to USB mode if no recording
1954 is taking place */
1955 if((!is_recording || is_prerecording) && mpeg_stop_done)
1957 /* Even if we aren't recording, we still call this
1958 function, to put the MAS in monitoring mode,
1959 to save power. */
1960 stop_recording();
1962 /* Tell the USB thread that we are safe */
1963 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1964 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1966 /* Wait until the USB cable is extracted again */
1967 usb_wait_for_disconnect(&mpeg_queue);
1969 break;
1972 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1975 #endif /* SIMULATOR */
1977 #ifdef SIMULATOR
1978 static struct mp3entry taginfo;
1979 #endif /* #ifdef SIMULATOR */
1981 void mpeg_id3_options(bool _v1first)
1983 v1first = _v1first;
1986 struct mp3entry* mpeg_current_track()
1988 #ifdef SIMULATOR
1989 return &taginfo;
1990 #else
1991 if(num_tracks_in_memory())
1992 return &id3tags[tag_read_idx].id3;
1993 else
1994 return NULL;
1995 #endif /* #ifdef SIMULATOR */
1998 struct mp3entry* mpeg_next_track()
2000 #ifdef SIMULATOR
2001 return &taginfo;
2002 #else
2003 if(num_tracks_in_memory() > 1)
2004 return &(id3tags[(tag_read_idx+1) & MAX_ID3_TAGS_MASK].id3);
2005 else
2006 return NULL;
2007 #endif /* #ifdef SIMULATOR */
2010 bool mpeg_has_changed_track(void)
2012 if(last_track_counter != current_track_counter)
2014 last_track_counter = current_track_counter;
2015 return true;
2017 return false;
2020 #if CONFIG_HWCODEC == MAS3587F
2021 void mpeg_init_playback(void)
2023 init_playback_done = false;
2024 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, NULL);
2026 while(!init_playback_done)
2027 sleep_thread();
2028 wake_up_thread();
2032 /****************************************************************************
2035 ** Recording functions
2038 ***************************************************************************/
2039 void mpeg_init_recording(void)
2041 init_recording_done = false;
2042 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, NULL);
2044 while(!init_recording_done)
2045 sleep_thread();
2046 wake_up_thread();
2049 static void init_recording(void)
2051 unsigned long val;
2052 int rc;
2054 /* Disable IRQ6 */
2055 IPRB &= 0xff0f;
2057 stop_playing();
2058 is_playing = false;
2059 paused = false;
2061 /* Init the recording variables */
2062 is_recording = false;
2063 is_prerecording = false;
2065 mpeg_stop_done = true;
2067 mas_reset();
2069 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2070 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2071 if(rc < 0)
2072 panicf("mas_ctrl_w: %d", rc);
2074 /* Stop the current application */
2075 val = 0;
2076 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2079 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2080 } while(val);
2082 /* Perform black magic as described by the data sheet */
2083 if((mas_version_code & 0x0fff) == 0x0102)
2085 DEBUGF("Performing MAS black magic for B2 version\n");
2086 mas_writereg(0xa3, 0x98);
2087 mas_writereg(0x94, 0xfffff);
2088 val = 0;
2089 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2090 mas_writereg(0xa3, 0x90);
2093 /* Enable A/D Converters */
2094 shadow_codec_reg0 = 0xcccd;
2095 mas_codec_writereg(0x0, shadow_codec_reg0);
2097 /* Copy left channel to right (mono mode) */
2098 mas_codec_writereg(8, 0x8000);
2100 /* ADC scale 0%, DSP scale 100%
2101 We use the DSP output for monitoring, because it works with all
2102 sources including S/PDIF */
2103 mas_codec_writereg(6, 0x0000);
2104 mas_codec_writereg(7, 0x4000);
2106 /* No mute */
2107 shadow_soft_mute = 0;
2108 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2110 /* Set Demand mode, monitoring OFF and validate all settings */
2111 shadow_io_control_main = 0x125;
2112 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2114 /* Start the encoder application */
2115 val = 0x40;
2116 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2119 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2120 } while(!(val & 0x40));
2122 #if 1
2123 /* We have started the recording application with monitoring OFF.
2124 This is because we want to record at least one frame to fill the DMA
2125 buffer, because the silly MAS will not negate EOD until at least one
2126 DMA transfer has taken place.
2127 Now let's wait for some data to be encoded. */
2128 sleep(20);
2130 /* Now set it to Monitoring mode as default, saves power */
2131 shadow_io_control_main = 0x525;
2132 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2134 /* Wait until the DSP has accepted the settings */
2137 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2138 } while(val & 1);
2140 drain_dma_buffer();
2141 #endif
2142 mpeg_mode = MPEG_ENCODER;
2144 DEBUGF("MAS Recording application started\n");
2146 /* At this point, all settings are the reset MAS defaults, next thing is to
2147 call mpeg_set_recording_options(). */
2150 void mpeg_record(const char *filename)
2152 mpeg_errno = 0;
2154 strncpy(recording_filename, filename, MAX_PATH - 1);
2155 recording_filename[MAX_PATH - 1] = 0;
2157 disable_xing_header = false;
2158 queue_post(&mpeg_queue, MPEG_RECORD, NULL);
2161 void mpeg_pause_recording(void)
2163 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, NULL);
2166 void mpeg_resume_recording(void)
2168 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, NULL);
2171 static void start_prerecording(void)
2173 unsigned long val;
2175 DEBUGF("Starting prerecording\n");
2177 prerecord_index = 0;
2178 prerecord_count = 0;
2179 prerecord_timeout = current_tick + HZ;
2180 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2181 reset_mp3_buffer();
2183 is_prerecording = true;
2185 /* Stop monitoring and start the encoder */
2186 shadow_io_control_main &= ~(1 << 10);
2187 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2188 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2190 /* Wait until the DSP has accepted the settings */
2193 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2194 } while(val & 1);
2196 is_recording = true;
2197 stop_pending = false;
2198 saving = false;
2200 demand_irq_enable(true);
2203 static void start_recording(void)
2205 unsigned long val;
2207 num_recorded_frames = 0;
2209 if(is_prerecording)
2211 /* This will make the IRQ handler start recording
2212 for real, i.e send MPEG_SAVE_DATA messages when
2213 the buffer is full */
2214 is_prerecording = false;
2216 else
2218 /* If prerecording is off, we need to stop the monitoring
2219 and start the encoder */
2220 shadow_io_control_main &= ~(1 << 10);
2221 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2222 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2224 /* Wait until the DSP has accepted the settings */
2227 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2228 } while(val & 1);
2231 is_recording = true;
2232 stop_pending = false;
2233 saving = false;
2234 paused = false;
2236 /* Store the current time */
2237 if(prerecording)
2238 record_start_time = current_tick - prerecord_count * HZ;
2239 else
2240 record_start_time = current_tick;
2242 pause_start_time = 0;
2244 demand_irq_enable(true);
2247 static void pause_recording(void)
2249 pause_start_time = current_tick;
2251 /* Set the pause bit */
2252 shadow_soft_mute |= 2;
2253 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2255 paused = true;
2258 static void resume_recording(void)
2260 paused = false;
2262 /* Clear the pause bit */
2263 shadow_soft_mute &= ~2;
2264 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2266 /* Compensate for the time we have been paused */
2267 if(pause_start_time)
2269 record_start_time =
2270 current_tick - (pause_start_time - record_start_time);
2271 pause_start_time = 0;
2275 static void stop_recording(void)
2277 unsigned long val;
2279 /* Let it finish the last frame */
2280 if(!paused)
2281 pause_recording();
2282 sleep(HZ/5);
2284 demand_irq_enable(false);
2286 is_recording = false;
2287 is_prerecording = false;
2289 /* Read the number of frames recorded */
2290 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &num_recorded_frames, 1);
2292 /* Start monitoring */
2293 shadow_io_control_main |= (1 << 10);
2294 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2295 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2297 /* Wait until the DSP has accepted the settings */
2300 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2301 } while(val & 1);
2303 resume_recording();
2306 void mpeg_set_recording_options(int frequency, int quality,
2307 int source, int channel_mode,
2308 bool editable, int prerecord_time)
2310 bool is_mpeg1;
2312 is_mpeg1 = (frequency < 3)?true:false;
2314 rec_version_index = is_mpeg1?3:2;
2315 rec_frequency_index = frequency % 3;
2317 shadow_encoder_control = (quality << 17) |
2318 (rec_frequency_index << 10) |
2319 ((is_mpeg1?1:0) << 9) |
2320 (((channel_mode * 2 + 1) & 3) << 6) |
2321 (1 << 5) /* MS-stereo */ |
2322 (1 << 2) /* Is an original */;
2323 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2325 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2327 shadow_soft_mute = editable?4:0;
2328 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2330 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2332 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2333 ((source < 2)?1:2) << 8) | /* Input select */
2334 (1 << 5) | /* SDO strobe invert */
2335 ((is_mpeg1?0:1) << 3) |
2336 (1 << 2) | /* Inverted SIBC clock signal */
2337 1; /* Validate */
2338 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2340 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2342 if(source == 0) /* Mic */
2344 /* Copy left channel to right (mono mode) */
2345 mas_codec_writereg(8, 0x8000);
2347 else
2349 /* Stereo input mode */
2350 mas_codec_writereg(8, 0);
2353 prerecording_max_seconds = prerecord_time;
2354 if(prerecording_max_seconds)
2356 prerecording = true;
2357 start_prerecording();
2359 else
2361 prerecording = false;
2362 is_prerecording = false;
2363 is_recording = false;
2367 /* If use_mic is true, the left gain is used */
2368 void mpeg_set_recording_gain(int left, int right, bool use_mic)
2370 /* Enable both left and right A/D */
2371 shadow_codec_reg0 = (left << 12) |
2372 (right << 8) |
2373 (left << 4) |
2374 (use_mic?0x0008:0) | /* Connect left A/D to mic */
2375 0x0007;
2376 mas_codec_writereg(0x0, shadow_codec_reg0);
2379 /* try to make some kind of beep, also in recording mode */
2380 void mpeg_beep(int duration)
2382 long starttick = current_tick;
2384 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2385 * While this is still audible even without an external signal,
2386 * it doesn't affect the (pre-)recording. */
2387 mas_codec_writereg(0, shadow_codec_reg0 ^ 1);
2388 mas_codec_writereg(0, shadow_codec_reg0);
2390 while (current_tick - starttick < duration);
2393 void mpeg_new_file(const char *filename)
2395 mpeg_errno = 0;
2397 strncpy(recording_filename, filename, MAX_PATH - 1);
2398 recording_filename[MAX_PATH - 1] = 0;
2400 num_rec_bytes = 0;
2401 disable_xing_header = true;
2403 /* Store the current time */
2404 record_start_time = current_tick;
2405 if(paused)
2406 pause_start_time = record_start_time;
2408 queue_post(&mpeg_queue, MPEG_NEW_FILE, NULL);
2411 unsigned long mpeg_recorded_time(void)
2413 if(is_prerecording)
2414 return prerecord_count * HZ;
2416 if(is_recording)
2418 if(paused)
2419 return pause_start_time - record_start_time;
2420 else
2421 return current_tick - record_start_time;
2424 return 0;
2427 unsigned long mpeg_num_recorded_bytes(void)
2429 int num_bytes;
2430 int index;
2432 if(is_recording)
2434 if(is_prerecording)
2436 index = prerecord_index - prerecord_count;
2437 if(index < 0)
2438 index += prerecording_max_seconds;
2440 num_bytes = mp3buf_write - prerecord_buffer[index];
2441 if(num_bytes < 0)
2442 num_bytes += mp3buflen;
2444 return num_bytes;;
2446 else
2447 return num_rec_bytes;
2449 else
2450 return 0;
2453 #endif
2455 void mpeg_play(int offset)
2457 #ifdef SIMULATOR
2458 char* trackname;
2459 int steps=0;
2461 is_playing = true;
2463 do {
2464 trackname = playlist_peek( steps );
2465 if (!trackname)
2466 break;
2467 if(mp3info(&taginfo, trackname, v1first)) {
2468 /* bad mp3, move on */
2469 if(++steps > playlist_amount())
2470 break;
2471 continue;
2473 #ifdef HAVE_MPEG_PLAY
2474 real_mpeg_play(trackname);
2475 #endif
2476 playlist_next(steps);
2477 taginfo.offset = offset;
2478 set_elapsed(&taginfo);
2479 is_playing = true;
2480 playing = true;
2481 break;
2482 } while(1);
2483 #else
2484 is_playing = true;
2486 queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset);
2487 #endif /* #ifdef SIMULATOR */
2489 mpeg_errno = 0;
2492 void mpeg_stop(void)
2494 #ifndef SIMULATOR
2495 mpeg_stop_done = false;
2496 queue_post(&mpeg_queue, MPEG_STOP, NULL);
2497 while(!mpeg_stop_done)
2498 yield();
2499 #else
2500 paused = false;
2501 is_playing = false;
2502 playing = false;
2503 #endif /* #ifndef SIMULATOR */
2507 void mpeg_pause(void)
2509 #ifndef SIMULATOR
2510 queue_post(&mpeg_queue, MPEG_PAUSE, NULL);
2511 #else
2512 is_playing = true;
2513 playing = false;
2514 paused = true;
2515 #endif /* #ifndef SIMULATOR */
2518 void mpeg_resume(void)
2520 #ifndef SIMULATOR
2521 queue_post(&mpeg_queue, MPEG_RESUME, NULL);
2522 #else
2523 is_playing = true;
2524 playing = true;
2525 paused = false;
2526 #endif /* #ifndef SIMULATOR */
2529 void mpeg_next(void)
2531 #ifndef SIMULATOR
2532 queue_post(&mpeg_queue, MPEG_NEXT, NULL);
2533 #else
2534 char* file;
2535 int steps = 1;
2536 int index;
2538 do {
2539 file = playlist_peek(steps);
2540 if(!file)
2541 break;
2542 if(mp3info(&taginfo, file, v1first)) {
2543 if(++steps > playlist_amount())
2544 break;
2545 continue;
2547 index = playlist_next(steps);
2548 taginfo.index = index;
2549 current_track_counter++;
2550 is_playing = true;
2551 playing = true;
2552 break;
2553 } while(1);
2554 #endif /* #ifndef SIMULATOR */
2557 void mpeg_prev(void)
2559 #ifndef SIMULATOR
2560 queue_post(&mpeg_queue, MPEG_PREV, NULL);
2561 #else
2562 char* file;
2563 int steps = -1;
2564 int index;
2566 do {
2567 file = playlist_peek(steps);
2568 if(!file)
2569 break;
2570 if(mp3info(&taginfo, file, v1first)) {
2571 steps--;
2572 continue;
2574 index = playlist_next(steps);
2575 taginfo.index = index;
2576 current_track_counter++;
2577 is_playing = true;
2578 playing = true;
2579 break;
2580 } while(1);
2581 #endif /* #ifndef SIMULATOR */
2584 void mpeg_ff_rewind(int newtime)
2586 #ifndef SIMULATOR
2587 queue_post(&mpeg_queue, MPEG_FF_REWIND, (void *)newtime);
2588 #else
2589 (void)newtime;
2590 #endif /* #ifndef SIMULATOR */
2593 void mpeg_flush_and_reload_tracks(void)
2595 #ifndef SIMULATOR
2596 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, NULL);
2597 #endif /* #ifndef SIMULATOR*/
2600 int mpeg_status(void)
2602 int ret = 0;
2604 if(is_playing)
2605 ret |= MPEG_STATUS_PLAY;
2607 if(paused)
2608 ret |= MPEG_STATUS_PAUSE;
2610 #if CONFIG_HWCODEC == MAS3587F
2611 if(is_recording && !is_prerecording)
2612 ret |= MPEG_STATUS_RECORD;
2614 if(is_prerecording)
2615 ret |= MPEG_STATUS_PRERECORD;
2616 #endif /* #if CONFIG_HWCODEC == MAS3587F */
2618 if(mpeg_errno)
2619 ret |= MPEG_STATUS_ERROR;
2621 return ret;
2624 unsigned int mpeg_error(void)
2626 return mpeg_errno;
2629 void mpeg_error_clear(void)
2631 mpeg_errno = 0;
2634 #ifdef SIMULATOR
2635 static char mpeg_stack[DEFAULT_STACK_SIZE];
2636 static const char mpeg_thread_name[] = "mpeg";
2637 static void mpeg_thread(void)
2639 struct mp3entry* id3;
2640 while ( 1 ) {
2641 if (is_playing) {
2642 id3 = mpeg_current_track();
2643 if (!paused)
2645 id3->elapsed+=1000;
2646 id3->offset+=1000;
2648 if (id3->elapsed>=id3->length)
2649 mpeg_next();
2651 sleep(HZ);
2654 #endif /* #ifdef SIMULATOR */
2656 void mpeg_init(void)
2658 mpeg_errno = 0;
2660 #ifndef SIMULATOR
2661 mp3buflen = mp3end - mp3buf;
2662 queue_init(&mpeg_queue);
2663 #endif /* #ifndef SIMULATOR */
2664 create_thread(mpeg_thread, mpeg_stack,
2665 sizeof(mpeg_stack), mpeg_thread_name);
2667 memset(id3tags, sizeof(id3tags), 0);
2669 #if CONFIG_HWCODEC == MAS3587F
2670 if(read_hw_mask() & PR_ACTIVE_HIGH)
2671 and_b(~0x08, &PADRH);
2672 else
2673 or_b(0x08, &PADRH);
2674 #endif /* #if CONFIG_HWCODEC == MAS3587F */
2676 #ifdef DEBUG
2677 dbg_timer_start();
2678 dbg_cnt2us(0);
2679 #endif /* DEBUG */