1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 #if CONFIG_CODEC != SWCODEC
37 #include "mp3_playback.h"
49 #endif /* !SIMULATOR */
50 #ifdef HAVE_LCD_BITMAP
55 extern unsigned long mas_version_code
;
58 #if CONFIG_CODEC == MAS3587F
59 extern enum /* from mp3_playback.c */
64 #endif /* CONFIG_CODEC == MAS3587F */
66 extern char* playlist_peek(int steps
);
67 extern bool playlist_check(int steps
);
68 extern int playlist_next(int steps
);
69 extern int playlist_amount(void);
70 extern int playlist_update_resume_info(const struct mp3entry
* id3
);
78 #define MPEG_FF_REWIND 7
79 #define MPEG_FLUSH_RELOAD 8
81 #define MPEG_INIT_RECORDING 10
82 #define MPEG_INIT_PLAYBACK 11
83 #define MPEG_NEW_FILE 12
84 #define MPEG_PAUSE_RECORDING 13
85 #define MPEG_RESUME_RECORDING 14
86 #define MPEG_NEED_DATA 100
87 #define MPEG_TRACK_CHANGE 101
88 #define MPEG_SAVE_DATA 102
89 #define MPEG_STOP_DONE 103
90 #define MPEG_PRERECORDING_TICK 104
92 /* indicator for MPEG_NEED_DATA */
93 #define GENERATE_UNBUFFER_EVENTS 1
95 /* list of tracks in memory */
96 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
97 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
103 int load_ahead_index
;
106 static struct trackdata trackdata
[MAX_TRACK_ENTRIES
];
108 static unsigned int current_track_counter
= 0;
109 static unsigned int last_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
= ata_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 #ifndef HAVE_FLASH_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
;
855 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES
)
857 DEBUGF("Tag memory is full\n");
861 track
= &trackdata
[track_write_idx
];
863 /* grab id3 tag of new file and
864 remember where in memory it starts */
865 if(mp3info(&track
->id3
, filename
))
870 track
->mempos
= audiobuf_write
;
871 track
->id3
.elapsed
= 0;
872 #ifdef HAVE_LCD_BITMAP
873 if (track
->id3
.title
)
874 lcd_getstringsize(track
->id3
.title
, NULL
, NULL
);
875 if (track
->id3
.artist
)
876 lcd_getstringsize(track
->id3
.artist
, NULL
, NULL
);
877 if (track
->id3
.album
)
878 lcd_getstringsize(track
->id3
.album
, NULL
, NULL
);
880 if (cuesheet_callback
)
881 if (cuesheet_callback(filename
))
882 track
->id3
.cuesheet_type
= 1;
884 track_write_idx
= (track_write_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
889 static int new_file(int steps
)
891 int max_steps
= playlist_amount();
894 struct trackdata
*track
;
896 /* Find out how many steps to advance. The load_ahead_index field tells
897 us how many playlist entries it had to skip to get to a valid one.
898 We add those together to find out where to start. */
899 if(steps
> 0 && num_tracks_in_memory() > 1)
901 /* Begin with the song after the currently playing one */
903 while((track
= get_trackdata(i
++)))
905 start
+= track
->load_ahead_index
;
912 trackname
= playlist_peek( start
+ steps
);
916 DEBUGF("Loading %s\n", trackname
);
918 mpeg_file
= open(trackname
, O_RDONLY
);
920 DEBUGF("Couldn't open file: %s\n",trackname
);
928 struct trackdata
*track
= add_track_to_tag_list(trackname
);
942 /* skip past id3v2 tag */
944 track
->id3
.first_frame_offset
,
946 track
->id3
.index
= steps
;
947 track
->load_ahead_index
= steps
;
948 track
->id3
.offset
= 0;
951 /* Average bitrate * 1.5 */
952 recalculate_watermark(
953 (track
->id3
.bitrate
* 3) / 2);
955 recalculate_watermark(
961 /* Bail out if no file could be opened */
962 if(abs(steps
) > max_steps
)
964 } while ( mpeg_file
< 0 );
969 static void stop_playing(void)
971 struct trackdata
*track
;
973 /* Stop the current stream */
978 track
= get_trackdata(0);
980 prev_track_elapsed
= track
->id3
.elapsed
;
986 generate_unbuffer_events();
990 static void end_current_track(void) {
991 struct trackdata
*track
;
993 play_pending
= false;
995 mp3_play_pause(false);
997 track
= get_trackdata(0);
999 prev_track_elapsed
= track
->id3
.elapsed
;
1003 generate_unbuffer_events();
1009 /* Is this a really the end of playback or is a new playlist starting */
1010 static void check_playlist_end(int direction
)
1012 /* Use the largest possible step size to account for skipped tracks */
1013 int steps
= playlist_amount();
1018 if (playlist_next(steps
) < 0)
1022 static void update_playlist(void)
1024 if (num_tracks_in_memory() > 0)
1026 struct trackdata
*track
= get_trackdata(0);
1027 track
->id3
.index
= playlist_next(track
->id3
.index
);
1031 /* End of playlist? */
1032 check_playlist_end(1);
1035 playlist_update_resume_info(audio_current_track());
1038 static void track_change(void)
1040 DEBUGF("Track change\n");
1042 struct trackdata
*track
= get_trackdata(0);
1043 prev_track_elapsed
= track
->id3
.elapsed
;
1045 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1048 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1050 if (num_tracks_in_memory() > 0)
1052 remove_current_tag();
1053 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1057 current_track_counter
++;
1060 unsigned long audio_prev_elapsed(void)
1062 return prev_track_elapsed
;
1066 void hexdump(const unsigned char *buf
, int len
)
1070 for(i
= 0;i
< len
;i
++)
1072 if(i
&& (i
& 15) == 0)
1076 DEBUGF("%02x ", buf
[i
]);
1082 static void start_playback_if_ready(void)
1086 playable_space
= audiobuf_swapwrite
- audiobuf_read
;
1087 if(playable_space
< 0)
1088 playable_space
+= audiobuflen
;
1090 /* See if we have started playing yet. If not, do it. */
1091 if(play_pending
|| dma_underrun
)
1093 /* If the filling has stopped, and we still haven't reached
1094 the watermark, the file must be smaller than the
1095 watermark. We must still play it. */
1096 if((playable_space
>= MPEG_PLAY_PENDING_THRESHOLD
) ||
1097 !filling
|| dma_underrun
)
1100 if (play_pending
) /* don't do this when recovering from DMA underrun */
1102 generate_postbuffer_events(); /* signal first track as buffered */
1103 if (play_pending_track_change
)
1105 play_pending_track_change
= false;
1106 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1108 play_pending
= false;
1112 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1113 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1114 dma_underrun
= false;
1118 last_dma_tick
= current_tick
;
1119 mp3_play_pause(true);
1122 /* Tell ourselves that we need more data */
1123 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1128 static bool swap_one_chunk(void)
1130 int free_space_left
;
1133 free_space_left
= get_unswapped_space();
1135 if(free_space_left
== 0 && !play_pending
)
1138 /* Swap in larger chunks when the user is waiting for the playback
1139 to start, or when there is dangerously little playable data left */
1141 amount_to_swap
= MIN(MPEG_PLAY_PENDING_SWAPSIZE
, free_space_left
);
1144 if(get_playable_space() < low_watermark
)
1145 amount_to_swap
= MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE
,
1148 amount_to_swap
= MIN(MPEG_SWAP_CHUNKSIZE
, free_space_left
);
1151 if(audiobuf_write
< audiobuf_swapwrite
)
1152 amount_to_swap
= MIN(audiobuflen
- audiobuf_swapwrite
,
1155 amount_to_swap
= MIN(audiobuf_write
- audiobuf_swapwrite
,
1158 bitswap(audiobuf
+ audiobuf_swapwrite
, amount_to_swap
);
1160 audiobuf_swapwrite
+= amount_to_swap
;
1161 if(audiobuf_swapwrite
>= audiobuflen
)
1163 audiobuf_swapwrite
= 0;
1169 static void mpeg_thread(void)
1171 static int pause_tick
= 0;
1172 static unsigned int pause_track
= 0;
1173 struct queue_event ev
;
1175 int free_space_left
;
1176 int unplayed_space_left
;
1180 #if CONFIG_CODEC == MAS3587F
1182 int save_endpos
= 0;
1186 #endif /* CONFIG_CODEC == MAS3587F */
1189 play_pending
= false;
1195 #if CONFIG_CODEC == MAS3587F
1196 if(mpeg_mode
== MPEG_DECODER
)
1198 #endif /* CONFIG_CODEC == MAS3587F */
1201 /* Swap if necessary, and don't block on the queue_wait() */
1202 if(swap_one_chunk())
1204 queue_wait_w_tmo(&mpeg_queue
, &ev
, 0);
1208 /* periodically update resume info */
1209 queue_wait_w_tmo(&mpeg_queue
, &ev
, HZ
/2);
1213 DEBUGF("S R:%x W:%x SW:%x\n",
1214 audiobuf_read
, audiobuf_write
, audiobuf_swapwrite
);
1215 queue_wait(&mpeg_queue
, &ev
);
1218 start_playback_if_ready();
1223 DEBUGF("MPEG_PLAY\n");
1226 /* Silence the A/D input, it may be on because the radio
1228 mas_codec_writereg(6, 0x0000);
1229 #endif /* CONFIG_TUNER */
1231 /* Stop the current stream */
1233 end_current_track();
1235 if ( new_file(0) == -1 )
1242 start_offset
= (int)ev
.data
;
1244 /* mid-song resume? */
1246 struct mp3entry
* id3
= &get_trackdata(0)->id3
;
1247 lseek(mpeg_file
, start_offset
, SEEK_SET
);
1248 id3
->offset
= start_offset
;
1252 /* skip past id3v2 tag */
1254 get_trackdata(0)->id3
.first_frame_offset
,
1259 /* Make it read more data */
1261 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1263 /* Tell the file loading code that we want to start playing
1264 as soon as we have some data */
1265 play_pending
= true;
1266 play_pending_track_change
= true;
1269 current_track_counter
++;
1273 DEBUGF("MPEG_STOP\n");
1278 playlist_update_resume_info(audio_current_track());
1281 mpeg_stop_done
= true;
1285 DEBUGF("MPEG_PAUSE\n");
1286 /* Stop the current stream */
1288 playlist_update_resume_info(audio_current_track());
1291 pause_tick
= current_tick
;
1292 pause_track
= current_track_counter
;
1293 mp3_play_pause(false);
1297 DEBUGF("MPEG_RESUME\n");
1298 /* Continue the current stream */
1303 if ( current_track_counter
== pause_track
)
1304 last_dma_tick
+= current_tick
- pause_tick
;
1306 last_dma_tick
= current_tick
;
1308 mp3_play_pause(true);
1313 DEBUGF("MPEG_NEXT\n");
1314 /* is next track in ram? */
1315 if ( num_tracks_in_memory() > 1 ) {
1316 int unplayed_space_left
, unswapped_space_left
;
1318 /* stop the current stream */
1319 play_pending
= false;
1321 mp3_play_pause(false);
1324 audiobuf_read
= get_trackdata(0)->mempos
;
1325 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1326 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1327 dma_underrun
= false;
1328 last_dma_tick
= current_tick
;
1330 unplayed_space_left
= get_unplayed_space();
1331 unswapped_space_left
= get_unswapped_space();
1333 /* should we start reading more data? */
1334 if(!filling
&& (unplayed_space_left
< low_watermark
)) {
1336 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1337 play_pending
= true;
1338 } else if(unswapped_space_left
&&
1339 unswapped_space_left
> unplayed_space_left
) {
1340 /* Stop swapping the data from the previous file */
1341 audiobuf_swapwrite
= audiobuf_read
;
1342 play_pending
= true;
1346 mp3_play_pause(true);
1350 if (!playlist_check(1))
1353 /* stop the current stream */
1354 end_current_track();
1356 if (new_file(1) < 0) {
1357 DEBUGF("No more files to play\n");
1360 check_playlist_end(1);
1361 current_track_counter
++;
1363 /* Make it read more data */
1365 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1367 /* Tell the file loading code that we want
1368 to start playing as soon as we have some data */
1369 play_pending
= true;
1370 play_pending_track_change
= true;
1373 current_track_counter
++;
1379 DEBUGF("MPEG_PREV\n");
1381 if (!playlist_check(-1))
1384 /* stop the current stream */
1385 end_current_track();
1387 /* Open the next file */
1388 if (new_file(-1) < 0) {
1389 DEBUGF("No more files to play\n");
1392 check_playlist_end(-1);
1393 current_track_counter
++;
1395 /* Make it read more data */
1397 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1399 /* Tell the file loading code that we want to
1400 start playing as soon as we have some data */
1401 play_pending
= true;
1402 play_pending_track_change
= true;
1405 current_track_counter
++;
1410 case MPEG_FF_REWIND
: {
1411 struct mp3entry
*id3
= audio_current_track();
1412 unsigned int oldtime
= id3
->elapsed
;
1413 unsigned int newtime
= (unsigned int)ev
.data
;
1414 int curpos
, newpos
, diffpos
;
1415 DEBUGF("MPEG_FF_REWIND\n");
1417 id3
->elapsed
= newtime
;
1419 newpos
= audio_get_file_pos();
1422 id3
->elapsed
= oldtime
;
1427 curpos
= lseek(mpeg_file
, 0, SEEK_CUR
);
1429 curpos
= id3
->filesize
;
1431 if (num_tracks_in_memory() > 1)
1433 /* We have started loading other tracks that need to be
1435 struct trackdata
*track
;
1438 while((track
= get_trackdata(i
++)))
1440 curpos
+= track
->id3
.filesize
;
1444 diffpos
= curpos
- newpos
;
1446 if(!filling
&& diffpos
>= 0 && diffpos
< audiobuflen
)
1448 int unplayed_space_left
, unswapped_space_left
;
1450 /* We are changing to a position that's already in
1451 memory, so we just move the DMA read pointer. */
1452 audiobuf_read
= audiobuf_write
- diffpos
;
1453 if (audiobuf_read
< 0)
1455 audiobuf_read
+= audiobuflen
;
1458 unplayed_space_left
= get_unplayed_space();
1459 unswapped_space_left
= get_unswapped_space();
1461 /* If unswapped_space_left is larger than
1462 unplayed_space_left, it means that the swapwrite pointer
1463 hasn't yet advanced up to the new location of the read
1464 pointer. We just move it, there is no need to swap
1465 data that won't be played anyway. */
1467 if (unswapped_space_left
> unplayed_space_left
)
1469 DEBUGF("Moved swapwrite\n");
1470 audiobuf_swapwrite
= audiobuf_read
;
1471 play_pending
= true;
1474 if (mpeg_file
>=0 && unplayed_space_left
< low_watermark
)
1476 /* We need to load more data before starting */
1478 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1479 play_pending
= true;
1483 /* resume will start at new position */
1484 last_dma_chunk_size
=
1485 MIN(0x2000, get_unplayed_space_current_song());
1486 mp3_play_data(audiobuf
+ audiobuf_read
,
1487 last_dma_chunk_size
, transfer_end
);
1488 dma_underrun
= false;
1493 /* Move to the new position in the file and start
1497 if (num_tracks_in_memory() > 1)
1499 /* We have to reload the current track */
1501 remove_all_non_current_tags();
1502 generate_unbuffer_events();
1508 mpeg_file
= open(id3
->path
, O_RDONLY
);
1511 id3
->elapsed
= oldtime
;
1516 if(-1 == lseek(mpeg_file
, newpos
, SEEK_SET
))
1518 id3
->elapsed
= oldtime
;
1523 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1525 /* Tell the file loading code that we want to start playing
1526 as soon as we have some data */
1527 play_pending
= true;
1530 id3
->offset
= newpos
;
1535 case MPEG_FLUSH_RELOAD
: {
1536 int numtracks
= num_tracks_in_memory();
1537 bool reload_track
= false;
1541 /* Reset the buffer */
1542 audiobuf_write
= get_trackdata(1)->mempos
;
1544 /* Reset swapwrite unless we're still swapping current
1546 if (get_unplayed_space() <= get_playable_space())
1547 audiobuf_swapwrite
= audiobuf_write
;
1550 remove_all_non_current_tags();
1551 generate_unbuffer_events();
1553 reload_track
= true;
1555 else if (numtracks
== 1 && mpeg_file
< 0)
1557 reload_track
= true;
1560 if(reload_track
&& new_file(1) >= 0)
1562 /* Tell ourselves that we want more data */
1564 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1570 case MPEG_NEED_DATA
:
1571 free_space_left
= audiobuf_read
- audiobuf_write
;
1573 /* We interpret 0 as "empty buffer" */
1574 if(free_space_left
<= 0)
1575 free_space_left
+= audiobuflen
;
1577 unplayed_space_left
= audiobuflen
- free_space_left
;
1579 /* Make sure that we don't fill the entire buffer */
1580 free_space_left
-= MPEG_HIGH_WATER
;
1582 if (ev
.data
== GENERATE_UNBUFFER_EVENTS
)
1583 generate_unbuffer_events();
1585 /* do we have any more buffer space to fill? */
1586 if(free_space_left
<= 0)
1590 generate_postbuffer_events();
1595 /* Read small chunks while we are below the low water mark */
1596 if(unplayed_space_left
< low_watermark
)
1597 amount_to_read
= MIN(MPEG_LOW_WATER_CHUNKSIZE
,
1600 amount_to_read
= free_space_left
;
1602 /* Don't read more than until the end of the buffer */
1603 amount_to_read
= MIN(audiobuflen
- audiobuf_write
,
1605 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1606 amount_to_read
= MIN(0x40000, amount_to_read
);
1608 amount_to_read
= MIN(0x100000, amount_to_read
);
1611 /* Read as much mpeg data as we can fit in the buffer */
1616 len
= read(mpeg_file
, audiobuf
+ audiobuf_write
,
1621 DEBUGF("time: %d\n", t2
- t1
);
1622 DEBUGF("R: %x\n", len
);
1624 /* Now make sure that we don't feed the MAS with ID3V1
1626 if (len
< amount_to_read
)
1629 static const unsigned char tag
[] = "TAG";
1631 int tagptr
= audiobuf_write
+ len
- 128;
1633 /* Really rare case: entire potential tag wasn't
1634 read in this call AND audiobuf_write < 128 */
1636 tagptr
+= audiobuflen
;
1638 for(i
= 0;i
< 3;i
++)
1640 if(tagptr
>= audiobuflen
)
1641 tagptr
-= audiobuflen
;
1643 if(audiobuf
[tagptr
] != tag
[i
])
1654 /* Skip id3v1 tag */
1655 DEBUGF("Skipping ID3v1 tag\n");
1658 /* In the very rare case when the entire tag
1659 wasn't read in this read() len will be < 0.
1660 Take care of this when changing the write
1665 audiobuf_write
+= len
;
1667 if (audiobuf_write
< 0)
1668 audiobuf_write
+= audiobuflen
;
1670 if(audiobuf_write
>= audiobuflen
)
1676 /* Tell ourselves that we want more data */
1677 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1683 DEBUGF("MPEG read error\n");
1691 /* No more data to play */
1692 DEBUGF("No more files to play\n");
1697 /* Tell ourselves that we want more data */
1698 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1704 case MPEG_TRACK_CHANGE
:
1709 case SYS_USB_CONNECTED
:
1714 /* Tell the USB thread that we are safe */
1715 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1716 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1718 /* Wait until the USB cable is extracted again */
1719 usb_wait_for_disconnect(&mpeg_queue
);
1721 #endif /* !USB_NONE */
1723 #if CONFIG_CODEC == MAS3587F
1724 case MPEG_INIT_RECORDING
:
1726 init_recording_done
= true;
1728 #endif /* CONFIG_CODEC == MAS3587F */
1732 playlist_update_resume_info(audio_current_track());
1735 #if CONFIG_CODEC == MAS3587F
1739 queue_wait(&mpeg_queue
, &ev
);
1743 if (is_prerecording
)
1747 /* Go back prerecord_count seconds in the buffer */
1748 startpos
= prerecord_index
- prerecord_count
;
1750 startpos
+= prerecording_max_seconds
;
1752 /* Read the position data from the prerecord buffer */
1753 frame_count_start
= prerecord_buffer
[startpos
].framecount
;
1754 startpos
= prerecord_buffer
[startpos
].mempos
;
1756 DEBUGF("Start looking at address %x (%x)\n",
1757 audiobuf
+startpos
, startpos
);
1759 saved_header
= mpeg_get_last_header();
1761 mem_find_next_frame(startpos
, &offset
, 1800,
1764 audiobuf_read
= startpos
+ offset
;
1765 if(audiobuf_read
>= audiobuflen
)
1766 audiobuf_read
-= audiobuflen
;
1768 DEBUGF("New audiobuf_read address: %x (%x)\n",
1769 audiobuf
+audiobuf_read
, audiobuf_read
);
1771 level
= disable_irq_save();
1772 num_rec_bytes
= get_unsaved_space();
1777 frame_count_start
= 0;
1779 audiobuf_read
= MPEG_RESERVED_HEADER_SPACE
;
1780 audiobuf_write
= MPEG_RESERVED_HEADER_SPACE
;
1784 DEBUGF("Recording...\n");
1787 /* Wait until at least one frame is encoded and get the
1788 frame header, for later use by the Xing header
1791 saved_header
= mpeg_get_last_header();
1793 /* delayed until buffer is saved, don't open yet */
1794 strcpy(delayed_filename
, recording_filename
);
1800 DEBUGF("MPEG_STOP\n");
1804 /* Save the remaining data in the buffer */
1805 save_endpos
= audiobuf_write
;
1806 saving_status
= STOP_RECORDING
;
1807 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1810 case MPEG_STOP_DONE
:
1811 DEBUGF("MPEG_STOP_DONE\n");
1821 for(i
= 0;i
< 512;i
++)
1823 DEBUGF("%d - %d us (%d bytes)\n",
1825 (timing_info
[i
*2+1] & 0xffff) *
1827 timing_info
[i
*2+1] >> 16);
1834 start_prerecording();
1836 mpeg_stop_done
= true;
1840 /* Bail out when a more important save is happening */
1841 if (saving_status
> NEW_FILE
)
1844 /* Make sure we have at least one complete frame
1845 in the buffer. If we haven't recorded a single
1846 frame within 200ms, the MAS is probably not recording
1847 anything, and we bail out. */
1848 amount_to_save
= get_unsaved_space();
1849 if (amount_to_save
< 1800)
1852 amount_to_save
= get_unsaved_space();
1855 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1856 &frame_count_end
, 1);
1858 last_rec_time
= current_tick
- record_start_time
;
1859 record_start_time
= current_tick
;
1861 pause_start_time
= record_start_time
;
1863 /* capture all values at one point */
1864 level
= disable_irq_save();
1865 save_endpos
= audiobuf_write
;
1866 last_rec_bytes
= num_rec_bytes
;
1870 if (amount_to_save
>= 1800)
1872 /* Now find a frame boundary to split at */
1873 save_endpos
-= 1800;
1874 if (save_endpos
< 0)
1875 save_endpos
+= audiobuflen
;
1877 rc
= mem_find_next_frame(save_endpos
, &offset
, 1800,
1879 if (!rc
) /* No header found, save whole buffer */
1882 save_endpos
+= offset
;
1883 if (save_endpos
>= audiobuflen
)
1884 save_endpos
-= audiobuflen
;
1886 last_rec_bytes
+= offset
- 1800;
1887 level
= disable_irq_save();
1888 num_rec_bytes
+= 1800 - offset
;
1892 saving_status
= NEW_FILE
;
1893 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1896 case MPEG_SAVE_DATA
:
1897 if (saving_status
== BUFFER_FULL
)
1898 save_endpos
= audiobuf_write
;
1900 if (mpeg_file
< 0) /* delayed file open */
1902 mpeg_file
= open(delayed_filename
, O_WRONLY
|O_CREAT
);
1905 panicf("recfile: %d", mpeg_file
);
1908 amount_to_save
= save_endpos
- audiobuf_read
;
1909 if (amount_to_save
< 0)
1910 amount_to_save
+= audiobuflen
;
1912 amount_to_save
= MIN(amount_to_save
,
1913 audiobuflen
- audiobuf_read
);
1914 #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */
1915 amount_to_save
= MIN(0x40000, amount_to_save
);
1917 amount_to_save
= MIN(0x100000, amount_to_save
);
1919 rc
= write(mpeg_file
, audiobuf
+ audiobuf_read
,
1923 if (errno
== ENOSPC
)
1925 mpeg_errno
= AUDIOERR_DISK_FULL
;
1927 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1928 /* will close the file */
1932 panicf("rec wrt: %d", rc
);
1935 audiobuf_read
+= amount_to_save
;
1936 if (audiobuf_read
>= audiobuflen
)
1939 if (audiobuf_read
== save_endpos
) /* all saved */
1941 switch (saving_status
)
1944 rc
= fsync(mpeg_file
);
1946 panicf("rec fls: %d", rc
);
1951 /* Close the current file */
1952 rc
= close(mpeg_file
);
1954 panicf("rec cls: %d", rc
);
1959 /* copy new filename */
1960 strcpy(delayed_filename
, recording_filename
);
1962 frame_count_start
= frame_count_end
;
1965 case STOP_RECORDING
:
1966 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1967 /* will close the file */
1973 saving_status
= NOT_SAVING
;
1975 else /* tell ourselves to save the next chunk */
1976 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1980 case MPEG_PRERECORDING_TICK
:
1981 if(!is_prerecording
)
1984 /* Store the write pointer every second */
1985 prerecord_buffer
[prerecord_index
].mempos
= audiobuf_write
;
1986 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1987 &prerecord_buffer
[prerecord_index
].framecount
, 1);
1989 /* Wrap if necessary */
1990 if(++prerecord_index
== prerecording_max_seconds
)
1991 prerecord_index
= 0;
1993 /* Update the number of seconds recorded */
1994 if(prerecord_count
< prerecording_max_seconds
)
1998 case MPEG_INIT_PLAYBACK
:
1999 /* Stop the prerecording */
2003 init_playback_done
= true;
2006 case MPEG_PAUSE_RECORDING
:
2010 case MPEG_RESUME_RECORDING
:
2014 case SYS_USB_CONNECTED
:
2015 /* We can safely go to USB mode if no recording
2017 if((!is_recording
|| is_prerecording
) && mpeg_stop_done
)
2019 /* Even if we aren't recording, we still call this
2020 function, to put the MAS in monitoring mode,
2024 /* Tell the USB thread that we are safe */
2025 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2026 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
2028 /* Wait until the USB cable is extracted again */
2029 usb_wait_for_disconnect(&mpeg_queue
);
2034 #endif /* CONFIG_CODEC == MAS3587F */
2037 #endif /* !SIMULATOR */
2039 struct mp3entry
* audio_current_track()
2043 #else /* !SIMULATOR */
2044 if(num_tracks_in_memory())
2045 return &get_trackdata(0)->id3
;
2048 #endif /* !SIMULATOR */
2051 struct mp3entry
* audio_next_track()
2055 #else /* !SIMULATOR */
2056 if(num_tracks_in_memory() > 1)
2057 return &get_trackdata(1)->id3
;
2060 #endif /* !SIMULATOR */
2063 bool audio_has_changed_track(void)
2065 if(last_track_counter
!= current_track_counter
)
2067 last_track_counter
= current_track_counter
;
2073 #if CONFIG_CODEC == MAS3587F
2075 void audio_init_playback(void)
2077 init_playback_done
= false;
2078 queue_post(&mpeg_queue
, MPEG_INIT_PLAYBACK
, 0);
2080 while(!init_playback_done
)
2085 /****************************************************************************
2086 * Recording functions
2087 ***************************************************************************/
2088 void audio_init_recording(unsigned int buffer_offset
)
2090 buffer_offset
= buffer_offset
;
2091 init_recording_done
= false;
2092 queue_post(&mpeg_queue
, MPEG_INIT_RECORDING
, 0);
2094 while(!init_recording_done
)
2098 static void init_recording(void)
2110 /* Init the recording variables */
2111 is_recording
= false;
2112 is_prerecording
= false;
2114 mpeg_stop_done
= true;
2118 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2119 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
2121 panicf("mas_ctrl_w: %d", rc
);
2123 /* Stop the current application */
2125 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2128 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2131 /* Perform black magic as described by the data sheet */
2132 if((mas_version_code
& 0x0fff) == 0x0102)
2134 DEBUGF("Performing MAS black magic for B2 version\n");
2135 mas_writereg(0xa3, 0x98);
2136 mas_writereg(0x94, 0xfffff);
2138 mas_writemem(MAS_BANK_D1
, 0, &val
, 1);
2139 mas_writereg(0xa3, 0x90);
2142 /* Enable A/D Converters */
2143 shadow_codec_reg0
= 0xcccd;
2144 mas_codec_writereg(0x0, shadow_codec_reg0
);
2146 /* Copy left channel to right (mono mode) */
2147 mas_codec_writereg(8, 0x8000);
2149 /* ADC scale 0%, DSP scale 100%
2150 We use the DSP output for monitoring, because it works with all
2151 sources including S/PDIF */
2152 mas_codec_writereg(6, 0x0000);
2153 mas_codec_writereg(7, 0x4000);
2156 shadow_soft_mute
= 0;
2157 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2159 #ifdef HAVE_SPDIF_OUT
2160 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2162 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2164 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
2166 /* Set Demand mode, monitoring OFF and validate all settings */
2167 shadow_io_control_main
= 0x125;
2168 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2170 /* Start the encoder application */
2172 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2175 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2176 } while(!(val
& 0x40));
2178 /* We have started the recording application with monitoring OFF.
2179 This is because we want to record at least one frame to fill the DMA
2180 buffer, because the silly MAS will not negate EOD until at least one
2181 DMA transfer has taken place.
2182 Now let's wait for some data to be encoded. */
2185 /* Now set it to Monitoring mode as default, saves power */
2186 shadow_io_control_main
= 0x525;
2187 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2189 /* Wait until the DSP has accepted the settings */
2192 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2196 mpeg_mode
= MPEG_ENCODER
;
2198 DEBUGF("MAS Recording application started\n");
2200 /* At this point, all settings are the reset MAS defaults, next thing is to
2201 call mpeg_set_recording_options(). */
2204 void audio_record(const char *filename
)
2208 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2209 recording_filename
[MAX_PATH
- 1] = 0;
2211 queue_post(&mpeg_queue
, MPEG_RECORD
, 0);
2214 void audio_pause_recording(void)
2216 queue_post(&mpeg_queue
, MPEG_PAUSE_RECORDING
, 0);
2219 void audio_resume_recording(void)
2221 queue_post(&mpeg_queue
, MPEG_RESUME_RECORDING
, 0);
2224 static void prepend_header(void)
2229 /* Make room for header */
2230 audiobuf_read
-= MPEG_RESERVED_HEADER_SPACE
;
2231 if(audiobuf_read
< 0)
2233 /* Clear the bottom half */
2234 memset(audiobuf
, 0, audiobuf_read
+ MPEG_RESERVED_HEADER_SPACE
);
2236 /* And the top half */
2237 audiobuf_read
+= audiobuflen
;
2238 memset(audiobuf
+ audiobuf_read
, 0, audiobuflen
- audiobuf_read
);
2242 memset(audiobuf
+ audiobuf_read
, 0, MPEG_RESERVED_HEADER_SPACE
);
2244 /* Copy the empty ID3 header */
2245 startpos
= audiobuf_read
;
2246 for(i
= 0; i
< sizeof(empty_id3_header
); i
++)
2248 audiobuf
[startpos
++] = empty_id3_header
[i
];
2249 if(startpos
== audiobuflen
)
2254 static void update_header(void)
2257 unsigned long frames
;
2259 if (last_rec_bytes
> 0)
2261 /* Create the Xing header */
2262 fd
= open(delayed_filename
, O_RDWR
);
2264 panicf("rec upd: %d (%s)", fd
, recording_filename
);
2266 frames
= frame_count_end
- frame_count_start
;
2267 /* If the number of recorded frames has reached 0x7ffff,
2268 we can no longer trust it */
2269 if (frame_count_end
== 0x7ffff)
2272 /* saved_header is saved right before stopping the MAS */
2273 framelen
= create_xing_header(fd
, 0, last_rec_bytes
, xing_buffer
,
2274 frames
, last_rec_time
* (1000/HZ
),
2275 saved_header
, NULL
, false);
2277 lseek(fd
, MPEG_RESERVED_HEADER_SPACE
- framelen
, SEEK_SET
);
2278 write(fd
, xing_buffer
, framelen
);
2283 static void start_prerecording(void)
2287 DEBUGF("Starting prerecording\n");
2289 prerecord_index
= 0;
2290 prerecord_count
= 0;
2291 prerecord_timeout
= current_tick
+ HZ
;
2292 memset(prerecord_buffer
, 0, sizeof(prerecord_buffer
));
2295 is_prerecording
= true;
2297 /* Stop monitoring and start the encoder */
2298 shadow_io_control_main
&= ~(1 << 10);
2299 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2300 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2302 /* Wait until the DSP has accepted the settings */
2305 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2308 is_recording
= true;
2309 saving_status
= NOT_SAVING
;
2311 demand_irq_enable(true);
2314 static void start_recording(void)
2320 /* This will make the IRQ handler start recording
2321 for real, i.e send MPEG_SAVE_DATA messages when
2322 the buffer is full */
2323 is_prerecording
= false;
2327 /* If prerecording is off, we need to stop the monitoring
2328 and start the encoder */
2329 shadow_io_control_main
&= ~(1 << 10);
2330 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2331 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2333 /* Wait until the DSP has accepted the settings */
2336 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2340 is_recording
= true;
2341 saving_status
= NOT_SAVING
;
2344 /* Store the current time */
2346 record_start_time
= current_tick
- prerecord_count
* HZ
;
2348 record_start_time
= current_tick
;
2350 pause_start_time
= 0;
2352 demand_irq_enable(true);
2355 static void pause_recording(void)
2357 pause_start_time
= current_tick
;
2359 /* Set the pause bit */
2360 shadow_soft_mute
|= 2;
2361 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2366 static void resume_recording(void)
2370 /* Clear the pause bit */
2371 shadow_soft_mute
&= ~2;
2372 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2374 /* Compensate for the time we have been paused */
2375 if(pause_start_time
)
2378 current_tick
- (pause_start_time
- record_start_time
);
2379 pause_start_time
= 0;
2383 static void stop_recording(void)
2387 /* Let it finish the last frame */
2392 demand_irq_enable(false);
2394 is_recording
= false;
2395 is_prerecording
= false;
2397 last_rec_bytes
= num_rec_bytes
;
2398 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
, &frame_count_end
, 1);
2399 last_rec_time
= current_tick
- record_start_time
;
2401 /* Start monitoring */
2402 shadow_io_control_main
|= (1 << 10);
2403 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2404 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2406 /* Wait until the DSP has accepted the settings */
2409 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2415 void audio_set_recording_options(struct audio_recording_options
*options
)
2419 is_mpeg1
= (options
->rec_frequency
< 3)?true:false;
2421 rec_version_index
= is_mpeg1
?3:2;
2422 rec_frequency_index
= options
->rec_frequency
% 3;
2424 shadow_encoder_control
= (options
->rec_quality
<< 17) |
2425 (rec_frequency_index
<< 10) |
2426 ((is_mpeg1
?1:0) << 9) |
2427 (((options
->rec_channels
* 2 + 1) & 3) << 6) |
2428 (1 << 5) /* MS-stereo */ |
2429 (1 << 2) /* Is an original */;
2430 mas_writemem(MAS_BANK_D0
, MAS_D0_ENCODER_CONTROL
, &shadow_encoder_control
,1);
2432 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control
);
2434 shadow_soft_mute
= options
->rec_editable
?4:0;
2435 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
,1);
2437 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute
);
2439 shadow_io_control_main
= ((1 << 10) | /* Monitoring ON */
2440 ((options
->rec_source
< 2)?1:2) << 8) | /* Input select */
2441 (1 << 5) | /* SDO strobe invert */
2442 ((is_mpeg1
?0:1) << 3) |
2443 (1 << 2) | /* Inverted SIBC clock signal */
2445 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
,1);
2447 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2449 if(options
->rec_source
== AUDIO_SRC_MIC
)
2451 /* Copy left channel to right (mono mode) */
2452 mas_codec_writereg(8, 0x8000);
2456 /* Stereo input mode */
2457 mas_codec_writereg(8, 0);
2460 prerecording_max_seconds
= options
->rec_prerecord_time
;
2461 if(prerecording_max_seconds
)
2463 prerecording
= true;
2464 start_prerecording();
2468 prerecording
= false;
2469 is_prerecording
= false;
2470 is_recording
= false;
2474 /* If use_mic is true, the left gain is used */
2475 void audio_set_recording_gain(int left
, int right
, int type
)
2477 /* Enable both left and right A/D */
2478 shadow_codec_reg0
= (left
<< 12) |
2481 (type
==AUDIO_GAIN_MIC
?0x0008:0) | /* Connect left A/D to mic */
2483 mas_codec_writereg(0x0, shadow_codec_reg0
);
2486 #if CONFIG_TUNER & S1A0903X01
2487 /* Get the (unpitched) MAS PLL frequency, for avoiding FM interference with the
2488 * Samsung tuner. Zero means unknown. Currently handles recording from analog
2490 int mpeg_get_mas_pllfreq(void)
2492 if (mpeg_mode
!= MPEG_ENCODER
)
2495 if (rec_frequency_index
== 0) /* 44.1 kHz / 22.05 kHz */
2500 #endif /* CONFIG_TUNER & S1A0903X01 */
2502 /* try to make some kind of beep, also in recording mode */
2503 void audio_beep(int duration
)
2505 long starttick
= current_tick
;
2507 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2508 * While this is still audible even without an external signal,
2509 * it doesn't affect the (pre-)recording. */
2510 mas_codec_writereg(0, shadow_codec_reg0
^ 1);
2511 mas_codec_writereg(0, shadow_codec_reg0
);
2514 while (current_tick
- starttick
< duration
);
2517 void audio_new_file(const char *filename
)
2521 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2522 recording_filename
[MAX_PATH
- 1] = 0;
2524 queue_post(&mpeg_queue
, MPEG_NEW_FILE
, 0);
2527 unsigned long audio_recorded_time(void)
2530 return prerecord_count
* HZ
;
2535 return pause_start_time
- record_start_time
;
2537 return current_tick
- record_start_time
;
2543 unsigned long audio_num_recorded_bytes(void)
2552 index
= prerecord_index
- prerecord_count
;
2554 index
+= prerecording_max_seconds
;
2556 num_bytes
= audiobuf_write
- prerecord_buffer
[index
].mempos
;
2558 num_bytes
+= audiobuflen
;
2563 return num_rec_bytes
;
2569 #else /* SIMULATOR */
2571 /* dummies coming up */
2573 void audio_init_playback(void)
2577 unsigned long audio_recorded_time(void)
2582 void audio_beep(int duration
)
2587 void audio_pause_recording(void)
2591 void audio_resume_recording(void)
2595 unsigned long audio_num_recorded_bytes(void)
2600 void audio_record(const char *filename
)
2605 void audio_new_file(const char *filename
)
2611 void audio_set_recording_gain(int left
, int right
, int type
)
2618 void audio_init_recording(unsigned int buffer_offset
)
2621 (void)buffer_offset
;
2623 void audio_set_recording_options(struct audio_recording_options
*options
)
2628 #endif /* SIMULATOR */
2629 #endif /* CONFIG_CODEC == MAS3587F */
2631 void audio_play(long offset
)
2640 trackname
= playlist_peek( steps
);
2643 if(mp3info(&taginfo
, trackname
)) {
2644 /* bad mp3, move on */
2645 if(++steps
> playlist_amount())
2649 #ifdef HAVE_MPEG_PLAY
2650 real_mpeg_play(trackname
);
2652 playlist_next(steps
);
2653 taginfo
.offset
= offset
;
2654 set_elapsed(&taginfo
);
2659 #else /* !SIMULATOR */
2662 queue_post(&mpeg_queue
, MPEG_PLAY
, offset
);
2663 #endif /* !SIMULATOR */
2668 void audio_stop(void)
2673 struct trackdata
*track
= get_trackdata(0);
2674 prev_track_elapsed
= track
->id3
.elapsed
;
2676 mpeg_stop_done
= false;
2677 queue_post(&mpeg_queue
, MPEG_STOP
, 0);
2678 while(!mpeg_stop_done
)
2680 #else /* SIMULATOR */
2684 #endif /* SIMULATOR */
2688 void audio_stop_recording(void)
2693 void audio_pause(void)
2696 queue_post(&mpeg_queue
, MPEG_PAUSE
, 0);
2697 #else /* SIMULATOR */
2701 #endif /* SIMULATOR */
2704 void audio_resume(void)
2707 queue_post(&mpeg_queue
, MPEG_RESUME
, 0);
2708 #else /* SIMULATOR */
2712 #endif /* SIMULATOR */
2715 void audio_next(void)
2718 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2719 queue_post(&mpeg_queue
, MPEG_NEXT
, 0);
2720 #else /* SIMULATOR */
2726 file
= playlist_peek(steps
);
2729 if(mp3info(&taginfo
, file
)) {
2730 if(++steps
> playlist_amount())
2734 index
= playlist_next(steps
);
2735 taginfo
.index
= index
;
2736 current_track_counter
++;
2741 #endif /* SIMULATOR */
2744 void audio_prev(void)
2747 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2748 queue_post(&mpeg_queue
, MPEG_PREV
, 0);
2749 #else /* SIMULATOR */
2755 file
= playlist_peek(steps
);
2758 if(mp3info(&taginfo
, file
)) {
2762 index
= playlist_next(steps
);
2763 taginfo
.index
= index
;
2764 current_track_counter
++;
2769 #endif /* SIMULATOR */
2772 void audio_ff_rewind(long newtime
)
2775 queue_post(&mpeg_queue
, MPEG_FF_REWIND
, newtime
);
2776 #else /* SIMULATOR */
2778 #endif /* SIMULATOR */
2781 void audio_flush_and_reload_tracks(void)
2784 queue_post(&mpeg_queue
, MPEG_FLUSH_RELOAD
, 0);
2785 #endif /* !SIMULATOR*/
2788 int audio_status(void)
2793 ret
|= AUDIO_STATUS_PLAY
;
2796 ret
|= AUDIO_STATUS_PAUSE
;
2798 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2799 if(is_recording
&& !is_prerecording
)
2800 ret
|= AUDIO_STATUS_RECORD
;
2803 ret
|= AUDIO_STATUS_PRERECORD
;
2804 #endif /* CONFIG_CODEC == MAS3587F */
2807 ret
|= AUDIO_STATUS_ERROR
;
2812 unsigned int audio_error(void)
2817 void audio_error_clear(void)
2823 static void mpeg_thread(void)
2825 struct mp3entry
* id3
;
2828 id3
= audio_current_track();
2834 if (id3
->elapsed
>=id3
->length
)
2840 #endif /* SIMULATOR */
2842 void audio_init(void)
2847 audiobuflen
= audiobufend
- audiobuf
;
2848 queue_init(&mpeg_queue
, true);
2849 #endif /* !SIMULATOR */
2850 create_thread(mpeg_thread
, mpeg_stack
,
2851 sizeof(mpeg_stack
), 0, mpeg_thread_name
2852 IF_PRIO(, PRIORITY_SYSTEM
)
2855 memset(trackdata
, sizeof(trackdata
), 0);
2857 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2858 if (HW_MASK
& PR_ACTIVE_HIGH
)
2859 and_b(~0x08, &PADRH
);
2862 #endif /* CONFIG_CODEC == MAS3587F */
2870 #endif /* CONFIG_CODEC != SWCODEC */