Renamed has_new_lcd() to is_new_player(), and got rid of the alias
[kugel-rb.git] / firmware / mpeg.c
blob5a199a4169c4b37d718536320550479b47b4eed0
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 #endif
366 static int mpeg_file;
368 /* Synchronization variables */
369 #if CONFIG_HWCODEC == MAS3587F
370 static bool init_recording_done;
371 static bool init_playback_done;
372 #endif /* #if CONFIG_HWCODEC == MAS3587F */
373 static bool mpeg_stop_done;
375 static void recalculate_watermark(int bitrate)
377 int bytes_per_sec;
378 int time = ata_spinup_time;
380 /* A bitrate of 0 probably means empty VBR header. We play safe
381 and set a high threshold */
382 if(bitrate == 0)
383 bitrate = 320;
385 bytes_per_sec = bitrate * 1000 / 8;
387 if(time)
389 /* No drive spins up faster than 3.5s */
390 if(time < 350)
391 time = 350;
393 time = time * 3;
394 low_watermark = ((low_watermark_margin * HZ + time) *
395 bytes_per_sec) / HZ;
397 else
399 low_watermark = MPEG_LOW_WATER;
403 void mpeg_set_buffer_margin(int seconds)
405 low_watermark_margin = seconds;
408 void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
410 dbgdata->mp3buflen = mp3buflen;
411 dbgdata->mp3buf_write = mp3buf_write;
412 dbgdata->mp3buf_swapwrite = mp3buf_swapwrite;
413 dbgdata->mp3buf_read = mp3buf_read;
415 dbgdata->last_dma_chunk_size = last_dma_chunk_size;
417 dbgdata->dma_on = (SCR0 & 0x80) != 0;
418 dbgdata->playing = playing;
419 dbgdata->play_pending = play_pending;
420 dbgdata->is_playing = is_playing;
421 dbgdata->filling = filling;
422 dbgdata->dma_underrun = dma_underrun;
424 dbgdata->unplayed_space = get_unplayed_space();
425 dbgdata->playable_space = get_playable_space();
426 dbgdata->unswapped_space = get_unswapped_space();
428 dbgdata->low_watermark_level = low_watermark;
429 dbgdata->lowest_watermark_level = lowest_watermark_level;
432 #ifdef DEBUG
433 static void dbg_timer_start(void)
435 /* We are using timer 2 */
437 TSTR &= ~0x04; /* Stop the timer */
438 TSNC &= ~0x04; /* No synchronization */
439 TMDR &= ~0x44; /* Operate normally */
441 TCNT2 = 0; /* Start counting at 0 */
442 TCR2 = 0x03; /* Sysclock/8 */
444 TSTR |= 0x04; /* Start timer 2 */
447 static int dbg_cnt2us(unsigned int cnt)
449 return (cnt * 10000) / (FREQ/800);
451 #endif /* #ifdef DEBUG */
453 static int get_unplayed_space(void)
455 int space = mp3buf_write - mp3buf_read;
456 if (space < 0)
457 space += mp3buflen;
458 return space;
461 static int get_playable_space(void)
463 int space = mp3buf_swapwrite - mp3buf_read;
464 if (space < 0)
465 space += mp3buflen;
466 return space;
469 static int get_unplayed_space_current_song(void)
471 int space;
473 if (num_tracks_in_memory() > 1)
475 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
477 space = id3tags[track_offset].mempos - mp3buf_read;
479 else
481 space = mp3buf_write - mp3buf_read;
484 if (space < 0)
485 space += mp3buflen;
487 return space;
490 static int get_unswapped_space(void)
492 int space = mp3buf_write - mp3buf_swapwrite;
493 if (space < 0)
494 space += mp3buflen;
495 return space;
498 #if CONFIG_HWCODEC == MAS3587F
499 static int get_unsaved_space(void)
501 int space = mp3buf_write - mp3buf_read;
502 if (space < 0)
503 space += mp3buflen;
504 return space;
506 #endif /* #if CONFIG_HWCODEC == MAS3587F */
508 #if CONFIG_HWCODEC == MAS3587F
509 #ifdef DEBUG
510 static long timing_info_index = 0;
511 static long timing_info[1024];
512 #endif /* #ifdef DEBUG */
513 static unsigned long num_rec_bytes;
514 static unsigned long num_recorded_frames;
516 static void drain_dma_buffer(void)
518 asm (
519 "mov #0x40,r2 \n" /* mask for EOD check */
520 "bra .d_start \n"
521 "mov.b @%0,r1 \n" /* read PBDR (first time) */
523 ".d_loop: \n"
524 "xor.b #0x08,@(r0,gbr) \n" /* set PR active */
525 ".d_wait1: \n"
526 "mov.b @%0,r1 \n" /* read PBDR */
527 "cmp/pz r1 \n" /* and wait for PRTW */
528 "bf .d_wait1 \n"
530 "xor.b #0x08,@(r0,gbr) \n" /* reset PR to inactive */
531 ".d_wait2: \n"
532 "mov.b @%0,r1 \n" /* read PBDR */
533 "cmp/pz r1 \n" /* and wait for /PRTW */
534 "bt .d_wait2 \n"
536 ".d_start: \n"
537 "tst r1,r2 \n" /* EOD low? */
538 "bf .d_loop \n" /* no: next pass */
540 : /* outputs */
541 : /* inputs */
542 /* %0 */ "r"(PBDR_ADDR),
543 /* %1 = r0 */ "z"(&PADRH)
544 : /* clobbers */
545 "r1","r2"
549 #endif /* #if CONFIG_HWCODEC == MAS3587F */
551 void rec_tick (void) __attribute__ ((section (".icode")));
552 void rec_tick(void)
554 #if CONFIG_HWCODEC == MAS3587F
555 int i;
556 int num_bytes;
557 if(is_recording && (PBDR & 0x4000))
559 #ifdef DEBUG
560 timing_info[timing_info_index++] = current_tick;
561 TCNT2 = 0;
562 #endif /* #ifdef DEBUG */
563 /* We read as long as EOD is high, but max 30 bytes. */
564 asm (
565 "mov #30,r3 \n" /* i_max = 30 */
566 "mov #0x40,r2 \n" /* mask for EOD check */
567 "mov #0,%0 \n" /* i = 0; */
568 "add %2,%1 \n" /* mp3buf_write -> cur_addr */
569 "add %2,%3 \n" /* mp3buflen -> end_addr */
570 "bra .r_start \n"
571 "mov.b @%4,r1 \n" /* read PBDR (first time) */
573 ".align 2 \n"
575 ".r_loop: \n"
576 "xor.b #0x08,@(r0,gbr) \n" /* set PR active */
577 ".r_wait1: \n"
578 "mov.b @%4,r1 \n" /* read PBDR */
579 "cmp/pz r1 \n" /* and wait for PRTW */
580 "bf .r_wait1 \n"
582 "mov.b @%6,r1 \n" /* read byte from mas */
583 "add #1,%0 \n" /* i++; */
584 "mov.b r1,@%1 \n" /* store byte */
585 "add #1,%1 \n" /* increment current address */
587 "cmp/hi %1,%3 \n" /* end address reached? */
588 "bt .r_nowrap \n" /* no: do nothing */
589 "mov %2,%1 \n" /* yes: reset to start address */
590 ".r_nowrap: \n"
592 "xor.b #0x08,@(r0,gbr) \n" /* set PR inactive again */
593 ".r_wait2: \n"
594 "mov.b @%4,r1 \n" /* read PBDR */
595 "cmp/pz r1 \n" /* and wait for /PRTW */
596 "bt .r_wait2 \n"
598 ".r_start: \n"
599 "tst r2,r1 \n" /* EOD low? */
600 "bt .r_end \n" /* yes: end of transfer */
601 "cmp/hi %0,r3 \n" /* i < i_max? */
602 "bt .r_loop \n" /* yes: next pass */
604 ".r_end: \n"
605 "sub %2,%1 \n" /* cur_addr -> mp3buf_write */
606 : /* outputs */
607 /* %0 */ "=&r"(i),
608 /* %1, in & out */ "+r"(mp3buf_write)
609 : /* inputs */
610 /* %2 */ "r"(mp3buf),
611 /* %3 */ "r"(mp3buflen),
612 /* %4 */ "r"(PBDR_ADDR),
613 /* %5 = r0 */ "z"(&PADRH),
614 /* %6 */ "r"(0x4000000)
615 : /* clobbers */
616 "r1","r2","r3"
618 #ifdef DEBUG
619 timing_info[timing_info_index++] = TCNT2 + (i << 16);
620 timing_info_index &= 0x3ff;
621 #endif /* #ifdef DEBUG */
623 num_rec_bytes += i;
625 if(is_prerecording)
627 if(TIME_AFTER(current_tick, prerecord_timeout))
629 prerecord_timeout = current_tick + HZ;
631 /* Store the write pointer every second */
632 prerecord_buffer[prerecord_index++] = mp3buf_write;
634 /* Wrap if necessary */
635 if(prerecord_index == prerecording_max_seconds)
636 prerecord_index = 0;
638 /* Update the number of seconds recorded */
639 if(prerecord_count < prerecording_max_seconds)
640 prerecord_count++;
643 else
645 /* Signal to save the data if we are running out of buffer
646 space */
647 num_bytes = mp3buf_write - mp3buf_read;
648 if(num_bytes < 0)
649 num_bytes += mp3buflen;
651 if(mp3buflen - num_bytes < MPEG_RECORDING_LOW_WATER && !saving)
653 saving = true;
654 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
655 wake_up_thread();
659 #endif /* #if CONFIG_HWCODEC == MAS3587F */
662 void playback_tick(void)
664 id3tags[tag_read_idx].id3.elapsed +=
665 (current_tick - last_dma_tick) * 1000 / HZ;
666 last_dma_tick = current_tick;
669 static void reset_mp3_buffer(void)
671 mp3buf_read = 0;
672 mp3buf_write = 0;
673 mp3buf_swapwrite = 0;
674 lowest_watermark_level = mp3buflen;
677 /* DMA transfer end interrupt callback */
678 static void transfer_end(unsigned char** ppbuf, int* psize)
680 if(playing && !paused)
682 int unplayed_space_left;
683 int space_until_end_of_buffer;
684 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
686 mp3buf_read += last_dma_chunk_size;
687 if(mp3buf_read >= mp3buflen)
688 mp3buf_read = 0;
690 /* First, check if we are on a track boundary */
691 if (num_tracks_in_memory() > 1)
693 if (mp3buf_read == id3tags[track_offset].mempos)
695 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
696 track_offset = (track_offset+1) & MAX_ID3_TAGS_MASK;
700 unplayed_space_left = get_unplayed_space();
702 space_until_end_of_buffer = mp3buflen - mp3buf_read;
704 if(!filling && unplayed_space_left < low_watermark)
706 filling = true;
707 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
710 if(unplayed_space_left)
712 last_dma_chunk_size = MIN(0x2000, unplayed_space_left);
713 last_dma_chunk_size = MIN(last_dma_chunk_size,
714 space_until_end_of_buffer);
716 /* several tracks loaded? */
717 if (num_tracks_in_memory() > 1)
719 /* will we move across the track boundary? */
720 if (( mp3buf_read < id3tags[track_offset].mempos ) &&
721 ((mp3buf_read+last_dma_chunk_size) >
722 id3tags[track_offset].mempos ))
724 /* Make sure that we end exactly on the boundary */
725 last_dma_chunk_size = id3tags[track_offset].mempos
726 - mp3buf_read;
730 *psize = last_dma_chunk_size & 0xffff;
731 *ppbuf = mp3buf + mp3buf_read;
732 id3tags[tag_read_idx].id3.offset += last_dma_chunk_size;
734 /* Update the watermark debug level */
735 if(unplayed_space_left < lowest_watermark_level)
736 lowest_watermark_level = unplayed_space_left;
738 else
740 /* Check if the end of data is because of a hard disk error.
741 If there is an open file handle, we are still playing music.
742 If not, the last file has been loaded, and the file handle is
743 closed. */
744 if(mpeg_file >= 0)
746 /* Update the watermark debug level */
747 if(unplayed_space_left < lowest_watermark_level)
748 lowest_watermark_level = unplayed_space_left;
750 DEBUGF("DMA underrun.\n");
751 dma_underrun = true;
753 else
755 DEBUGF("No more MP3 data. Stopping.\n");
757 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
758 playing = false;
759 is_playing = false;
761 *psize = 0; /* no more transfer */
765 wake_up_thread();
768 static int add_track_to_tag_list(const char *filename)
770 if(num_tracks_in_memory() >= MAX_ID3_TAGS)
772 DEBUGF("Tag memory is full\n");
773 return -1;
776 /* grab id3 tag of new file and
777 remember where in memory it starts */
778 if(mp3info(&id3tags[tag_write_idx].id3, filename, v1first))
780 DEBUGF("Bad mp3\n");
781 return -1;
783 id3tags[tag_write_idx].mempos = mp3buf_write;
784 id3tags[tag_write_idx].id3.elapsed = 0;
786 tag_write_idx = (tag_write_idx+1) & MAX_ID3_TAGS_MASK;
787 debug_tags();
788 return 0;
791 static int new_file(int steps)
793 int max_steps = playlist_amount();
794 int start = 0;
795 int i;
797 /* Find out how many steps to advance. The load_ahead_index field tells
798 us how many playlist entries it had to skip to get to a valid one.
799 We add those together to find out where to start. */
800 if(steps > 0 && num_tracks_in_memory() > 1)
802 /* Begin with the song after the currently playing one */
803 i = (tag_read_idx + 1) & MAX_ID3_TAGS_MASK;
804 while(i != tag_write_idx)
806 start += id3tags[i].load_ahead_index;
807 i = (i+1) & MAX_ID3_TAGS_MASK;
811 do {
812 char *trackname;
814 trackname = playlist_peek( start + steps );
815 if ( !trackname )
816 return -1;
818 DEBUGF("Loading %s\n", trackname);
820 mpeg_file = open(trackname, O_RDONLY);
821 if(mpeg_file < 0) {
822 DEBUGF("Couldn't open file: %s\n",trackname);
823 if(steps < 0)
824 steps--;
825 else
826 steps++;
828 else
830 int new_tag_idx = tag_write_idx;
832 if(add_track_to_tag_list(trackname))
834 /* Bad mp3 file */
835 if(steps < 0)
836 steps--;
837 else
838 steps++;
839 close(mpeg_file);
840 mpeg_file = -1;
842 else
844 /* skip past id3v2 tag */
845 lseek(mpeg_file,
846 id3tags[new_tag_idx].id3.first_frame_offset,
847 SEEK_SET);
848 id3tags[new_tag_idx].id3.index = steps;
849 id3tags[new_tag_idx].load_ahead_index = steps;
850 id3tags[new_tag_idx].id3.offset = 0;
852 if(id3tags[new_tag_idx].id3.vbr)
853 /* Average bitrate * 1.5 */
854 recalculate_watermark(
855 (id3tags[new_tag_idx].id3.bitrate * 3) / 2);
856 else
857 recalculate_watermark(
858 id3tags[new_tag_idx].id3.bitrate);
863 /* Bail out if no file could be opened */
864 if(abs(steps) > max_steps)
865 return -1;
866 } while ( mpeg_file < 0 );
868 return 0;
871 static void stop_playing(void)
873 /* Stop the current stream */
874 mp3_play_stop();
875 playing = false;
876 filling = false;
877 if(mpeg_file >= 0)
878 close(mpeg_file);
879 mpeg_file = -1;
880 remove_all_tags();
881 reset_mp3_buffer();
884 static void update_playlist(void)
886 int index;
888 if (num_tracks_in_memory() > 0)
890 index = playlist_next(id3tags[tag_read_idx].id3.index);
891 id3tags[tag_read_idx].id3.index = index;
895 static void track_change(void)
897 DEBUGF("Track change\n");
899 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
900 /* Reset the AVC */
901 mpeg_sound_set(SOUND_AVC, -1);
902 #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
903 remove_current_tag();
905 update_playlist();
906 current_track_counter++;
909 #ifdef DEBUG
910 void hexdump(const unsigned char *buf, int len)
912 int i;
914 for(i = 0;i < len;i++)
916 if(i && (i & 15) == 0)
918 DEBUGF("\n");
920 DEBUGF("%02x ", buf[i]);
922 DEBUGF("\n");
924 #endif /* #ifdef DEBUG */
926 static void start_playback_if_ready(void)
928 int playable_space;
930 playable_space = mp3buf_swapwrite - mp3buf_read;
931 if(playable_space < 0)
932 playable_space += mp3buflen;
934 /* See if we have started playing yet. If not, do it. */
935 if(play_pending || dma_underrun)
937 /* If the filling has stopped, and we still haven't reached
938 the watermark, the file must be smaller than the
939 watermark. We must still play it. */
940 if((playable_space >= MPEG_PLAY_PENDING_THRESHOLD) ||
941 !filling || dma_underrun)
943 DEBUGF("P\n");
944 play_pending = false;
945 playing = true;
947 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
948 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
949 dma_underrun = false;
951 if (!paused)
953 last_dma_tick = current_tick;
954 mp3_play_pause(true);
957 /* Tell ourselves that we need more data */
958 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
963 static bool swap_one_chunk(void)
965 int free_space_left;
966 int amount_to_swap;
968 free_space_left = get_unswapped_space();
970 if(free_space_left == 0 && !play_pending)
971 return false;
973 /* Swap in larger chunks when the user is waiting for the playback
974 to start, or when there is dangerously little playable data left */
975 if(play_pending)
976 amount_to_swap = MIN(MPEG_PLAY_PENDING_SWAPSIZE, free_space_left);
977 else
979 if(get_playable_space() < low_watermark)
980 amount_to_swap = MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE,
981 free_space_left);
982 else
983 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
986 if(mp3buf_write < mp3buf_swapwrite)
987 amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
988 amount_to_swap);
989 else
990 amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite,
991 amount_to_swap);
993 bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap);
995 mp3buf_swapwrite += amount_to_swap;
996 if(mp3buf_swapwrite >= mp3buflen)
998 mp3buf_swapwrite = 0;
1001 return true;
1004 static const unsigned char empty_id3_header[] =
1006 'I', 'D', '3', 0x03, 0x00, 0x00,
1007 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
1010 static void mpeg_thread(void)
1012 static int pause_tick = 0;
1013 static unsigned int pause_track = 0;
1014 struct event ev;
1015 int len;
1016 int free_space_left;
1017 int unplayed_space_left;
1018 int amount_to_read;
1019 int t1, t2;
1020 int start_offset;
1021 #if CONFIG_HWCODEC == MAS3587F
1022 int amount_to_save;
1023 int writelen;
1024 int framelen;
1025 unsigned long saved_header = 0;
1026 int startpos;
1027 int rc;
1028 int offset;
1029 int countdown;
1030 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1032 is_playing = false;
1033 play_pending = false;
1034 playing = false;
1035 mpeg_file = -1;
1037 while(1)
1039 #if CONFIG_HWCODEC == MAS3587F
1040 if(mpeg_mode == MPEG_DECODER)
1042 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1043 yield();
1045 /* Swap if necessary, and don't block on the queue_wait() */
1046 if(swap_one_chunk())
1048 queue_wait_w_tmo(&mpeg_queue, &ev, 0);
1050 else
1052 DEBUGF("S R:%x W:%x SW:%x\n",
1053 mp3buf_read, mp3buf_write, mp3buf_swapwrite);
1054 queue_wait(&mpeg_queue, &ev);
1057 start_playback_if_ready();
1059 switch(ev.id)
1061 case MPEG_PLAY:
1062 DEBUGF("MPEG_PLAY\n");
1064 #ifdef CONFIG_TUNER
1065 /* Silence the A/D input, it may be on because the radio
1066 may be playing */
1067 mas_codec_writereg(6, 0x0000);
1068 #endif /* #ifdef CONFIG_TUNER */
1070 /* Stop the current stream */
1071 play_pending = false;
1072 playing = false;
1073 paused = false;
1074 mp3_play_pause(false);
1076 reset_mp3_buffer();
1077 remove_all_tags();
1079 if(mpeg_file >= 0)
1080 close(mpeg_file);
1082 if ( new_file(0) == -1 )
1084 is_playing = false;
1085 track_change();
1086 break;
1089 start_offset = (int)ev.data;
1091 /* mid-song resume? */
1092 if (start_offset) {
1093 struct mp3entry* id3 = &id3tags[tag_read_idx].id3;
1094 lseek(mpeg_file, start_offset, SEEK_SET);
1095 id3->offset = start_offset;
1096 set_elapsed(id3);
1098 else {
1099 /* skip past id3v2 tag */
1100 lseek(mpeg_file,
1101 id3tags[tag_read_idx].id3.first_frame_offset,
1102 SEEK_SET);
1106 /* Make it read more data */
1107 filling = true;
1108 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1110 /* Tell the file loading code that we want to start playing
1111 as soon as we have some data */
1112 play_pending = true;
1114 update_playlist();
1115 current_track_counter++;
1116 break;
1118 case MPEG_STOP:
1119 DEBUGF("MPEG_STOP\n");
1120 is_playing = false;
1121 paused = false;
1122 stop_playing();
1123 mpeg_stop_done = true;
1124 break;
1126 case MPEG_PAUSE:
1127 DEBUGF("MPEG_PAUSE\n");
1128 /* Stop the current stream */
1129 paused = true;
1130 playing = false;
1131 pause_tick = current_tick;
1132 pause_track = current_track_counter;
1133 mp3_play_pause(false);
1134 break;
1136 case MPEG_RESUME:
1137 DEBUGF("MPEG_RESUME\n");
1138 /* Continue the current stream */
1139 paused = false;
1140 if (!play_pending)
1142 playing = true;
1143 if ( current_track_counter == pause_track )
1144 last_dma_tick += current_tick - pause_tick;
1145 else
1146 last_dma_tick = current_tick;
1147 pause_tick = 0;
1148 mp3_play_pause(true);
1150 break;
1152 case MPEG_NEXT:
1153 DEBUGF("MPEG_NEXT\n");
1154 /* is next track in ram? */
1155 if ( num_tracks_in_memory() > 1 ) {
1156 int unplayed_space_left, unswapped_space_left;
1158 /* stop the current stream */
1159 play_pending = false;
1160 playing = false;
1161 mp3_play_pause(false);
1163 track_change();
1164 mp3buf_read = id3tags[tag_read_idx].mempos;
1165 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1166 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
1167 dma_underrun = false;
1168 last_dma_tick = current_tick;
1170 unplayed_space_left = get_unplayed_space();
1171 unswapped_space_left = get_unswapped_space();
1173 /* should we start reading more data? */
1174 if(!filling && (unplayed_space_left < low_watermark)) {
1175 filling = true;
1176 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1177 play_pending = true;
1178 } else if(unswapped_space_left &&
1179 unswapped_space_left > unplayed_space_left) {
1180 /* Stop swapping the data from the previous file */
1181 mp3buf_swapwrite = mp3buf_read;
1182 play_pending = true;
1183 } else {
1184 playing = true;
1185 if (!paused)
1186 mp3_play_pause(true);
1189 else {
1190 if (!playlist_check(1))
1191 break;
1193 /* stop the current stream */
1194 play_pending = false;
1195 playing = false;
1196 mp3_play_pause(false);
1198 reset_mp3_buffer();
1199 remove_all_tags();
1201 /* Open the next file */
1202 if (mpeg_file >= 0)
1203 close(mpeg_file);
1205 if (new_file(1) < 0) {
1206 DEBUGF("No more files to play\n");
1207 filling = false;
1208 } else {
1209 /* Make it read more data */
1210 filling = true;
1211 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1213 /* Tell the file loading code that we want
1214 to start playing as soon as we have some data */
1215 play_pending = true;
1217 update_playlist();
1218 current_track_counter++;
1221 break;
1223 case MPEG_PREV: {
1224 DEBUGF("MPEG_PREV\n");
1226 if (!playlist_check(-1))
1227 break;
1229 /* stop the current stream */
1230 play_pending = false;
1231 playing = false;
1232 mp3_play_pause(false);
1234 reset_mp3_buffer();
1235 remove_all_tags();
1237 /* Open the next file */
1238 if (mpeg_file >= 0)
1239 close(mpeg_file);
1241 if (new_file(-1) < 0) {
1242 DEBUGF("No more files to play\n");
1243 filling = false;
1244 } else {
1245 /* Make it read more data */
1246 filling = true;
1247 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1249 /* Tell the file loading code that we want to
1250 start playing as soon as we have some data */
1251 play_pending = true;
1253 update_playlist();
1254 current_track_counter++;
1256 break;
1259 case MPEG_FF_REWIND: {
1260 struct mp3entry *id3 = mpeg_current_track();
1261 unsigned int oldtime = id3->elapsed;
1262 unsigned int newtime = (unsigned int)ev.data;
1263 int curpos, newpos, diffpos;
1264 DEBUGF("MPEG_FF_REWIND\n");
1266 id3->elapsed = newtime;
1268 newpos = mpeg_get_file_pos();
1269 if(newpos < 0)
1271 id3->elapsed = oldtime;
1272 break;
1275 if (mpeg_file >= 0)
1276 curpos = lseek(mpeg_file, 0, SEEK_CUR);
1277 else
1278 curpos = id3->filesize;
1280 if (num_tracks_in_memory() > 1)
1282 /* We have started loading other tracks that need to be
1283 accounted for */
1284 int i = tag_read_idx;
1285 int j = tag_write_idx - 1;
1287 if (j < 0)
1288 j = MAX_ID3_TAGS - 1;
1290 while (i != j)
1292 curpos += id3tags[i].id3.filesize;
1293 i = (i+1) & MAX_ID3_TAGS_MASK;
1297 diffpos = curpos - newpos;
1299 if(!filling && diffpos >= 0 && diffpos < mp3buflen)
1301 int unplayed_space_left, unswapped_space_left;
1303 /* We are changing to a position that's already in
1304 memory, so we just move the DMA read pointer. */
1305 mp3buf_read = mp3buf_write - diffpos;
1306 if (mp3buf_read < 0)
1308 mp3buf_read += mp3buflen;
1311 unplayed_space_left = get_unplayed_space();
1312 unswapped_space_left = get_unswapped_space();
1314 /* If unswapped_space_left is larger than
1315 unplayed_space_left, it means that the swapwrite pointer
1316 hasn't yet advanced up to the new location of the read
1317 pointer. We just move it, there is no need to swap
1318 data that won't be played anyway. */
1320 if (unswapped_space_left > unplayed_space_left)
1322 DEBUGF("Moved swapwrite\n");
1323 mp3buf_swapwrite = mp3buf_read;
1324 play_pending = true;
1327 if (mpeg_file>=0 && unplayed_space_left < low_watermark)
1329 /* We need to load more data before starting */
1330 filling = true;
1331 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1332 play_pending = true;
1334 else
1336 /* resume will start at new position */
1337 last_dma_chunk_size =
1338 MIN(0x2000, get_unplayed_space_current_song());
1339 mp3_play_data(mp3buf + mp3buf_read,
1340 last_dma_chunk_size, transfer_end);
1341 dma_underrun = false;
1344 else
1346 /* Move to the new position in the file and start
1347 loading data */
1348 reset_mp3_buffer();
1350 if (num_tracks_in_memory() > 1)
1352 /* We have to reload the current track */
1353 close(mpeg_file);
1354 remove_all_non_current_tags();
1355 mpeg_file = -1;
1358 if (mpeg_file < 0)
1360 mpeg_file = open(id3->path, O_RDONLY);
1361 if (mpeg_file < 0)
1363 id3->elapsed = oldtime;
1364 break;
1368 if(-1 == lseek(mpeg_file, newpos, SEEK_SET))
1370 id3->elapsed = oldtime;
1371 break;
1374 filling = true;
1375 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1377 /* Tell the file loading code that we want to start playing
1378 as soon as we have some data */
1379 play_pending = true;
1382 id3->offset = newpos;
1384 break;
1387 case MPEG_FLUSH_RELOAD: {
1388 int numtracks = num_tracks_in_memory();
1389 bool reload_track = false;
1391 if (numtracks > 1)
1393 /* Reload songs */
1394 int next = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
1396 /* Reset the buffer */
1397 mp3buf_write = id3tags[next].mempos;
1399 /* Reset swapwrite unless we're still swapping current
1400 track */
1401 if (get_unplayed_space() <= get_playable_space())
1402 mp3buf_swapwrite = mp3buf_write;
1404 close(mpeg_file);
1405 remove_all_non_current_tags();
1406 mpeg_file = -1;
1407 reload_track = true;
1409 else if (numtracks == 1 && mpeg_file < 0)
1411 reload_track = true;
1414 if(reload_track && new_file(1) >= 0)
1416 /* Tell ourselves that we want more data */
1417 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1418 filling = true;
1421 break;
1424 case MPEG_NEED_DATA:
1425 free_space_left = mp3buf_read - mp3buf_write;
1427 /* We interpret 0 as "empty buffer" */
1428 if(free_space_left <= 0)
1429 free_space_left = mp3buflen + free_space_left;
1431 unplayed_space_left = mp3buflen - free_space_left;
1433 /* Make sure that we don't fill the entire buffer */
1434 free_space_left -= MPEG_HIGH_WATER;
1436 /* do we have any more buffer space to fill? */
1437 if(free_space_left <= MPEG_HIGH_WATER)
1439 DEBUGF("0\n");
1440 filling = false;
1441 ata_sleep();
1442 break;
1445 /* Read small chunks while we are below the low water mark */
1446 if(unplayed_space_left < low_watermark)
1447 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
1448 free_space_left);
1449 else
1450 amount_to_read = free_space_left;
1452 /* Don't read more than until the end of the buffer */
1453 amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
1454 #if MEM == 8
1455 amount_to_read = MIN(0x100000, amount_to_read);
1456 #endif /* #if MEM == 8 */
1457 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1458 amount_to_read = MIN(0x40000, amount_to_read);
1459 #endif
1461 /* Read as much mpeg data as we can fit in the buffer */
1462 if(mpeg_file >= 0)
1464 DEBUGF("R\n");
1465 t1 = current_tick;
1466 len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
1467 if(len > 0)
1469 t2 = current_tick;
1470 DEBUGF("time: %d\n", t2 - t1);
1471 DEBUGF("R: %x\n", len);
1473 /* Now make sure that we don't feed the MAS with ID3V1
1474 data */
1475 if (len < amount_to_read)
1477 int tagptr = mp3buf_write + len - 128;
1478 int i;
1479 char *tag = "TAG";
1480 int taglen = 128;
1482 for(i = 0;i < 3;i++)
1484 if(tagptr >= mp3buflen)
1485 tagptr -= mp3buflen;
1487 if(mp3buf[tagptr] != tag[i])
1488 taglen = 0;
1490 tagptr++;
1493 if(taglen)
1495 /* Skip id3v1 tag */
1496 DEBUGF("Skipping ID3v1 tag\n");
1497 len -= taglen;
1499 /* The very rare case when the entire tag
1500 wasn't read in this read() call must be
1501 taken care of */
1502 if(len < 0)
1503 len = 0;
1507 mp3buf_write += len;
1509 if(mp3buf_write >= mp3buflen)
1511 mp3buf_write = 0;
1512 DEBUGF("W\n");
1515 /* Tell ourselves that we want more data */
1516 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1518 else
1520 if(len < 0)
1522 DEBUGF("MPEG read error\n");
1525 close(mpeg_file);
1526 mpeg_file = -1;
1528 if(new_file(1) < 0)
1530 /* No more data to play */
1531 DEBUGF("No more files to play\n");
1532 filling = false;
1534 else
1536 /* Tell ourselves that we want more data */
1537 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
1541 break;
1543 case MPEG_TRACK_CHANGE:
1544 track_change();
1545 break;
1547 #ifndef USB_NONE
1548 case SYS_USB_CONNECTED:
1549 is_playing = false;
1550 paused = false;
1551 stop_playing();
1552 #ifndef SIMULATOR
1554 /* Tell the USB thread that we are safe */
1555 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1556 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1558 /* Wait until the USB cable is extracted again */
1559 usb_wait_for_disconnect(&mpeg_queue);
1560 #endif /* #ifndef SIMULATOR */
1561 break;
1562 #endif /* #ifndef USB_NONE */
1564 #if CONFIG_HWCODEC == MAS3587F
1565 case MPEG_INIT_RECORDING:
1566 init_recording();
1567 init_recording_done = true;
1568 break;
1569 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1571 #if CONFIG_HWCODEC == MAS3587F
1573 else
1575 queue_wait(&mpeg_queue, &ev);
1576 switch(ev.id)
1578 case MPEG_RECORD:
1579 if(is_prerecording)
1581 int startpos, i;
1583 /* Go back prerecord_count seconds in the buffer */
1584 startpos = prerecord_index - prerecord_count;
1585 if(startpos < 0)
1586 startpos += prerecording_max_seconds;
1588 /* Read the mp3 buffer pointer from the prerecord buffer */
1589 startpos = prerecord_buffer[startpos];
1591 DEBUGF("Start looking at address %x (%x)\n",
1592 mp3buf+startpos, startpos);
1594 saved_header = mpeg_get_last_header();
1596 mem_find_next_frame(startpos, &offset, 5000,
1597 saved_header);
1599 mp3buf_read = startpos + offset;
1601 DEBUGF("New mp3buf_read address: %x (%x)\n",
1602 mp3buf+mp3buf_read, mp3buf_read);
1604 /* Make room for headers */
1605 mp3buf_read -= MPEG_RESERVED_HEADER_SPACE;
1606 if(mp3buf_read < 0)
1608 /* Clear the bottom half */
1609 memset(mp3buf, 0,
1610 mp3buf_read + MPEG_RESERVED_HEADER_SPACE);
1612 /* And the top half */
1613 mp3buf_read += mp3buflen;
1614 memset(mp3buf + mp3buf_read, 0,
1615 mp3buflen - mp3buf_read);
1617 else
1619 memset(mp3buf + mp3buf_read, 0,
1620 MPEG_RESERVED_HEADER_SPACE);
1623 /* Copy the empty ID3 header */
1624 startpos = mp3buf_read;
1625 for(i = 0;i < (int)sizeof(empty_id3_header);i++)
1627 mp3buf[startpos++] = empty_id3_header[i];
1628 if(startpos == mp3buflen)
1629 startpos = 0;
1632 DEBUGF("New mp3buf_read address (reservation): %x\n",
1633 mp3buf+mp3buf_read);
1635 DEBUGF("Prerecording...\n");
1637 else
1639 reset_mp3_buffer();
1641 num_rec_bytes = 0;
1643 /* Advance the write pointer to make
1644 room for an ID3 tag plus a VBR header */
1645 mp3buf_write = MPEG_RESERVED_HEADER_SPACE;
1646 memset(mp3buf, 0, MPEG_RESERVED_HEADER_SPACE);
1648 /* Insert the ID3 header */
1649 memcpy(mp3buf, empty_id3_header,
1650 sizeof(empty_id3_header));
1652 DEBUGF("Recording...\n");
1655 start_recording();
1657 /* Wait until at least one frame is encoded and get the
1658 frame header, for later use by the Xing header
1659 generation */
1660 sleep(HZ/10);
1661 saved_header = mpeg_get_last_header();
1663 /* delayed until buffer is saved, don't open yet */
1664 strcpy(delayed_filename, recording_filename);
1665 mpeg_file = -1;
1667 break;
1669 case MPEG_STOP:
1670 DEBUGF("MPEG_STOP\n");
1672 stop_recording();
1674 /* Save the remaining data in the buffer */
1675 stop_pending = true;
1676 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1677 break;
1679 case MPEG_STOP_DONE:
1680 DEBUGF("MPEG_STOP_DONE\n");
1682 if(mpeg_file >= 0)
1683 close(mpeg_file);
1685 if(!disable_xing_header && num_rec_bytes > 0)
1687 /* Create the Xing header */
1688 mpeg_file = open(recording_filename, O_RDWR);
1689 if(mpeg_file < 0)
1690 panicf("rec upd: %d (%s)", mpeg_file,
1691 recording_filename);
1693 /* If the number of recorded frames have
1694 reached 0x7ffff, we can no longer trust it */
1695 if(num_recorded_frames == 0x7ffff)
1696 num_recorded_frames = 0;
1698 /* Also, if we have been prerecording, the frame count
1699 will be wrong */
1700 if(prerecording)
1701 num_recorded_frames = 0;
1703 /* saved_header is saved right before stopping
1704 the MAS */
1705 framelen = create_xing_header(mpeg_file, 0,
1706 num_rec_bytes, mp3buf,
1707 num_recorded_frames,
1708 saved_header, NULL,
1709 false);
1711 lseek(mpeg_file, MPEG_RESERVED_HEADER_SPACE-framelen,
1712 SEEK_SET);
1713 write(mpeg_file, mp3buf, framelen);
1714 close(mpeg_file);
1716 mpeg_file = -1;
1718 #ifdef DEBUG1
1720 int i;
1721 for(i = 0;i < 512;i++)
1723 DEBUGF("%d - %d us (%d bytes)\n",
1724 timing_info[i*2],
1725 (timing_info[i*2+1] & 0xffff) *
1726 10000 / 13824,
1727 timing_info[i*2+1] >> 16);
1730 #endif /* #ifdef DEBUG1 */
1732 if(prerecording)
1734 start_prerecording();
1736 mpeg_stop_done = true;
1737 break;
1739 case MPEG_NEW_FILE:
1740 /* Make sure we have at least one complete frame
1741 in the buffer. If we haven't recorded a single
1742 frame within 200ms, the MAS is probably not recording
1743 anything, and we bail out. */
1744 countdown = 20;
1745 amount_to_save = get_unsaved_space();
1746 while(countdown-- && amount_to_save < 1800)
1748 sleep(HZ/10);
1749 amount_to_save = get_unsaved_space();
1752 if(amount_to_save >= 1800)
1754 /* Now find a frame boundary to split at */
1755 startpos = mp3buf_write - 1800;
1756 if(startpos < 0)
1757 startpos += mp3buflen;
1759 rc = mem_find_next_frame(startpos, &offset, 1800,
1760 saved_header);
1761 if(rc) /* Header found? */
1763 /* offset will now contain the number of bytes to
1764 add to startpos to find the frame boundary */
1765 startpos += offset;
1766 if(startpos >= mp3buflen)
1767 startpos -= mp3buflen;
1769 else
1771 /* No header found. Let's save the whole buffer. */
1772 startpos = mp3buf_write;
1775 else
1777 /* Too few bytes recorded, timeout */
1778 startpos = mp3buf_write;
1781 amount_to_save = startpos - mp3buf_read;
1782 if(amount_to_save < 0)
1783 amount_to_save += mp3buflen;
1785 /* First save up to the end of the buffer */
1786 writelen = MIN(amount_to_save,
1787 mp3buflen - mp3buf_read);
1789 if (mpeg_file < 0) /* delayed file opening */
1791 mpeg_file = open(delayed_filename, O_WRONLY|O_CREAT);
1793 if(mpeg_file < 0)
1794 panicf("recfile: %d", mpeg_file);
1797 if(writelen)
1799 rc = write(mpeg_file, mp3buf + mp3buf_read, writelen);
1800 if(rc < 0)
1802 if(errno == ENOSPC)
1804 mpeg_errno = MPEGERR_DISK_FULL;
1805 demand_irq_enable(false);
1806 stop_recording();
1807 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1808 break;
1810 else
1812 panicf("spt wrt: %d", rc);
1817 /* Then save the rest */
1818 writelen = amount_to_save - writelen;
1819 if(writelen)
1821 rc = write(mpeg_file, mp3buf, writelen);
1822 if(rc < 0)
1824 if(errno == ENOSPC)
1826 mpeg_errno = MPEGERR_DISK_FULL;
1827 demand_irq_enable(false);
1828 stop_recording();
1829 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1830 break;
1832 else
1834 panicf("spt wrt: %d", rc);
1839 /* Advance the buffer pointers */
1840 mp3buf_read += amount_to_save;
1841 if(mp3buf_read >= mp3buflen)
1842 mp3buf_read -= mp3buflen;
1844 /* Close the current file */
1845 rc = close(mpeg_file);
1846 if(rc < 0)
1847 panicf("spt cls: %d", rc);
1849 /* Open the new file */
1850 mpeg_file = open(recording_filename, O_WRONLY|O_CREAT);
1851 if(mpeg_file < 0)
1852 panicf("sptfile: %d", mpeg_file);
1853 break;
1855 case MPEG_SAVE_DATA:
1856 amount_to_save = get_unsaved_space();
1858 /* If the result is negative, the write index has
1859 wrapped */
1860 if(amount_to_save < 0)
1862 amount_to_save += mp3buflen;
1865 DEBUGF("r: %x w: %x\n", mp3buf_read, mp3buf_write);
1866 DEBUGF("ats: %x\n", amount_to_save);
1868 /* Save data only if the buffer is getting full,
1869 or if we should stop recording */
1870 if(amount_to_save)
1872 if(mp3buflen -
1873 amount_to_save < MPEG_RECORDING_LOW_WATER ||
1874 stop_pending)
1876 /* Only save up to the end of the buffer */
1877 writelen = MIN(amount_to_save,
1878 mp3buflen - mp3buf_read);
1880 DEBUGF("wrl: %x\n", writelen);
1882 if (mpeg_file < 0) /* delayed file opening */
1884 mpeg_file = open(delayed_filename,
1885 O_WRONLY|O_CREAT);
1887 if(mpeg_file < 0)
1888 panicf("recfile: %d", mpeg_file);
1891 rc = write(mpeg_file, mp3buf + mp3buf_read,
1892 writelen);
1894 if(rc < 0)
1896 if(errno == ENOSPC)
1898 mpeg_errno = MPEGERR_DISK_FULL;
1899 stop_recording();
1900 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1901 break;
1903 else
1905 panicf("rec wrt: %d", rc);
1909 mp3buf_read += amount_to_save;
1910 if(mp3buf_read >= mp3buflen)
1911 mp3buf_read = 0;
1913 rc = fsync(mpeg_file);
1914 if(rc < 0)
1915 panicf("rec fls: %d", rc);
1917 queue_post(&mpeg_queue, MPEG_SAVE_DATA, 0);
1919 else
1921 saving = false;
1922 ata_sleep();
1925 else
1927 /* We have saved all data,
1928 time to stop for real */
1929 if(stop_pending)
1930 queue_post(&mpeg_queue, MPEG_STOP_DONE, 0);
1931 saving = false;
1932 ata_sleep();
1934 break;
1936 case MPEG_INIT_PLAYBACK:
1937 /* Stop the prerecording */
1938 stop_recording();
1939 mp3_play_init();
1940 init_playback_done = true;
1941 break;
1943 case MPEG_PAUSE_RECORDING:
1944 pause_recording();
1945 break;
1947 case MPEG_RESUME_RECORDING:
1948 resume_recording();
1949 break;
1951 case SYS_USB_CONNECTED:
1952 /* We can safely go to USB mode if no recording
1953 is taking place */
1954 if((!is_recording || is_prerecording) && mpeg_stop_done)
1956 /* Even if we aren't recording, we still call this
1957 function, to put the MAS in monitoring mode,
1958 to save power. */
1959 stop_recording();
1961 /* Tell the USB thread that we are safe */
1962 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1963 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1965 /* Wait until the USB cable is extracted again */
1966 usb_wait_for_disconnect(&mpeg_queue);
1968 break;
1971 #endif /* #if CONFIG_HWCODEC == MAS3587F */
1974 #endif /* SIMULATOR */
1976 #ifdef SIMULATOR
1977 static struct mp3entry taginfo;
1978 #endif /* #ifdef SIMULATOR */
1980 void mpeg_id3_options(bool _v1first)
1982 v1first = _v1first;
1985 struct mp3entry* mpeg_current_track()
1987 #ifdef SIMULATOR
1988 return &taginfo;
1989 #else
1990 if(num_tracks_in_memory())
1991 return &id3tags[tag_read_idx].id3;
1992 else
1993 return NULL;
1994 #endif /* #ifdef SIMULATOR */
1997 struct mp3entry* mpeg_next_track()
1999 #ifdef SIMULATOR
2000 return &taginfo;
2001 #else
2002 if(num_tracks_in_memory() > 1)
2003 return &(id3tags[(tag_read_idx+1) & MAX_ID3_TAGS_MASK].id3);
2004 else
2005 return NULL;
2006 #endif /* #ifdef SIMULATOR */
2009 bool mpeg_has_changed_track(void)
2011 if(last_track_counter != current_track_counter)
2013 last_track_counter = current_track_counter;
2014 return true;
2016 return false;
2019 #if CONFIG_HWCODEC == MAS3587F
2020 void mpeg_init_playback(void)
2022 init_playback_done = false;
2023 queue_post(&mpeg_queue, MPEG_INIT_PLAYBACK, NULL);
2025 while(!init_playback_done)
2026 sleep_thread();
2027 wake_up_thread();
2031 /****************************************************************************
2034 ** Recording functions
2037 ***************************************************************************/
2038 void mpeg_init_recording(void)
2040 init_recording_done = false;
2041 queue_post(&mpeg_queue, MPEG_INIT_RECORDING, NULL);
2043 while(!init_recording_done)
2044 sleep_thread();
2045 wake_up_thread();
2048 static void init_recording(void)
2050 unsigned long val;
2051 int rc;
2053 /* Disable IRQ6 */
2054 IPRB &= 0xff0f;
2056 stop_playing();
2057 is_playing = false;
2058 paused = false;
2060 /* Init the recording variables */
2061 is_recording = false;
2062 is_prerecording = false;
2064 mpeg_stop_done = true;
2066 mas_reset();
2068 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2069 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
2070 if(rc < 0)
2071 panicf("mas_ctrl_w: %d", rc);
2073 /* Stop the current application */
2074 val = 0;
2075 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2078 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2079 } while(val);
2081 /* Perform black magic as described by the data sheet */
2082 if((mas_version_code & 0x0fff) == 0x0102)
2084 DEBUGF("Performing MAS black magic for B2 version\n");
2085 mas_writereg(0xa3, 0x98);
2086 mas_writereg(0x94, 0xfffff);
2087 val = 0;
2088 mas_writemem(MAS_BANK_D1, 0, &val, 1);
2089 mas_writereg(0xa3, 0x90);
2092 /* Enable A/D Converters */
2093 mas_codec_writereg(0x0, 0xcccd);
2095 /* Copy left channel to right (mono mode) */
2096 mas_codec_writereg(8, 0x8000);
2098 /* ADC scale 0%, DSP scale 100%
2099 We use the DSP output for monitoring, because it works with all
2100 sources including S/PDIF */
2101 mas_codec_writereg(6, 0x0000);
2102 mas_codec_writereg(7, 0x4000);
2104 /* No mute */
2105 shadow_soft_mute = 0;
2106 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2108 /* Set Demand mode, monitoring OFF and validate all settings */
2109 shadow_io_control_main = 0x125;
2110 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2112 /* Start the encoder application */
2113 val = 0x40;
2114 mas_writemem(MAS_BANK_D0, MAS_D0_APP_SELECT, &val, 1);
2117 mas_readmem(MAS_BANK_D0, MAS_D0_APP_RUNNING, &val, 1);
2118 } while(!(val & 0x40));
2120 #if 1
2121 /* We have started the recording application with monitoring OFF.
2122 This is because we want to record at least one frame to fill the DMA
2123 buffer, because the silly MAS will not negate EOD until at least one
2124 DMA transfer has taken place.
2125 Now let's wait for some data to be encoded. */
2126 sleep(20);
2128 /* Now set it to Monitoring mode as default, saves power */
2129 shadow_io_control_main = 0x525;
2130 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2132 /* Wait until the DSP has accepted the settings */
2135 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2136 } while(val & 1);
2138 drain_dma_buffer();
2139 #endif
2140 mpeg_mode = MPEG_ENCODER;
2142 DEBUGF("MAS Recording application started\n");
2144 /* At this point, all settings are the reset MAS defaults, next thing is to
2145 call mpeg_set_recording_options(). */
2148 void mpeg_record(const char *filename)
2150 mpeg_errno = 0;
2152 strncpy(recording_filename, filename, MAX_PATH - 1);
2153 recording_filename[MAX_PATH - 1] = 0;
2155 disable_xing_header = false;
2156 queue_post(&mpeg_queue, MPEG_RECORD, NULL);
2159 void mpeg_pause_recording(void)
2161 queue_post(&mpeg_queue, MPEG_PAUSE_RECORDING, NULL);
2164 void mpeg_resume_recording(void)
2166 queue_post(&mpeg_queue, MPEG_RESUME_RECORDING, NULL);
2169 static void start_prerecording(void)
2171 unsigned long val;
2173 DEBUGF("Starting prerecording\n");
2175 prerecord_index = 0;
2176 prerecord_count = 0;
2177 prerecord_timeout = current_tick + HZ;
2178 memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
2179 reset_mp3_buffer();
2181 is_prerecording = true;
2183 /* Stop monitoring and start the encoder */
2184 shadow_io_control_main &= ~(1 << 10);
2185 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2186 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2188 /* Wait until the DSP has accepted the settings */
2191 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2192 } while(val & 1);
2194 is_recording = true;
2195 stop_pending = false;
2196 saving = false;
2198 demand_irq_enable(true);
2201 static void start_recording(void)
2203 unsigned long val;
2205 num_recorded_frames = 0;
2207 if(is_prerecording)
2209 /* This will make the IRQ handler start recording
2210 for real, i.e send MPEG_SAVE_DATA messages when
2211 the buffer is full */
2212 is_prerecording = false;
2214 else
2216 /* If prerecording is off, we need to stop the monitoring
2217 and start the encoder */
2218 shadow_io_control_main &= ~(1 << 10);
2219 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2220 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2222 /* Wait until the DSP has accepted the settings */
2225 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2226 } while(val & 1);
2229 is_recording = true;
2230 stop_pending = false;
2231 saving = false;
2232 paused = false;
2234 /* Store the current time */
2235 if(prerecording)
2236 record_start_time = current_tick - prerecord_count * HZ;
2237 else
2238 record_start_time = current_tick;
2240 pause_start_time = 0;
2242 demand_irq_enable(true);
2245 static void pause_recording(void)
2247 pause_start_time = current_tick;
2249 /* Set the pause bit */
2250 shadow_soft_mute |= 2;
2251 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2253 paused = true;
2256 static void resume_recording(void)
2258 paused = false;
2260 /* Clear the pause bit */
2261 shadow_soft_mute &= ~2;
2262 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute, 1);
2264 /* Compensate for the time we have been paused */
2265 if(pause_start_time)
2267 record_start_time =
2268 current_tick - (pause_start_time - record_start_time);
2269 pause_start_time = 0;
2273 static void stop_recording(void)
2275 unsigned long val;
2277 /* Let it finish the last frame */
2278 if(!paused)
2279 pause_recording();
2280 sleep(HZ/5);
2282 demand_irq_enable(false);
2284 is_recording = false;
2285 is_prerecording = false;
2287 /* Read the number of frames recorded */
2288 mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &num_recorded_frames, 1);
2290 /* Start monitoring */
2291 shadow_io_control_main |= (1 << 10);
2292 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1);
2293 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2295 /* Wait until the DSP has accepted the settings */
2298 mas_readmem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &val,1);
2299 } while(val & 1);
2301 resume_recording();
2304 void mpeg_set_recording_options(int frequency, int quality,
2305 int source, int channel_mode,
2306 bool editable, int prerecord_time)
2308 bool is_mpeg1;
2310 is_mpeg1 = (frequency < 3)?true:false;
2312 rec_version_index = is_mpeg1?3:2;
2313 rec_frequency_index = frequency % 3;
2315 shadow_encoder_control = (quality << 17) |
2316 (rec_frequency_index << 10) |
2317 ((is_mpeg1?1:0) << 9) |
2318 (((channel_mode * 2 + 1) & 3) << 6) |
2319 (1 << 5) /* MS-stereo */ |
2320 (1 << 2) /* Is an original */;
2321 mas_writemem(MAS_BANK_D0, MAS_D0_ENCODER_CONTROL, &shadow_encoder_control,1);
2323 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control);
2325 shadow_soft_mute = editable?4:0;
2326 mas_writemem(MAS_BANK_D0, MAS_D0_SOFT_MUTE, &shadow_soft_mute,1);
2328 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute);
2330 shadow_io_control_main = ((1 << 10) | /* Monitoring ON */
2331 ((source < 2)?1:2) << 8) | /* Input select */
2332 (1 << 5) | /* SDO strobe invert */
2333 ((is_mpeg1?0:1) << 3) |
2334 (1 << 2) | /* Inverted SIBC clock signal */
2335 1; /* Validate */
2336 mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main,1);
2338 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main);
2340 if(source == 0) /* Mic */
2342 /* Copy left channel to right (mono mode) */
2343 mas_codec_writereg(8, 0x8000);
2345 else
2347 /* Stereo input mode */
2348 mas_codec_writereg(8, 0);
2351 prerecording_max_seconds = prerecord_time;
2352 if(prerecording_max_seconds)
2354 prerecording = true;
2355 start_prerecording();
2357 else
2359 prerecording = false;
2360 is_prerecording = false;
2361 is_recording = false;
2365 /* If use_mic is true, the left gain is used */
2366 void mpeg_set_recording_gain(int left, int right, bool use_mic)
2368 /* Enable both left and right A/D */
2369 mas_codec_writereg(0x0,
2370 (left << 12) |
2371 (right << 8) |
2372 (left << 4) |
2373 (use_mic?0x0008:0) | /* Connect left A/D to mic */
2374 0x0007);
2377 void mpeg_new_file(const char *filename)
2379 mpeg_errno = 0;
2381 strncpy(recording_filename, filename, MAX_PATH - 1);
2382 recording_filename[MAX_PATH - 1] = 0;
2384 num_rec_bytes = 0;
2385 disable_xing_header = true;
2387 /* Store the current time */
2388 record_start_time = current_tick;
2389 if(paused)
2390 pause_start_time = record_start_time;
2392 queue_post(&mpeg_queue, MPEG_NEW_FILE, NULL);
2395 unsigned long mpeg_recorded_time(void)
2397 if(is_prerecording)
2398 return prerecord_count * HZ;
2400 if(is_recording)
2402 if(paused)
2403 return pause_start_time - record_start_time;
2404 else
2405 return current_tick - record_start_time;
2408 return 0;
2411 unsigned long mpeg_num_recorded_bytes(void)
2413 int num_bytes;
2414 int index;
2416 if(is_recording)
2418 if(is_prerecording)
2420 index = prerecord_index - prerecord_count;
2421 if(index < 0)
2422 index += prerecording_max_seconds;
2424 num_bytes = mp3buf_write - prerecord_buffer[index];
2425 if(num_bytes < 0)
2426 num_bytes += mp3buflen;
2428 return num_bytes;;
2430 else
2431 return num_rec_bytes;
2433 else
2434 return 0;
2437 #endif
2439 void mpeg_play(int offset)
2441 #ifdef SIMULATOR
2442 char* trackname;
2443 int steps=0;
2445 is_playing = true;
2447 do {
2448 trackname = playlist_peek( steps );
2449 if (!trackname)
2450 break;
2451 if(mp3info(&taginfo, trackname, v1first)) {
2452 /* bad mp3, move on */
2453 if(++steps > playlist_amount())
2454 break;
2455 continue;
2457 #ifdef HAVE_MPEG_PLAY
2458 real_mpeg_play(trackname);
2459 #endif
2460 playlist_next(steps);
2461 taginfo.offset = offset;
2462 set_elapsed(&taginfo);
2463 is_playing = true;
2464 playing = true;
2465 break;
2466 } while(1);
2467 #else
2468 is_playing = true;
2470 queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset);
2471 #endif /* #ifdef SIMULATOR */
2473 mpeg_errno = 0;
2476 void mpeg_stop(void)
2478 #ifndef SIMULATOR
2479 mpeg_stop_done = false;
2480 queue_post(&mpeg_queue, MPEG_STOP, NULL);
2481 while(!mpeg_stop_done)
2482 yield();
2483 #else
2484 paused = false;
2485 is_playing = false;
2486 playing = false;
2487 #endif /* #ifndef SIMULATOR */
2491 void mpeg_pause(void)
2493 #ifndef SIMULATOR
2494 queue_post(&mpeg_queue, MPEG_PAUSE, NULL);
2495 #else
2496 is_playing = true;
2497 playing = false;
2498 paused = true;
2499 #endif /* #ifndef SIMULATOR */
2502 void mpeg_resume(void)
2504 #ifndef SIMULATOR
2505 queue_post(&mpeg_queue, MPEG_RESUME, NULL);
2506 #else
2507 is_playing = true;
2508 playing = true;
2509 paused = false;
2510 #endif /* #ifndef SIMULATOR */
2513 void mpeg_next(void)
2515 #ifndef SIMULATOR
2516 queue_post(&mpeg_queue, MPEG_NEXT, NULL);
2517 #else
2518 char* file;
2519 int steps = 1;
2520 int index;
2522 do {
2523 file = playlist_peek(steps);
2524 if(!file)
2525 break;
2526 if(mp3info(&taginfo, file, v1first)) {
2527 if(++steps > playlist_amount())
2528 break;
2529 continue;
2531 index = playlist_next(steps);
2532 taginfo.index = index;
2533 current_track_counter++;
2534 is_playing = true;
2535 playing = true;
2536 break;
2537 } while(1);
2538 #endif /* #ifndef SIMULATOR */
2541 void mpeg_prev(void)
2543 #ifndef SIMULATOR
2544 queue_post(&mpeg_queue, MPEG_PREV, NULL);
2545 #else
2546 char* file;
2547 int steps = -1;
2548 int index;
2550 do {
2551 file = playlist_peek(steps);
2552 if(!file)
2553 break;
2554 if(mp3info(&taginfo, file, v1first)) {
2555 steps--;
2556 continue;
2558 index = playlist_next(steps);
2559 taginfo.index = index;
2560 current_track_counter++;
2561 is_playing = true;
2562 playing = true;
2563 break;
2564 } while(1);
2565 #endif /* #ifndef SIMULATOR */
2568 void mpeg_ff_rewind(int newtime)
2570 #ifndef SIMULATOR
2571 queue_post(&mpeg_queue, MPEG_FF_REWIND, (void *)newtime);
2572 #else
2573 (void)newtime;
2574 #endif /* #ifndef SIMULATOR */
2577 void mpeg_flush_and_reload_tracks(void)
2579 #ifndef SIMULATOR
2580 queue_post(&mpeg_queue, MPEG_FLUSH_RELOAD, NULL);
2581 #endif /* #ifndef SIMULATOR*/
2584 int mpeg_status(void)
2586 int ret = 0;
2588 if(is_playing)
2589 ret |= MPEG_STATUS_PLAY;
2591 if(paused)
2592 ret |= MPEG_STATUS_PAUSE;
2594 #if CONFIG_HWCODEC == MAS3587F
2595 if(is_recording && !is_prerecording)
2596 ret |= MPEG_STATUS_RECORD;
2598 if(is_prerecording)
2599 ret |= MPEG_STATUS_PRERECORD;
2600 #endif /* #if CONFIG_HWCODEC == MAS3587F */
2602 if(mpeg_errno)
2603 ret |= MPEG_STATUS_ERROR;
2605 return ret;
2608 unsigned int mpeg_error(void)
2610 return mpeg_errno;
2613 void mpeg_error_clear(void)
2615 mpeg_errno = 0;
2618 #ifdef SIMULATOR
2619 static char mpeg_stack[DEFAULT_STACK_SIZE];
2620 static const char mpeg_thread_name[] = "mpeg";
2621 static void mpeg_thread(void)
2623 struct mp3entry* id3;
2624 while ( 1 ) {
2625 if (is_playing) {
2626 id3 = mpeg_current_track();
2627 if (!paused)
2629 id3->elapsed+=1000;
2630 id3->offset+=1000;
2632 if (id3->elapsed>=id3->length)
2633 mpeg_next();
2635 sleep(HZ);
2638 #endif /* #ifdef SIMULATOR */
2640 void mpeg_init(void)
2642 mpeg_errno = 0;
2644 #ifndef SIMULATOR
2645 mp3buflen = mp3end - mp3buf;
2646 queue_init(&mpeg_queue);
2647 #endif /* #ifndef SIMULATOR */
2648 create_thread(mpeg_thread, mpeg_stack,
2649 sizeof(mpeg_stack), mpeg_thread_name);
2651 memset(id3tags, sizeof(id3tags), 0);
2653 #if CONFIG_HWCODEC == MAS3587F
2654 if(read_hw_mask() & PR_ACTIVE_HIGH)
2655 and_b(~0x08, &PADRH);
2656 else
2657 or_b(0x08, &PADRH);
2658 #endif /* #if CONFIG_HWCODEC == MAS3587F */
2660 #ifdef DEBUG
2661 dbg_timer_start();
2662 dbg_cnt2us(0);
2663 #endif /* DEBUG */