1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 #if CONFIG_CODEC != SWCODEC
38 #include "core_alloc.h"
39 #include "mp3_playback.h"
43 #include "appevents.h"
54 #endif /* !SIMULATOR */
55 #ifdef HAVE_LCD_BITMAP
57 #endif /* CONFIG_CODEC != SWCODEC */
59 #define MPEG_SWAP_CHUNKSIZE 0x2000
60 #define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
61 wouldn't be able to see the difference between
62 an empty buffer and a full one. */
63 #define MPEG_LOW_WATER 0x60000
64 #define MPEG_RECORDING_LOW_WATER 0x80000
65 #define MPEG_LOW_WATER_CHUNKSIZE 0x40000
66 #define MPEG_LOW_WATER_SWAP_CHUNKSIZE 0x10000
67 #if (CONFIG_STORAGE & STORAGE_MMC)
68 #define MPEG_PLAY_PENDING_THRESHOLD 0x20000
69 #define MPEG_PLAY_PENDING_SWAPSIZE 0x20000
71 #define MPEG_PLAY_PENDING_THRESHOLD 0x10000
72 #define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
75 #define MPEG_MAX_PRERECORD_SECONDS 30
77 /* For ID3 info and VBR header */
78 #define MPEG_RESERVED_HEADER_SPACE (4096 + 576)
81 extern unsigned long mas_version_code
;
84 #if CONFIG_CODEC == MAS3587F
85 extern enum /* from mp3_playback.c */
90 #endif /* CONFIG_CODEC == MAS3587F */
98 #define MPEG_FF_REWIND 7
99 #define MPEG_FLUSH_RELOAD 8
100 #define MPEG_RECORD 9
101 #define MPEG_INIT_RECORDING 10
102 #define MPEG_INIT_PLAYBACK 11
103 #define MPEG_NEW_FILE 12
104 #define MPEG_PAUSE_RECORDING 13
105 #define MPEG_RESUME_RECORDING 14
106 #define MPEG_NEED_DATA 100
107 #define MPEG_TRACK_CHANGE 101
108 #define MPEG_SAVE_DATA 102
109 #define MPEG_STOP_DONE 103
110 #define MPEG_PRERECORDING_TICK 104
112 /* indicator for MPEG_NEED_DATA */
113 #define GENERATE_UNBUFFER_EVENTS 1
115 /* list of tracks in memory */
116 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
117 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
123 int load_ahead_index
;
126 static struct trackdata trackdata
[MAX_TRACK_ENTRIES
];
128 static unsigned int current_track_counter
= 0;
131 static void stop_playing(void);
132 /* Play time of the previous track */
133 static unsigned long prev_track_elapsed
;
135 static int track_read_idx
= 0;
136 static int track_write_idx
= 0;
137 #endif /* !SIMULATOR */
139 /* Cuesheet support */
140 static struct cuesheet
*curr_cuesheet
= NULL
;
141 static bool checked_for_cuesheet
= false;
143 static const char mpeg_thread_name
[] = "mpeg";
144 static unsigned int audio_thread_id
;
145 static bool audio_is_initialized
;
146 static unsigned int mpeg_errno
;
148 static bool playing
= false; /* We are playing an MP3 stream */
149 static bool is_playing
= false; /* We are (attempting to) playing MP3 files */
150 static bool paused
; /* playback is paused */
151 static int audiobuf_handle
; /* handle to the audio buffer */
152 static char* mpeg_audiobuf
; /* poiunter to the audio buffer */
153 static long audiobuflen
; /* length of the audio buffer */
156 static char mpeg_stack
[DEFAULT_STACK_SIZE
];
157 static struct mp3entry taginfo
;
158 #else /* !SIMULATOR */
159 static struct event_queue mpeg_queue SHAREDBSS_ATTR
;
160 static long mpeg_stack
[(DEFAULT_STACK_SIZE
+ 0x1000)/sizeof(long)];
162 static int audiobuf_write
;
163 static int audiobuf_swapwrite
;
164 static long audiobuf_read
;
166 static int mpeg_file
;
168 static bool play_pending
; /* We are about to start playing */
169 static bool play_pending_track_change
; /* When starting play we're starting a new file */
170 static bool filling
; /* We are filling the buffer with data from disk */
171 static bool dma_underrun
; /* True when the DMA has stopped because of
172 slow disk reading (read error, shaking) */
173 static bool mpeg_stop_done
;
175 static int last_dma_tick
= 0;
176 static int last_dma_chunk_size
;
178 static long low_watermark
; /* Dynamic low watermark level */
179 static long low_watermark_margin
= 0; /* Extra time in seconds for watermark */
180 static long lowest_watermark_level
; /* Debug value to observe the buffer
182 #if CONFIG_CODEC == MAS3587F
183 static char recording_filename
[MAX_PATH
]; /* argument to thread */
184 static char delayed_filename
[MAX_PATH
]; /* internal copy of above */
186 static char xing_buffer
[MAX_XING_HEADER_SIZE
];
188 static bool init_recording_done
;
189 static bool init_playback_done
;
190 static bool prerecording
; /* True if prerecording is enabled */
191 static bool is_prerecording
; /* True if we are prerecording */
192 static bool is_recording
; /* We are recording */
195 NOT_SAVING
= 0, /* reasons to save data, sorted by importance */
201 static int rec_frequency_index
; /* For create_xing_header() calls */
202 static int rec_version_index
; /* For create_xing_header() calls */
204 struct prerecord_info
{
206 unsigned long framecount
;
209 static struct prerecord_info prerecord_buffer
[MPEG_MAX_PRERECORD_SECONDS
];
210 static int prerecord_index
; /* Current index in the prerecord buffer */
211 static int prerecording_max_seconds
; /* Max number of seconds to store */
212 static int prerecord_count
; /* Number of seconds in the prerecord buffer */
213 static int prerecord_timeout
; /* The tick count of the next prerecord data
216 static unsigned long record_start_time
; /* Value of current_tick when recording
218 static unsigned long pause_start_time
; /* Value of current_tick when pause was
220 static unsigned long last_rec_time
;
221 static unsigned long num_rec_bytes
;
222 static unsigned long last_rec_bytes
;
223 static unsigned long frame_count_start
;
224 static unsigned long frame_count_end
;
225 static unsigned long saved_header
= 0;
227 /* Shadow MAS registers */
228 unsigned long shadow_encoder_control
= 0;
229 #endif /* CONFIG_CODEC == MAS3587F */
231 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
232 unsigned long shadow_io_control_main
= 0;
233 unsigned long shadow_soft_mute
= 0;
234 unsigned shadow_codec_reg0
;
235 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
237 #ifdef HAVE_RECORDING
238 static const unsigned char empty_id3_header
[] =
240 'I', 'D', '3', 0x03, 0x00, 0x00,
241 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
243 #endif /* HAVE_RECORDING */
246 static int get_unplayed_space(void);
247 static int get_playable_space(void);
248 static int get_unswapped_space(void);
249 #endif /* !SIMULATOR */
251 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
252 static void init_recording(void);
253 static void prepend_header(void);
254 static void update_header(void);
255 static void start_prerecording(void);
256 static void start_recording(void);
257 static void stop_recording(void);
258 static int get_unsaved_space(void);
259 static void pause_recording(void);
260 static void resume_recording(void);
261 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
265 static int num_tracks_in_memory(void)
267 return (track_write_idx
- track_read_idx
) & MAX_TRACK_ENTRIES_MASK
;
271 static void debug_tags(void)
275 for(i
= 0;i
< MAX_TRACK_ENTRIES
;i
++)
277 DEBUGF("%d - %s\n", i
, trackdata
[i
].id3
.path
);
279 DEBUGF("read: %d, write :%d\n", track_read_idx
, track_write_idx
);
280 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
282 #else /* !DEBUG_TAGS */
284 #endif /* !DEBUG_TAGS */
286 static void remove_current_tag(void)
288 if(num_tracks_in_memory() > 0)
290 /* First move the index, so nobody tries to access the tag */
291 track_read_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
292 checked_for_cuesheet
= false;
297 DEBUGF("remove_current_tag: no tracks to remove\n");
301 static void remove_all_non_current_tags(void)
303 track_write_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
307 static void remove_all_tags(void)
309 track_write_idx
= track_read_idx
;
314 static struct trackdata
*get_trackdata(int offset
)
316 if(offset
>= num_tracks_in_memory())
319 return &trackdata
[(track_read_idx
+ offset
) & MAX_TRACK_ENTRIES_MASK
];
321 #endif /* !SIMULATOR */
323 /***********************************************************************/
324 /* audio event handling */
326 #define MAX_EVENT_HANDLERS 10
327 struct event_handlers_table
329 AUDIO_EVENT_HANDLER handler
;
332 static struct event_handlers_table event_handlers
[MAX_EVENT_HANDLERS
];
333 static int event_handlers_count
= 0;
335 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler
, unsigned short mask
)
337 if (event_handlers_count
< MAX_EVENT_HANDLERS
)
339 event_handlers
[event_handlers_count
].handler
= handler
;
340 event_handlers
[event_handlers_count
].mask
= mask
;
341 event_handlers_count
++;
345 /* dispatch calls each handler in the order registered and returns after some
346 handler actually handles the event (the event is assumed to no longer be valid
347 after this, due to the handler changing some condition); returns true if someone
348 handled the event, which is expected to cause the caller to skip its own handling
351 static bool audio_dispatch_event(unsigned short event
, unsigned long data
)
354 for(i
=0; i
< event_handlers_count
; i
++)
356 if ( event_handlers
[i
].mask
& event
)
358 int rc
= event_handlers
[i
].handler(event
, data
);
359 if ( rc
== AUDIO_EVENT_RC_HANDLED
)
367 /***********************************************************************/
369 static void set_elapsed(struct mp3entry
* id3
)
372 if ( id3
->has_toc
) {
373 /* calculate elapsed time using TOC */
375 unsigned int remainder
, plen
, relpos
, nextpos
;
377 /* find wich percent we're at */
378 for (i
=0; i
<100; i
++ )
380 if ( id3
->offset
< id3
->toc
[i
] * (id3
->filesize
/ 256) )
390 relpos
= id3
->toc
[i
];
394 nextpos
= id3
->toc
[i
+1];
401 remainder
= id3
->offset
- (relpos
* (id3
->filesize
/ 256));
403 /* set time for this percent (divide before multiply to prevent
404 overflow on long files. loss of precision is negligible on
406 id3
->elapsed
= i
* (id3
->length
/ 100);
408 /* calculate remainder time */
409 plen
= (nextpos
- relpos
) * (id3
->filesize
/ 256);
410 id3
->elapsed
+= (((remainder
* 100) / plen
) *
411 (id3
->length
/ 10000));
414 /* no TOC exists. set a rough estimate using average bitrate */
415 int tpk
= id3
->length
/ (id3
->filesize
/ 1024);
416 id3
->elapsed
= id3
->offset
/ 1024 * tpk
;
420 /* constant bitrate, use exact calculation */
421 id3
->elapsed
= id3
->offset
/ (id3
->bitrate
/ 8);
424 int audio_get_file_pos(void)
427 struct mp3entry
*id3
= audio_current_track();
433 /* Use the TOC to find the new position */
434 unsigned int percent
, remainder
;
435 int curtoc
, nexttoc
, plen
;
437 percent
= (id3
->elapsed
*100)/id3
->length
;
441 curtoc
= id3
->toc
[percent
];
444 nexttoc
= id3
->toc
[percent
+1];
448 pos
= (id3
->filesize
/256)*curtoc
;
450 /* Use the remainder to get a more accurate position */
451 remainder
= (id3
->elapsed
*100)%id3
->length
;
452 remainder
= (remainder
*100)/id3
->length
;
453 plen
= (nexttoc
- curtoc
)*(id3
->filesize
/256);
454 pos
+= (plen
/100)*remainder
;
458 /* No TOC exists, estimate the new position */
459 pos
= (id3
->filesize
/ (id3
->length
/ 1000)) *
460 (id3
->elapsed
/ 1000);
463 else if (id3
->bitrate
)
464 pos
= id3
->elapsed
* (id3
->bitrate
/ 8);
470 if (pos
>= (int)(id3
->filesize
- id3
->id3v1len
))
472 /* Don't seek right to the end of the file so that we can
473 transition properly to the next song */
474 pos
= id3
->filesize
- id3
->id3v1len
- 1;
476 else if (pos
< (int)id3
->first_frame_offset
)
478 /* skip past id3v2 tag and other leading garbage */
479 pos
= id3
->first_frame_offset
;
484 unsigned long mpeg_get_last_header(void)
488 #else /* !SIMULATOR */
489 unsigned long tmp
[2];
491 /* Read the frame data from the MAS and reconstruct it with the
492 frame sync and all */
493 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_STATUS_1
, tmp
, 2);
494 return 0xffe00000 | ((tmp
[0] & 0x7c00) << 6) | (tmp
[1] & 0xffff);
495 #endif /* !SIMULATOR */
498 static void do_stop(void)
505 playlist_update_resume_info(audio_current_track());
508 mpeg_stop_done
= true;
514 static void audio_reset_buffer_noalloc(void* buf
, size_t bufsize
);
515 /* Buffer must not move. */
516 static int shrink_callback(int handle
, unsigned hints
, void* start
, size_t old_size
)
518 long offset
= audio_current_track()->offset
;
519 int status
= audio_status();
520 /* TODO: Do it without stopping playback, if possible */
521 /* don't call audio_hard_stop() as it frees this handle */
522 if (thread_self() == audio_thread_id
)
523 { /* inline case MPEG_STOP (audio_stop()) response
524 * if we're in the audio thread since audio_stop() otherwise deadlocks */
529 talk_buffer_steal(); /* we obtain control over the buffer */
531 /* we should be free to change the buffer now */
532 size_t wanted_size
= (hints
& BUFLIB_SHRINK_SIZE_MASK
);
533 ssize_t size
= (ssize_t
)old_size
- wanted_size
;
534 switch (hints
& BUFLIB_SHRINK_POS_MASK
)
536 case BUFLIB_SHRINK_POS_BACK
:
537 core_shrink(handle
, start
, size
);
538 audio_reset_buffer_noalloc(start
, size
);
540 case BUFLIB_SHRINK_POS_FRONT
:
541 core_shrink(handle
, start
+ wanted_size
, size
);
542 audio_reset_buffer_noalloc(start
+ wanted_size
, size
);
545 if (!(status
& AUDIO_STATUS_PAUSE
))
546 { /* safe to call even from the audio thread (due to queue_post()) */
553 static struct buflib_callbacks ops
= {
554 .move_callback
= NULL
,
555 .shrink_callback
= shrink_callback
,
558 unsigned char * audio_get_buffer(bool talk_buf
, size_t *buffer_size
)
560 (void)talk_buf
; /* always grab the voice buffer for now */
562 if (audio_is_initialized
)
565 if (!buffer_size
) /* special case for talk_init() */
568 if (!audiobuf_handle
)
571 /* audio_hard_stop() frees audiobuf, so re-aquire */
572 audiobuf_handle
= core_alloc_maximum("audiobuf", &bufsize
, &ops
);
573 audiobuflen
= bufsize
;
575 *buffer_size
= audiobuflen
;
577 mpeg_audiobuf
= core_get_data(audiobuf_handle
);
578 /* tell talk about the new buffer, don't re-enable just yet because the
579 * buffer is stolen */
580 talkbuf_init(mpeg_audiobuf
);
582 return mpeg_audiobuf
;
587 /* Send callback events to notify about removing old tracks. */
588 static void generate_unbuffer_events(void)
591 int numentries
= MAX_TRACK_ENTRIES
- num_tracks_in_memory();
592 int cur_idx
= track_write_idx
;
594 for (i
= 0; i
< numentries
; i
++)
596 /* Send an event to notify that track has finished. */
597 send_event(PLAYBACK_EVENT_TRACK_FINISH
, &trackdata
[cur_idx
].id3
);
598 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
602 /* Send callback events to notify about new tracks. */
603 static void generate_postbuffer_events(void)
606 int numentries
= num_tracks_in_memory();
607 int cur_idx
= track_read_idx
;
609 for (i
= 0; i
< numentries
; i
++)
611 send_event(PLAYBACK_EVENT_TRACK_BUFFER
, &trackdata
[cur_idx
].id3
);
612 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
616 static void recalculate_watermark(int bitrate
)
619 int time
= storage_spinup_time();
621 /* A bitrate of 0 probably means empty VBR header. We play safe
622 and set a high threshold */
626 bytes_per_sec
= bitrate
* 1000 / 8;
630 /* No drive spins up faster than 3.5s */
635 low_watermark
= ((low_watermark_margin
* HZ
+ time
) *
640 low_watermark
= MPEG_LOW_WATER
;
644 #ifdef HAVE_DISK_STORAGE
645 void audio_set_buffer_margin(int setting
)
647 low_watermark_margin
= setting
; /* in seconds */
651 void audio_get_debugdata(struct audio_debug
*dbgdata
)
653 dbgdata
->audiobuflen
= audiobuflen
;
654 dbgdata
->audiobuf_write
= audiobuf_write
;
655 dbgdata
->audiobuf_swapwrite
= audiobuf_swapwrite
;
656 dbgdata
->audiobuf_read
= audiobuf_read
;
658 dbgdata
->last_dma_chunk_size
= last_dma_chunk_size
;
660 #if CONFIG_CPU == SH7034
661 dbgdata
->dma_on
= (SCR0
& 0x80) != 0;
663 dbgdata
->playing
= playing
;
664 dbgdata
->play_pending
= play_pending
;
665 dbgdata
->is_playing
= is_playing
;
666 dbgdata
->filling
= filling
;
667 dbgdata
->dma_underrun
= dma_underrun
;
669 dbgdata
->unplayed_space
= get_unplayed_space();
670 dbgdata
->playable_space
= get_playable_space();
671 dbgdata
->unswapped_space
= get_unswapped_space();
673 dbgdata
->low_watermark_level
= low_watermark
;
674 dbgdata
->lowest_watermark_level
= lowest_watermark_level
;
678 static void dbg_timer_start(void)
680 /* We are using timer 2 */
682 TSTR
&= ~0x04; /* Stop the timer */
683 TSNC
&= ~0x04; /* No synchronization */
684 TMDR
&= ~0x44; /* Operate normally */
686 TCNT2
= 0; /* Start counting at 0 */
687 TCR2
= 0x03; /* Sysclock/8 */
689 TSTR
|= 0x04; /* Start timer 2 */
692 static int dbg_cnt2us(unsigned int cnt
)
694 return (cnt
* 10000) / (FREQ
/800);
698 static int get_unplayed_space(void)
700 int space
= audiobuf_write
- audiobuf_read
;
702 space
+= audiobuflen
;
706 static int get_playable_space(void)
708 int space
= audiobuf_swapwrite
- audiobuf_read
;
710 space
+= audiobuflen
;
714 static int get_unplayed_space_current_song(void)
718 if (num_tracks_in_memory() > 1)
720 space
= get_trackdata(1)->mempos
- audiobuf_read
;
724 space
= audiobuf_write
- audiobuf_read
;
728 space
+= audiobuflen
;
733 static int get_unswapped_space(void)
735 int space
= audiobuf_write
- audiobuf_swapwrite
;
737 space
+= audiobuflen
;
741 #if CONFIG_CODEC == MAS3587F
742 static int get_unsaved_space(void)
744 int space
= audiobuf_write
- audiobuf_read
;
746 space
+= audiobuflen
;
750 static void drain_dma_buffer(void)
756 while (PBDRH
& 0x80);
760 while (!(PBDRH
& 0x80));
765 static long timing_info_index
= 0;
766 static long timing_info
[1024];
769 void rec_tick (void) __attribute__ ((section (".icode")));
776 if(is_recording
&& (PBDRH
& 0x40))
779 timing_info
[timing_info_index
++] = current_tick
;
782 /* Note: Although this loop is run in interrupt context, further
783 * optimisation will do no good. The MAS would then deliver bad
784 * frames occasionally, as observed in extended experiments. */
786 while (PBDRH
& 0x40) /* We try to read as long as EOD is high */
788 xor_b(0x08, &PADRH
); /* Set PR active, independent of polarity */
791 while (PBDRH
& 0x80) /* Wait until /RTW becomes active */
793 if (--delay
<= 0) /* Bail out if we have to wait too long */
794 { /* i.e. the MAS doesn't want to talk to us */
795 xor_b(0x08, &PADRH
); /* Set PR inactive */
796 goto transfer_end
; /* and get out of here */
800 data
= *(unsigned char *)0x04000000; /* read data byte */
802 xor_b(0x08, &PADRH
); /* Set PR inactive */
804 mpeg_audiobuf
[audiobuf_write
++] = data
;
806 if (audiobuf_write
>= audiobuflen
)
814 timing_info
[timing_info_index
++] = TCNT2
+ (i
<< 16);
815 timing_info_index
&= 0x3ff;
822 if(TIME_AFTER(current_tick
, prerecord_timeout
))
824 prerecord_timeout
= current_tick
+ HZ
;
825 queue_post(&mpeg_queue
, MPEG_PRERECORDING_TICK
, 0);
830 /* Signal to save the data if we are running out of buffer
832 if (audiobuflen
- get_unsaved_space() < MPEG_RECORDING_LOW_WATER
833 && saving_status
== NOT_SAVING
)
835 saving_status
= BUFFER_FULL
;
836 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
841 #endif /* CONFIG_CODEC == MAS3587F */
843 void playback_tick(void)
845 struct trackdata
*ptd
= get_trackdata(0);
848 ptd
->id3
.elapsed
+= (current_tick
- last_dma_tick
) * 1000 / HZ
;
849 last_dma_tick
= current_tick
;
850 audio_dispatch_event(AUDIO_EVENT_POS_REPORT
,
851 (unsigned long)ptd
->id3
.elapsed
);
855 static void reset_mp3_buffer(void)
859 audiobuf_swapwrite
= 0;
860 lowest_watermark_level
= audiobuflen
;
863 /* DMA transfer end interrupt callback */
864 static void transfer_end(unsigned char** ppbuf
, size_t* psize
)
866 if(playing
&& !paused
)
868 int unplayed_space_left
;
869 int space_until_end_of_buffer
;
870 int track_offset
= 1;
871 struct trackdata
*track
;
873 audiobuf_read
+= last_dma_chunk_size
;
874 if(audiobuf_read
>= audiobuflen
)
877 /* First, check if we are on a track boundary */
878 if (num_tracks_in_memory() > 1)
880 if (audiobuf_read
== get_trackdata(track_offset
)->mempos
)
882 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
884 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
890 unplayed_space_left
= get_unplayed_space();
892 space_until_end_of_buffer
= audiobuflen
- audiobuf_read
;
894 if(!filling
&& unplayed_space_left
< low_watermark
)
897 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
900 if(unplayed_space_left
)
902 last_dma_chunk_size
= MIN(0x2000, unplayed_space_left
);
903 last_dma_chunk_size
= MIN(last_dma_chunk_size
,
904 space_until_end_of_buffer
);
906 /* several tracks loaded? */
907 track
= get_trackdata(track_offset
);
910 /* will we move across the track boundary? */
911 if (( audiobuf_read
< track
->mempos
) &&
912 ((audiobuf_read
+last_dma_chunk_size
) >
915 /* Make sure that we end exactly on the boundary */
916 last_dma_chunk_size
= track
->mempos
- audiobuf_read
;
920 *psize
= last_dma_chunk_size
& 0xffff;
921 *ppbuf
= mpeg_audiobuf
+ audiobuf_read
;
922 track
= get_trackdata(0);
924 track
->id3
.offset
+= last_dma_chunk_size
;
926 /* Update the watermark debug level */
927 if(unplayed_space_left
< lowest_watermark_level
)
928 lowest_watermark_level
= unplayed_space_left
;
932 /* Check if the end of data is because of a hard disk error.
933 If there is an open file handle, we are still playing music.
934 If not, the last file has been loaded, and the file handle is
938 /* Update the watermark debug level */
939 if(unplayed_space_left
< lowest_watermark_level
)
940 lowest_watermark_level
= unplayed_space_left
;
942 DEBUGF("DMA underrun.\n");
947 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
949 DEBUGF("No more MP3 data. Stopping.\n");
950 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
954 *psize
= 0; /* no more transfer */
959 static struct trackdata
*add_track_to_tag_list(const char *filename
)
961 struct trackdata
*track
;
962 bool send_nid3_event
;
964 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES
)
966 DEBUGF("Tag memory is full\n");
970 track
= &trackdata
[track_write_idx
];
972 /* grab id3 tag of new file and
973 remember where in memory it starts */
974 if(mp3info(&track
->id3
, filename
))
979 track
->mempos
= audiobuf_write
;
980 track
->id3
.elapsed
= 0;
981 #ifdef HAVE_LCD_BITMAP
982 if (track
->id3
.title
)
983 lcd_getstringsize(track
->id3
.title
, NULL
, NULL
);
984 if (track
->id3
.artist
)
985 lcd_getstringsize(track
->id3
.artist
, NULL
, NULL
);
986 if (track
->id3
.album
)
987 lcd_getstringsize(track
->id3
.album
, NULL
, NULL
);
990 /* if this track is the next track then let the UI know it can get it */
991 send_nid3_event
= (track_write_idx
== track_read_idx
+ 1);
992 track_write_idx
= (track_write_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
994 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE
, NULL
);
999 static int new_file(int steps
)
1001 int max_steps
= playlist_amount();
1004 struct trackdata
*track
;
1005 char name_buf
[MAX_PATH
+1];
1006 const char *trackname
;
1008 /* Find out how many steps to advance. The load_ahead_index field tells
1009 us how many playlist entries it had to skip to get to a valid one.
1010 We add those together to find out where to start. */
1011 if(steps
> 0 && num_tracks_in_memory() > 1)
1013 /* Begin with the song after the currently playing one */
1015 while((track
= get_trackdata(i
++)))
1017 start
+= track
->load_ahead_index
;
1022 trackname
= playlist_peek(start
+ steps
, name_buf
, sizeof(name_buf
));
1026 DEBUGF("Loading %s\n", trackname
);
1028 mpeg_file
= open(trackname
, O_RDONLY
);
1030 DEBUGF("Couldn't open file: %s\n",trackname
);
1038 struct trackdata
*track
= add_track_to_tag_list(trackname
);
1052 /* skip past id3v2 tag */
1054 track
->id3
.first_frame_offset
,
1056 track
->id3
.index
= steps
;
1057 track
->load_ahead_index
= steps
;
1058 track
->id3
.offset
= 0;
1061 /* Average bitrate * 1.5 */
1062 recalculate_watermark(
1063 (track
->id3
.bitrate
* 3) / 2);
1065 recalculate_watermark(
1066 track
->id3
.bitrate
);
1071 /* Bail out if no file could be opened */
1072 if(abs(steps
) > max_steps
)
1074 } while ( mpeg_file
< 0 );
1079 static void stop_playing(void)
1081 struct trackdata
*track
;
1083 /* Stop the current stream */
1088 track
= get_trackdata(0);
1090 prev_track_elapsed
= track
->id3
.elapsed
;
1096 generate_unbuffer_events();
1100 static void end_current_track(void) {
1101 struct trackdata
*track
;
1103 play_pending
= false;
1105 mp3_play_pause(false);
1107 track
= get_trackdata(0);
1109 prev_track_elapsed
= track
->id3
.elapsed
;
1113 generate_unbuffer_events();
1119 /* Is this a really the end of playback or is a new playlist starting */
1120 static void check_playlist_end(int direction
)
1122 /* Use the largest possible step size to account for skipped tracks */
1123 int steps
= playlist_amount();
1128 if (playlist_next(steps
) < 0)
1132 static void update_playlist(void)
1134 if (num_tracks_in_memory() > 0)
1136 struct trackdata
*track
= get_trackdata(0);
1137 track
->id3
.index
= playlist_next(track
->id3
.index
);
1141 /* End of playlist? */
1142 check_playlist_end(1);
1145 playlist_update_resume_info(audio_current_track());
1148 static void track_change(void)
1150 DEBUGF("Track change\n");
1152 struct trackdata
*track
= get_trackdata(0);
1153 prev_track_elapsed
= track
->id3
.elapsed
;
1155 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1158 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1160 if (num_tracks_in_memory() > 0)
1162 remove_current_tag();
1165 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1168 current_track_counter
++;
1171 unsigned long audio_prev_elapsed(void)
1173 return prev_track_elapsed
;
1177 void hexdump(const unsigned char *buf
, int len
)
1181 for(i
= 0;i
< len
;i
++)
1183 if(i
&& (i
& 15) == 0)
1187 DEBUGF("%02x ", buf
[i
]);
1193 static void start_playback_if_ready(void)
1197 playable_space
= audiobuf_swapwrite
- audiobuf_read
;
1198 if(playable_space
< 0)
1199 playable_space
+= audiobuflen
;
1201 /* See if we have started playing yet. If not, do it. */
1202 if(play_pending
|| dma_underrun
)
1204 /* If the filling has stopped, and we still haven't reached
1205 the watermark, the file must be smaller than the
1206 watermark. We must still play it. */
1207 if((playable_space
>= MPEG_PLAY_PENDING_THRESHOLD
) ||
1208 !filling
|| dma_underrun
)
1211 if (play_pending
) /* don't do this when recovering from DMA underrun */
1213 generate_postbuffer_events(); /* signal first track as buffered */
1214 if (play_pending_track_change
)
1216 play_pending_track_change
= false;
1217 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1219 play_pending
= false;
1223 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1224 mp3_play_data(mpeg_audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1225 dma_underrun
= false;
1229 last_dma_tick
= current_tick
;
1230 mp3_play_pause(true);
1233 /* Tell ourselves that we need more data */
1234 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1239 static bool swap_one_chunk(void)
1241 int free_space_left
;
1244 free_space_left
= get_unswapped_space();
1246 if(free_space_left
== 0 && !play_pending
)
1249 /* Swap in larger chunks when the user is waiting for the playback
1250 to start, or when there is dangerously little playable data left */
1252 amount_to_swap
= MIN(MPEG_PLAY_PENDING_SWAPSIZE
, free_space_left
);
1255 if(get_playable_space() < low_watermark
)
1256 amount_to_swap
= MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE
,
1259 amount_to_swap
= MIN(MPEG_SWAP_CHUNKSIZE
, free_space_left
);
1262 if(audiobuf_write
< audiobuf_swapwrite
)
1263 amount_to_swap
= MIN(audiobuflen
- audiobuf_swapwrite
,
1266 amount_to_swap
= MIN(audiobuf_write
- audiobuf_swapwrite
,
1269 bitswap(mpeg_audiobuf
+ audiobuf_swapwrite
, amount_to_swap
);
1271 audiobuf_swapwrite
+= amount_to_swap
;
1272 if(audiobuf_swapwrite
>= audiobuflen
)
1274 audiobuf_swapwrite
= 0;
1280 static void mpeg_thread(void)
1282 static int pause_tick
= 0;
1283 static unsigned int pause_track
= 0;
1284 struct queue_event ev
;
1286 int free_space_left
;
1287 int unplayed_space_left
;
1291 #if CONFIG_CODEC == MAS3587F
1293 int save_endpos
= 0;
1297 #endif /* CONFIG_CODEC == MAS3587F */
1300 play_pending
= false;
1306 #if CONFIG_CODEC == MAS3587F
1307 if(mpeg_mode
== MPEG_DECODER
)
1309 #endif /* CONFIG_CODEC == MAS3587F */
1312 /* Swap if necessary, and don't block on the queue_wait() */
1313 if(swap_one_chunk())
1315 queue_wait_w_tmo(&mpeg_queue
, &ev
, 0);
1319 /* periodically update resume info */
1320 queue_wait_w_tmo(&mpeg_queue
, &ev
, HZ
/2);
1324 DEBUGF("S R:%x W:%x SW:%x\n",
1325 audiobuf_read
, audiobuf_write
, audiobuf_swapwrite
);
1326 queue_wait(&mpeg_queue
, &ev
);
1329 start_playback_if_ready();
1334 DEBUGF("MPEG_PLAY\n");
1337 /* Silence the A/D input, it may be on because the radio
1339 mas_codec_writereg(6, 0x0000);
1340 #endif /* CONFIG_TUNER */
1342 /* Stop the current stream */
1344 end_current_track();
1346 if ( new_file(0) == -1 )
1353 start_offset
= (int)ev
.data
;
1355 /* mid-song resume? */
1357 struct mp3entry
* id3
= &get_trackdata(0)->id3
;
1358 lseek(mpeg_file
, start_offset
, SEEK_SET
);
1359 id3
->offset
= start_offset
;
1363 /* skip past id3v2 tag */
1365 get_trackdata(0)->id3
.first_frame_offset
,
1370 /* Make it read more data */
1372 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1374 /* Tell the file loading code that we want to start playing
1375 as soon as we have some data */
1376 play_pending
= true;
1377 play_pending_track_change
= true;
1380 current_track_counter
++;
1388 DEBUGF("MPEG_PAUSE\n");
1389 /* Stop the current stream */
1391 playlist_update_resume_info(audio_current_track());
1394 pause_tick
= current_tick
;
1395 pause_track
= current_track_counter
;
1396 mp3_play_pause(false);
1400 DEBUGF("MPEG_RESUME\n");
1401 /* Continue the current stream */
1406 if ( current_track_counter
== pause_track
)
1407 last_dma_tick
+= current_tick
- pause_tick
;
1409 last_dma_tick
= current_tick
;
1411 mp3_play_pause(true);
1416 DEBUGF("MPEG_NEXT\n");
1417 /* is next track in ram? */
1418 if ( num_tracks_in_memory() > 1 ) {
1419 int unplayed_space_left
, unswapped_space_left
;
1421 /* stop the current stream */
1422 play_pending
= false;
1424 mp3_play_pause(false);
1427 audiobuf_read
= get_trackdata(0)->mempos
;
1428 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1429 mp3_play_data(mpeg_audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1430 dma_underrun
= false;
1431 last_dma_tick
= current_tick
;
1433 unplayed_space_left
= get_unplayed_space();
1434 unswapped_space_left
= get_unswapped_space();
1436 /* should we start reading more data? */
1437 if(!filling
&& (unplayed_space_left
< low_watermark
)) {
1439 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1440 play_pending
= true;
1441 } else if(unswapped_space_left
&&
1442 unswapped_space_left
> unplayed_space_left
) {
1443 /* Stop swapping the data from the previous file */
1444 audiobuf_swapwrite
= audiobuf_read
;
1445 play_pending
= true;
1449 mp3_play_pause(true);
1453 if (!playlist_check(1))
1456 /* stop the current stream */
1457 end_current_track();
1459 if (new_file(1) < 0) {
1460 DEBUGF("No more files to play\n");
1463 check_playlist_end(1);
1464 current_track_counter
++;
1466 /* Make it read more data */
1468 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1470 /* Tell the file loading code that we want
1471 to start playing as soon as we have some data */
1472 play_pending
= true;
1473 play_pending_track_change
= true;
1476 current_track_counter
++;
1482 DEBUGF("MPEG_PREV\n");
1484 if (!playlist_check(-1))
1487 /* stop the current stream */
1488 end_current_track();
1490 /* Open the next file */
1491 if (new_file(-1) < 0) {
1492 DEBUGF("No more files to play\n");
1495 check_playlist_end(-1);
1496 current_track_counter
++;
1498 /* Make it read more data */
1500 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1502 /* Tell the file loading code that we want to
1503 start playing as soon as we have some data */
1504 play_pending
= true;
1505 play_pending_track_change
= true;
1508 current_track_counter
++;
1513 case MPEG_FF_REWIND
: {
1514 struct mp3entry
*id3
= audio_current_track();
1515 unsigned int oldtime
= id3
->elapsed
;
1516 unsigned int newtime
= (unsigned int)ev
.data
;
1517 int curpos
, newpos
, diffpos
;
1518 DEBUGF("MPEG_FF_REWIND\n");
1520 id3
->elapsed
= newtime
;
1522 newpos
= audio_get_file_pos();
1525 id3
->elapsed
= oldtime
;
1530 curpos
= lseek(mpeg_file
, 0, SEEK_CUR
);
1532 curpos
= id3
->filesize
;
1534 if (num_tracks_in_memory() > 1)
1536 /* We have started loading other tracks that need to be
1538 struct trackdata
*track
;
1541 while((track
= get_trackdata(i
++)))
1543 curpos
+= track
->id3
.filesize
;
1547 diffpos
= curpos
- newpos
;
1549 if(!filling
&& diffpos
>= 0 && diffpos
< audiobuflen
)
1551 int unplayed_space_left
, unswapped_space_left
;
1553 /* We are changing to a position that's already in
1554 memory, so we just move the DMA read pointer. */
1555 audiobuf_read
= audiobuf_write
- diffpos
;
1556 if (audiobuf_read
< 0)
1558 audiobuf_read
+= audiobuflen
;
1561 unplayed_space_left
= get_unplayed_space();
1562 unswapped_space_left
= get_unswapped_space();
1564 /* If unswapped_space_left is larger than
1565 unplayed_space_left, it means that the swapwrite pointer
1566 hasn't yet advanced up to the new location of the read
1567 pointer. We just move it, there is no need to swap
1568 data that won't be played anyway. */
1570 if (unswapped_space_left
> unplayed_space_left
)
1572 DEBUGF("Moved swapwrite\n");
1573 audiobuf_swapwrite
= audiobuf_read
;
1574 play_pending
= true;
1577 if (mpeg_file
>=0 && unplayed_space_left
< low_watermark
)
1579 /* We need to load more data before starting */
1581 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1582 play_pending
= true;
1586 /* resume will start at new position */
1587 last_dma_chunk_size
=
1588 MIN(0x2000, get_unplayed_space_current_song());
1589 mp3_play_data(mpeg_audiobuf
+ audiobuf_read
,
1590 last_dma_chunk_size
, transfer_end
);
1591 dma_underrun
= false;
1596 /* Move to the new position in the file and start
1600 if (num_tracks_in_memory() > 1)
1602 /* We have to reload the current track */
1604 remove_all_non_current_tags();
1605 generate_unbuffer_events();
1611 mpeg_file
= open(id3
->path
, O_RDONLY
);
1614 id3
->elapsed
= oldtime
;
1619 if(-1 == lseek(mpeg_file
, newpos
, SEEK_SET
))
1621 id3
->elapsed
= oldtime
;
1626 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1628 /* Tell the file loading code that we want to start playing
1629 as soon as we have some data */
1630 play_pending
= true;
1633 id3
->offset
= newpos
;
1638 case MPEG_FLUSH_RELOAD
: {
1639 int numtracks
= num_tracks_in_memory();
1640 bool reload_track
= false;
1644 /* Reset the buffer */
1645 audiobuf_write
= get_trackdata(1)->mempos
;
1647 /* Reset swapwrite unless we're still swapping current
1649 if (get_unplayed_space() <= get_playable_space())
1650 audiobuf_swapwrite
= audiobuf_write
;
1653 remove_all_non_current_tags();
1654 generate_unbuffer_events();
1656 reload_track
= true;
1658 else if (numtracks
== 1 && mpeg_file
< 0)
1660 reload_track
= true;
1663 if(reload_track
&& new_file(1) >= 0)
1665 /* Tell ourselves that we want more data */
1667 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1673 case MPEG_NEED_DATA
:
1674 free_space_left
= audiobuf_read
- audiobuf_write
;
1676 /* We interpret 0 as "empty buffer" */
1677 if(free_space_left
<= 0)
1678 free_space_left
+= audiobuflen
;
1680 unplayed_space_left
= audiobuflen
- free_space_left
;
1682 /* Make sure that we don't fill the entire buffer */
1683 free_space_left
-= MPEG_HIGH_WATER
;
1685 if (ev
.data
== GENERATE_UNBUFFER_EVENTS
)
1686 generate_unbuffer_events();
1688 /* do we have any more buffer space to fill? */
1689 if(free_space_left
<= 0)
1693 generate_postbuffer_events();
1698 /* Read small chunks while we are below the low water mark */
1699 if(unplayed_space_left
< low_watermark
)
1700 amount_to_read
= MIN(MPEG_LOW_WATER_CHUNKSIZE
,
1703 amount_to_read
= free_space_left
;
1705 /* Don't read more than until the end of the buffer */
1706 amount_to_read
= MIN(audiobuflen
- audiobuf_write
,
1708 #if (CONFIG_STORAGE & STORAGE_MMC)
1709 /* MMC is slow, so don't read too large chunks */
1710 amount_to_read
= MIN(0x40000, amount_to_read
);
1711 #elif MEMORYSIZE == 8
1712 amount_to_read
= MIN(0x100000, amount_to_read
);
1715 /* Read as much mpeg data as we can fit in the buffer */
1720 len
= read(mpeg_file
, mpeg_audiobuf
+ audiobuf_write
,
1725 DEBUGF("time: %d\n", t2
- t1
);
1726 DEBUGF("R: %x\n", len
);
1728 /* Now make sure that we don't feed the MAS with ID3V1
1730 if (len
< amount_to_read
)
1733 static const unsigned char tag
[] = "TAG";
1735 int tagptr
= audiobuf_write
+ len
- 128;
1737 /* Really rare case: entire potential tag wasn't
1738 read in this call AND audiobuf_write < 128 */
1740 tagptr
+= audiobuflen
;
1742 for(i
= 0;i
< 3;i
++)
1744 if(tagptr
>= audiobuflen
)
1745 tagptr
-= audiobuflen
;
1747 if(mpeg_audiobuf
[tagptr
] != tag
[i
])
1758 /* Skip id3v1 tag */
1759 DEBUGF("Skipping ID3v1 tag\n");
1762 /* In the very rare case when the entire tag
1763 wasn't read in this read() len will be < 0.
1764 Take care of this when changing the write
1769 audiobuf_write
+= len
;
1771 if (audiobuf_write
< 0)
1772 audiobuf_write
+= audiobuflen
;
1774 if(audiobuf_write
>= audiobuflen
)
1780 /* Tell ourselves that we want more data */
1781 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1787 DEBUGF("MPEG read error\n");
1795 /* No more data to play */
1796 DEBUGF("No more files to play\n");
1801 /* Tell ourselves that we want more data */
1802 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1808 case MPEG_TRACK_CHANGE
:
1813 case SYS_USB_CONNECTED
:
1818 /* Tell the USB thread that we are safe */
1819 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1820 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1822 /* Wait until the USB cable is extracted again */
1823 usb_wait_for_disconnect(&mpeg_queue
);
1825 #endif /* !USB_NONE */
1827 #if CONFIG_CODEC == MAS3587F
1828 case MPEG_INIT_RECORDING
:
1830 init_recording_done
= true;
1832 #endif /* CONFIG_CODEC == MAS3587F */
1836 playlist_update_resume_info(audio_current_track());
1839 #if CONFIG_CODEC == MAS3587F
1843 queue_wait(&mpeg_queue
, &ev
);
1847 if (is_prerecording
)
1851 /* Go back prerecord_count seconds in the buffer */
1852 startpos
= prerecord_index
- prerecord_count
;
1854 startpos
+= prerecording_max_seconds
;
1856 /* Read the position data from the prerecord buffer */
1857 frame_count_start
= prerecord_buffer
[startpos
].framecount
;
1858 startpos
= prerecord_buffer
[startpos
].mempos
;
1860 DEBUGF("Start looking at address %x (%x)\n",
1861 mpeg_audiobuf
+startpos
, startpos
);
1863 saved_header
= mpeg_get_last_header();
1865 mem_find_next_frame(startpos
, &offset
, 1800,
1866 saved_header
, mpeg_audiobuf
,
1869 audiobuf_read
= startpos
+ offset
;
1870 if(audiobuf_read
>= audiobuflen
)
1871 audiobuf_read
-= audiobuflen
;
1873 DEBUGF("New audiobuf_read address: %x (%x)\n",
1874 mpeg_audiobuf
+audiobuf_read
, audiobuf_read
);
1876 level
= disable_irq_save();
1877 num_rec_bytes
= get_unsaved_space();
1882 frame_count_start
= 0;
1884 audiobuf_read
= MPEG_RESERVED_HEADER_SPACE
;
1885 audiobuf_write
= MPEG_RESERVED_HEADER_SPACE
;
1889 DEBUGF("Recording...\n");
1892 /* Wait until at least one frame is encoded and get the
1893 frame header, for later use by the Xing header
1896 saved_header
= mpeg_get_last_header();
1898 /* delayed until buffer is saved, don't open yet */
1899 strcpy(delayed_filename
, recording_filename
);
1905 DEBUGF("MPEG_STOP\n");
1909 /* Save the remaining data in the buffer */
1910 save_endpos
= audiobuf_write
;
1911 saving_status
= STOP_RECORDING
;
1912 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1915 case MPEG_STOP_DONE
:
1916 DEBUGF("MPEG_STOP_DONE\n");
1926 for(i
= 0;i
< 512;i
++)
1928 DEBUGF("%d - %d us (%d bytes)\n",
1930 (timing_info
[i
*2+1] & 0xffff) *
1932 timing_info
[i
*2+1] >> 16);
1939 start_prerecording();
1941 mpeg_stop_done
= true;
1945 /* Bail out when a more important save is happening */
1946 if (saving_status
> NEW_FILE
)
1949 /* Make sure we have at least one complete frame
1950 in the buffer. If we haven't recorded a single
1951 frame within 200ms, the MAS is probably not recording
1952 anything, and we bail out. */
1953 amount_to_save
= get_unsaved_space();
1954 if (amount_to_save
< 1800)
1957 amount_to_save
= get_unsaved_space();
1960 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1961 &frame_count_end
, 1);
1963 last_rec_time
= current_tick
- record_start_time
;
1964 record_start_time
= current_tick
;
1966 pause_start_time
= record_start_time
;
1968 /* capture all values at one point */
1969 level
= disable_irq_save();
1970 save_endpos
= audiobuf_write
;
1971 last_rec_bytes
= num_rec_bytes
;
1975 if (amount_to_save
>= 1800)
1977 /* Now find a frame boundary to split at */
1978 save_endpos
-= 1800;
1979 if (save_endpos
< 0)
1980 save_endpos
+= audiobuflen
;
1982 rc
= mem_find_next_frame(save_endpos
, &offset
, 1800,
1983 saved_header
, mpeg_audiobuf
,
1985 if (!rc
) /* No header found, save whole buffer */
1988 save_endpos
+= offset
;
1989 if (save_endpos
>= audiobuflen
)
1990 save_endpos
-= audiobuflen
;
1992 last_rec_bytes
+= offset
- 1800;
1993 level
= disable_irq_save();
1994 num_rec_bytes
+= 1800 - offset
;
1998 saving_status
= NEW_FILE
;
1999 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
2002 case MPEG_SAVE_DATA
:
2003 if (saving_status
== BUFFER_FULL
)
2004 save_endpos
= audiobuf_write
;
2006 if (mpeg_file
< 0) /* delayed file open */
2008 mpeg_file
= open(delayed_filename
, O_WRONLY
|O_CREAT
, 0666);
2011 panicf("recfile: %d", mpeg_file
);
2014 amount_to_save
= save_endpos
- audiobuf_read
;
2015 if (amount_to_save
< 0)
2016 amount_to_save
+= audiobuflen
;
2018 amount_to_save
= MIN(amount_to_save
,
2019 audiobuflen
- audiobuf_read
);
2020 #if (CONFIG_STORAGE & STORAGE_MMC)
2021 /* MMC is slow, so don't save too large chunks at once */
2022 amount_to_save
= MIN(0x40000, amount_to_save
);
2023 #elif MEMORYSIZE == 8
2024 amount_to_save
= MIN(0x100000, amount_to_save
);
2026 rc
= write(mpeg_file
, mpeg_audiobuf
+ audiobuf_read
,
2030 if (errno
== ENOSPC
)
2032 mpeg_errno
= AUDIOERR_DISK_FULL
;
2034 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
2035 /* will close the file */
2039 panicf("rec wrt: %d", rc
);
2042 audiobuf_read
+= amount_to_save
;
2043 if (audiobuf_read
>= audiobuflen
)
2046 if (audiobuf_read
== save_endpos
) /* all saved */
2048 switch (saving_status
)
2051 rc
= fsync(mpeg_file
);
2053 panicf("rec fls: %d", rc
);
2058 /* Close the current file */
2059 rc
= close(mpeg_file
);
2061 panicf("rec cls: %d", rc
);
2066 /* copy new filename */
2067 strcpy(delayed_filename
, recording_filename
);
2069 frame_count_start
= frame_count_end
;
2072 case STOP_RECORDING
:
2073 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
2074 /* will close the file */
2080 saving_status
= NOT_SAVING
;
2082 else /* tell ourselves to save the next chunk */
2083 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
2087 case MPEG_PRERECORDING_TICK
:
2088 if(!is_prerecording
)
2091 /* Store the write pointer every second */
2092 prerecord_buffer
[prerecord_index
].mempos
= audiobuf_write
;
2093 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
2094 &prerecord_buffer
[prerecord_index
].framecount
, 1);
2096 /* Wrap if necessary */
2097 if(++prerecord_index
== prerecording_max_seconds
)
2098 prerecord_index
= 0;
2100 /* Update the number of seconds recorded */
2101 if(prerecord_count
< prerecording_max_seconds
)
2105 case MPEG_INIT_PLAYBACK
:
2106 /* Stop the prerecording */
2110 init_playback_done
= true;
2113 case MPEG_PAUSE_RECORDING
:
2117 case MPEG_RESUME_RECORDING
:
2121 case SYS_USB_CONNECTED
:
2122 /* We can safely go to USB mode if no recording
2124 if((!is_recording
|| is_prerecording
) && mpeg_stop_done
)
2126 /* Even if we aren't recording, we still call this
2127 function, to put the MAS in monitoring mode,
2131 /* Tell the USB thread that we are safe */
2132 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2133 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
2135 /* Wait until the USB cable is extracted again */
2136 usb_wait_for_disconnect(&mpeg_queue
);
2141 #endif /* CONFIG_CODEC == MAS3587F */
2144 #endif /* !SIMULATOR */
2146 struct mp3entry
* audio_current_track(void)
2149 struct mp3entry
*id3
= &taginfo
;
2150 #else /* !SIMULATOR */
2151 if(num_tracks_in_memory())
2153 struct mp3entry
*id3
= &get_trackdata(0)->id3
;
2155 if (!checked_for_cuesheet
&& curr_cuesheet
&& id3
->cuesheet
== NULL
)
2157 checked_for_cuesheet
= true; /* only check once per track */
2158 char cuepath
[MAX_PATH
];
2160 if (look_for_cuesheet_file(id3
->path
, cuepath
) &&
2161 parse_cuesheet(cuepath
, curr_cuesheet
))
2163 id3
->cuesheet
= curr_cuesheet
;
2171 #endif /* !SIMULATOR */
2174 struct mp3entry
* audio_next_track(void)
2178 #else /* !SIMULATOR */
2179 if(num_tracks_in_memory() > 1)
2180 return &get_trackdata(1)->id3
;
2183 #endif /* !SIMULATOR */
2186 #if CONFIG_CODEC == MAS3587F
2188 void audio_init_playback(void)
2190 init_playback_done
= false;
2191 queue_post(&mpeg_queue
, MPEG_INIT_PLAYBACK
, 0);
2193 while(!init_playback_done
)
2198 /****************************************************************************
2199 * Recording functions
2200 ***************************************************************************/
2201 void audio_init_recording(void)
2203 init_recording_done
= false;
2204 queue_post(&mpeg_queue
, MPEG_INIT_RECORDING
, 0);
2206 while(!init_recording_done
)
2210 static void init_recording(void)
2222 /* Init the recording variables */
2223 is_recording
= false;
2224 is_prerecording
= false;
2226 mpeg_stop_done
= true;
2230 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2231 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
2233 panicf("mas_ctrl_w: %d", rc
);
2235 /* Stop the current application */
2237 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2240 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2243 /* Perform black magic as described by the data sheet */
2244 if((mas_version_code
& 0x0fff) == 0x0102)
2246 DEBUGF("Performing MAS black magic for B2 version\n");
2247 mas_writereg(0xa3, 0x98);
2248 mas_writereg(0x94, 0xfffff);
2250 mas_writemem(MAS_BANK_D1
, 0, &val
, 1);
2251 mas_writereg(0xa3, 0x90);
2254 /* Enable A/D Converters */
2255 shadow_codec_reg0
= 0xcccd;
2256 mas_codec_writereg(0x0, shadow_codec_reg0
);
2258 /* Copy left channel to right (mono mode) */
2259 mas_codec_writereg(8, 0x8000);
2261 /* ADC scale 0%, DSP scale 100%
2262 We use the DSP output for monitoring, because it works with all
2263 sources including S/PDIF */
2264 mas_codec_writereg(6, 0x0000);
2265 mas_codec_writereg(7, 0x4000);
2268 shadow_soft_mute
= 0;
2269 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2271 #ifdef HAVE_SPDIF_OUT
2272 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2274 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2276 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
2278 /* Set Demand mode, monitoring OFF and validate all settings */
2279 shadow_io_control_main
= 0x125;
2280 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2282 /* Start the encoder application */
2284 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2287 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2288 } while(!(val
& 0x40));
2290 /* We have started the recording application with monitoring OFF.
2291 This is because we want to record at least one frame to fill the DMA
2292 buffer, because the silly MAS will not negate EOD until at least one
2293 DMA transfer has taken place.
2294 Now let's wait for some data to be encoded. */
2297 /* Now set it to Monitoring mode as default, saves power */
2298 shadow_io_control_main
= 0x525;
2299 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2301 /* Wait until the DSP has accepted the settings */
2304 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2308 mpeg_mode
= MPEG_ENCODER
;
2310 DEBUGF("MAS Recording application started\n");
2312 /* At this point, all settings are the reset MAS defaults, next thing is to
2313 call mpeg_set_recording_options(). */
2316 void audio_record(const char *filename
)
2320 strlcpy(recording_filename
, filename
, MAX_PATH
);
2322 queue_post(&mpeg_queue
, MPEG_RECORD
, 0);
2325 void audio_pause_recording(void)
2327 queue_post(&mpeg_queue
, MPEG_PAUSE_RECORDING
, 0);
2330 void audio_resume_recording(void)
2332 queue_post(&mpeg_queue
, MPEG_RESUME_RECORDING
, 0);
2335 static void prepend_header(void)
2340 /* Make room for header */
2341 audiobuf_read
-= MPEG_RESERVED_HEADER_SPACE
;
2342 if(audiobuf_read
< 0)
2344 /* Clear the bottom half */
2345 memset(mpeg_audiobuf
, 0, audiobuf_read
+ MPEG_RESERVED_HEADER_SPACE
);
2347 /* And the top half */
2348 audiobuf_read
+= audiobuflen
;
2349 memset(mpeg_audiobuf
+ audiobuf_read
, 0, audiobuflen
- audiobuf_read
);
2353 memset(mpeg_audiobuf
+ audiobuf_read
, 0, MPEG_RESERVED_HEADER_SPACE
);
2355 /* Copy the empty ID3 header */
2356 startpos
= audiobuf_read
;
2357 for(i
= 0; i
< sizeof(empty_id3_header
); i
++)
2359 mpeg_audiobuf
[startpos
++] = empty_id3_header
[i
];
2360 if(startpos
== audiobuflen
)
2365 static void update_header(void)
2368 unsigned long frames
;
2370 if (last_rec_bytes
> 0)
2372 /* Create the Xing header */
2373 fd
= open(delayed_filename
, O_RDWR
);
2375 panicf("rec upd: %d (%s)", fd
, recording_filename
);
2377 frames
= frame_count_end
- frame_count_start
;
2378 /* If the number of recorded frames has reached 0x7ffff,
2379 we can no longer trust it */
2380 if (frame_count_end
== 0x7ffff)
2383 /* saved_header is saved right before stopping the MAS */
2384 framelen
= create_xing_header(fd
, 0, last_rec_bytes
, xing_buffer
,
2385 frames
, last_rec_time
* (1000/HZ
),
2386 saved_header
, NULL
, false,
2387 mpeg_audiobuf
, audiobuflen
);
2389 lseek(fd
, MPEG_RESERVED_HEADER_SPACE
- framelen
, SEEK_SET
);
2390 write(fd
, xing_buffer
, framelen
);
2395 static void start_prerecording(void)
2399 DEBUGF("Starting prerecording\n");
2401 prerecord_index
= 0;
2402 prerecord_count
= 0;
2403 prerecord_timeout
= current_tick
+ HZ
;
2404 memset(prerecord_buffer
, 0, sizeof(prerecord_buffer
));
2407 is_prerecording
= true;
2409 /* Stop monitoring and start the encoder */
2410 shadow_io_control_main
&= ~(1 << 10);
2411 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2412 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2414 /* Wait until the DSP has accepted the settings */
2417 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2420 is_recording
= true;
2421 saving_status
= NOT_SAVING
;
2423 demand_irq_enable(true);
2426 static void start_recording(void)
2432 /* This will make the IRQ handler start recording
2433 for real, i.e send MPEG_SAVE_DATA messages when
2434 the buffer is full */
2435 is_prerecording
= false;
2439 /* If prerecording is off, we need to stop the monitoring
2440 and start the encoder */
2441 shadow_io_control_main
&= ~(1 << 10);
2442 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2443 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2445 /* Wait until the DSP has accepted the settings */
2448 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2452 is_recording
= true;
2453 saving_status
= NOT_SAVING
;
2456 /* Store the current time */
2458 record_start_time
= current_tick
- prerecord_count
* HZ
;
2460 record_start_time
= current_tick
;
2462 pause_start_time
= 0;
2464 demand_irq_enable(true);
2467 static void pause_recording(void)
2469 pause_start_time
= current_tick
;
2471 /* Set the pause bit */
2472 shadow_soft_mute
|= 2;
2473 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2478 static void resume_recording(void)
2482 /* Clear the pause bit */
2483 shadow_soft_mute
&= ~2;
2484 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2486 /* Compensate for the time we have been paused */
2487 if(pause_start_time
)
2490 current_tick
- (pause_start_time
- record_start_time
);
2491 pause_start_time
= 0;
2495 static void stop_recording(void)
2499 /* Let it finish the last frame */
2504 demand_irq_enable(false);
2506 is_recording
= false;
2507 is_prerecording
= false;
2509 last_rec_bytes
= num_rec_bytes
;
2510 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
, &frame_count_end
, 1);
2511 last_rec_time
= current_tick
- record_start_time
;
2513 /* Start monitoring */
2514 shadow_io_control_main
|= (1 << 10);
2515 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2516 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2518 /* Wait until the DSP has accepted the settings */
2521 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2527 void audio_set_recording_options(struct audio_recording_options
*options
)
2531 is_mpeg1
= (options
->rec_frequency
< 3);
2533 rec_version_index
= is_mpeg1
?3:2;
2534 rec_frequency_index
= options
->rec_frequency
% 3;
2536 shadow_encoder_control
= (options
->rec_quality
<< 17) |
2537 (rec_frequency_index
<< 10) |
2538 ((is_mpeg1
?1:0) << 9) |
2539 (((options
->rec_channels
* 2 + 1) & 3) << 6) |
2540 (1 << 5) /* MS-stereo */ |
2541 (1 << 2) /* Is an original */;
2542 mas_writemem(MAS_BANK_D0
, MAS_D0_ENCODER_CONTROL
, &shadow_encoder_control
,1);
2544 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control
);
2546 #if CONFIG_TUNER & S1A0903X01
2547 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2548 interference with the Samsung tuner. */
2549 if (rec_frequency_index
)
2550 mas_store_pllfreq(24576000);
2552 mas_store_pllfreq(22579000);
2555 shadow_soft_mute
= options
->rec_editable
?4:0;
2556 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
,1);
2558 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute
);
2560 shadow_io_control_main
= ((1 << 10) | /* Monitoring ON */
2561 ((options
->rec_source
< 2)?1:2) << 8) | /* Input select */
2562 (1 << 5) | /* SDO strobe invert */
2563 ((is_mpeg1
?0:1) << 3) |
2564 (1 << 2) | /* Inverted SIBC clock signal */
2566 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
,1);
2568 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2570 if(options
->rec_source
== AUDIO_SRC_MIC
)
2572 /* Copy left channel to right (mono mode) */
2573 mas_codec_writereg(8, 0x8000);
2577 /* Stereo input mode */
2578 mas_codec_writereg(8, 0);
2581 prerecording_max_seconds
= options
->rec_prerecord_time
;
2582 if(prerecording_max_seconds
)
2584 prerecording
= true;
2585 start_prerecording();
2589 prerecording
= false;
2590 is_prerecording
= false;
2591 is_recording
= false;
2595 /* If use_mic is true, the left gain is used */
2596 void audio_set_recording_gain(int left
, int right
, int type
)
2598 /* Enable both left and right A/D */
2599 shadow_codec_reg0
= (left
<< 12) |
2602 (type
==AUDIO_GAIN_MIC
?0x0008:0) | /* Connect left A/D to mic */
2604 mas_codec_writereg(0x0, shadow_codec_reg0
);
2607 /* try to make some kind of beep, also in recording mode */
2608 void audio_beep(int duration
)
2610 long starttick
= current_tick
;
2612 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2613 * While this is still audible even without an external signal,
2614 * it doesn't affect the (pre-)recording. */
2615 mas_codec_writereg(0, shadow_codec_reg0
^ 1);
2616 mas_codec_writereg(0, shadow_codec_reg0
);
2619 while (current_tick
- starttick
< duration
);
2622 void audio_new_file(const char *filename
)
2626 strlcpy(recording_filename
, filename
, MAX_PATH
);
2628 queue_post(&mpeg_queue
, MPEG_NEW_FILE
, 0);
2631 unsigned long audio_recorded_time(void)
2634 return prerecord_count
* HZ
;
2639 return pause_start_time
- record_start_time
;
2641 return current_tick
- record_start_time
;
2647 unsigned long audio_num_recorded_bytes(void)
2656 index
= prerecord_index
- prerecord_count
;
2658 index
+= prerecording_max_seconds
;
2660 num_bytes
= audiobuf_write
- prerecord_buffer
[index
].mempos
;
2662 num_bytes
+= audiobuflen
;
2667 return num_rec_bytes
;
2673 #else /* SIMULATOR */
2675 /* dummies coming up */
2677 void audio_init_playback(void)
2681 unsigned long audio_recorded_time(void)
2686 void audio_beep(int duration
)
2691 void audio_pause_recording(void)
2695 void audio_resume_recording(void)
2699 unsigned long audio_num_recorded_bytes(void)
2704 void audio_record(const char *filename
)
2709 void audio_new_file(const char *filename
)
2715 void audio_set_recording_gain(int left
, int right
, int type
)
2722 void audio_init_recording(void)
2726 void audio_set_recording_options(struct audio_recording_options
*options
)
2731 #endif /* SIMULATOR */
2732 #endif /* CONFIG_CODEC == MAS3587F */
2734 size_t audio_buffer_available(void)
2736 if (audiobuf_handle
> 0)
2738 return core_available();
2741 static void audio_reset_buffer_noalloc(void* buf
, size_t bufsize
)
2743 talk_buffer_steal(); /* will use the mp3 buffer */
2744 mpeg_audiobuf
= buf
;
2745 audiobuflen
= bufsize
;
2746 if (global_settings
.cuesheet
)
2747 { /* enable cuesheet support */
2748 curr_cuesheet
= (struct cuesheet
*)mpeg_audiobuf
;
2749 mpeg_audiobuf
= SKIPBYTES(mpeg_audiobuf
, sizeof(struct cuesheet
));
2750 audiobuflen
-= sizeof(struct cuesheet
);
2752 talkbuf_init(mpeg_audiobuf
);
2755 static void audio_reset_buffer(void)
2757 size_t bufsize
= audiobuflen
;
2759 /* alloc buffer if it's was never allocated or freed by audio_hard_stop() */
2760 if (!audiobuf_handle
)
2761 audiobuf_handle
= core_alloc_maximum("audiobuf", &bufsize
, &ops
);
2763 audio_reset_buffer_noalloc(core_get_data(audiobuf_handle
), bufsize
);
2766 void audio_play(long offset
)
2768 audio_reset_buffer();
2770 char name_buf
[MAX_PATH
+1];
2771 const char* trackname
;
2777 trackname
= playlist_peek(steps
, name_buf
, sizeof(name_buf
));
2780 if(mp3info(&taginfo
, trackname
)) {
2781 /* bad mp3, move on */
2782 if(++steps
> playlist_amount())
2786 #ifdef HAVE_MPEG_PLAY
2787 real_mpeg_play(trackname
);
2789 playlist_next(steps
);
2790 taginfo
.offset
= offset
;
2791 set_elapsed(&taginfo
);
2796 #else /* !SIMULATOR */
2798 queue_post(&mpeg_queue
, MPEG_PLAY
, offset
);
2799 #endif /* !SIMULATOR */
2804 void audio_stop(void)
2809 struct trackdata
*track
= get_trackdata(0);
2810 prev_track_elapsed
= track
->id3
.elapsed
;
2812 mpeg_stop_done
= false;
2813 queue_post(&mpeg_queue
, MPEG_STOP
, 0);
2814 while(!mpeg_stop_done
)
2816 #else /* SIMULATOR */
2820 #endif /* SIMULATOR */
2821 /* give voice our entire buffer */
2822 talkbuf_init(mpeg_audiobuf
);
2826 void audio_stop_recording(void)
2831 void audio_hard_stop(void)
2834 /* tell voice we obtain the buffer before freeing */
2835 talk_buffer_steal();
2836 if (audiobuf_handle
> 0)
2838 audiobuf_handle
= core_free(audiobuf_handle
);
2839 mpeg_audiobuf
= NULL
;
2843 void audio_pause(void)
2846 queue_post(&mpeg_queue
, MPEG_PAUSE
, 0);
2847 #else /* SIMULATOR */
2851 #endif /* SIMULATOR */
2854 void audio_resume(void)
2857 queue_post(&mpeg_queue
, MPEG_RESUME
, 0);
2858 #else /* SIMULATOR */
2862 #endif /* SIMULATOR */
2865 void audio_next(void)
2868 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2869 queue_post(&mpeg_queue
, MPEG_NEXT
, 0);
2870 #else /* SIMULATOR */
2871 char name_buf
[MAX_PATH
+1];
2876 file
= playlist_peek(steps
, name_buf
, sizeof(name_buf
));
2879 if(mp3info(&taginfo
, file
)) {
2880 if(++steps
> playlist_amount())
2884 playlist_next(steps
);
2885 current_track_counter
++;
2890 #endif /* SIMULATOR */
2893 void audio_prev(void)
2896 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2897 queue_post(&mpeg_queue
, MPEG_PREV
, 0);
2898 #else /* SIMULATOR */
2899 char name_buf
[MAX_PATH
+1];
2904 file
= playlist_peek(steps
, name_buf
, sizeof(name_buf
));
2907 if(mp3info(&taginfo
, file
)) {
2911 playlist_next(steps
);
2912 current_track_counter
++;
2917 #endif /* SIMULATOR */
2920 void audio_ff_rewind(long newpos
)
2923 queue_post(&mpeg_queue
, MPEG_FF_REWIND
, newpos
);
2924 #else /* SIMULATOR */
2926 #endif /* SIMULATOR */
2929 void audio_flush_and_reload_tracks(void)
2932 queue_post(&mpeg_queue
, MPEG_FLUSH_RELOAD
, 0);
2933 #endif /* !SIMULATOR*/
2936 int audio_status(void)
2941 ret
|= AUDIO_STATUS_PLAY
;
2944 ret
|= AUDIO_STATUS_PAUSE
;
2946 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2947 if(is_recording
&& !is_prerecording
)
2948 ret
|= AUDIO_STATUS_RECORD
;
2951 ret
|= AUDIO_STATUS_PRERECORD
;
2952 #endif /* CONFIG_CODEC == MAS3587F */
2955 ret
|= AUDIO_STATUS_ERROR
;
2961 unsigned int audio_error(void)
2967 void audio_error_clear(void)
2973 static void mpeg_thread(void)
2975 struct mp3entry
* id3
;
2978 id3
= audio_current_track();
2984 if (id3
->elapsed
>=id3
->length
)
2990 #endif /* SIMULATOR */
2992 void audio_init(void)
2997 audio_reset_buffer();
3000 queue_init(&mpeg_queue
, true);
3001 #endif /* !SIMULATOR */
3002 audio_thread_id
= create_thread(mpeg_thread
, mpeg_stack
,
3003 sizeof(mpeg_stack
), 0, mpeg_thread_name
3004 IF_PRIO(, PRIORITY_SYSTEM
)
3007 memset(trackdata
, 0, sizeof(trackdata
));
3009 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
3010 if (HW_MASK
& PR_ACTIVE_HIGH
)
3011 and_b(~0x08, &PADRH
);
3014 #endif /* CONFIG_CODEC == MAS3587F */
3020 #endif /* !SIMULATOR */
3022 audio_is_initialized
= true;
3025 #endif /* CONFIG_CODEC != SWCODEC */