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
39 #include "mp3_playback.h"
42 #include "appevents.h"
50 #endif /* !SIMULATOR */
51 #ifdef HAVE_LCD_BITMAP
56 extern unsigned long mas_version_code
;
59 #if CONFIG_CODEC == MAS3587F
60 extern enum /* from mp3_playback.c */
65 #endif /* CONFIG_CODEC == MAS3587F */
67 extern char* playlist_peek(int steps
);
68 extern bool playlist_check(int steps
);
69 extern int playlist_next(int steps
);
70 extern int playlist_amount(void);
71 extern int playlist_update_resume_info(const struct mp3entry
* id3
);
79 #define MPEG_FF_REWIND 7
80 #define MPEG_FLUSH_RELOAD 8
82 #define MPEG_INIT_RECORDING 10
83 #define MPEG_INIT_PLAYBACK 11
84 #define MPEG_NEW_FILE 12
85 #define MPEG_PAUSE_RECORDING 13
86 #define MPEG_RESUME_RECORDING 14
87 #define MPEG_NEED_DATA 100
88 #define MPEG_TRACK_CHANGE 101
89 #define MPEG_SAVE_DATA 102
90 #define MPEG_STOP_DONE 103
91 #define MPEG_PRERECORDING_TICK 104
93 /* indicator for MPEG_NEED_DATA */
94 #define GENERATE_UNBUFFER_EVENTS 1
96 /* list of tracks in memory */
97 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
98 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
104 int load_ahead_index
;
107 static struct trackdata trackdata
[MAX_TRACK_ENTRIES
];
109 static unsigned int current_track_counter
= 0;
111 /* Play time of the previous track */
112 unsigned long prev_track_elapsed
;
115 static int track_read_idx
= 0;
116 static int track_write_idx
= 0;
117 #endif /* !SIMULATOR */
119 /* Cuesheet callback */
120 static bool (*cuesheet_callback
)(const char *filename
) = NULL
;
122 static const char mpeg_thread_name
[] = "mpeg";
123 static unsigned int mpeg_errno
;
125 static bool playing
= false; /* We are playing an MP3 stream */
126 static bool is_playing
= false; /* We are (attempting to) playing MP3 files */
127 static bool paused
; /* playback is paused */
130 static char mpeg_stack
[DEFAULT_STACK_SIZE
];
131 static struct mp3entry taginfo
;
133 #else /* !SIMULATOR */
134 static struct event_queue mpeg_queue
;
135 static long mpeg_stack
[(DEFAULT_STACK_SIZE
+ 0x1000)/sizeof(long)];
137 static int audiobuflen
;
138 static int audiobuf_write
;
139 static int audiobuf_swapwrite
;
140 static int audiobuf_read
;
142 static int mpeg_file
;
144 static bool play_pending
; /* We are about to start playing */
145 static bool play_pending_track_change
; /* When starting play we're starting a new file */
146 static bool filling
; /* We are filling the buffer with data from disk */
147 static bool dma_underrun
; /* True when the DMA has stopped because of
148 slow disk reading (read error, shaking) */
149 static bool mpeg_stop_done
;
151 static int last_dma_tick
= 0;
152 static int last_dma_chunk_size
;
154 static long low_watermark
; /* Dynamic low watermark level */
155 static long low_watermark_margin
= 0; /* Extra time in seconds for watermark */
156 static long lowest_watermark_level
; /* Debug value to observe the buffer
158 #if CONFIG_CODEC == MAS3587F
159 static char recording_filename
[MAX_PATH
]; /* argument to thread */
160 static char delayed_filename
[MAX_PATH
]; /* internal copy of above */
162 static char xing_buffer
[MAX_XING_HEADER_SIZE
];
164 static bool init_recording_done
;
165 static bool init_playback_done
;
166 static bool prerecording
; /* True if prerecording is enabled */
167 static bool is_prerecording
; /* True if we are prerecording */
168 static bool is_recording
; /* We are recording */
171 NOT_SAVING
= 0, /* reasons to save data, sorted by importance */
177 static int rec_frequency_index
; /* For create_xing_header() calls */
178 static int rec_version_index
; /* For create_xing_header() calls */
180 struct prerecord_info
{
182 unsigned long framecount
;
185 static struct prerecord_info prerecord_buffer
[MPEG_MAX_PRERECORD_SECONDS
];
186 static int prerecord_index
; /* Current index in the prerecord buffer */
187 static int prerecording_max_seconds
; /* Max number of seconds to store */
188 static int prerecord_count
; /* Number of seconds in the prerecord buffer */
189 static int prerecord_timeout
; /* The tick count of the next prerecord data
192 unsigned long record_start_time
; /* Value of current_tick when recording
194 unsigned long pause_start_time
; /* Value of current_tick when pause was
196 static unsigned long last_rec_time
;
197 static unsigned long num_rec_bytes
;
198 static unsigned long last_rec_bytes
;
199 static unsigned long frame_count_start
;
200 static unsigned long frame_count_end
;
201 static unsigned long saved_header
= 0;
203 /* Shadow MAS registers */
204 unsigned long shadow_encoder_control
= 0;
205 #endif /* CONFIG_CODEC == MAS3587F */
207 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
208 unsigned long shadow_io_control_main
= 0;
209 unsigned long shadow_soft_mute
= 0;
210 unsigned shadow_codec_reg0
;
211 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
213 #ifdef HAVE_RECORDING
214 static const unsigned char empty_id3_header
[] =
216 'I', 'D', '3', 0x03, 0x00, 0x00,
217 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
219 #endif /* HAVE_RECORDING */
222 static int get_unplayed_space(void);
223 static int get_playable_space(void);
224 static int get_unswapped_space(void);
225 #endif /* !SIMULATOR */
227 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
228 static void init_recording(void);
229 static void prepend_header(void);
230 static void update_header(void);
231 static void start_prerecording(void);
232 static void start_recording(void);
233 static void stop_recording(void);
234 static int get_unsaved_space(void);
235 static void pause_recording(void);
236 static void resume_recording(void);
237 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
241 static int num_tracks_in_memory(void)
243 return (track_write_idx
- track_read_idx
) & MAX_TRACK_ENTRIES_MASK
;
247 static void debug_tags(void)
251 for(i
= 0;i
< MAX_TRACK_ENTRIES
;i
++)
253 DEBUGF("%d - %s\n", i
, trackdata
[i
].id3
.path
);
255 DEBUGF("read: %d, write :%d\n", track_read_idx
, track_write_idx
);
256 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
258 #else /* !DEBUG_TAGS */
260 #endif /* !DEBUG_TAGS */
262 static void remove_current_tag(void)
264 if(num_tracks_in_memory() > 0)
266 /* First move the index, so nobody tries to access the tag */
267 track_read_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
272 DEBUGF("remove_current_tag: no tracks to remove\n");
276 static void remove_all_non_current_tags(void)
278 track_write_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
282 static void remove_all_tags(void)
284 track_write_idx
= track_read_idx
;
289 static struct trackdata
*get_trackdata(int offset
)
291 if(offset
>= num_tracks_in_memory())
294 return &trackdata
[(track_read_idx
+ offset
) & MAX_TRACK_ENTRIES_MASK
];
296 #endif /* !SIMULATOR */
298 /***********************************************************************/
299 /* audio event handling */
301 #define MAX_EVENT_HANDLERS 10
302 struct event_handlers_table
304 AUDIO_EVENT_HANDLER handler
;
307 static struct event_handlers_table event_handlers
[MAX_EVENT_HANDLERS
];
308 static int event_handlers_count
= 0;
310 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler
, unsigned short mask
)
312 if (event_handlers_count
< MAX_EVENT_HANDLERS
)
314 event_handlers
[event_handlers_count
].handler
= handler
;
315 event_handlers
[event_handlers_count
].mask
= mask
;
316 event_handlers_count
++;
320 /* dispatch calls each handler in the order registered and returns after some
321 handler actually handles the event (the event is assumed to no longer be valid
322 after this, due to the handler changing some condition); returns true if someone
323 handled the event, which is expected to cause the caller to skip its own handling
326 static bool audio_dispatch_event(unsigned short event
, unsigned long data
)
329 for(i
=0; i
< event_handlers_count
; i
++)
331 if ( event_handlers
[i
].mask
& event
)
333 int rc
= event_handlers
[i
].handler(event
, data
);
334 if ( rc
== AUDIO_EVENT_RC_HANDLED
)
342 /***********************************************************************/
344 static void set_elapsed(struct mp3entry
* id3
)
347 if ( id3
->has_toc
) {
348 /* calculate elapsed time using TOC */
350 unsigned int remainder
, plen
, relpos
, nextpos
;
352 /* find wich percent we're at */
353 for (i
=0; i
<100; i
++ )
355 if ( id3
->offset
< id3
->toc
[i
] * (id3
->filesize
/ 256) )
365 relpos
= id3
->toc
[i
];
369 nextpos
= id3
->toc
[i
+1];
376 remainder
= id3
->offset
- (relpos
* (id3
->filesize
/ 256));
378 /* set time for this percent (divide before multiply to prevent
379 overflow on long files. loss of precision is negligible on
381 id3
->elapsed
= i
* (id3
->length
/ 100);
383 /* calculate remainder time */
384 plen
= (nextpos
- relpos
) * (id3
->filesize
/ 256);
385 id3
->elapsed
+= (((remainder
* 100) / plen
) *
386 (id3
->length
/ 10000));
389 /* no TOC exists. set a rough estimate using average bitrate */
390 int tpk
= id3
->length
/ (id3
->filesize
/ 1024);
391 id3
->elapsed
= id3
->offset
/ 1024 * tpk
;
395 /* constant bitrate, use exact calculation */
396 id3
->elapsed
= id3
->offset
/ (id3
->bitrate
/ 8);
399 int audio_get_file_pos(void)
402 struct mp3entry
*id3
= audio_current_track();
408 /* Use the TOC to find the new position */
409 unsigned int percent
, remainder
;
410 int curtoc
, nexttoc
, plen
;
412 percent
= (id3
->elapsed
*100)/id3
->length
;
416 curtoc
= id3
->toc
[percent
];
419 nexttoc
= id3
->toc
[percent
+1];
423 pos
= (id3
->filesize
/256)*curtoc
;
425 /* Use the remainder to get a more accurate position */
426 remainder
= (id3
->elapsed
*100)%id3
->length
;
427 remainder
= (remainder
*100)/id3
->length
;
428 plen
= (nexttoc
- curtoc
)*(id3
->filesize
/256);
429 pos
+= (plen
/100)*remainder
;
433 /* No TOC exists, estimate the new position */
434 pos
= (id3
->filesize
/ (id3
->length
/ 1000)) *
435 (id3
->elapsed
/ 1000);
438 else if (id3
->bitrate
)
439 pos
= id3
->elapsed
* (id3
->bitrate
/ 8);
445 if (pos
>= (int)(id3
->filesize
- id3
->id3v1len
))
447 /* Don't seek right to the end of the file so that we can
448 transition properly to the next song */
449 pos
= id3
->filesize
- id3
->id3v1len
- 1;
451 else if (pos
< (int)id3
->first_frame_offset
)
453 /* skip past id3v2 tag and other leading garbage */
454 pos
= id3
->first_frame_offset
;
459 unsigned long mpeg_get_last_header(void)
463 #else /* !SIMULATOR */
464 unsigned long tmp
[2];
466 /* Read the frame data from the MAS and reconstruct it with the
467 frame sync and all */
468 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_STATUS_1
, tmp
, 2);
469 return 0xffe00000 | ((tmp
[0] & 0x7c00) << 6) | (tmp
[1] & 0xffff);
470 #endif /* !SIMULATOR */
473 void audio_set_cuesheet_callback(bool (*handler
)(const char *filename
))
475 cuesheet_callback
= handler
;
479 /* Send callback events to notify about removing old tracks. */
480 static void generate_unbuffer_events(void)
483 int numentries
= MAX_TRACK_ENTRIES
- num_tracks_in_memory();
484 int cur_idx
= track_write_idx
;
486 for (i
= 0; i
< numentries
; i
++)
488 /* Send an event to notify that track has finished. */
489 send_event(PLAYBACK_EVENT_TRACK_FINISH
, &trackdata
[cur_idx
].id3
);
490 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
494 /* Send callback events to notify about new tracks. */
495 static void generate_postbuffer_events(void)
498 int numentries
= num_tracks_in_memory();
499 int cur_idx
= track_read_idx
;
501 for (i
= 0; i
< numentries
; i
++)
503 send_event(PLAYBACK_EVENT_TRACK_BUFFER
, &trackdata
[cur_idx
].id3
);
504 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
508 static void recalculate_watermark(int bitrate
)
511 int time
= storage_spinup_time();
513 /* A bitrate of 0 probably means empty VBR header. We play safe
514 and set a high threshold */
518 bytes_per_sec
= bitrate
* 1000 / 8;
522 /* No drive spins up faster than 3.5s */
527 low_watermark
= ((low_watermark_margin
* HZ
+ time
) *
532 low_watermark
= MPEG_LOW_WATER
;
536 #ifdef HAVE_DISK_STORAGE
537 void audio_set_buffer_margin(int seconds
)
539 low_watermark_margin
= seconds
;
543 void audio_get_debugdata(struct audio_debug
*dbgdata
)
545 dbgdata
->audiobuflen
= audiobuflen
;
546 dbgdata
->audiobuf_write
= audiobuf_write
;
547 dbgdata
->audiobuf_swapwrite
= audiobuf_swapwrite
;
548 dbgdata
->audiobuf_read
= audiobuf_read
;
550 dbgdata
->last_dma_chunk_size
= last_dma_chunk_size
;
552 #if CONFIG_CPU == SH7034
553 dbgdata
->dma_on
= (SCR0
& 0x80) != 0;
555 dbgdata
->playing
= playing
;
556 dbgdata
->play_pending
= play_pending
;
557 dbgdata
->is_playing
= is_playing
;
558 dbgdata
->filling
= filling
;
559 dbgdata
->dma_underrun
= dma_underrun
;
561 dbgdata
->unplayed_space
= get_unplayed_space();
562 dbgdata
->playable_space
= get_playable_space();
563 dbgdata
->unswapped_space
= get_unswapped_space();
565 dbgdata
->low_watermark_level
= low_watermark
;
566 dbgdata
->lowest_watermark_level
= lowest_watermark_level
;
570 static void dbg_timer_start(void)
572 /* We are using timer 2 */
574 TSTR
&= ~0x04; /* Stop the timer */
575 TSNC
&= ~0x04; /* No synchronization */
576 TMDR
&= ~0x44; /* Operate normally */
578 TCNT2
= 0; /* Start counting at 0 */
579 TCR2
= 0x03; /* Sysclock/8 */
581 TSTR
|= 0x04; /* Start timer 2 */
584 static int dbg_cnt2us(unsigned int cnt
)
586 return (cnt
* 10000) / (FREQ
/800);
590 static int get_unplayed_space(void)
592 int space
= audiobuf_write
- audiobuf_read
;
594 space
+= audiobuflen
;
598 static int get_playable_space(void)
600 int space
= audiobuf_swapwrite
- audiobuf_read
;
602 space
+= audiobuflen
;
606 static int get_unplayed_space_current_song(void)
610 if (num_tracks_in_memory() > 1)
612 space
= get_trackdata(1)->mempos
- audiobuf_read
;
616 space
= audiobuf_write
- audiobuf_read
;
620 space
+= audiobuflen
;
625 static int get_unswapped_space(void)
627 int space
= audiobuf_write
- audiobuf_swapwrite
;
629 space
+= audiobuflen
;
633 #if CONFIG_CODEC == MAS3587F
634 static int get_unsaved_space(void)
636 int space
= audiobuf_write
- audiobuf_read
;
638 space
+= audiobuflen
;
642 static void drain_dma_buffer(void)
648 while (PBDRH
& 0x80);
652 while (!(PBDRH
& 0x80));
657 static long timing_info_index
= 0;
658 static long timing_info
[1024];
661 void rec_tick (void) __attribute__ ((section (".icode")));
668 if(is_recording
&& (PBDRH
& 0x40))
671 timing_info
[timing_info_index
++] = current_tick
;
674 /* Note: Although this loop is run in interrupt context, further
675 * optimisation will do no good. The MAS would then deliver bad
676 * frames occasionally, as observed in extended experiments. */
678 while (PBDRH
& 0x40) /* We try to read as long as EOD is high */
680 xor_b(0x08, &PADRH
); /* Set PR active, independent of polarity */
683 while (PBDRH
& 0x80) /* Wait until /RTW becomes active */
685 if (--delay
<= 0) /* Bail out if we have to wait too long */
686 { /* i.e. the MAS doesn't want to talk to us */
687 xor_b(0x08, &PADRH
); /* Set PR inactive */
688 goto transfer_end
; /* and get out of here */
692 data
= *(unsigned char *)0x04000000; /* read data byte */
694 xor_b(0x08, &PADRH
); /* Set PR inactive */
696 audiobuf
[audiobuf_write
++] = data
;
698 if (audiobuf_write
>= audiobuflen
)
706 timing_info
[timing_info_index
++] = TCNT2
+ (i
<< 16);
707 timing_info_index
&= 0x3ff;
714 if(TIME_AFTER(current_tick
, prerecord_timeout
))
716 prerecord_timeout
= current_tick
+ HZ
;
717 queue_post(&mpeg_queue
, MPEG_PRERECORDING_TICK
, 0);
722 /* Signal to save the data if we are running out of buffer
724 if (audiobuflen
- get_unsaved_space() < MPEG_RECORDING_LOW_WATER
725 && saving_status
== NOT_SAVING
)
727 saving_status
= BUFFER_FULL
;
728 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
733 #endif /* CONFIG_CODEC == MAS3587F */
735 void playback_tick(void)
737 struct trackdata
*ptd
= get_trackdata(0);
740 ptd
->id3
.elapsed
+= (current_tick
- last_dma_tick
) * 1000 / HZ
;
741 last_dma_tick
= current_tick
;
742 audio_dispatch_event(AUDIO_EVENT_POS_REPORT
,
743 (unsigned long)ptd
->id3
.elapsed
);
747 static void reset_mp3_buffer(void)
751 audiobuf_swapwrite
= 0;
752 lowest_watermark_level
= audiobuflen
;
755 /* DMA transfer end interrupt callback */
756 static void transfer_end(unsigned char** ppbuf
, size_t* psize
)
758 if(playing
&& !paused
)
760 int unplayed_space_left
;
761 int space_until_end_of_buffer
;
762 int track_offset
= 1;
763 struct trackdata
*track
;
765 audiobuf_read
+= last_dma_chunk_size
;
766 if(audiobuf_read
>= audiobuflen
)
769 /* First, check if we are on a track boundary */
770 if (num_tracks_in_memory() > 1)
772 if (audiobuf_read
== get_trackdata(track_offset
)->mempos
)
774 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
776 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
782 unplayed_space_left
= get_unplayed_space();
784 space_until_end_of_buffer
= audiobuflen
- audiobuf_read
;
786 if(!filling
&& unplayed_space_left
< low_watermark
)
789 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
792 if(unplayed_space_left
)
794 last_dma_chunk_size
= MIN(0x2000, unplayed_space_left
);
795 last_dma_chunk_size
= MIN(last_dma_chunk_size
,
796 space_until_end_of_buffer
);
798 /* several tracks loaded? */
799 track
= get_trackdata(track_offset
);
802 /* will we move across the track boundary? */
803 if (( audiobuf_read
< track
->mempos
) &&
804 ((audiobuf_read
+last_dma_chunk_size
) >
807 /* Make sure that we end exactly on the boundary */
808 last_dma_chunk_size
= track
->mempos
- audiobuf_read
;
812 *psize
= last_dma_chunk_size
& 0xffff;
813 *ppbuf
= audiobuf
+ audiobuf_read
;
814 track
= get_trackdata(0);
816 track
->id3
.offset
+= last_dma_chunk_size
;
818 /* Update the watermark debug level */
819 if(unplayed_space_left
< lowest_watermark_level
)
820 lowest_watermark_level
= unplayed_space_left
;
824 /* Check if the end of data is because of a hard disk error.
825 If there is an open file handle, we are still playing music.
826 If not, the last file has been loaded, and the file handle is
830 /* Update the watermark debug level */
831 if(unplayed_space_left
< lowest_watermark_level
)
832 lowest_watermark_level
= unplayed_space_left
;
834 DEBUGF("DMA underrun.\n");
839 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
841 DEBUGF("No more MP3 data. Stopping.\n");
842 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
846 *psize
= 0; /* no more transfer */
851 static struct trackdata
*add_track_to_tag_list(const char *filename
)
853 struct trackdata
*track
;
854 bool send_nid3_event
;
856 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES
)
858 DEBUGF("Tag memory is full\n");
862 track
= &trackdata
[track_write_idx
];
864 /* grab id3 tag of new file and
865 remember where in memory it starts */
866 if(mp3info(&track
->id3
, filename
))
871 track
->mempos
= audiobuf_write
;
872 track
->id3
.elapsed
= 0;
873 #ifdef HAVE_LCD_BITMAP
874 if (track
->id3
.title
)
875 lcd_getstringsize(track
->id3
.title
, NULL
, NULL
);
876 if (track
->id3
.artist
)
877 lcd_getstringsize(track
->id3
.artist
, NULL
, NULL
);
878 if (track
->id3
.album
)
879 lcd_getstringsize(track
->id3
.album
, NULL
, NULL
);
881 if (cuesheet_callback
)
882 if (cuesheet_callback(filename
))
883 track
->id3
.cuesheet_type
= 1;
885 /* if this track is the next track then let the UI know it can get it */
886 send_nid3_event
= (track_write_idx
== track_read_idx
+ 1);
887 track_write_idx
= (track_write_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
889 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE
, NULL
);
894 static int new_file(int steps
)
896 int max_steps
= playlist_amount();
899 struct trackdata
*track
;
901 /* Find out how many steps to advance. The load_ahead_index field tells
902 us how many playlist entries it had to skip to get to a valid one.
903 We add those together to find out where to start. */
904 if(steps
> 0 && num_tracks_in_memory() > 1)
906 /* Begin with the song after the currently playing one */
908 while((track
= get_trackdata(i
++)))
910 start
+= track
->load_ahead_index
;
917 trackname
= playlist_peek( start
+ steps
);
921 DEBUGF("Loading %s\n", trackname
);
923 mpeg_file
= open(trackname
, O_RDONLY
);
925 DEBUGF("Couldn't open file: %s\n",trackname
);
933 struct trackdata
*track
= add_track_to_tag_list(trackname
);
947 /* skip past id3v2 tag */
949 track
->id3
.first_frame_offset
,
951 track
->id3
.index
= steps
;
952 track
->load_ahead_index
= steps
;
953 track
->id3
.offset
= 0;
956 /* Average bitrate * 1.5 */
957 recalculate_watermark(
958 (track
->id3
.bitrate
* 3) / 2);
960 recalculate_watermark(
966 /* Bail out if no file could be opened */
967 if(abs(steps
) > max_steps
)
969 } while ( mpeg_file
< 0 );
974 static void stop_playing(void)
976 struct trackdata
*track
;
978 /* Stop the current stream */
983 track
= get_trackdata(0);
985 prev_track_elapsed
= track
->id3
.elapsed
;
991 generate_unbuffer_events();
995 static void end_current_track(void) {
996 struct trackdata
*track
;
998 play_pending
= false;
1000 mp3_play_pause(false);
1002 track
= get_trackdata(0);
1004 prev_track_elapsed
= track
->id3
.elapsed
;
1008 generate_unbuffer_events();
1014 /* Is this a really the end of playback or is a new playlist starting */
1015 static void check_playlist_end(int direction
)
1017 /* Use the largest possible step size to account for skipped tracks */
1018 int steps
= playlist_amount();
1023 if (playlist_next(steps
) < 0)
1027 static void update_playlist(void)
1029 if (num_tracks_in_memory() > 0)
1031 struct trackdata
*track
= get_trackdata(0);
1032 track
->id3
.index
= playlist_next(track
->id3
.index
);
1036 /* End of playlist? */
1037 check_playlist_end(1);
1040 playlist_update_resume_info(audio_current_track());
1043 static void track_change(void)
1045 DEBUGF("Track change\n");
1047 struct trackdata
*track
= get_trackdata(0);
1048 prev_track_elapsed
= track
->id3
.elapsed
;
1050 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1053 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1055 if (num_tracks_in_memory() > 0)
1057 remove_current_tag();
1060 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1063 current_track_counter
++;
1066 unsigned long audio_prev_elapsed(void)
1068 return prev_track_elapsed
;
1072 void hexdump(const unsigned char *buf
, int len
)
1076 for(i
= 0;i
< len
;i
++)
1078 if(i
&& (i
& 15) == 0)
1082 DEBUGF("%02x ", buf
[i
]);
1088 static void start_playback_if_ready(void)
1092 playable_space
= audiobuf_swapwrite
- audiobuf_read
;
1093 if(playable_space
< 0)
1094 playable_space
+= audiobuflen
;
1096 /* See if we have started playing yet. If not, do it. */
1097 if(play_pending
|| dma_underrun
)
1099 /* If the filling has stopped, and we still haven't reached
1100 the watermark, the file must be smaller than the
1101 watermark. We must still play it. */
1102 if((playable_space
>= MPEG_PLAY_PENDING_THRESHOLD
) ||
1103 !filling
|| dma_underrun
)
1106 if (play_pending
) /* don't do this when recovering from DMA underrun */
1108 generate_postbuffer_events(); /* signal first track as buffered */
1109 if (play_pending_track_change
)
1111 play_pending_track_change
= false;
1112 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1114 play_pending
= false;
1118 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1119 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1120 dma_underrun
= false;
1124 last_dma_tick
= current_tick
;
1125 mp3_play_pause(true);
1128 /* Tell ourselves that we need more data */
1129 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1134 static bool swap_one_chunk(void)
1136 int free_space_left
;
1139 free_space_left
= get_unswapped_space();
1141 if(free_space_left
== 0 && !play_pending
)
1144 /* Swap in larger chunks when the user is waiting for the playback
1145 to start, or when there is dangerously little playable data left */
1147 amount_to_swap
= MIN(MPEG_PLAY_PENDING_SWAPSIZE
, free_space_left
);
1150 if(get_playable_space() < low_watermark
)
1151 amount_to_swap
= MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE
,
1154 amount_to_swap
= MIN(MPEG_SWAP_CHUNKSIZE
, free_space_left
);
1157 if(audiobuf_write
< audiobuf_swapwrite
)
1158 amount_to_swap
= MIN(audiobuflen
- audiobuf_swapwrite
,
1161 amount_to_swap
= MIN(audiobuf_write
- audiobuf_swapwrite
,
1164 bitswap(audiobuf
+ audiobuf_swapwrite
, amount_to_swap
);
1166 audiobuf_swapwrite
+= amount_to_swap
;
1167 if(audiobuf_swapwrite
>= audiobuflen
)
1169 audiobuf_swapwrite
= 0;
1175 static void mpeg_thread(void)
1177 static int pause_tick
= 0;
1178 static unsigned int pause_track
= 0;
1179 struct queue_event ev
;
1181 int free_space_left
;
1182 int unplayed_space_left
;
1186 #if CONFIG_CODEC == MAS3587F
1188 int save_endpos
= 0;
1192 #endif /* CONFIG_CODEC == MAS3587F */
1195 play_pending
= false;
1201 #if CONFIG_CODEC == MAS3587F
1202 if(mpeg_mode
== MPEG_DECODER
)
1204 #endif /* CONFIG_CODEC == MAS3587F */
1207 /* Swap if necessary, and don't block on the queue_wait() */
1208 if(swap_one_chunk())
1210 queue_wait_w_tmo(&mpeg_queue
, &ev
, 0);
1214 /* periodically update resume info */
1215 queue_wait_w_tmo(&mpeg_queue
, &ev
, HZ
/2);
1219 DEBUGF("S R:%x W:%x SW:%x\n",
1220 audiobuf_read
, audiobuf_write
, audiobuf_swapwrite
);
1221 queue_wait(&mpeg_queue
, &ev
);
1224 start_playback_if_ready();
1229 DEBUGF("MPEG_PLAY\n");
1232 /* Silence the A/D input, it may be on because the radio
1234 mas_codec_writereg(6, 0x0000);
1235 #endif /* CONFIG_TUNER */
1237 /* Stop the current stream */
1239 end_current_track();
1241 if ( new_file(0) == -1 )
1248 start_offset
= (int)ev
.data
;
1250 /* mid-song resume? */
1252 struct mp3entry
* id3
= &get_trackdata(0)->id3
;
1253 lseek(mpeg_file
, start_offset
, SEEK_SET
);
1254 id3
->offset
= start_offset
;
1258 /* skip past id3v2 tag */
1260 get_trackdata(0)->id3
.first_frame_offset
,
1265 /* Make it read more data */
1267 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1269 /* Tell the file loading code that we want to start playing
1270 as soon as we have some data */
1271 play_pending
= true;
1272 play_pending_track_change
= true;
1275 current_track_counter
++;
1279 DEBUGF("MPEG_STOP\n");
1284 playlist_update_resume_info(audio_current_track());
1287 mpeg_stop_done
= true;
1291 DEBUGF("MPEG_PAUSE\n");
1292 /* Stop the current stream */
1294 playlist_update_resume_info(audio_current_track());
1297 pause_tick
= current_tick
;
1298 pause_track
= current_track_counter
;
1299 mp3_play_pause(false);
1303 DEBUGF("MPEG_RESUME\n");
1304 /* Continue the current stream */
1309 if ( current_track_counter
== pause_track
)
1310 last_dma_tick
+= current_tick
- pause_tick
;
1312 last_dma_tick
= current_tick
;
1314 mp3_play_pause(true);
1319 DEBUGF("MPEG_NEXT\n");
1320 /* is next track in ram? */
1321 if ( num_tracks_in_memory() > 1 ) {
1322 int unplayed_space_left
, unswapped_space_left
;
1324 /* stop the current stream */
1325 play_pending
= false;
1327 mp3_play_pause(false);
1330 audiobuf_read
= get_trackdata(0)->mempos
;
1331 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1332 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1333 dma_underrun
= false;
1334 last_dma_tick
= current_tick
;
1336 unplayed_space_left
= get_unplayed_space();
1337 unswapped_space_left
= get_unswapped_space();
1339 /* should we start reading more data? */
1340 if(!filling
&& (unplayed_space_left
< low_watermark
)) {
1342 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1343 play_pending
= true;
1344 } else if(unswapped_space_left
&&
1345 unswapped_space_left
> unplayed_space_left
) {
1346 /* Stop swapping the data from the previous file */
1347 audiobuf_swapwrite
= audiobuf_read
;
1348 play_pending
= true;
1352 mp3_play_pause(true);
1356 if (!playlist_check(1))
1359 /* stop the current stream */
1360 end_current_track();
1362 if (new_file(1) < 0) {
1363 DEBUGF("No more files to play\n");
1366 check_playlist_end(1);
1367 current_track_counter
++;
1369 /* Make it read more data */
1371 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1373 /* Tell the file loading code that we want
1374 to start playing as soon as we have some data */
1375 play_pending
= true;
1376 play_pending_track_change
= true;
1379 current_track_counter
++;
1385 DEBUGF("MPEG_PREV\n");
1387 if (!playlist_check(-1))
1390 /* stop the current stream */
1391 end_current_track();
1393 /* Open the next file */
1394 if (new_file(-1) < 0) {
1395 DEBUGF("No more files to play\n");
1398 check_playlist_end(-1);
1399 current_track_counter
++;
1401 /* Make it read more data */
1403 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1405 /* Tell the file loading code that we want to
1406 start playing as soon as we have some data */
1407 play_pending
= true;
1408 play_pending_track_change
= true;
1411 current_track_counter
++;
1416 case MPEG_FF_REWIND
: {
1417 struct mp3entry
*id3
= audio_current_track();
1418 unsigned int oldtime
= id3
->elapsed
;
1419 unsigned int newtime
= (unsigned int)ev
.data
;
1420 int curpos
, newpos
, diffpos
;
1421 DEBUGF("MPEG_FF_REWIND\n");
1423 id3
->elapsed
= newtime
;
1425 newpos
= audio_get_file_pos();
1428 id3
->elapsed
= oldtime
;
1433 curpos
= lseek(mpeg_file
, 0, SEEK_CUR
);
1435 curpos
= id3
->filesize
;
1437 if (num_tracks_in_memory() > 1)
1439 /* We have started loading other tracks that need to be
1441 struct trackdata
*track
;
1444 while((track
= get_trackdata(i
++)))
1446 curpos
+= track
->id3
.filesize
;
1450 diffpos
= curpos
- newpos
;
1452 if(!filling
&& diffpos
>= 0 && diffpos
< audiobuflen
)
1454 int unplayed_space_left
, unswapped_space_left
;
1456 /* We are changing to a position that's already in
1457 memory, so we just move the DMA read pointer. */
1458 audiobuf_read
= audiobuf_write
- diffpos
;
1459 if (audiobuf_read
< 0)
1461 audiobuf_read
+= audiobuflen
;
1464 unplayed_space_left
= get_unplayed_space();
1465 unswapped_space_left
= get_unswapped_space();
1467 /* If unswapped_space_left is larger than
1468 unplayed_space_left, it means that the swapwrite pointer
1469 hasn't yet advanced up to the new location of the read
1470 pointer. We just move it, there is no need to swap
1471 data that won't be played anyway. */
1473 if (unswapped_space_left
> unplayed_space_left
)
1475 DEBUGF("Moved swapwrite\n");
1476 audiobuf_swapwrite
= audiobuf_read
;
1477 play_pending
= true;
1480 if (mpeg_file
>=0 && unplayed_space_left
< low_watermark
)
1482 /* We need to load more data before starting */
1484 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1485 play_pending
= true;
1489 /* resume will start at new position */
1490 last_dma_chunk_size
=
1491 MIN(0x2000, get_unplayed_space_current_song());
1492 mp3_play_data(audiobuf
+ audiobuf_read
,
1493 last_dma_chunk_size
, transfer_end
);
1494 dma_underrun
= false;
1499 /* Move to the new position in the file and start
1503 if (num_tracks_in_memory() > 1)
1505 /* We have to reload the current track */
1507 remove_all_non_current_tags();
1508 generate_unbuffer_events();
1514 mpeg_file
= open(id3
->path
, O_RDONLY
);
1517 id3
->elapsed
= oldtime
;
1522 if(-1 == lseek(mpeg_file
, newpos
, SEEK_SET
))
1524 id3
->elapsed
= oldtime
;
1529 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1531 /* Tell the file loading code that we want to start playing
1532 as soon as we have some data */
1533 play_pending
= true;
1536 id3
->offset
= newpos
;
1541 case MPEG_FLUSH_RELOAD
: {
1542 int numtracks
= num_tracks_in_memory();
1543 bool reload_track
= false;
1547 /* Reset the buffer */
1548 audiobuf_write
= get_trackdata(1)->mempos
;
1550 /* Reset swapwrite unless we're still swapping current
1552 if (get_unplayed_space() <= get_playable_space())
1553 audiobuf_swapwrite
= audiobuf_write
;
1556 remove_all_non_current_tags();
1557 generate_unbuffer_events();
1559 reload_track
= true;
1561 else if (numtracks
== 1 && mpeg_file
< 0)
1563 reload_track
= true;
1566 if(reload_track
&& new_file(1) >= 0)
1568 /* Tell ourselves that we want more data */
1570 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1576 case MPEG_NEED_DATA
:
1577 free_space_left
= audiobuf_read
- audiobuf_write
;
1579 /* We interpret 0 as "empty buffer" */
1580 if(free_space_left
<= 0)
1581 free_space_left
+= audiobuflen
;
1583 unplayed_space_left
= audiobuflen
- free_space_left
;
1585 /* Make sure that we don't fill the entire buffer */
1586 free_space_left
-= MPEG_HIGH_WATER
;
1588 if (ev
.data
== GENERATE_UNBUFFER_EVENTS
)
1589 generate_unbuffer_events();
1591 /* do we have any more buffer space to fill? */
1592 if(free_space_left
<= 0)
1596 generate_postbuffer_events();
1601 /* Read small chunks while we are below the low water mark */
1602 if(unplayed_space_left
< low_watermark
)
1603 amount_to_read
= MIN(MPEG_LOW_WATER_CHUNKSIZE
,
1606 amount_to_read
= free_space_left
;
1608 /* Don't read more than until the end of the buffer */
1609 amount_to_read
= MIN(audiobuflen
- audiobuf_write
,
1611 #if (CONFIG_STORAGE & STORAGE_MMC)
1612 /* MMC is slow, so don't read too large chunks */
1613 amount_to_read
= MIN(0x40000, amount_to_read
);
1615 amount_to_read
= MIN(0x100000, amount_to_read
);
1618 /* Read as much mpeg data as we can fit in the buffer */
1623 len
= read(mpeg_file
, audiobuf
+ audiobuf_write
,
1628 DEBUGF("time: %d\n", t2
- t1
);
1629 DEBUGF("R: %x\n", len
);
1631 /* Now make sure that we don't feed the MAS with ID3V1
1633 if (len
< amount_to_read
)
1636 static const unsigned char tag
[] = "TAG";
1638 int tagptr
= audiobuf_write
+ len
- 128;
1640 /* Really rare case: entire potential tag wasn't
1641 read in this call AND audiobuf_write < 128 */
1643 tagptr
+= audiobuflen
;
1645 for(i
= 0;i
< 3;i
++)
1647 if(tagptr
>= audiobuflen
)
1648 tagptr
-= audiobuflen
;
1650 if(audiobuf
[tagptr
] != tag
[i
])
1661 /* Skip id3v1 tag */
1662 DEBUGF("Skipping ID3v1 tag\n");
1665 /* In the very rare case when the entire tag
1666 wasn't read in this read() len will be < 0.
1667 Take care of this when changing the write
1672 audiobuf_write
+= len
;
1674 if (audiobuf_write
< 0)
1675 audiobuf_write
+= audiobuflen
;
1677 if(audiobuf_write
>= audiobuflen
)
1683 /* Tell ourselves that we want more data */
1684 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1690 DEBUGF("MPEG read error\n");
1698 /* No more data to play */
1699 DEBUGF("No more files to play\n");
1704 /* Tell ourselves that we want more data */
1705 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1711 case MPEG_TRACK_CHANGE
:
1716 case SYS_USB_CONNECTED
:
1721 /* Tell the USB thread that we are safe */
1722 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1723 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1725 /* Wait until the USB cable is extracted again */
1726 usb_wait_for_disconnect(&mpeg_queue
);
1728 #endif /* !USB_NONE */
1730 #if CONFIG_CODEC == MAS3587F
1731 case MPEG_INIT_RECORDING
:
1733 init_recording_done
= true;
1735 #endif /* CONFIG_CODEC == MAS3587F */
1739 playlist_update_resume_info(audio_current_track());
1742 #if CONFIG_CODEC == MAS3587F
1746 queue_wait(&mpeg_queue
, &ev
);
1750 if (is_prerecording
)
1754 /* Go back prerecord_count seconds in the buffer */
1755 startpos
= prerecord_index
- prerecord_count
;
1757 startpos
+= prerecording_max_seconds
;
1759 /* Read the position data from the prerecord buffer */
1760 frame_count_start
= prerecord_buffer
[startpos
].framecount
;
1761 startpos
= prerecord_buffer
[startpos
].mempos
;
1763 DEBUGF("Start looking at address %x (%x)\n",
1764 audiobuf
+startpos
, startpos
);
1766 saved_header
= mpeg_get_last_header();
1768 mem_find_next_frame(startpos
, &offset
, 1800,
1771 audiobuf_read
= startpos
+ offset
;
1772 if(audiobuf_read
>= audiobuflen
)
1773 audiobuf_read
-= audiobuflen
;
1775 DEBUGF("New audiobuf_read address: %x (%x)\n",
1776 audiobuf
+audiobuf_read
, audiobuf_read
);
1778 level
= disable_irq_save();
1779 num_rec_bytes
= get_unsaved_space();
1784 frame_count_start
= 0;
1786 audiobuf_read
= MPEG_RESERVED_HEADER_SPACE
;
1787 audiobuf_write
= MPEG_RESERVED_HEADER_SPACE
;
1791 DEBUGF("Recording...\n");
1794 /* Wait until at least one frame is encoded and get the
1795 frame header, for later use by the Xing header
1798 saved_header
= mpeg_get_last_header();
1800 /* delayed until buffer is saved, don't open yet */
1801 strcpy(delayed_filename
, recording_filename
);
1807 DEBUGF("MPEG_STOP\n");
1811 /* Save the remaining data in the buffer */
1812 save_endpos
= audiobuf_write
;
1813 saving_status
= STOP_RECORDING
;
1814 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1817 case MPEG_STOP_DONE
:
1818 DEBUGF("MPEG_STOP_DONE\n");
1828 for(i
= 0;i
< 512;i
++)
1830 DEBUGF("%d - %d us (%d bytes)\n",
1832 (timing_info
[i
*2+1] & 0xffff) *
1834 timing_info
[i
*2+1] >> 16);
1841 start_prerecording();
1843 mpeg_stop_done
= true;
1847 /* Bail out when a more important save is happening */
1848 if (saving_status
> NEW_FILE
)
1851 /* Make sure we have at least one complete frame
1852 in the buffer. If we haven't recorded a single
1853 frame within 200ms, the MAS is probably not recording
1854 anything, and we bail out. */
1855 amount_to_save
= get_unsaved_space();
1856 if (amount_to_save
< 1800)
1859 amount_to_save
= get_unsaved_space();
1862 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1863 &frame_count_end
, 1);
1865 last_rec_time
= current_tick
- record_start_time
;
1866 record_start_time
= current_tick
;
1868 pause_start_time
= record_start_time
;
1870 /* capture all values at one point */
1871 level
= disable_irq_save();
1872 save_endpos
= audiobuf_write
;
1873 last_rec_bytes
= num_rec_bytes
;
1877 if (amount_to_save
>= 1800)
1879 /* Now find a frame boundary to split at */
1880 save_endpos
-= 1800;
1881 if (save_endpos
< 0)
1882 save_endpos
+= audiobuflen
;
1884 rc
= mem_find_next_frame(save_endpos
, &offset
, 1800,
1886 if (!rc
) /* No header found, save whole buffer */
1889 save_endpos
+= offset
;
1890 if (save_endpos
>= audiobuflen
)
1891 save_endpos
-= audiobuflen
;
1893 last_rec_bytes
+= offset
- 1800;
1894 level
= disable_irq_save();
1895 num_rec_bytes
+= 1800 - offset
;
1899 saving_status
= NEW_FILE
;
1900 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1903 case MPEG_SAVE_DATA
:
1904 if (saving_status
== BUFFER_FULL
)
1905 save_endpos
= audiobuf_write
;
1907 if (mpeg_file
< 0) /* delayed file open */
1909 mpeg_file
= open(delayed_filename
, O_WRONLY
|O_CREAT
);
1912 panicf("recfile: %d", mpeg_file
);
1915 amount_to_save
= save_endpos
- audiobuf_read
;
1916 if (amount_to_save
< 0)
1917 amount_to_save
+= audiobuflen
;
1919 amount_to_save
= MIN(amount_to_save
,
1920 audiobuflen
- audiobuf_read
);
1921 #if (CONFIG_STORAGE & STORAGE_MMC)
1922 /* MMC is slow, so don't save too large chunks at once */
1923 amount_to_save
= MIN(0x40000, amount_to_save
);
1925 amount_to_save
= MIN(0x100000, amount_to_save
);
1927 rc
= write(mpeg_file
, audiobuf
+ audiobuf_read
,
1931 if (errno
== ENOSPC
)
1933 mpeg_errno
= AUDIOERR_DISK_FULL
;
1935 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1936 /* will close the file */
1940 panicf("rec wrt: %d", rc
);
1943 audiobuf_read
+= amount_to_save
;
1944 if (audiobuf_read
>= audiobuflen
)
1947 if (audiobuf_read
== save_endpos
) /* all saved */
1949 switch (saving_status
)
1952 rc
= fsync(mpeg_file
);
1954 panicf("rec fls: %d", rc
);
1959 /* Close the current file */
1960 rc
= close(mpeg_file
);
1962 panicf("rec cls: %d", rc
);
1967 /* copy new filename */
1968 strcpy(delayed_filename
, recording_filename
);
1970 frame_count_start
= frame_count_end
;
1973 case STOP_RECORDING
:
1974 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1975 /* will close the file */
1981 saving_status
= NOT_SAVING
;
1983 else /* tell ourselves to save the next chunk */
1984 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1988 case MPEG_PRERECORDING_TICK
:
1989 if(!is_prerecording
)
1992 /* Store the write pointer every second */
1993 prerecord_buffer
[prerecord_index
].mempos
= audiobuf_write
;
1994 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1995 &prerecord_buffer
[prerecord_index
].framecount
, 1);
1997 /* Wrap if necessary */
1998 if(++prerecord_index
== prerecording_max_seconds
)
1999 prerecord_index
= 0;
2001 /* Update the number of seconds recorded */
2002 if(prerecord_count
< prerecording_max_seconds
)
2006 case MPEG_INIT_PLAYBACK
:
2007 /* Stop the prerecording */
2011 init_playback_done
= true;
2014 case MPEG_PAUSE_RECORDING
:
2018 case MPEG_RESUME_RECORDING
:
2022 case SYS_USB_CONNECTED
:
2023 /* We can safely go to USB mode if no recording
2025 if((!is_recording
|| is_prerecording
) && mpeg_stop_done
)
2027 /* Even if we aren't recording, we still call this
2028 function, to put the MAS in monitoring mode,
2032 /* Tell the USB thread that we are safe */
2033 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2034 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
2036 /* Wait until the USB cable is extracted again */
2037 usb_wait_for_disconnect(&mpeg_queue
);
2042 #endif /* CONFIG_CODEC == MAS3587F */
2045 #endif /* !SIMULATOR */
2047 struct mp3entry
* audio_current_track()
2051 #else /* !SIMULATOR */
2052 if(num_tracks_in_memory())
2053 return &get_trackdata(0)->id3
;
2056 #endif /* !SIMULATOR */
2059 struct mp3entry
* audio_next_track()
2063 #else /* !SIMULATOR */
2064 if(num_tracks_in_memory() > 1)
2065 return &get_trackdata(1)->id3
;
2068 #endif /* !SIMULATOR */
2071 #if CONFIG_CODEC == MAS3587F
2073 void audio_init_playback(void)
2075 init_playback_done
= false;
2076 queue_post(&mpeg_queue
, MPEG_INIT_PLAYBACK
, 0);
2078 while(!init_playback_done
)
2083 /****************************************************************************
2084 * Recording functions
2085 ***************************************************************************/
2086 void audio_init_recording(unsigned int buffer_offset
)
2088 buffer_offset
= buffer_offset
;
2089 init_recording_done
= false;
2090 queue_post(&mpeg_queue
, MPEG_INIT_RECORDING
, 0);
2092 while(!init_recording_done
)
2096 static void init_recording(void)
2108 /* Init the recording variables */
2109 is_recording
= false;
2110 is_prerecording
= false;
2112 mpeg_stop_done
= true;
2116 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2117 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
2119 panicf("mas_ctrl_w: %d", rc
);
2121 /* Stop the current application */
2123 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2126 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2129 /* Perform black magic as described by the data sheet */
2130 if((mas_version_code
& 0x0fff) == 0x0102)
2132 DEBUGF("Performing MAS black magic for B2 version\n");
2133 mas_writereg(0xa3, 0x98);
2134 mas_writereg(0x94, 0xfffff);
2136 mas_writemem(MAS_BANK_D1
, 0, &val
, 1);
2137 mas_writereg(0xa3, 0x90);
2140 /* Enable A/D Converters */
2141 shadow_codec_reg0
= 0xcccd;
2142 mas_codec_writereg(0x0, shadow_codec_reg0
);
2144 /* Copy left channel to right (mono mode) */
2145 mas_codec_writereg(8, 0x8000);
2147 /* ADC scale 0%, DSP scale 100%
2148 We use the DSP output for monitoring, because it works with all
2149 sources including S/PDIF */
2150 mas_codec_writereg(6, 0x0000);
2151 mas_codec_writereg(7, 0x4000);
2154 shadow_soft_mute
= 0;
2155 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2157 #ifdef HAVE_SPDIF_OUT
2158 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2160 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2162 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
2164 /* Set Demand mode, monitoring OFF and validate all settings */
2165 shadow_io_control_main
= 0x125;
2166 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2168 /* Start the encoder application */
2170 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2173 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2174 } while(!(val
& 0x40));
2176 /* We have started the recording application with monitoring OFF.
2177 This is because we want to record at least one frame to fill the DMA
2178 buffer, because the silly MAS will not negate EOD until at least one
2179 DMA transfer has taken place.
2180 Now let's wait for some data to be encoded. */
2183 /* Now set it to Monitoring mode as default, saves power */
2184 shadow_io_control_main
= 0x525;
2185 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2187 /* Wait until the DSP has accepted the settings */
2190 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2194 mpeg_mode
= MPEG_ENCODER
;
2196 DEBUGF("MAS Recording application started\n");
2198 /* At this point, all settings are the reset MAS defaults, next thing is to
2199 call mpeg_set_recording_options(). */
2202 void audio_record(const char *filename
)
2206 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2207 recording_filename
[MAX_PATH
- 1] = 0;
2209 queue_post(&mpeg_queue
, MPEG_RECORD
, 0);
2212 void audio_pause_recording(void)
2214 queue_post(&mpeg_queue
, MPEG_PAUSE_RECORDING
, 0);
2217 void audio_resume_recording(void)
2219 queue_post(&mpeg_queue
, MPEG_RESUME_RECORDING
, 0);
2222 static void prepend_header(void)
2227 /* Make room for header */
2228 audiobuf_read
-= MPEG_RESERVED_HEADER_SPACE
;
2229 if(audiobuf_read
< 0)
2231 /* Clear the bottom half */
2232 memset(audiobuf
, 0, audiobuf_read
+ MPEG_RESERVED_HEADER_SPACE
);
2234 /* And the top half */
2235 audiobuf_read
+= audiobuflen
;
2236 memset(audiobuf
+ audiobuf_read
, 0, audiobuflen
- audiobuf_read
);
2240 memset(audiobuf
+ audiobuf_read
, 0, MPEG_RESERVED_HEADER_SPACE
);
2242 /* Copy the empty ID3 header */
2243 startpos
= audiobuf_read
;
2244 for(i
= 0; i
< sizeof(empty_id3_header
); i
++)
2246 audiobuf
[startpos
++] = empty_id3_header
[i
];
2247 if(startpos
== audiobuflen
)
2252 static void update_header(void)
2255 unsigned long frames
;
2257 if (last_rec_bytes
> 0)
2259 /* Create the Xing header */
2260 fd
= open(delayed_filename
, O_RDWR
);
2262 panicf("rec upd: %d (%s)", fd
, recording_filename
);
2264 frames
= frame_count_end
- frame_count_start
;
2265 /* If the number of recorded frames has reached 0x7ffff,
2266 we can no longer trust it */
2267 if (frame_count_end
== 0x7ffff)
2270 /* saved_header is saved right before stopping the MAS */
2271 framelen
= create_xing_header(fd
, 0, last_rec_bytes
, xing_buffer
,
2272 frames
, last_rec_time
* (1000/HZ
),
2273 saved_header
, NULL
, false);
2275 lseek(fd
, MPEG_RESERVED_HEADER_SPACE
- framelen
, SEEK_SET
);
2276 write(fd
, xing_buffer
, framelen
);
2281 static void start_prerecording(void)
2285 DEBUGF("Starting prerecording\n");
2287 prerecord_index
= 0;
2288 prerecord_count
= 0;
2289 prerecord_timeout
= current_tick
+ HZ
;
2290 memset(prerecord_buffer
, 0, sizeof(prerecord_buffer
));
2293 is_prerecording
= true;
2295 /* Stop monitoring and start the encoder */
2296 shadow_io_control_main
&= ~(1 << 10);
2297 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2298 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2300 /* Wait until the DSP has accepted the settings */
2303 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2306 is_recording
= true;
2307 saving_status
= NOT_SAVING
;
2309 demand_irq_enable(true);
2312 static void start_recording(void)
2318 /* This will make the IRQ handler start recording
2319 for real, i.e send MPEG_SAVE_DATA messages when
2320 the buffer is full */
2321 is_prerecording
= false;
2325 /* If prerecording is off, we need to stop the monitoring
2326 and start the encoder */
2327 shadow_io_control_main
&= ~(1 << 10);
2328 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2329 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2331 /* Wait until the DSP has accepted the settings */
2334 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2338 is_recording
= true;
2339 saving_status
= NOT_SAVING
;
2342 /* Store the current time */
2344 record_start_time
= current_tick
- prerecord_count
* HZ
;
2346 record_start_time
= current_tick
;
2348 pause_start_time
= 0;
2350 demand_irq_enable(true);
2353 static void pause_recording(void)
2355 pause_start_time
= current_tick
;
2357 /* Set the pause bit */
2358 shadow_soft_mute
|= 2;
2359 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2364 static void resume_recording(void)
2368 /* Clear the pause bit */
2369 shadow_soft_mute
&= ~2;
2370 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2372 /* Compensate for the time we have been paused */
2373 if(pause_start_time
)
2376 current_tick
- (pause_start_time
- record_start_time
);
2377 pause_start_time
= 0;
2381 static void stop_recording(void)
2385 /* Let it finish the last frame */
2390 demand_irq_enable(false);
2392 is_recording
= false;
2393 is_prerecording
= false;
2395 last_rec_bytes
= num_rec_bytes
;
2396 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
, &frame_count_end
, 1);
2397 last_rec_time
= current_tick
- record_start_time
;
2399 /* Start monitoring */
2400 shadow_io_control_main
|= (1 << 10);
2401 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2402 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2404 /* Wait until the DSP has accepted the settings */
2407 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2413 void audio_set_recording_options(struct audio_recording_options
*options
)
2417 is_mpeg1
= (options
->rec_frequency
< 3);
2419 rec_version_index
= is_mpeg1
?3:2;
2420 rec_frequency_index
= options
->rec_frequency
% 3;
2422 shadow_encoder_control
= (options
->rec_quality
<< 17) |
2423 (rec_frequency_index
<< 10) |
2424 ((is_mpeg1
?1:0) << 9) |
2425 (((options
->rec_channels
* 2 + 1) & 3) << 6) |
2426 (1 << 5) /* MS-stereo */ |
2427 (1 << 2) /* Is an original */;
2428 mas_writemem(MAS_BANK_D0
, MAS_D0_ENCODER_CONTROL
, &shadow_encoder_control
,1);
2430 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control
);
2432 #if CONFIG_TUNER & S1A0903X01
2433 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2434 interference with the Samsung tuner. */
2435 if (rec_frequency_index
)
2436 mas_store_pllfreq(24576000);
2438 mas_store_pllfreq(22579000);
2441 shadow_soft_mute
= options
->rec_editable
?4:0;
2442 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
,1);
2444 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute
);
2446 shadow_io_control_main
= ((1 << 10) | /* Monitoring ON */
2447 ((options
->rec_source
< 2)?1:2) << 8) | /* Input select */
2448 (1 << 5) | /* SDO strobe invert */
2449 ((is_mpeg1
?0:1) << 3) |
2450 (1 << 2) | /* Inverted SIBC clock signal */
2452 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
,1);
2454 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2456 if(options
->rec_source
== AUDIO_SRC_MIC
)
2458 /* Copy left channel to right (mono mode) */
2459 mas_codec_writereg(8, 0x8000);
2463 /* Stereo input mode */
2464 mas_codec_writereg(8, 0);
2467 prerecording_max_seconds
= options
->rec_prerecord_time
;
2468 if(prerecording_max_seconds
)
2470 prerecording
= true;
2471 start_prerecording();
2475 prerecording
= false;
2476 is_prerecording
= false;
2477 is_recording
= false;
2481 /* If use_mic is true, the left gain is used */
2482 void audio_set_recording_gain(int left
, int right
, int type
)
2484 /* Enable both left and right A/D */
2485 shadow_codec_reg0
= (left
<< 12) |
2488 (type
==AUDIO_GAIN_MIC
?0x0008:0) | /* Connect left A/D to mic */
2490 mas_codec_writereg(0x0, shadow_codec_reg0
);
2493 /* try to make some kind of beep, also in recording mode */
2494 void audio_beep(int duration
)
2496 long starttick
= current_tick
;
2498 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2499 * While this is still audible even without an external signal,
2500 * it doesn't affect the (pre-)recording. */
2501 mas_codec_writereg(0, shadow_codec_reg0
^ 1);
2502 mas_codec_writereg(0, shadow_codec_reg0
);
2505 while (current_tick
- starttick
< duration
);
2508 void audio_new_file(const char *filename
)
2512 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2513 recording_filename
[MAX_PATH
- 1] = 0;
2515 queue_post(&mpeg_queue
, MPEG_NEW_FILE
, 0);
2518 unsigned long audio_recorded_time(void)
2521 return prerecord_count
* HZ
;
2526 return pause_start_time
- record_start_time
;
2528 return current_tick
- record_start_time
;
2534 unsigned long audio_num_recorded_bytes(void)
2543 index
= prerecord_index
- prerecord_count
;
2545 index
+= prerecording_max_seconds
;
2547 num_bytes
= audiobuf_write
- prerecord_buffer
[index
].mempos
;
2549 num_bytes
+= audiobuflen
;
2554 return num_rec_bytes
;
2560 #else /* SIMULATOR */
2562 /* dummies coming up */
2564 void audio_init_playback(void)
2568 unsigned long audio_recorded_time(void)
2573 void audio_beep(int duration
)
2578 void audio_pause_recording(void)
2582 void audio_resume_recording(void)
2586 unsigned long audio_num_recorded_bytes(void)
2591 void audio_record(const char *filename
)
2596 void audio_new_file(const char *filename
)
2602 void audio_set_recording_gain(int left
, int right
, int type
)
2609 void audio_init_recording(unsigned int buffer_offset
)
2612 (void)buffer_offset
;
2614 void audio_set_recording_options(struct audio_recording_options
*options
)
2619 #endif /* SIMULATOR */
2620 #endif /* CONFIG_CODEC == MAS3587F */
2622 void audio_play(long offset
)
2631 trackname
= playlist_peek( steps
);
2634 if(mp3info(&taginfo
, trackname
)) {
2635 /* bad mp3, move on */
2636 if(++steps
> playlist_amount())
2640 #ifdef HAVE_MPEG_PLAY
2641 real_mpeg_play(trackname
);
2643 playlist_next(steps
);
2644 taginfo
.offset
= offset
;
2645 set_elapsed(&taginfo
);
2650 #else /* !SIMULATOR */
2653 queue_post(&mpeg_queue
, MPEG_PLAY
, offset
);
2654 #endif /* !SIMULATOR */
2659 void audio_stop(void)
2664 struct trackdata
*track
= get_trackdata(0);
2665 prev_track_elapsed
= track
->id3
.elapsed
;
2667 mpeg_stop_done
= false;
2668 queue_post(&mpeg_queue
, MPEG_STOP
, 0);
2669 while(!mpeg_stop_done
)
2671 #else /* SIMULATOR */
2675 #endif /* SIMULATOR */
2679 void audio_stop_recording(void)
2684 void audio_pause(void)
2687 queue_post(&mpeg_queue
, MPEG_PAUSE
, 0);
2688 #else /* SIMULATOR */
2692 #endif /* SIMULATOR */
2695 void audio_resume(void)
2698 queue_post(&mpeg_queue
, MPEG_RESUME
, 0);
2699 #else /* SIMULATOR */
2703 #endif /* SIMULATOR */
2706 void audio_next(void)
2709 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2710 queue_post(&mpeg_queue
, MPEG_NEXT
, 0);
2711 #else /* SIMULATOR */
2717 file
= playlist_peek(steps
);
2720 if(mp3info(&taginfo
, file
)) {
2721 if(++steps
> playlist_amount())
2725 index
= playlist_next(steps
);
2726 taginfo
.index
= index
;
2727 current_track_counter
++;
2732 #endif /* SIMULATOR */
2735 void audio_prev(void)
2738 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2739 queue_post(&mpeg_queue
, MPEG_PREV
, 0);
2740 #else /* SIMULATOR */
2746 file
= playlist_peek(steps
);
2749 if(mp3info(&taginfo
, file
)) {
2753 index
= playlist_next(steps
);
2754 taginfo
.index
= index
;
2755 current_track_counter
++;
2760 #endif /* SIMULATOR */
2763 void audio_ff_rewind(long newtime
)
2766 queue_post(&mpeg_queue
, MPEG_FF_REWIND
, newtime
);
2767 #else /* SIMULATOR */
2769 #endif /* SIMULATOR */
2772 void audio_flush_and_reload_tracks(void)
2775 queue_post(&mpeg_queue
, MPEG_FLUSH_RELOAD
, 0);
2776 #endif /* !SIMULATOR*/
2779 int audio_status(void)
2784 ret
|= AUDIO_STATUS_PLAY
;
2787 ret
|= AUDIO_STATUS_PAUSE
;
2789 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2790 if(is_recording
&& !is_prerecording
)
2791 ret
|= AUDIO_STATUS_RECORD
;
2794 ret
|= AUDIO_STATUS_PRERECORD
;
2795 #endif /* CONFIG_CODEC == MAS3587F */
2798 ret
|= AUDIO_STATUS_ERROR
;
2803 unsigned int audio_error(void)
2808 void audio_error_clear(void)
2814 static void mpeg_thread(void)
2816 struct mp3entry
* id3
;
2819 id3
= audio_current_track();
2825 if (id3
->elapsed
>=id3
->length
)
2831 #endif /* SIMULATOR */
2833 void audio_init(void)
2838 audiobuflen
= audiobufend
- audiobuf
;
2839 queue_init(&mpeg_queue
, true);
2840 #endif /* !SIMULATOR */
2841 create_thread(mpeg_thread
, mpeg_stack
,
2842 sizeof(mpeg_stack
), 0, mpeg_thread_name
2843 IF_PRIO(, PRIORITY_SYSTEM
)
2846 memset(trackdata
, 0, sizeof(trackdata
));
2848 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2849 if (HW_MASK
& PR_ACTIVE_HIGH
)
2850 and_b(~0x08, &PADRH
);
2853 #endif /* CONFIG_CODEC == MAS3587F */
2859 #endif /* !SIMULATOR */
2863 #endif /* CONFIG_CODEC != SWCODEC */