new SOURCES file that specifies which files to build in each dir, use
[kugel-rb.git] / firmware / mpeg.c
blob0eea71228c07c047151087704b2fbe4a755d1bc0
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 "config.h"
21 #include "debug.h"
22 #include "panic.h"
23 #include "id3.h"
24 #include "mpeg.h"
25 #include "ata.h"
26 #include "string.h"
27 #include <kernel.h>
28 #include "thread.h"
29 #include "errno.h"
30 #include "mp3data.h"
31 #include "buffer.h"
32 #include "mp3_playback.h"
33 #ifndef SIMULATOR
34 #include "i2c.h"
35 #include "mas.h"
36 #include "dac.h"
37 #include "system.h"
38 #include "usb.h"
39 #include "file.h"
40 #include "hwcompat.h"
41 #else
42 #include "mpegplay.h"
43 #endif /* #ifndef SIMULATOR */
45 #include "bitswap.h"
47 #if CONFIG_HWCODEC == MAS3587F
48 static void init_recording(void);
49 static void start_prerecording(void);
50 static void start_recording(void);
51 static void stop_recording(void);
52 static int get_unsaved_space(void);
53 static void pause_recording(void);
54 static void resume_recording(void);
55 #endif /* #if CONFIG_HWCODEC == MAS3587F */
57 #ifndef SIMULATOR
58 static int get_unplayed_space(void);
59 static int get_playable_space(void);
60 static int get_unswapped_space(void);
61 #endif /* #ifndef SIMULATOR */
63 #define MPEG_PLAY 1
64 #define MPEG_STOP 2
65 #define MPEG_PAUSE 3
66 #define MPEG_RESUME 4
67 #define MPEG_NEXT 5
68 #define MPEG_PREV 6
69 #define MPEG_FF_REWIND 7
70 #define MPEG_FLUSH_RELOAD 8
71 #define MPEG_RECORD 9
72 #define MPEG_INIT_RECORDING 10
73 #define MPEG_INIT_PLAYBACK 11
74 #define MPEG_NEW_FILE 12
75 #define MPEG_PAUSE_RECORDING 13
76 #define MPEG_RESUME_RECORDING 14
77 #define MPEG_NEED_DATA 100
78 #define MPEG_TRACK_CHANGE 101
79 #define MPEG_SAVE_DATA 102
80 #define MPEG_STOP_DONE 103
82 #if CONFIG_HWCODEC == MAS3587F
83 extern enum /* from mp3_playback.c */
85 MPEG_DECODER,
86 MPEG_ENCODER
87 } mpeg_mode;
88 #endif /* #if CONFIG_HWCODEC == MAS3587F */
90 extern char* playlist_peek(int steps);
91 extern bool playlist_check(int steps);
92 extern int playlist_next(int steps);
93 extern int playlist_amount(void);
94 extern void update_file_pos( int id, int pos );
96 /* list of tracks in memory */
97 #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
98 #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
100 struct id3tag
102 struct mp3entry id3;
103 int mempos;
104 bool used;
107 static struct id3tag *id3tags[MAX_ID3_TAGS];
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("id3tags[%d]: %08x", i, id3tags[i]);
135 if(id3tags[i])
136 DEBUGF(" - %s", id3tags[i]->id3.path);
137 DEBUGF("\n");
139 DEBUGF("read: %d, write :%d\n", tag_read_idx, tag_write_idx);
140 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
141 #endif /* #ifdef DEBUG_TAGS */
144 static bool append_tag(struct id3tag *tag)
146 if(num_tracks_in_memory() < MAX_ID3_TAGS - 1)
148 id3tags[tag_write_idx] = tag;
149 tag_write_idx = (tag_write_idx+1) & MAX_ID3_TAGS_MASK;
150 debug_tags();
151 return true;
153 else
155 DEBUGF("Tag memory is full\n");
156 return false;
160 static void remove_current_tag(void)
162 int oldidx = tag_read_idx;
164 if(num_tracks_in_memory() > 0)
166 /* First move the index, so nobody tries to access the tag */
167 tag_read_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
169 /* Now delete it */
170 id3tags[oldidx]->used = false;
171 id3tags[oldidx] = NULL;
172 debug_tags();
176 static void remove_all_non_current_tags(void)
178 int i = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
180 while (i != tag_write_idx)
182 id3tags[i]->used = false;
183 id3tags[i] = NULL;
185 i = (i+1) & MAX_ID3_TAGS_MASK;
188 tag_write_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
189 debug_tags();
192 static void remove_all_tags(void)
194 int i;
196 for(i = 0;i < MAX_ID3_TAGS;i++)
197 remove_current_tag();
199 tag_write_idx = tag_read_idx;
201 debug_tags();
203 #endif /* #ifndef SIMULATOR */
205 static void set_elapsed(struct mp3entry* id3)
207 if ( id3->vbr ) {
208 if ( id3->has_toc ) {
209 /* calculate elapsed time using TOC */
210 int i;
211 unsigned int remainder, plen, relpos, nextpos;
213 /* find wich percent we're at */
214 for (i=0; i<100; i++ )
216 if ( id3->offset < (int)(id3->toc[i] * (id3->filesize / 256)) )
218 break;
222 i--;
223 if (i < 0)
224 i = 0;
226 relpos = id3->toc[i];
228 if (i < 99)
230 nextpos = id3->toc[i+1];
232 else
234 nextpos = 256;
237 remainder = id3->offset - (relpos * (id3->filesize / 256));
239 /* set time for this percent (divide before multiply to prevent
240 overflow on long files. loss of precision is negligible on
241 short files) */
242 id3->elapsed = i * (id3->length / 100);
244 /* calculate remainder time */
245 plen = (nextpos - relpos) * (id3->filesize / 256);
246 id3->elapsed += (((remainder * 100) / plen) *
247 (id3->length / 10000));
249 else {
250 /* no TOC exists. set a rough estimate using average bitrate */
251 int tpk = id3->length / (id3->filesize / 1024);
252 id3->elapsed = id3->offset / 1024 * tpk;
255 else
256 /* constant bitrate == simple frame calculation */
257 id3->elapsed = id3->offset / id3->bpf * id3->tpf;
260 int mpeg_get_file_pos(void)
262 int pos = -1;
263 struct mp3entry *id3 = mpeg_current_track();
265 if (id3->vbr)
267 if (id3->has_toc)
269 /* Use the TOC to find the new position */
270 unsigned int percent, remainder;
271 int curtoc, nexttoc, plen;
273 percent = (id3->elapsed*100)/id3->length;
274 if (percent > 99)
275 percent = 99;
277 curtoc = id3->toc[percent];
279 if (percent < 99)
280 nexttoc = id3->toc[percent+1];
281 else
282 nexttoc = 256;
284 pos = (id3->filesize/256)*curtoc;
286 /* Use the remainder to get a more accurate position */
287 remainder = (id3->elapsed*100)%id3->length;
288 remainder = (remainder*100)/id3->length;
289 plen = (nexttoc - curtoc)*(id3->filesize/256);
290 pos += (plen/100)*remainder;
292 else
294 /* No TOC exists, estimate the new position */
295 pos = (id3->filesize / (id3->length / 1000)) *
296 (id3->elapsed / 1000);
299 else if (id3->bpf && id3->tpf)
300 pos = (id3->elapsed/id3->tpf)*id3->bpf;
301 else
303 return -1;
306 if (pos >= (int)(id3->filesize - id3->id3v1len))
308 /* Don't seek right to the end of the file so that we can
309 transition properly to the next song */
310 pos = id3->filesize - id3->id3v1len - 1;
312 else if (pos < (int)id3->first_frame_offset)
314 /* skip past id3v2 tag and other leading garbage */
315 pos = id3->first_frame_offset;
317 return pos;
320 unsigned long mpeg_get_last_header(void)
322 #ifdef SIMULATOR
323 return 0;
324 #else
325 unsigned long tmp[2];
327 /* Read the frame data from the MAS and reconstruct it with the
328 frame sync and all */
329 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_STATUS_1, tmp, 2);
330 return 0xffe00000 | ((tmp[0] & 0x7c00) << 6) | (tmp[1] & 0xffff);
331 #endif
334 static bool paused; /* playback is paused */
336 static unsigned int mpeg_errno;
338 #ifdef SIMULATOR
339 static bool is_playing = false;
340 static bool playing = false;
341 #else
342 static int last_dma_tick = 0;
344 extern unsigned long mas_version_code;
346 static struct event_queue mpeg_queue;
347 static char mpeg_stack[DEFAULT_STACK_SIZE + 0x1000];
348 static const char mpeg_thread_name[] = "mpeg";
350 static int mp3buflen;
351 static int mp3buf_write;
352 static int mp3buf_swapwrite;
353 static int mp3buf_read;
355 static int last_dma_chunk_size;
357 static bool playing; /* We are playing an MP3 stream */
358 static bool play_pending; /* We are about to start playing */
359 static bool is_playing; /* We are (attempting to) playing MP3 files */
360 static bool filling; /* We are filling the buffer with data from disk */
361 static bool dma_underrun; /* True when the DMA has stopped because of
362 slow disk reading (read error, shaking) */
363 static int low_watermark; /* Dynamic low watermark level */
364 static int low_watermark_margin; /* Extra time in seconds for watermark */
365 static int lowest_watermark_level; /* Debug value to observe the buffer
366 usage */
367 #if CONFIG_HWCODEC == MAS3587F
368 static bool is_recording; /* We are recording */
369 static bool stop_pending;
370 unsigned long record_start_time; /* Value of current_tick when recording
371 was started */
372 unsigned long pause_start_time; /* Value of current_tick when pause was
373 started */
374 static bool saving; /* We are saving the buffer to disk */
375 static char recording_filename[MAX_PATH]; /* argument to thread */
376 static char delayed_filename[MAX_PATH]; /* internal copy of above */
377 static int rec_frequency_index; /* For create_xing_header() calls */
378 static int rec_version_index; /* For create_xing_header() calls */
379 static bool disable_xing_header; /* When splitting files */
381 static bool prerecording; /* True if prerecording is enabled */
382 static bool is_prerecording; /* True if we are prerecording */
383 static int prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS]; /* Array of buffer
384 indexes for each
385 prerecorded
386 second */
387 static int prerecord_index; /* Current index in the prerecord buffer */
388 static int prerecording_max_seconds; /* Max number of seconds to store */
389 static int prerecord_count; /* Number of seconds in the prerecord buffer */
390 static int prerecord_timeout; /* The tick count of the next prerecord data store */
392 /* Shadow MAS registers */
393 unsigned long shadow_encoder_control = 0;
394 #endif /* #if CONFIG_HWCODEC == MAS3587F */
396 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
397 unsigned long shadow_io_control_main = 0;
398 unsigned long shadow_app_select = 0;
399 unsigned long shadow_soft_mute = 0;
400 #endif
402 static int mpeg_file;
404 /* Synchronization variables */
405 #if CONFIG_HWCODEC == MAS3587F
406 static bool init_recording_done;
407 static bool init_playback_done;
408 #endif /* #if CONFIG_HWCODEC == MAS3587F */
409 static bool mpeg_stop_done;
411 static void recalculate_watermark(int bitrate)
413 int bytes_per_sec;
414 int time = ata_spinup_time;
416 /* A bitrate of 0 probably means empty VBR header. We play safe
417 and set a high threshold */
418 if(bitrate == 0)
419 bitrate = 320;
421 bytes_per_sec = bitrate * 1000 / 8;
423 if(time)
425 /* No drive spins up faster than 3.5s */
426 if(time < 350)
427 time = 350;
429 time = time * 3;
430 low_watermark = ((low_watermark_margin * HZ + time) *
431 bytes_per_sec) / HZ;
433 else
435 low_watermark = MPEG_LOW_WATER;
439 void mpeg_set_buffer_margin(int seconds)
441 low_watermark_margin = seconds;
444 void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
446 dbgdata->mp3buflen = mp3buflen;
447 dbgdata->mp3buf_write = mp3buf_write;
448 dbgdata->mp3buf_swapwrite = mp3buf_swapwrite;
449 dbgdata->mp3buf_read = mp3buf_read;
451 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
453 dbgdata->dma_on = (SCR0 & 0x80) != 0;
454 dbgdata->playing = playing;
455 dbgdata->play_pending = play_pending;
456 dbgdata->is_playing = is_playing;
457 dbgdata->filling = filling;
458 dbgdata->dma_underrun = dma_underrun;
460 dbgdata->unplayed_space = get_unplayed_space();
461 dbgdata->playable_space = get_playable_space();
462 dbgdata->unswapped_space = get_unswapped_space();
464 dbgdata->low_watermark_level = low_watermark;
465 dbgdata->lowest_watermark_level = lowest_watermark_level;
468 #ifdef DEBUG
469 static void dbg_timer_start(void)
471 /* We are using timer 2 */
473 TSTR &= ~0x04; /* Stop the timer */
474 TSNC &= ~0x04; /* No synchronization */
475 TMDR &= ~0x44; /* Operate normally */
477 TCNT2 = 0; /* Start counting at 0 */
478 TCR2 = 0x03; /* Sysclock/8 */
480 TSTR |= 0x04; /* Start timer 2 */
483 static int dbg_cnt2us(unsigned int cnt)
485 return (cnt * 10000) / (FREQ/800);
487 #endif /* #ifdef DEBUG */
489 static int get_unplayed_space(void)
491 int space = mp3buf_write - mp3buf_read;
492 if (space < 0)
493 space += mp3buflen;
494 return space;
497 static int get_playable_space(void)
499 int space = mp3buf_swapwrite - mp3buf_read;
500 if (space < 0)
501 space += mp3buflen;
502 return space;
505 static int get_unplayed_space_current_song(void)
507 int space;
509 if (num_tracks_in_memory() > 1)
511 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
513 space = id3tags[track_offset]->mempos - mp3buf_read;
515 else
517 space = mp3buf_write - mp3buf_read;
520 if (space < 0)
521 space += mp3buflen;
523 return space;
526 static int get_unswapped_space(void)
528 int space = mp3buf_write - mp3buf_swapwrite;
529 if (space < 0)
530 space += mp3buflen;
531 return space;
534 #if CONFIG_HWCODEC == MAS3587F
535 static int get_unsaved_space(void)
537 int space = mp3buf_write - mp3buf_read;
538 if (space < 0)
539 space += mp3buflen;
540 return space;
542 #endif /* #if CONFIG_HWCODEC == MAS3587F */
544 #if CONFIG_HWCODEC == MAS3587F
545 #ifdef DEBUG
546 static long timing_info_index = 0;
547 static long timing_info[1024];
548 #endif /* #ifdef DEBUG */
549 static unsigned long num_rec_bytes;
550 static unsigned long num_recorded_frames;
552 static void drain_dma_buffer(void)
554 asm (
555 "mov #0x40,r2 \n" /* mask for EOD check */
556 "bra .d_start \n"
557 "mov.b @%0,r1 \n" /* read PBDR (first time) */
559 ".d_loop: \n"
560 "xor.b #0x08,@(r0,gbr) \n" /* set PR active */
561 ".d_wait1: \n"
562 "mov.b @%0,r1 \n" /* read PBDR */
563 "cmp/pz r1 \n" /* and wait for PRTW */
564 "bf .d_wait1 \n"
566 "xor.b #0x08,@(r0,gbr) \n" /* reset PR to inactive */
567 ".d_wait2: \n"
568 "mov.b @%0,r1 \n" /* read PBDR */
569 "cmp/pz r1 \n" /* and wait for /PRTW */
570 "bt .d_wait2 \n"
572 ".d_start: \n"
573 "tst r1,r2 \n" /* EOD low? */
574 "bf .d_loop \n" /* no: next pass */
576 : /* outputs */
577 : /* inputs */
578 /* %0 */ "r"(PBDR_ADDR),
579 /* %1 = r0 */ "z"(&PADRH)
580 : /* clobbers */
581 "r1","r2"
585 #endif /* #if CONFIG_HWCODEC == MAS3587F */
587 void rec_tick (void) __attribute__ ((section (".icode")));
588 void rec_tick(void)
590 #if CONFIG_HWCODEC == MAS3587F
591 int i;
592 int num_bytes;
593 if(is_recording && (PBDR & 0x4000))
595 #ifdef DEBUG
596 timing_info[timing_info_index++] = current_tick;
597 TCNT2 = 0;
598 #endif /* #ifdef DEBUG */
599 /* We read as long as EOD is high, but max 30 bytes. */
600 asm (
601 "mov #30,r3 \n" /* i_max = 30 */
602 "mov #0x40,r2 \n" /* mask for EOD check */
603 "mov #0,%0 \n" /* i = 0; */
604 "add %2,%1 \n" /* mp3buf_write -> cur_addr */
605 "add %2,%3 \n" /* mp3buflen -> end_addr */
606 "bra .r_start \n"
607 "mov.b @%4,r1 \n" /* read PBDR (first time) */
609 ".align 2 \n"
611 ".r_loop: \n"
612 "xor.b #0x08,@(r0,gbr) \n" /* set PR active */
613 ".r_wait1: \n"
614 "mov.b @%4,r1 \n" /* read PBDR */
615 "cmp/pz r1 \n" /* and wait for PRTW */
616 "bf .r_wait1 \n"
618 "mov.b @%6,r1 \n" /* read byte from mas */
619 "add #1,%0 \n" /* i++; */
620 "mov.b r1,@%1 \n" /* store byte */
621 "add #1,%1 \n" /* increment current address */
623 "cmp/hi %1,%3 \n" /* end address reached? */
624 "bt .r_nowrap \n" /* no: do nothing */
625 "mov %2,%1 \n" /* yes: reset to start address */
626 ".r_nowrap: \n"
628 "xor.b #0x08,@(r0,gbr) \n" /* set PR inactive again */
629 ".r_wait2: \n"
630 "mov.b @%4,r1 \n" /* read PBDR */
631 "cmp/pz r1 \n" /* and wait for /PRTW */
632 "bt .r_wait2 \n"
634 ".r_start: \n"
635 "tst r2,r1 \n" /* EOD low? */
636 "bt .r_end \n" /* yes: end of transfer */
637 "cmp/hi %0,r3 \n" /* i < i_max? */
638 "bt .r_loop \n" /* yes: next pass */
640 ".r_end: \n"
641 "sub %2,%1 \n" /* cur_addr -> mp3buf_write */
642 : /* outputs */
643 /* %0 */ "=&r"(i),
644 /* %1, in & out */ "+r"(mp3buf_write)
645 : /* inputs */
646 /* %2 */ "r"(mp3buf),
647 /* %3 */ "r"(mp3buflen),
648 /* %4 */ "r"(PBDR_ADDR),
649 /* %5 = r0 */ "z"(&PADRH),
650 /* %6 */ "r"(0x4000000)
651 : /* clobbers */
652 "r1","r2","r3"
654 #ifdef DEBUG
655 timing_info[timing_info_index++] = TCNT2 + (i << 16);
656 timing_info_index &= 0x3ff;
657 #endif /* #ifdef DEBUG */
659 num_rec_bytes += i;
661 if(is_prerecording)
663 if(TIME_AFTER(current_tick, prerecord_timeout))
665 prerecord_timeout = current_tick + HZ;
667 /* Store the write pointer every second */
668 prerecord_buffer[prerecord_index++] = mp3buf_write;
670 /* Wrap if necessary */
671 if(prerecord_index == prerecording_max_seconds)
672 prerecord_index = 0;
674 /* Update the number of seconds recorded */
675 if(prerecord_count < prerecording_max_seconds)
676 prerecord_count++;
679 else
681 /* Signal to save the data if we are running out of buffer
682 space */
683 num_bytes = mp3buf_write - mp3buf_read;
684 if(num_bytes < 0)
685 num_bytes += mp3buflen;
687 if(mp3buflen - num_bytes < MPEG_RECORDING_LOW_WATER && !saving)
689 saving = true;
690 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
691 wake_up_thread();
695 #endif /* #if CONFIG_HWCODEC == MAS3587F */
698 void playback_tick(void)
700 id3tags[tag_read_idx]->id3.elapsed +=
701 (current_tick - last_dma_tick) * 1000 / HZ;
702 last_dma_tick = current_tick;
705 static void reset_mp3_buffer(void)
707 mp3buf_read = 0;
708 mp3buf_write = 0;
709 mp3buf_swapwrite = 0;
710 lowest_watermark_level = mp3buflen;
713 /* DMA transfer end interrupt callback */
714 static void transfer_end(unsigned char** ppbuf, int* psize)
716 if(playing && !paused)
718 int unplayed_space_left;
719 int space_until_end_of_buffer;
720 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
722 mp3buf_read += last_dma_chunk_size;
723 if(mp3buf_read >= mp3buflen)
724 mp3buf_read = 0;
726 /* First, check if we are on a track boundary */
727 if (num_tracks_in_memory() > 0)
729 if (mp3buf_read == id3tags[track_offset]->mempos)
731 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
732 track_offset = (track_offset+1) & MAX_ID3_TAGS_MASK;
736 unplayed_space_left = get_unplayed_space();
738 space_until_end_of_buffer = mp3buflen - mp3buf_read;
740 if(!filling && unplayed_space_left < low_watermark)
742 filling = true;
743 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
746 if(unplayed_space_left)
748 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
749 last_dma_chunk_size = MIN(last_dma_chunk_size,
750 space_until_end_of_buffer);
752 /* several tracks loaded? */
753 if (num_tracks_in_memory() > 1)
755 /* will we move across the track boundary? */
756 if (( mp3buf_read < id3tags[track_offset]->mempos ) &&
757 ((mp3buf_read+last_dma_chunk_size) >
758 id3tags[track_offset]->mempos ))
760 /* Make sure that we end exactly on the boundary */
761 last_dma_chunk_size = id3tags[track_offset]->mempos
762 - mp3buf_read;
766 *psize = last_dma_chunk_size & 0xffff;
767 *ppbuf = mp3buf + mp3buf_read;
768 id3tags[tag_read_idx]->id3.offset += last_dma_chunk_size;
770 /* Update the watermark debug level */
771 if(unplayed_space_left < lowest_watermark_level)
772 lowest_watermark_level = unplayed_space_left;
774 else
776 /* Check if the end of data is because of a hard disk error.
777 If there is an open file handle, we are still playing music.
778 If not, the last file has been loaded, and the file handle is
779 closed. */
780 if(mpeg_file >= 0)
782 /* Update the watermark debug level */
783 if(unplayed_space_left < lowest_watermark_level)
784 lowest_watermark_level = unplayed_space_left;
786 DEBUGF("DMA underrun.\n");
787 dma_underrun = true;
789 else
791 DEBUGF("No more MP3 data. Stopping.\n");
793 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
794 playing = false;
795 is_playing = false;
797 *psize = 0; /* no more transfer */
801 wake_up_thread();
804 static int add_track_to_tag_list(const char *filename)
806 struct id3tag *t = NULL;
807 int i;
809 /* find a free tag */
810 for (i=0; i < MAX_ID3_TAGS_MASK; i++ )
811 if ( !_id3tags[i].used )
812 t = &_id3tags[i];
813 if(t)
815 /* grab id3 tag of new file and
816 remember where in memory it starts */
817 if(mp3info(&(t->id3), filename, v1first))
819 DEBUGF("Bad mp3\n");
820 return -1;
822 t->mempos = mp3buf_write;
823 t->id3.elapsed = 0;
824 if(!append_tag(t))
826 DEBUGF("Tag list is full\n");
828 else
829 t->used = true;
831 else
833 DEBUGF("No memory available for id3 tag");
835 return 0;
838 /* If next_track is true, opens the next track, if false, opens prev track */
839 static int new_file(int steps)
841 int max_steps = playlist_amount();
842 int start = num_tracks_in_memory() - 1;
844 if (start < 0)
845 start = 0;
847 do {
848 char *trackname;
850 trackname = playlist_peek( start + steps );
851 if ( !trackname )
852 return -1;
854 DEBUGF("playing %s\n", trackname);
856 mpeg_file = open(trackname, O_RDONLY);
857 if(mpeg_file < 0) {
858 DEBUGF("Couldn't open file: %s\n",trackname);
859 steps++;
861 /* Bail out if no file could be opened */
862 if(steps > max_steps)
863 return -1;
865 else
867 int new_tag_idx = tag_write_idx;
869 if(add_track_to_tag_list(trackname))
871 /* Bad mp3 file */
872 steps++;
873 close(mpeg_file);
874 mpeg_file = -1;
876 else
878 /* skip past id3v2 tag */
879 lseek(mpeg_file,
880 id3tags[new_tag_idx]->id3.first_frame_offset,
881 SEEK_SET);
882 id3tags[new_tag_idx]->id3.index = steps;
883 id3tags[new_tag_idx]->id3.offset = 0;
885 if(id3tags[new_tag_idx]->id3.vbr)
886 /* Average bitrate * 1.5 */
887 recalculate_watermark(
888 (id3tags[new_tag_idx]->id3.bitrate * 3) / 2);
889 else
890 recalculate_watermark(
891 id3tags[new_tag_idx]->id3.bitrate);
895 } while ( mpeg_file < 0 );
897 return 0;
900 static void stop_playing(void)
902 /* Stop the current stream */
903 mp3_play_stop();
904 playing = false;
905 filling = false;
906 if(mpeg_file >= 0)
907 close(mpeg_file);
908 mpeg_file = -1;
909 remove_all_tags();
910 reset_mp3_buffer();
913 static void update_playlist(void)
915 int index;
917 if (num_tracks_in_memory() > 0)
919 index = playlist_next(id3tags[tag_read_idx]->id3.index);
920 id3tags[tag_read_idx]->id3.index = index;
924 static void track_change(void)
926 DEBUGF("Track change\n");
928 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
929 /* Reset the AVC */
930 mpeg_sound_set(SOUND_AVC, -1);
931 #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
932 remove_current_tag();
934 update_playlist();
935 current_track_counter++;
938 #ifdef DEBUG
939 void hexdump(const unsigned char *buf, int len)
941 int i;
943 for(i = 0;i < len;i++)
945 if(i && (i & 15) == 0)
947 DEBUGF("\n");
949 DEBUGF("%02x ", buf[i]);
951 DEBUGF("\n");
953 #endif /* #ifdef DEBUG */
955 static void start_playback_if_ready(void)
957 int playable_space;
959 playable_space = mp3buf_swapwrite - mp3buf_read;
960 if(playable_space < 0)
961 playable_space += mp3buflen;
963 /* See if we have started playing yet. If not, do it. */
964 if(play_pending || dma_underrun)
966 /* If the filling has stopped, and we still haven't reached
967 the watermark, the file must be smaller than the
968 watermark. We must still play it. */
969 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
970 !filling || dma_underrun)
972 DEBUGF("P\n");
973 play_pending = false;
974 playing = true;
976 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
977 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
978 dma_underrun = false;
980 if (!paused)
982 last_dma_tick = current_tick;
983 mp3_play_pause(true);
986 /* Tell ourselves that we need more data */
987 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
992 static bool swap_one_chunk(void)
994 int free_space_left;
995 int amount_to_swap;
997 free_space_left = get_unswapped_space();
999 if(free_space_left == 0 && !play_pending)
1000 return false;
1002 /* Swap in larger chunks when the user is waiting for the playback
1003 to start, or when there is dangerously little playable data left */
1004 if(play_pending)
1005 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
1006 else
1008 if(get_playable_space() < low_watermark)
1009 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
1010 free_space_left);
1011 else
1012 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
1015 if(mp3buf_write < mp3buf_swapwrite)
1016 amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
1017 amount_to_swap);
1018 else
1019 amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite,
1020 amount_to_swap);
1022 bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap);
1024 mp3buf_swapwrite += amount_to_swap;
1025 if(mp3buf_swapwrite >= mp3buflen)
1027 mp3buf_swapwrite = 0;
1030 return true;
1033 static const unsigned char empty_id3_header[] =
1035 'I', 'D', '3', 0x03, 0x00, 0x00,
1036 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
1039 static void mpeg_thread(void)
1041 static int pause_tick = 0;
1042 static unsigned int pause_track = 0;
1043 struct event ev;
1044 int len;
1045 int free_space_left;
1046 int unplayed_space_left;
1047 int amount_to_read;
1048 int t1, t2;
1049 int start_offset;
1050 #if CONFIG_HWCODEC == MAS3587F
1051 int amount_to_save;
1052 int writelen;
1053 int framelen;
1054 unsigned long saved_header = 0;
1055 int startpos;
1056 int rc;
1057 int offset;
1058 int countdown;
1059 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1061 is_playing = false;
1062 play_pending = false;
1063 playing = false;
1064 mpeg_file = -1;
1066 while(1)
1068 #if CONFIG_HWCODEC == MAS3587F
1069 if(mpeg_mode == MPEG_DECODER)
1071 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1072 yield();
1074 /* Swap if necessary, and don't block on the queue_wait() */
1075 if(swap_one_chunk())
1077 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1079 else
1081 DEBUGF("S R:%x W:%x SW:%x\n",
1082 mp3buf_read, mp3buf_write, mp3buf_swapwrite);
1083 queue_wait(&mpeg_queue, &ev);
1086 start_playback_if_ready();
1088 switch(ev.id)
1090 case MPEG_PLAY:
1091 DEBUGF("MPEG_PLAY\n");
1093 #ifdef CONFIG_TUNER
1094 /* Silence the A/D input, it may be on because the radio
1095 may be playing */
1096 mas_codec_writereg(6, 0x0000);
1097 #endif /* #ifdef CONFIG_TUNER */
1099 /* Stop the current stream */
1100 play_pending = false;
1101 playing = false;
1102 paused = false;
1103 mp3_play_pause(false);
1105 reset_mp3_buffer();
1106 remove_all_tags();
1108 if(mpeg_file >= 0)
1109 close(mpeg_file);
1111 if ( new_file(0) == -1 )
1113 is_playing = false;
1114 track_change();
1115 break;
1118 start_offset = (int)ev.data;
1120 /* mid-song resume? */
1121 if (start_offset) {
1122 struct mp3entry* id3 = &id3tags[tag_read_idx]->id3;
1123 lseek(mpeg_file, start_offset, SEEK_SET);
1124 id3->offset = start_offset;
1125 set_elapsed(id3);
1127 else {
1128 /* skip past id3v2 tag */
1129 lseek(mpeg_file,
1130 id3tags[tag_read_idx]->id3.first_frame_offset,
1131 SEEK_SET);
1135 /* Make it read more data */
1136 filling = true;
1137 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1139 /* Tell the file loading code that we want to start playing
1140 as soon as we have some data */
1141 play_pending = true;
1143 update_playlist();
1144 current_track_counter++;
1145 break;
1147 case MPEG_STOP:
1148 DEBUGF("MPEG_STOP\n");
1149 is_playing = false;
1150 paused = false;
1151 stop_playing();
1152 mpeg_stop_done = true;
1153 break;
1155 case MPEG_PAUSE:
1156 DEBUGF("MPEG_PAUSE\n");
1157 /* Stop the current stream */
1158 paused = true;
1159 playing = false;
1160 pause_tick = current_tick;
1161 pause_track = current_track_counter;
1162 mp3_play_pause(false);
1163 break;
1165 case MPEG_RESUME:
1166 DEBUGF("MPEG_RESUME\n");
1167 /* Continue the current stream */
1168 paused = false;
1169 if (!play_pending)
1171 playing = true;
1172 if ( current_track_counter == pause_track )
1173 last_dma_tick += current_tick - pause_tick;
1174 else
1175 last_dma_tick = current_tick;
1176 pause_tick = 0;
1177 mp3_play_pause(true);
1179 break;
1181 case MPEG_NEXT:
1182 DEBUGF("MPEG_NEXT\n");
1183 /* is next track in ram? */
1184 if ( num_tracks_in_memory() > 1 ) {
1185 int unplayed_space_left, unswapped_space_left;
1187 /* stop the current stream */
1188 play_pending = false;
1189 playing = false;
1190 mp3_play_pause(false);
1192 track_change();
1193 mp3buf_read = id3tags[tag_read_idx]->mempos;
1194 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1195 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
1196 dma_underrun = false;
1197 last_dma_tick = current_tick;
1199 unplayed_space_left = get_unplayed_space();
1200 unswapped_space_left = get_unswapped_space();
1202 /* should we start reading more data? */
1203 if(!filling && (unplayed_space_left < low_watermark)) {
1204 filling = true;
1205 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1206 play_pending = true;
1207 } else if(unswapped_space_left &&
1208 unswapped_space_left > unplayed_space_left) {
1209 /* Stop swapping the data from the previous file */
1210 mp3buf_swapwrite = mp3buf_read;
1211 play_pending = true;
1212 } else {
1213 playing = true;
1214 if (!paused)
1215 mp3_play_pause(true);
1218 else {
1219 if (!playlist_check(1))
1220 break;
1222 /* stop the current stream */
1223 play_pending = false;
1224 playing = false;
1225 mp3_play_pause(false);
1227 reset_mp3_buffer();
1228 remove_all_tags();
1230 /* Open the next file */
1231 if (mpeg_file >= 0)
1232 close(mpeg_file);
1234 if (new_file(1) < 0) {
1235 DEBUGF("No more files to play\n");
1236 filling = false;
1237 } else {
1238 /* Make it read more data */
1239 filling = true;
1240 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1242 /* Tell the file loading code that we want
1243 to start playing as soon as we have some data */
1244 play_pending = true;
1246 update_playlist();
1247 current_track_counter++;
1250 break;
1252 case MPEG_PREV: {
1253 DEBUGF("MPEG_PREV\n");
1255 if (!playlist_check(-1))
1256 break;
1258 /* stop the current stream */
1259 play_pending = false;
1260 playing = false;
1261 mp3_play_pause(false);
1263 reset_mp3_buffer();
1264 remove_all_tags();
1266 /* Open the next file */
1267 if (mpeg_file >= 0)
1268 close(mpeg_file);
1270 if (new_file(-1) < 0) {
1271 DEBUGF("No more files to play\n");
1272 filling = false;
1273 } else {
1274 /* Make it read more data */
1275 filling = true;
1276 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1278 /* Tell the file loading code that we want to
1279 start playing as soon as we have some data */
1280 play_pending = true;
1282 update_playlist();
1283 current_track_counter++;
1285 break;
1288 case MPEG_FF_REWIND: {
1289 struct mp3entry *id3 = mpeg_current_track();
1290 unsigned int oldtime = id3->elapsed;
1291 unsigned int newtime = (unsigned int)ev.data;
1292 int curpos, newpos, diffpos;
1293 DEBUGF("MPEG_FF_REWIND\n");
1295 id3->elapsed = newtime;
1297 newpos = mpeg_get_file_pos();
1298 if(newpos < 0)
1300 id3->elapsed = oldtime;
1301 break;
1304 if (mpeg_file >= 0)
1305 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1306 else
1307 curpos = id3->filesize;
1309 if (num_tracks_in_memory() > 1)
1311 /* We have started loading other tracks that need to be
1312 accounted for */
1313 int i = tag_read_idx;
1314 int j = tag_write_idx - 1;
1316 if (j < 0)
1317 j = MAX_ID3_TAGS - 1;
1319 while (i != j)
1321 curpos += id3tags[i]->id3.filesize;
1322 i = (i+1) & MAX_ID3_TAGS_MASK;
1326 diffpos = curpos - newpos;
1328 if(!filling && diffpos >= 0 && diffpos < mp3buflen)
1330 int unplayed_space_left, unswapped_space_left;
1332 /* We are changing to a position that's already in
1333 memory, so we just move the DMA read pointer. */
1334 mp3buf_read = mp3buf_write - diffpos;
1335 if (mp3buf_read < 0)
1337 mp3buf_read += mp3buflen;
1340 unplayed_space_left = get_unplayed_space();
1341 unswapped_space_left = get_unswapped_space();
1343 /* If unswapped_space_left is larger than
1344 unplayed_space_left, it means that the swapwrite pointer
1345 hasn't yet advanced up to the new location of the read
1346 pointer. We just move it, there is no need to swap
1347 data that won't be played anyway. */
1349 if (unswapped_space_left > unplayed_space_left)
1351 DEBUGF("Moved swapwrite\n");
1352 mp3buf_swapwrite = mp3buf_read;
1353 play_pending = true;
1356 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1358 /* We need to load more data before starting */
1359 filling = true;
1360 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1361 play_pending = true;
1363 else
1365 /* resume will start at new position */
1366 last_dma_chunk_size =
1367 MIN(0x2000, get_unplayed_space_current_song());
1368 mp3_play_data(mp3buf + mp3buf_read,
1369 last_dma_chunk_size, transfer_end);
1370 dma_underrun = false;
1373 else
1375 /* Move to the new position in the file and start
1376 loading data */
1377 reset_mp3_buffer();
1379 if (num_tracks_in_memory() > 1)
1381 /* We have to reload the current track */
1382 close(mpeg_file);
1383 remove_all_non_current_tags();
1384 mpeg_file = -1;
1387 if (mpeg_file < 0)
1389 mpeg_file = open(id3->path, O_RDONLY);
1390 if (mpeg_file < 0)
1392 id3->elapsed = oldtime;
1393 break;
1397 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1399 id3->elapsed = oldtime;
1400 break;
1403 filling = true;
1404 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1406 /* Tell the file loading code that we want to start playing
1407 as soon as we have some data */
1408 play_pending = true;
1411 id3->offset = newpos;
1413 break;
1416 case MPEG_FLUSH_RELOAD: {
1417 int numtracks = num_tracks_in_memory();
1418 bool reload_track = false;
1420 if (numtracks > 1)
1422 /* Reload songs */
1423 int next = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
1425 /* Reset the buffer */
1426 mp3buf_write = id3tags[next]->mempos;
1428 /* Reset swapwrite unless we're still swapping current
1429 track */
1430 if (get_unplayed_space() <= get_playable_space())
1431 mp3buf_swapwrite = mp3buf_write;
1433 close(mpeg_file);
1434 remove_all_non_current_tags();
1435 mpeg_file = -1;
1436 reload_track = true;
1438 else if (numtracks == 1 && mpeg_file < 0)
1440 reload_track = true;
1443 if(reload_track && new_file(1) >= 0)
1445 /* Tell ourselves that we want more data */
1446 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1447 filling = true;
1450 break;
1453 case MPEG_NEED_DATA:
1454 free_space_left = mp3buf_read - mp3buf_write;
1456 /* We interpret 0 as "empty buffer" */
1457 if(free_space_left <= 0)
1458 free_space_left = mp3buflen + free_space_left;
1460 unplayed_space_left = mp3buflen - free_space_left;
1462 /* Make sure that we don't fill the entire buffer */
1463 free_space_left -= MPEG_HIGH_WATER;
1465 /* do we have any more buffer space to fill? */
1466 if(free_space_left <= MPEG_HIGH_WATER)
1468 DEBUGF("0\n");
1469 filling = false;
1470 ata_sleep();
1471 break;
1474 /* Read small chunks while we are below the low water mark */
1475 if(unplayed_space_left < low_watermark)
1476 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1477 free_space_left);
1478 else
1479 amount_to_read = free_space_left;
1481 /* Don't read more than until the end of the buffer */
1482 amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
1483 #if MEM == 8
1484 amount_to_read = MIN(0x100000, amount_to_read);
1485 #endif /* #if MEM == 8 */
1487 /* Read as much mpeg data as we can fit in the buffer */
1488 if(mpeg_file >= 0)
1490 DEBUGF("R\n");
1491 t1 = current_tick;
1492 len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
1493 if(len > 0)
1495 t2 = current_tick;
1496 DEBUGF("time: %d\n", t2 - t1);
1497 DEBUGF("R: %x\n", len);
1499 /* Now make sure that we don't feed the MAS with ID3V1
1500 data */
1501 if (len < amount_to_read)
1503 int tagptr = mp3buf_write + len - 128;
1504 int i;
1505 char *tag = "TAG";
1506 int taglen = 128;
1508 for(i = 0;i < 3;i++)
1510 if(tagptr >= mp3buflen)
1511 tagptr -= mp3buflen;
1513 if(mp3buf[tagptr] != tag[i])
1514 taglen = 0;
1516 tagptr++;
1519 if(taglen)
1521 /* Skip id3v1 tag */
1522 DEBUGF("Skipping ID3v1 tag\n");
1523 len -= taglen;
1525 /* The very rare case when the entire tag
1526 wasn't read in this read() call must be
1527 taken care of */
1528 if(len < 0)
1529 len = 0;
1533 mp3buf_write += len;
1535 if(mp3buf_write >= mp3buflen)
1537 mp3buf_write = 0;
1538 DEBUGF("W\n");
1541 /* Tell ourselves that we want more data */
1542 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1544 else
1546 if(len < 0)
1548 DEBUGF("MPEG read error\n");
1551 close(mpeg_file);
1552 mpeg_file = -1;
1554 if(new_file(1) < 0)
1556 /* No more data to play */
1557 DEBUGF("No more files to play\n");
1558 filling = false;
1560 else
1562 /* Tell ourselves that we want more data */
1563 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1567 break;
1569 case MPEG_TRACK_CHANGE:
1570 track_change();
1571 break;
1573 #ifndef USB_NONE
1574 case SYS_USB_CONNECTED:
1575 is_playing = false;
1576 paused = false;
1577 stop_playing();
1578 #ifndef SIMULATOR
1580 /* Tell the USB thread that we are safe */
1581 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1582 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1584 /* Wait until the USB cable is extracted again */
1585 usb_wait_for_disconnect(&mpeg_queue);
1586 #endif /* #ifndef SIMULATOR */
1587 break;
1588 #endif /* #ifndef USB_NONE */
1590 #if CONFIG_HWCODEC == MAS3587F
1591 case MPEG_INIT_RECORDING:
1592 init_recording();
1593 init_recording_done = true;
1594 break;
1595 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1597 #if CONFIG_HWCODEC == MAS3587F
1599 else
1601 queue_wait(&mpeg_queue, &ev);
1602 switch(ev.id)
1604 case MPEG_RECORD:
1605 if(is_prerecording)
1607 int startpos, i;
1609 /* Go back prerecord_count seconds in the buffer */
1610 startpos = prerecord_index - prerecord_count;
1611 if(startpos < 0)
1612 startpos += prerecording_max_seconds;
1614 /* Read the mp3 buffer pointer from the prerecord buffer */
1615 startpos = prerecord_buffer[startpos];
1617 DEBUGF("Start looking at address %x (%x)\n",
1618 mp3buf+startpos, startpos);
1620 saved_header = mpeg_get_last_header();
1622 mem_find_next_frame(startpos, &offset, 5000,
1623 saved_header);
1625 mp3buf_read = startpos + offset;
1627 DEBUGF("New mp3buf_read address: %x (%x)\n",
1628 mp3buf+mp3buf_read, mp3buf_read);
1630 /* Make room for headers */
1631 mp3buf_read -= MPEG_RESERVED_HEADER_SPACE;
1632 if(mp3buf_read < 0)
1634 /* Clear the bottom half */
1635 memset(mp3buf, 0,
1636 mp3buf_read + MPEG_RESERVED_HEADER_SPACE);
1638 /* And the top half */
1639 mp3buf_read += mp3buflen;
1640 memset(mp3buf + mp3buf_read, 0,
1641 mp3buflen - mp3buf_read);
1643 else
1645 memset(mp3buf + mp3buf_read, 0,
1646 MPEG_RESERVED_HEADER_SPACE);
1649 /* Copy the empty ID3 header */
1650 startpos = mp3buf_read;
1651 for(i = 0;i < (int)sizeof(empty_id3_header);i++)
1653 mp3buf[startpos++] = empty_id3_header[i];
1654 if(startpos == mp3buflen)
1655 startpos = 0;
1658 DEBUGF("New mp3buf_read address (reservation): %x\n",
1659 mp3buf+mp3buf_read);
1661 DEBUGF("Prerecording...\n");
1663 else
1665 reset_mp3_buffer();
1667 num_rec_bytes = 0;
1669 /* Advance the write pointer to make
1670 room for an ID3 tag plus a VBR header */
1671 mp3buf_write = MPEG_RESERVED_HEADER_SPACE;
1672 memset(mp3buf, 0, MPEG_RESERVED_HEADER_SPACE);
1674 /* Insert the ID3 header */
1675 memcpy(mp3buf, empty_id3_header,
1676 sizeof(empty_id3_header));
1678 DEBUGF("Recording...\n");
1681 start_recording();
1683 /* Wait until at least one frame is encoded and get the
1684 frame header, for later use by the Xing header
1685 generation */
1686 sleep(HZ/10);
1687 saved_header = mpeg_get_last_header();
1689 /* delayed until buffer is saved, don't open yet */
1690 strcpy(delayed_filename, recording_filename);
1691 mpeg_file = -1;
1693 break;
1695 case MPEG_STOP:
1696 DEBUGF("MPEG_STOP\n");
1698 stop_recording();
1700 /* Save the remaining data in the buffer */
1701 stop_pending = true;
1702 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1703 break;
1705 case MPEG_STOP_DONE:
1706 DEBUGF("MPEG_STOP_DONE\n");
1708 if(mpeg_file >= 0)
1709 close(mpeg_file);
1711 if(!disable_xing_header && num_rec_bytes > 0)
1713 /* Create the Xing header */
1714 mpeg_file = open(recording_filename, O_RDWR);
1715 if(mpeg_file < 0)
1716 panicf("rec upd: %d (%s)", mpeg_file,
1717 recording_filename);
1719 /* If the number of recorded frames have
1720 reached 0x7ffff, we can no longer trust it */
1721 if(num_recorded_frames == 0x7ffff)
1722 num_recorded_frames = 0;
1724 /* Also, if we have been prerecording, the frame count
1725 will be wrong */
1726 if(prerecording)
1727 num_recorded_frames = 0;
1729 /* saved_header is saved right before stopping
1730 the MAS */
1731 framelen = create_xing_header(mpeg_file, 0,
1732 num_rec_bytes, mp3buf,
1733 num_recorded_frames,
1734 saved_header, NULL,
1735 false);
1737 lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE-framelen,
1738 SEEK_SET);
1739 write(mpeg_file, mp3buf, framelen);
1740 close(mpeg_file);
1742 mpeg_file = -1;
1744 #ifdef DEBUG1
1746 int i;
1747 for(i = 0;i < 512;i++)
1749 DEBUGF("%d - %d us (%d bytes)\n",
1750 timing_info[i*2],
1751 (timing_info[i*2+1] & 0xffff) *
1752 10000 / 13824,
1753 timing_info[i*2+1] >> 16);
1756 #endif /* #ifdef DEBUG1 */
1758 if(prerecording)
1760 start_prerecording();
1762 mpeg_stop_done = true;
1763 break;
1765 case MPEG_NEW_FILE:
1766 /* Make sure we have at least one complete frame
1767 in the buffer. If we haven't recorded a single
1768 frame within 200ms, the MAS is probably not recording
1769 anything, and we bail out. */
1770 countdown = 20;
1771 amount_to_save = get_unsaved_space();
1772 while(countdown-- && amount_to_save < 1800)
1774 sleep(HZ/10);
1775 amount_to_save = get_unsaved_space();
1778 if(amount_to_save >= 1800)
1780 /* Now find a frame boundary to split at */
1781 startpos = mp3buf_write - 1800;
1782 if(startpos < 0)
1783 startpos += mp3buflen;
1785 rc = mem_find_next_frame(startpos, &offset, 1800,
1786 saved_header);
1787 if(rc) /* Header found? */
1789 /* offset will now contain the number of bytes to
1790 add to startpos to find the frame boundary */
1791 startpos += offset;
1792 if(startpos >= mp3buflen)
1793 startpos -= mp3buflen;
1795 else
1797 /* No header found. Let's save the whole buffer. */
1798 startpos = mp3buf_write;
1801 else
1803 /* Too few bytes recorded, timeout */
1804 startpos = mp3buf_write;
1807 amount_to_save = startpos - mp3buf_read;
1808 if(amount_to_save < 0)
1809 amount_to_save += mp3buflen;
1811 /* First save up to the end of the buffer */
1812 writelen = MIN(amount_to_save,
1813 mp3buflen - mp3buf_read);
1815 if (mpeg_file < 0) /* delayed file opening */
1817 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT);
1819 if(mpeg_file < 0)
1820 panicf("recfile: %d", mpeg_file);
1823 if(writelen)
1825 rc = write(mpeg_file, mp3buf + mp3buf_read, writelen);
1826 if(rc < 0)
1828 if(errno == ENOSPC)
1830 mpeg_errno = MPEGERR_DISK_FULL;
1831 demand_irq_enable(false);
1832 stop_recording();
1833 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1834 break;
1836 else
1838 panicf("spt wrt: %d", rc);
1843 /* Then save the rest */
1844 writelen = amount_to_save - writelen;
1845 if(writelen)
1847 rc = write(mpeg_file, mp3buf, writelen);
1848 if(rc < 0)
1850 if(errno == ENOSPC)
1852 mpeg_errno = MPEGERR_DISK_FULL;
1853 demand_irq_enable(false);
1854 stop_recording();
1855 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1856 break;
1858 else
1860 panicf("spt wrt: %d", rc);
1865 /* Advance the buffer pointers */
1866 mp3buf_read += amount_to_save;
1867 if(mp3buf_read >= mp3buflen)
1868 mp3buf_read -= mp3buflen;
1870 /* Close the current file */
1871 rc = close(mpeg_file);
1872 if(rc < 0)
1873 panicf("spt cls: %d", rc);
1875 /* Open the new file */
1876 mpeg_file = open(recording_filename, O_WRONLY|O_CREAT);
1877 if(mpeg_file < 0)
1878 panicf("sptfile: %d", mpeg_file);
1879 break;
1881 case MPEG_SAVE_DATA:
1882 amount_to_save = get_unsaved_space();
1884 /* If the result is negative, the write index has
1885 wrapped */
1886 if(amount_to_save < 0)
1888 amount_to_save += mp3buflen;
1891 DEBUGF("r: %x w: %x\n", mp3buf_read, mp3buf_write);
1892 DEBUGF("ats: %x\n", amount_to_save);
1894 /* Save data only if the buffer is getting full,
1895 or if we should stop recording */
1896 if(amount_to_save)
1898 if(mp3buflen -
1899 amount_to_save < MPEG_RECORDING_LOW_WATER ||
1900 stop_pending)
1902 /* Only save up to the end of the buffer */
1903 writelen = MIN(amount_to_save,
1904 mp3buflen - mp3buf_read);
1906 DEBUGF("wrl: %x\n", writelen);
1908 if (mpeg_file < 0) /* delayed file opening */
1910 mpeg_file = open(delayed_filename,
1911 O_WRONLY|O_CREAT);
1913 if(mpeg_file < 0)
1914 panicf("recfile: %d", mpeg_file);
1917 rc = write(mpeg_file, mp3buf + mp3buf_read,
1918 writelen);
1920 if(rc < 0)
1922 if(errno == ENOSPC)
1924 mpeg_errno = MPEGERR_DISK_FULL;
1925 stop_recording();
1926 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1927 break;
1929 else
1931 panicf("rec wrt: %d", rc);
1935 mp3buf_read += amount_to_save;
1936 if(mp3buf_read >= mp3buflen)
1937 mp3buf_read = 0;
1939 rc = fsync(mpeg_file);
1940 if(rc < 0)
1941 panicf("rec fls: %d", rc);
1943 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1945 else
1947 saving = false;
1948 ata_sleep();
1951 else
1953 /* We have saved all data,
1954 time to stop for real */
1955 if(stop_pending)
1956 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1957 saving = false;
1958 ata_sleep();
1960 break;
1962 case MPEG_INIT_PLAYBACK:
1963 /* Stop the prerecording */
1964 stop_recording();
1965 mp3_play_init();
1966 init_playback_done = true;
1967 break;
1969 case MPEG_PAUSE_RECORDING:
1970 pause_recording();
1971 break;
1973 case MPEG_RESUME_RECORDING:
1974 resume_recording();
1975 break;
1977 case SYS_USB_CONNECTED:
1978 /* We can safely go to USB mode if no recording
1979 is taking place */
1980 if((!is_recording || is_prerecording) && mpeg_stop_done)
1982 /* Even if we aren't recording, we still call this
1983 function, to put the MAS in monitoring mode,
1984 to save power. */
1985 stop_recording();
1987 /* Tell the USB thread that we are safe */
1988 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1989 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1991 /* Wait until the USB cable is extracted again */
1992 usb_wait_for_disconnect(&mpeg_queue);
1994 break;
1997 #endif /* #if CONFIG_HWCODEC == MAS3587F */
2000 #endif /* SIMULATOR */
2002 #ifdef SIMULATOR
2003 static struct mp3entry taginfo;
2004 #endif /* #ifdef SIMULATOR */
2006 void mpeg_id3_options(bool _v1first)
2008 v1first = _v1first;
2011 struct mp3entry* mpeg_current_track()
2013 #ifdef SIMULATOR
2014 return &taginfo;
2015 #else
2016 if(num_tracks_in_memory())
2017 return &(id3tags[tag_read_idx]->id3);
2018 else
2019 return NULL;
2020 #endif /* #ifdef SIMULATOR */
2023 struct mp3entry* mpeg_next_track()
2025 #ifdef SIMULATOR
2026 return &taginfo;
2027 #else
2028 if(num_tracks_in_memory() > 1)
2029 return &(id3tags[(tag_read_idx+1) & MAX_ID3_TAGS_MASK]->id3);
2030 else
2031 return NULL;
2032 #endif /* #ifdef SIMULATOR */
2035 bool mpeg_has_changed_track(void)
2037 if(last_track_counter != current_track_counter)
2039 last_track_counter = current_track_counter;
2040 return true;
2042 return false;
2045 #if CONFIG_HWCODEC == MAS3587F
2046 void mpeg_init_playback(void)
2048 init_playback_done = false;
2049 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, NULL);
2051 while(!init_playback_done)
2052 sleep_thread();
2053 wake_up_thread();
2057 /****************************************************************************
2060 ** Recording functions
2063 ***************************************************************************/
2064 void mpeg_init_recording(void)
2066 init_recording_done = false;
2067 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, NULL);
2069 while(!init_recording_done)
2070 sleep_thread();
2071 wake_up_thread();
2074 static void init_recording(void)
2076 unsigned long val;
2077 int rc;
2079 /* Disable IRQ6 */
2080 IPRB &= 0xff0f;
2082 stop_playing();
2083 is_playing = false;
2084 paused = false;
2086 /* Init the recording variables */
2087 is_recording = false;
2088 is_prerecording = false;
2090 mpeg_stop_done = true;
2092 mas_reset();
2094 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2095 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2096 if(rc < 0)
2097 panicf("mas_ctrl_w: %d", rc);
2099 /* Stop the current application */
2100 val = 0;
2101 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2104 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2105 } while(val);
2107 /* Perform black magic as described by the data sheet */
2108 if((mas_version_code & 0x0fff) == 0x0102)
2110 DEBUGF("Performing MAS black magic for B2 version\n");
2111 mas_writereg(0xa3, 0x98);
2112 mas_writereg(0x94, 0xfffff);
2113 val = 0;
2114 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2115 mas_writereg(0xa3, 0x90);
2118 /* Enable A/D Converters */
2119 mas_codec_writereg(0x0, 0xcccd);
2121 /* Copy left channel to right (mono mode) */
2122 mas_codec_writereg(8, 0x8000);
2124 /* ADC scale 0%, DSP scale 100%
2125 We use the DSP output for monitoring, because it works with all
2126 sources including S/PDIF */
2127 mas_codec_writereg(6, 0x0000);
2128 mas_codec_writereg(7, 0x4000);
2130 /* No mute */
2131 shadow_soft_mute = 0;
2132 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2134 /* Set Demand mode, monitoring OFF and validate all settings */
2135 shadow_io_control_main = 0x125;
2136 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2138 /* Start the encoder application */
2139 val = 0x40;
2140 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2143 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2144 } while(!(val & 0x40));
2146 #if 1
2147 /* We have started the recording application with monitoring OFF.
2148 This is because we want to record at least one frame to fill the DMA
2149 buffer, because the silly MAS will not negate EOD until at least one
2150 DMA transfer has taken place.
2151 Now let's wait for some data to be encoded. */
2152 sleep(20);
2154 /* Now set it to Monitoring mode as default, saves power */
2155 shadow_io_control_main = 0x525;
2156 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2158 /* Wait until the DSP has accepted the settings */
2161 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2162 } while(val & 1);
2164 drain_dma_buffer();
2165 #endif
2166 mpeg_mode = MPEG_ENCODER;
2168 DEBUGF("MAS Recording application started\n");
2170 /* At this point, all settings are the reset MAS defaults, next thing is to
2171 call mpeg_set_recording_options(). */
2174 void mpeg_record(const char *filename)
2176 mpeg_errno = 0;
2178 strncpy(recording_filename, filename, MAX_PATH - 1);
2179 recording_filename[MAX_PATH - 1] = 0;
2181 disable_xing_header = false;
2182 queue_post(&mpeg_queue, MPEG_RECORD, NULL);
2185 void mpeg_pause_recording(void)
2187 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, NULL);
2190 void mpeg_resume_recording(void)
2192 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, NULL);
2195 static void start_prerecording(void)
2197 unsigned long val;
2199 DEBUGF("Starting prerecording\n");
2201 prerecord_index = 0;
2202 prerecord_count = 0;
2203 prerecord_timeout = current_tick + HZ;
2204 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2205 reset_mp3_buffer();
2207 is_prerecording = true;
2209 /* Stop monitoring and start the encoder */
2210 shadow_io_control_main &= ~(1 << 10);
2211 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2212 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2214 /* Wait until the DSP has accepted the settings */
2217 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2218 } while(val & 1);
2220 is_recording = true;
2221 stop_pending = false;
2222 saving = false;
2224 demand_irq_enable(true);
2227 static void start_recording(void)
2229 unsigned long val;
2231 num_recorded_frames = 0;
2233 if(is_prerecording)
2235 /* This will make the IRQ handler start recording
2236 for real, i.e send MPEG_SAVE_DATA messages when
2237 the buffer is full */
2238 is_prerecording = false;
2240 else
2242 /* If prerecording is off, we need to stop the monitoring
2243 and start the encoder */
2244 shadow_io_control_main &= ~(1 << 10);
2245 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2246 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2248 /* Wait until the DSP has accepted the settings */
2251 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2252 } while(val & 1);
2255 is_recording = true;
2256 stop_pending = false;
2257 saving = false;
2258 paused = false;
2260 /* Store the current time */
2261 if(prerecording)
2262 record_start_time = current_tick - prerecord_count * HZ;
2263 else
2264 record_start_time = current_tick;
2266 pause_start_time = 0;
2268 demand_irq_enable(true);
2271 static void pause_recording(void)
2273 pause_start_time = current_tick;
2275 /* Set the pause bit */
2276 shadow_soft_mute |= 2;
2277 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2279 paused = true;
2282 static void resume_recording(void)
2284 paused = false;
2286 /* Clear the pause bit */
2287 shadow_soft_mute &= ~2;
2288 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2290 /* Compensate for the time we have been paused */
2291 if(pause_start_time)
2293 record_start_time =
2294 current_tick - (pause_start_time - record_start_time);
2295 pause_start_time = 0;
2299 static void stop_recording(void)
2301 unsigned long val;
2303 /* Let it finish the last frame */
2304 if(!paused)
2305 pause_recording();
2306 sleep(HZ/5);
2308 demand_irq_enable(false);
2310 is_recording = false;
2311 is_prerecording = false;
2313 /* Read the number of frames recorded */
2314 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &num_recorded_frames, 1);
2316 /* Start monitoring */
2317 shadow_io_control_main |= (1 << 10);
2318 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2319 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2321 /* Wait until the DSP has accepted the settings */
2324 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2325 } while(val & 1);
2327 resume_recording();
2330 void mpeg_set_recording_options(int frequency, int quality,
2331 int source, int channel_mode,
2332 bool editable, int prerecord_time)
2334 bool is_mpeg1;
2336 is_mpeg1 = (frequency < 3)?true:false;
2338 rec_version_index = is_mpeg1?3:2;
2339 rec_frequency_index = frequency % 3;
2341 shadow_encoder_control = (quality << 17) |
2342 (rec_frequency_index << 10) |
2343 ((is_mpeg1?1:0) << 9) |
2344 (((channel_mode * 2 + 1) & 3) << 6) |
2345 (1 << 5) /* MS-stereo */ |
2346 (1 << 2) /* Is an original */;
2347 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2349 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2351 shadow_soft_mute = editable?4:0;
2352 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2354 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2356 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2357 ((source < 2)?1:2) << 8) | /* Input select */
2358 (1 << 5) | /* SDO strobe invert */
2359 ((is_mpeg1?0:1) << 3) |
2360 (1 << 2) | /* Inverted SIBC clock signal */
2361 1; /* Validate */
2362 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2364 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2366 if(source == 0) /* Mic */
2368 /* Copy left channel to right (mono mode) */
2369 mas_codec_writereg(8, 0x8000);
2371 else
2373 /* Stereo input mode */
2374 mas_codec_writereg(8, 0);
2377 prerecording_max_seconds = prerecord_time;
2378 if(prerecording_max_seconds)
2380 prerecording = true;
2381 start_prerecording();
2383 else
2385 prerecording = false;
2386 is_prerecording = false;
2387 is_recording = false;
2391 /* If use_mic is true, the left gain is used */
2392 void mpeg_set_recording_gain(int left, int right, bool use_mic)
2394 /* Enable both left and right A/D */
2395 mas_codec_writereg(0x0,
2396 (left << 12) |
2397 (right << 8) |
2398 (left << 4) |
2399 (use_mic?0x0008:0) | /* Connect left A/D to mic */
2400 0x0007);
2403 void mpeg_new_file(const char *filename)
2405 mpeg_errno = 0;
2407 strncpy(recording_filename, filename, MAX_PATH - 1);
2408 recording_filename[MAX_PATH - 1] = 0;
2410 num_rec_bytes = 0;
2411 disable_xing_header = true;
2413 /* Store the current time */
2414 record_start_time = current_tick;
2416 queue_post(&mpeg_queue, MPEG_NEW_FILE, NULL);
2419 unsigned long mpeg_recorded_time(void)
2421 if(is_prerecording)
2422 return prerecord_count * HZ;
2424 if(is_recording)
2426 if(paused)
2427 return pause_start_time - record_start_time;
2428 else
2429 return current_tick - record_start_time;
2432 return 0;
2435 unsigned long mpeg_num_recorded_bytes(void)
2437 int num_bytes;
2438 int index;
2440 if(is_recording)
2442 if(is_prerecording)
2444 index = prerecord_index - prerecord_count;
2445 if(index < 0)
2446 index += prerecording_max_seconds;
2448 num_bytes = mp3buf_write - prerecord_buffer[index];
2449 if(num_bytes < 0)
2450 num_bytes += mp3buflen;
2452 return num_bytes;;
2454 else
2455 return num_rec_bytes;
2457 else
2458 return 0;
2461 #endif
2463 void mpeg_play(int offset)
2465 #ifdef SIMULATOR
2466 char* trackname;
2467 int steps=0;
2469 is_playing = true;
2471 do {
2472 trackname = playlist_peek( steps );
2473 if (!trackname)
2474 break;
2475 if(mp3info(&taginfo, trackname, v1first)) {
2476 /* bad mp3, move on */
2477 if(++steps > playlist_amount())
2478 break;
2479 continue;
2481 #ifdef HAVE_MPEG_PLAY
2482 real_mpeg_play(trackname);
2483 #endif
2484 playlist_next(steps);
2485 taginfo.offset = offset;
2486 set_elapsed(&taginfo);
2487 is_playing = true;
2488 playing = true;
2489 break;
2490 } while(1);
2491 #else
2492 is_playing = true;
2494 queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset);
2495 #endif /* #ifdef SIMULATOR */
2497 mpeg_errno = 0;
2500 void mpeg_stop(void)
2502 #ifndef SIMULATOR
2503 mpeg_stop_done = false;
2504 queue_post(&mpeg_queue, MPEG_STOP, NULL);
2505 while(!mpeg_stop_done)
2506 yield();
2507 #else
2508 paused = false;
2509 is_playing = false;
2510 playing = false;
2511 #endif /* #ifndef SIMULATOR */
2515 void mpeg_pause(void)
2517 #ifndef SIMULATOR
2518 queue_post(&mpeg_queue, MPEG_PAUSE, NULL);
2519 #else
2520 is_playing = true;
2521 playing = false;
2522 paused = true;
2523 #endif /* #ifndef SIMULATOR */
2526 void mpeg_resume(void)
2528 #ifndef SIMULATOR
2529 queue_post(&mpeg_queue, MPEG_RESUME, NULL);
2530 #else
2531 is_playing = true;
2532 playing = true;
2533 paused = false;
2534 #endif /* #ifndef SIMULATOR */
2537 void mpeg_next(void)
2539 #ifndef SIMULATOR
2540 queue_post(&mpeg_queue, MPEG_NEXT, NULL);
2541 #else
2542 char* file;
2543 int steps = 1;
2544 int index;
2546 do {
2547 file = playlist_peek(steps);
2548 if(!file)
2549 break;
2550 if(mp3info(&taginfo, file, v1first)) {
2551 if(++steps > playlist_amount())
2552 break;
2553 continue;
2555 index = playlist_next(steps);
2556 taginfo.index = index;
2557 current_track_counter++;
2558 is_playing = true;
2559 playing = true;
2560 break;
2561 } while(1);
2562 #endif /* #ifndef SIMULATOR */
2565 void mpeg_prev(void)
2567 #ifndef SIMULATOR
2568 queue_post(&mpeg_queue, MPEG_PREV, NULL);
2569 #else
2570 char* file;
2571 int steps = -1;
2572 int index;
2574 do {
2575 file = playlist_peek(steps);
2576 if(!file)
2577 break;
2578 if(mp3info(&taginfo, file, v1first)) {
2579 steps--;
2580 continue;
2582 index = playlist_next(steps);
2583 taginfo.index = index;
2584 current_track_counter++;
2585 is_playing = true;
2586 playing = true;
2587 break;
2588 } while(1);
2589 #endif /* #ifndef SIMULATOR */
2592 void mpeg_ff_rewind(int newtime)
2594 #ifndef SIMULATOR
2595 queue_post(&mpeg_queue, MPEG_FF_REWIND, (void *)newtime);
2596 #else
2597 (void)newtime;
2598 #endif /* #ifndef SIMULATOR */
2601 void mpeg_flush_and_reload_tracks(void)
2603 #ifndef SIMULATOR
2604 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, NULL);
2605 #endif /* #ifndef SIMULATOR*/
2608 int mpeg_status(void)
2610 int ret = 0;
2612 if(is_playing)
2613 ret |= MPEG_STATUS_PLAY;
2615 if(paused)
2616 ret |= MPEG_STATUS_PAUSE;
2618 #if CONFIG_HWCODEC == MAS3587F
2619 if(is_recording && !is_prerecording)
2620 ret |= MPEG_STATUS_RECORD;
2622 if(is_prerecording)
2623 ret |= MPEG_STATUS_PRERECORD;
2624 #endif /* #if CONFIG_HWCODEC == MAS3587F */
2626 if(mpeg_errno)
2627 ret |= MPEG_STATUS_ERROR;
2629 return ret;
2632 unsigned int mpeg_error(void)
2634 return mpeg_errno;
2637 void mpeg_error_clear(void)
2639 mpeg_errno = 0;
2642 #ifdef SIMULATOR
2643 static char mpeg_stack[DEFAULT_STACK_SIZE];
2644 static const char mpeg_thread_name[] = "mpeg";
2645 static void mpeg_thread(void)
2647 struct mp3entry* id3;
2648 while ( 1 ) {
2649 if (is_playing) {
2650 id3 = mpeg_current_track();
2651 if (!paused)
2653 id3->elapsed+=1000;
2654 id3->offset+=1000;
2656 if (id3->elapsed>=id3->length)
2657 mpeg_next();
2659 sleep(HZ);
2662 #endif /* #ifdef SIMULATOR */
2664 void mpeg_init(void)
2666 mpeg_errno = 0;
2668 #ifndef SIMULATOR
2669 mp3buflen = mp3end - mp3buf;
2670 queue_init(&mpeg_queue);
2671 #endif /* #ifndef SIMULATOR */
2672 create_thread(mpeg_thread, mpeg_stack,
2673 sizeof(mpeg_stack), mpeg_thread_name);
2675 memset(id3tags, sizeof(id3tags), 0);
2676 memset(_id3tags, sizeof(id3tags), 0);
2678 #if CONFIG_HWCODEC == MAS3587F
2679 if(read_hw_mask() & PR_ACTIVE_HIGH)
2680 and_b(~0x08, &PADRH);
2681 else
2682 or_b(0x08, &PADRH);
2683 #endif /* #if CONFIG_HWCODEC == MAS3587F */
2685 #ifdef DEBUG
2686 dbg_timer_start();
2687 dbg_cnt2us(0);
2688 #endif /* DEBUG */