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"
48 #endif /* !SIMULATOR */
49 #ifdef HAVE_LCD_BITMAP
54 extern unsigned long mas_version_code
;
57 #if CONFIG_CODEC == MAS3587F
58 extern enum /* from mp3_playback.c */
63 #endif /* CONFIG_CODEC == MAS3587F */
65 extern char* playlist_peek(int steps
);
66 extern bool playlist_check(int steps
);
67 extern int playlist_next(int steps
);
68 extern int playlist_amount(void);
69 extern int playlist_update_resume_info(const struct mp3entry
* id3
);
77 #define MPEG_FF_REWIND 7
78 #define MPEG_FLUSH_RELOAD 8
80 #define MPEG_INIT_RECORDING 10
81 #define MPEG_INIT_PLAYBACK 11
82 #define MPEG_NEW_FILE 12
83 #define MPEG_PAUSE_RECORDING 13
84 #define MPEG_RESUME_RECORDING 14
85 #define MPEG_NEED_DATA 100
86 #define MPEG_TRACK_CHANGE 101
87 #define MPEG_SAVE_DATA 102
88 #define MPEG_STOP_DONE 103
89 #define MPEG_PRERECORDING_TICK 104
91 /* indicator for MPEG_NEED_DATA */
92 #define GENERATE_UNBUFFER_EVENTS 1
94 /* list of tracks in memory */
95 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
96 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
102 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 /* Callback function to call when current track has really changed. */
120 void (*track_changed_callback
)(struct mp3entry
*id3
) = NULL
;
121 void (*track_buffer_callback
)(struct mp3entry
*id3
, bool last_track
);
122 void (*track_unbuffer_callback
)(struct mp3entry
*id3
, bool last_track
);
124 /* Cuesheet callback */
125 static bool (*cuesheet_callback
)(const char *filename
) = NULL
;
127 static const char mpeg_thread_name
[] = "mpeg";
128 static unsigned int mpeg_errno
;
130 static bool v1first
= false;
132 static bool playing
= false; /* We are playing an MP3 stream */
133 static bool is_playing
= false; /* We are (attempting to) playing MP3 files */
134 static bool paused
; /* playback is paused */
137 static char mpeg_stack
[DEFAULT_STACK_SIZE
];
138 static struct mp3entry taginfo
;
140 #else /* !SIMULATOR */
141 static struct event_queue mpeg_queue
;
142 static long mpeg_stack
[(DEFAULT_STACK_SIZE
+ 0x1000)/sizeof(long)];
144 static int audiobuflen
;
145 static int audiobuf_write
;
146 static int audiobuf_swapwrite
;
147 static int audiobuf_read
;
149 static int mpeg_file
;
151 static bool play_pending
; /* We are about to start playing */
152 static bool play_pending_track_change
; /* When starting play we're starting a new file */
153 static bool filling
; /* We are filling the buffer with data from disk */
154 static bool dma_underrun
; /* True when the DMA has stopped because of
155 slow disk reading (read error, shaking) */
156 static bool mpeg_stop_done
;
158 static int last_dma_tick
= 0;
159 static int last_dma_chunk_size
;
161 static long low_watermark
; /* Dynamic low watermark level */
162 static long low_watermark_margin
= 0; /* Extra time in seconds for watermark */
163 static long lowest_watermark_level
; /* Debug value to observe the buffer
165 #if CONFIG_CODEC == MAS3587F
166 static char recording_filename
[MAX_PATH
]; /* argument to thread */
167 static char delayed_filename
[MAX_PATH
]; /* internal copy of above */
169 static char xing_buffer
[MAX_XING_HEADER_SIZE
];
171 static bool init_recording_done
;
172 static bool init_playback_done
;
173 static bool prerecording
; /* True if prerecording is enabled */
174 static bool is_prerecording
; /* True if we are prerecording */
175 static bool is_recording
; /* We are recording */
178 NOT_SAVING
= 0, /* reasons to save data, sorted by importance */
184 static int rec_frequency_index
; /* For create_xing_header() calls */
185 static int rec_version_index
; /* For create_xing_header() calls */
187 struct prerecord_info
{
189 unsigned long framecount
;
192 static struct prerecord_info prerecord_buffer
[MPEG_MAX_PRERECORD_SECONDS
];
193 static int prerecord_index
; /* Current index in the prerecord buffer */
194 static int prerecording_max_seconds
; /* Max number of seconds to store */
195 static int prerecord_count
; /* Number of seconds in the prerecord buffer */
196 static int prerecord_timeout
; /* The tick count of the next prerecord data
199 unsigned long record_start_time
; /* Value of current_tick when recording
201 unsigned long pause_start_time
; /* Value of current_tick when pause was
203 static unsigned long last_rec_time
;
204 static unsigned long num_rec_bytes
;
205 static unsigned long last_rec_bytes
;
206 static unsigned long frame_count_start
;
207 static unsigned long frame_count_end
;
208 static unsigned long saved_header
= 0;
210 /* Shadow MAS registers */
211 unsigned long shadow_encoder_control
= 0;
212 #endif /* CONFIG_CODEC == MAS3587F */
214 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
215 unsigned long shadow_io_control_main
= 0;
216 unsigned long shadow_soft_mute
= 0;
217 unsigned shadow_codec_reg0
;
218 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
220 #ifdef HAVE_RECORDING
221 const unsigned char empty_id3_header
[] =
223 'I', 'D', '3', 0x03, 0x00, 0x00,
224 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
226 #endif /* HAVE_RECORDING */
229 static int get_unplayed_space(void);
230 static int get_playable_space(void);
231 static int get_unswapped_space(void);
232 #endif /* !SIMULATOR */
234 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
235 static void init_recording(void);
236 static void prepend_header(void);
237 static void update_header(void);
238 static void start_prerecording(void);
239 static void start_recording(void);
240 static void stop_recording(void);
241 static int get_unsaved_space(void);
242 static void pause_recording(void);
243 static void resume_recording(void);
244 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
248 static int num_tracks_in_memory(void)
250 return (track_write_idx
- track_read_idx
) & MAX_TRACK_ENTRIES_MASK
;
254 static void debug_tags(void)
258 for(i
= 0;i
< MAX_TRACK_ENTRIES
;i
++)
260 DEBUGF("%d - %s\n", i
, trackdata
[i
].id3
.path
);
262 DEBUGF("read: %d, write :%d\n", track_read_idx
, track_write_idx
);
263 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
265 #else /* !DEBUG_TAGS */
267 #endif /* !DEBUG_TAGS */
269 static void remove_current_tag(void)
271 if(num_tracks_in_memory() > 0)
273 /* First move the index, so nobody tries to access the tag */
274 track_read_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
279 DEBUGF("remove_current_tag: no tracks to remove\n");
283 static void remove_all_non_current_tags(void)
285 track_write_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
289 static void remove_all_tags(void)
291 track_write_idx
= track_read_idx
;
296 static struct trackdata
*get_trackdata(int offset
)
298 if(offset
>= num_tracks_in_memory())
301 return &trackdata
[(track_read_idx
+ offset
) & MAX_TRACK_ENTRIES_MASK
];
303 #endif /* !SIMULATOR */
305 /***********************************************************************/
306 /* audio event handling */
308 #define MAX_EVENT_HANDLERS 10
309 struct event_handlers_table
311 AUDIO_EVENT_HANDLER handler
;
314 static struct event_handlers_table event_handlers
[MAX_EVENT_HANDLERS
];
315 static int event_handlers_count
= 0;
317 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler
, unsigned short mask
)
319 if (event_handlers_count
< MAX_EVENT_HANDLERS
)
321 event_handlers
[event_handlers_count
].handler
= handler
;
322 event_handlers
[event_handlers_count
].mask
= mask
;
323 event_handlers_count
++;
327 /* dispatch calls each handler in the order registered and returns after some
328 handler actually handles the event (the event is assumed to no longer be valid
329 after this, due to the handler changing some condition); returns true if someone
330 handled the event, which is expected to cause the caller to skip its own handling
333 static bool audio_dispatch_event(unsigned short event
, unsigned long data
)
336 for(i
=0; i
< event_handlers_count
; i
++)
338 if ( event_handlers
[i
].mask
& event
)
340 int rc
= event_handlers
[i
].handler(event
, data
);
341 if ( rc
== AUDIO_EVENT_RC_HANDLED
)
349 /***********************************************************************/
351 static void set_elapsed(struct mp3entry
* id3
)
354 if ( id3
->has_toc
) {
355 /* calculate elapsed time using TOC */
357 unsigned int remainder
, plen
, relpos
, nextpos
;
359 /* find wich percent we're at */
360 for (i
=0; i
<100; i
++ )
362 if ( id3
->offset
< id3
->toc
[i
] * (id3
->filesize
/ 256) )
372 relpos
= id3
->toc
[i
];
376 nextpos
= id3
->toc
[i
+1];
383 remainder
= id3
->offset
- (relpos
* (id3
->filesize
/ 256));
385 /* set time for this percent (divide before multiply to prevent
386 overflow on long files. loss of precision is negligible on
388 id3
->elapsed
= i
* (id3
->length
/ 100);
390 /* calculate remainder time */
391 plen
= (nextpos
- relpos
) * (id3
->filesize
/ 256);
392 id3
->elapsed
+= (((remainder
* 100) / plen
) *
393 (id3
->length
/ 10000));
396 /* no TOC exists. set a rough estimate using average bitrate */
397 int tpk
= id3
->length
/ (id3
->filesize
/ 1024);
398 id3
->elapsed
= id3
->offset
/ 1024 * tpk
;
402 /* constant bitrate, use exact calculation */
403 id3
->elapsed
= id3
->offset
/ (id3
->bitrate
/ 8);
406 int audio_get_file_pos(void)
409 struct mp3entry
*id3
= audio_current_track();
415 /* Use the TOC to find the new position */
416 unsigned int percent
, remainder
;
417 int curtoc
, nexttoc
, plen
;
419 percent
= (id3
->elapsed
*100)/id3
->length
;
423 curtoc
= id3
->toc
[percent
];
426 nexttoc
= id3
->toc
[percent
+1];
430 pos
= (id3
->filesize
/256)*curtoc
;
432 /* Use the remainder to get a more accurate position */
433 remainder
= (id3
->elapsed
*100)%id3
->length
;
434 remainder
= (remainder
*100)/id3
->length
;
435 plen
= (nexttoc
- curtoc
)*(id3
->filesize
/256);
436 pos
+= (plen
/100)*remainder
;
440 /* No TOC exists, estimate the new position */
441 pos
= (id3
->filesize
/ (id3
->length
/ 1000)) *
442 (id3
->elapsed
/ 1000);
445 else if (id3
->bitrate
)
446 pos
= id3
->elapsed
* (id3
->bitrate
/ 8);
452 if (pos
>= (int)(id3
->filesize
- id3
->id3v1len
))
454 /* Don't seek right to the end of the file so that we can
455 transition properly to the next song */
456 pos
= id3
->filesize
- id3
->id3v1len
- 1;
458 else if (pos
< (int)id3
->first_frame_offset
)
460 /* skip past id3v2 tag and other leading garbage */
461 pos
= id3
->first_frame_offset
;
466 unsigned long mpeg_get_last_header(void)
470 #else /* !SIMULATOR */
471 unsigned long tmp
[2];
473 /* Read the frame data from the MAS and reconstruct it with the
474 frame sync and all */
475 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_STATUS_1
, tmp
, 2);
476 return 0xffe00000 | ((tmp
[0] & 0x7c00) << 6) | (tmp
[1] & 0xffff);
477 #endif /* !SIMULATOR */
480 void audio_set_track_buffer_event(void (*handler
)(struct mp3entry
*id3
,
483 track_buffer_callback
= handler
;
486 void audio_set_track_unbuffer_event(void (*handler
)(struct mp3entry
*id3
,
489 track_unbuffer_callback
= handler
;
492 void audio_set_track_changed_event(void (*handler
)(struct mp3entry
*id3
))
494 track_changed_callback
= handler
;
497 void audio_set_cuesheet_callback(bool (*handler
)(const char *filename
))
499 cuesheet_callback
= handler
;
503 /* Send callback events to notify about removing old tracks. */
504 static void generate_unbuffer_events(void)
508 int numentries
= MAX_TRACK_ENTRIES
- num_tracks_in_memory();
509 int cur_idx
= track_write_idx
;
511 for (i
= 0; i
< numentries
; i
++)
513 if (trackdata
[cur_idx
].event_sent
)
516 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
519 cur_idx
= track_write_idx
;
521 for (i
= 0; i
< numentries
; i
++)
523 /* Send an event to notify that track has finished. */
524 if (trackdata
[cur_idx
].event_sent
)
527 if (track_unbuffer_callback
)
528 track_unbuffer_callback(&trackdata
[cur_idx
].id3
,
530 trackdata
[cur_idx
].event_sent
= false;
532 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
536 /* Send callback events to notify about new tracks. */
537 static void generate_postbuffer_events(void)
541 int numentries
= num_tracks_in_memory();
542 int cur_idx
= track_read_idx
;
544 for (i
= 0; i
< numentries
; i
++)
546 if (!trackdata
[cur_idx
].event_sent
)
549 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
552 cur_idx
= track_read_idx
;
554 for (i
= 0; i
< numentries
; i
++)
556 if (!trackdata
[cur_idx
].event_sent
)
559 if (track_buffer_callback
)
560 track_buffer_callback(&trackdata
[cur_idx
].id3
,
562 trackdata
[cur_idx
].event_sent
= true;
564 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
568 static void recalculate_watermark(int bitrate
)
571 int time
= ata_spinup_time
;
573 /* A bitrate of 0 probably means empty VBR header. We play safe
574 and set a high threshold */
578 bytes_per_sec
= bitrate
* 1000 / 8;
582 /* No drive spins up faster than 3.5s */
587 low_watermark
= ((low_watermark_margin
* HZ
+ time
) *
592 low_watermark
= MPEG_LOW_WATER
;
596 #ifndef HAVE_FLASH_STORAGE
597 void audio_set_buffer_margin(int seconds
)
599 low_watermark_margin
= seconds
;
603 void audio_get_debugdata(struct audio_debug
*dbgdata
)
605 dbgdata
->audiobuflen
= audiobuflen
;
606 dbgdata
->audiobuf_write
= audiobuf_write
;
607 dbgdata
->audiobuf_swapwrite
= audiobuf_swapwrite
;
608 dbgdata
->audiobuf_read
= audiobuf_read
;
610 dbgdata
->last_dma_chunk_size
= last_dma_chunk_size
;
612 #if CONFIG_CPU == SH7034
613 dbgdata
->dma_on
= (SCR0
& 0x80) != 0;
615 dbgdata
->playing
= playing
;
616 dbgdata
->play_pending
= play_pending
;
617 dbgdata
->is_playing
= is_playing
;
618 dbgdata
->filling
= filling
;
619 dbgdata
->dma_underrun
= dma_underrun
;
621 dbgdata
->unplayed_space
= get_unplayed_space();
622 dbgdata
->playable_space
= get_playable_space();
623 dbgdata
->unswapped_space
= get_unswapped_space();
625 dbgdata
->low_watermark_level
= low_watermark
;
626 dbgdata
->lowest_watermark_level
= lowest_watermark_level
;
630 static void dbg_timer_start(void)
632 /* We are using timer 2 */
634 TSTR
&= ~0x04; /* Stop the timer */
635 TSNC
&= ~0x04; /* No synchronization */
636 TMDR
&= ~0x44; /* Operate normally */
638 TCNT2
= 0; /* Start counting at 0 */
639 TCR2
= 0x03; /* Sysclock/8 */
641 TSTR
|= 0x04; /* Start timer 2 */
644 static int dbg_cnt2us(unsigned int cnt
)
646 return (cnt
* 10000) / (FREQ
/800);
650 static int get_unplayed_space(void)
652 int space
= audiobuf_write
- audiobuf_read
;
654 space
+= audiobuflen
;
658 static int get_playable_space(void)
660 int space
= audiobuf_swapwrite
- audiobuf_read
;
662 space
+= audiobuflen
;
666 static int get_unplayed_space_current_song(void)
670 if (num_tracks_in_memory() > 1)
672 space
= get_trackdata(1)->mempos
- audiobuf_read
;
676 space
= audiobuf_write
- audiobuf_read
;
680 space
+= audiobuflen
;
685 static int get_unswapped_space(void)
687 int space
= audiobuf_write
- audiobuf_swapwrite
;
689 space
+= audiobuflen
;
693 #if CONFIG_CODEC == MAS3587F
694 static int get_unsaved_space(void)
696 int space
= audiobuf_write
- audiobuf_read
;
698 space
+= audiobuflen
;
702 static void drain_dma_buffer(void)
708 while (PBDRH
& 0x80);
712 while (!(PBDRH
& 0x80));
717 static long timing_info_index
= 0;
718 static long timing_info
[1024];
721 void rec_tick (void) __attribute__ ((section (".icode")));
728 if(is_recording
&& (PBDRH
& 0x40))
731 timing_info
[timing_info_index
++] = current_tick
;
734 /* Note: Although this loop is run in interrupt context, further
735 * optimisation will do no good. The MAS would then deliver bad
736 * frames occasionally, as observed in extended experiments. */
738 while (PBDRH
& 0x40) /* We try to read as long as EOD is high */
740 xor_b(0x08, &PADRH
); /* Set PR active, independent of polarity */
743 while (PBDRH
& 0x80) /* Wait until /RTW becomes active */
745 if (--delay
<= 0) /* Bail out if we have to wait too long */
746 { /* i.e. the MAS doesn't want to talk to us */
747 xor_b(0x08, &PADRH
); /* Set PR inactive */
748 goto transfer_end
; /* and get out of here */
752 data
= *(unsigned char *)0x04000000; /* read data byte */
754 xor_b(0x08, &PADRH
); /* Set PR inactive */
756 audiobuf
[audiobuf_write
++] = data
;
758 if (audiobuf_write
>= audiobuflen
)
766 timing_info
[timing_info_index
++] = TCNT2
+ (i
<< 16);
767 timing_info_index
&= 0x3ff;
774 if(TIME_AFTER(current_tick
, prerecord_timeout
))
776 prerecord_timeout
= current_tick
+ HZ
;
777 queue_post(&mpeg_queue
, MPEG_PRERECORDING_TICK
, 0);
782 /* Signal to save the data if we are running out of buffer
784 if (audiobuflen
- get_unsaved_space() < MPEG_RECORDING_LOW_WATER
785 && saving_status
== NOT_SAVING
)
787 saving_status
= BUFFER_FULL
;
788 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
793 #endif /* CONFIG_CODEC == MAS3587F */
795 void playback_tick(void)
797 struct trackdata
*ptd
= get_trackdata(0);
800 ptd
->id3
.elapsed
+= (current_tick
- last_dma_tick
) * 1000 / HZ
;
801 last_dma_tick
= current_tick
;
802 audio_dispatch_event(AUDIO_EVENT_POS_REPORT
,
803 (unsigned long)ptd
->id3
.elapsed
);
807 static void reset_mp3_buffer(void)
811 audiobuf_swapwrite
= 0;
812 lowest_watermark_level
= audiobuflen
;
815 /* DMA transfer end interrupt callback */
816 static void transfer_end(unsigned char** ppbuf
, size_t* psize
)
818 if(playing
&& !paused
)
820 int unplayed_space_left
;
821 int space_until_end_of_buffer
;
822 int track_offset
= 1;
823 struct trackdata
*track
;
825 audiobuf_read
+= last_dma_chunk_size
;
826 if(audiobuf_read
>= audiobuflen
)
829 /* First, check if we are on a track boundary */
830 if (num_tracks_in_memory() > 1)
832 if (audiobuf_read
== get_trackdata(track_offset
)->mempos
)
834 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
836 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
842 unplayed_space_left
= get_unplayed_space();
844 space_until_end_of_buffer
= audiobuflen
- audiobuf_read
;
846 if(!filling
&& unplayed_space_left
< low_watermark
)
849 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
852 if(unplayed_space_left
)
854 last_dma_chunk_size
= MIN(0x2000, unplayed_space_left
);
855 last_dma_chunk_size
= MIN(last_dma_chunk_size
,
856 space_until_end_of_buffer
);
858 /* several tracks loaded? */
859 track
= get_trackdata(track_offset
);
862 /* will we move across the track boundary? */
863 if (( audiobuf_read
< track
->mempos
) &&
864 ((audiobuf_read
+last_dma_chunk_size
) >
867 /* Make sure that we end exactly on the boundary */
868 last_dma_chunk_size
= track
->mempos
- audiobuf_read
;
872 *psize
= last_dma_chunk_size
& 0xffff;
873 *ppbuf
= audiobuf
+ audiobuf_read
;
874 track
= get_trackdata(0);
876 track
->id3
.offset
+= last_dma_chunk_size
;
878 /* Update the watermark debug level */
879 if(unplayed_space_left
< lowest_watermark_level
)
880 lowest_watermark_level
= unplayed_space_left
;
884 /* Check if the end of data is because of a hard disk error.
885 If there is an open file handle, we are still playing music.
886 If not, the last file has been loaded, and the file handle is
890 /* Update the watermark debug level */
891 if(unplayed_space_left
< lowest_watermark_level
)
892 lowest_watermark_level
= unplayed_space_left
;
894 DEBUGF("DMA underrun.\n");
899 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
901 DEBUGF("No more MP3 data. Stopping.\n");
902 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
906 *psize
= 0; /* no more transfer */
911 static struct trackdata
*add_track_to_tag_list(const char *filename
)
913 struct trackdata
*track
;
915 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES
)
917 DEBUGF("Tag memory is full\n");
921 track
= &trackdata
[track_write_idx
];
923 /* grab id3 tag of new file and
924 remember where in memory it starts */
925 if(mp3info(&track
->id3
, filename
, v1first
))
930 track
->mempos
= audiobuf_write
;
931 track
->id3
.elapsed
= 0;
932 #ifdef HAVE_LCD_BITMAP
933 if (track
->id3
.title
)
934 lcd_getstringsize(track
->id3
.title
, NULL
, NULL
);
935 if (track
->id3
.artist
)
936 lcd_getstringsize(track
->id3
.artist
, NULL
, NULL
);
937 if (track
->id3
.album
)
938 lcd_getstringsize(track
->id3
.album
, NULL
, NULL
);
940 if (cuesheet_callback
)
941 if (cuesheet_callback(filename
))
942 track
->id3
.cuesheet_type
= 1;
944 track_write_idx
= (track_write_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
949 static int new_file(int steps
)
951 int max_steps
= playlist_amount();
954 struct trackdata
*track
;
956 /* Find out how many steps to advance. The load_ahead_index field tells
957 us how many playlist entries it had to skip to get to a valid one.
958 We add those together to find out where to start. */
959 if(steps
> 0 && num_tracks_in_memory() > 1)
961 /* Begin with the song after the currently playing one */
963 while((track
= get_trackdata(i
++)))
965 start
+= track
->load_ahead_index
;
972 trackname
= playlist_peek( start
+ steps
);
976 DEBUGF("Loading %s\n", trackname
);
978 mpeg_file
= open(trackname
, O_RDONLY
);
980 DEBUGF("Couldn't open file: %s\n",trackname
);
988 struct trackdata
*track
= add_track_to_tag_list(trackname
);
1002 /* skip past id3v2 tag */
1004 track
->id3
.first_frame_offset
,
1006 track
->id3
.index
= steps
;
1007 track
->load_ahead_index
= steps
;
1008 track
->id3
.offset
= 0;
1011 /* Average bitrate * 1.5 */
1012 recalculate_watermark(
1013 (track
->id3
.bitrate
* 3) / 2);
1015 recalculate_watermark(
1016 track
->id3
.bitrate
);
1021 /* Bail out if no file could be opened */
1022 if(abs(steps
) > max_steps
)
1024 } while ( mpeg_file
< 0 );
1029 static void stop_playing(void)
1031 struct trackdata
*track
;
1033 /* Stop the current stream */
1038 track
= get_trackdata(0);
1040 prev_track_elapsed
= track
->id3
.elapsed
;
1046 generate_unbuffer_events();
1050 static void end_current_track(void) {
1051 struct trackdata
*track
;
1053 play_pending
= false;
1055 mp3_play_pause(false);
1057 track
= get_trackdata(0);
1059 prev_track_elapsed
= track
->id3
.elapsed
;
1063 generate_unbuffer_events();
1069 /* Is this a really the end of playback or is a new playlist starting */
1070 static void check_playlist_end(int direction
)
1072 /* Use the largest possible step size to account for skipped tracks */
1073 int steps
= playlist_amount();
1078 if (playlist_next(steps
) < 0)
1082 static void update_playlist(void)
1084 if (num_tracks_in_memory() > 0)
1086 struct trackdata
*track
= get_trackdata(0);
1087 track
->id3
.index
= playlist_next(track
->id3
.index
);
1091 /* End of playlist? */
1092 check_playlist_end(1);
1095 playlist_update_resume_info(audio_current_track());
1098 static void track_change(void)
1100 DEBUGF("Track change\n");
1102 struct trackdata
*track
= get_trackdata(0);
1103 prev_track_elapsed
= track
->id3
.elapsed
;
1105 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1108 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1110 if (num_tracks_in_memory() > 0)
1112 remove_current_tag();
1113 if (track_changed_callback
)
1114 track_changed_callback(audio_current_track());
1118 current_track_counter
++;
1121 unsigned long audio_prev_elapsed(void)
1123 return prev_track_elapsed
;
1127 void hexdump(const unsigned char *buf
, int len
)
1131 for(i
= 0;i
< len
;i
++)
1133 if(i
&& (i
& 15) == 0)
1137 DEBUGF("%02x ", buf
[i
]);
1143 static void start_playback_if_ready(void)
1147 playable_space
= audiobuf_swapwrite
- audiobuf_read
;
1148 if(playable_space
< 0)
1149 playable_space
+= audiobuflen
;
1151 /* See if we have started playing yet. If not, do it. */
1152 if(play_pending
|| dma_underrun
)
1154 /* If the filling has stopped, and we still haven't reached
1155 the watermark, the file must be smaller than the
1156 watermark. We must still play it. */
1157 if((playable_space
>= MPEG_PLAY_PENDING_THRESHOLD
) ||
1158 !filling
|| dma_underrun
)
1161 if (play_pending
) /* don't do this when recovering from DMA underrun */
1163 generate_postbuffer_events(); /* signal first track as buffered */
1164 if (play_pending_track_change
)
1166 play_pending_track_change
= false;
1167 if(track_changed_callback
)
1168 track_changed_callback(audio_current_track());
1170 play_pending
= false;
1174 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1175 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1176 dma_underrun
= false;
1180 last_dma_tick
= current_tick
;
1181 mp3_play_pause(true);
1184 /* Tell ourselves that we need more data */
1185 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1190 static bool swap_one_chunk(void)
1192 int free_space_left
;
1195 free_space_left
= get_unswapped_space();
1197 if(free_space_left
== 0 && !play_pending
)
1200 /* Swap in larger chunks when the user is waiting for the playback
1201 to start, or when there is dangerously little playable data left */
1203 amount_to_swap
= MIN(MPEG_PLAY_PENDING_SWAPSIZE
, free_space_left
);
1206 if(get_playable_space() < low_watermark
)
1207 amount_to_swap
= MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE
,
1210 amount_to_swap
= MIN(MPEG_SWAP_CHUNKSIZE
, free_space_left
);
1213 if(audiobuf_write
< audiobuf_swapwrite
)
1214 amount_to_swap
= MIN(audiobuflen
- audiobuf_swapwrite
,
1217 amount_to_swap
= MIN(audiobuf_write
- audiobuf_swapwrite
,
1220 bitswap(audiobuf
+ audiobuf_swapwrite
, amount_to_swap
);
1222 audiobuf_swapwrite
+= amount_to_swap
;
1223 if(audiobuf_swapwrite
>= audiobuflen
)
1225 audiobuf_swapwrite
= 0;
1231 static void mpeg_thread(void)
1233 static int pause_tick
= 0;
1234 static unsigned int pause_track
= 0;
1237 int free_space_left
;
1238 int unplayed_space_left
;
1242 #if CONFIG_CODEC == MAS3587F
1244 int save_endpos
= 0;
1248 #endif /* CONFIG_CODEC == MAS3587F */
1251 play_pending
= false;
1257 #if CONFIG_CODEC == MAS3587F
1258 if(mpeg_mode
== MPEG_DECODER
)
1260 #endif /* CONFIG_CODEC == MAS3587F */
1263 /* Swap if necessary, and don't block on the queue_wait() */
1264 if(swap_one_chunk())
1266 queue_wait_w_tmo(&mpeg_queue
, &ev
, 0);
1270 /* periodically update resume info */
1271 queue_wait_w_tmo(&mpeg_queue
, &ev
, HZ
/2);
1275 DEBUGF("S R:%x W:%x SW:%x\n",
1276 audiobuf_read
, audiobuf_write
, audiobuf_swapwrite
);
1277 queue_wait(&mpeg_queue
, &ev
);
1280 start_playback_if_ready();
1285 DEBUGF("MPEG_PLAY\n");
1288 /* Silence the A/D input, it may be on because the radio
1290 mas_codec_writereg(6, 0x0000);
1291 #endif /* CONFIG_TUNER */
1293 /* Stop the current stream */
1295 end_current_track();
1297 if ( new_file(0) == -1 )
1304 start_offset
= (int)ev
.data
;
1306 /* mid-song resume? */
1308 struct mp3entry
* id3
= &get_trackdata(0)->id3
;
1309 lseek(mpeg_file
, start_offset
, SEEK_SET
);
1310 id3
->offset
= start_offset
;
1314 /* skip past id3v2 tag */
1316 get_trackdata(0)->id3
.first_frame_offset
,
1321 /* Make it read more data */
1323 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1325 /* Tell the file loading code that we want to start playing
1326 as soon as we have some data */
1327 play_pending
= true;
1328 play_pending_track_change
= true;
1331 current_track_counter
++;
1335 DEBUGF("MPEG_STOP\n");
1340 playlist_update_resume_info(audio_current_track());
1343 mpeg_stop_done
= true;
1347 DEBUGF("MPEG_PAUSE\n");
1348 /* Stop the current stream */
1350 playlist_update_resume_info(audio_current_track());
1353 pause_tick
= current_tick
;
1354 pause_track
= current_track_counter
;
1355 mp3_play_pause(false);
1359 DEBUGF("MPEG_RESUME\n");
1360 /* Continue the current stream */
1365 if ( current_track_counter
== pause_track
)
1366 last_dma_tick
+= current_tick
- pause_tick
;
1368 last_dma_tick
= current_tick
;
1370 mp3_play_pause(true);
1375 DEBUGF("MPEG_NEXT\n");
1376 /* is next track in ram? */
1377 if ( num_tracks_in_memory() > 1 ) {
1378 int unplayed_space_left
, unswapped_space_left
;
1380 /* stop the current stream */
1381 play_pending
= false;
1383 mp3_play_pause(false);
1386 audiobuf_read
= get_trackdata(0)->mempos
;
1387 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1388 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1389 dma_underrun
= false;
1390 last_dma_tick
= current_tick
;
1392 unplayed_space_left
= get_unplayed_space();
1393 unswapped_space_left
= get_unswapped_space();
1395 /* should we start reading more data? */
1396 if(!filling
&& (unplayed_space_left
< low_watermark
)) {
1398 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1399 play_pending
= true;
1400 } else if(unswapped_space_left
&&
1401 unswapped_space_left
> unplayed_space_left
) {
1402 /* Stop swapping the data from the previous file */
1403 audiobuf_swapwrite
= audiobuf_read
;
1404 play_pending
= true;
1408 mp3_play_pause(true);
1412 if (!playlist_check(1))
1415 /* stop the current stream */
1416 end_current_track();
1418 if (new_file(1) < 0) {
1419 DEBUGF("No more files to play\n");
1422 check_playlist_end(1);
1423 current_track_counter
++;
1425 /* Make it read more data */
1427 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1429 /* Tell the file loading code that we want
1430 to start playing as soon as we have some data */
1431 play_pending
= true;
1432 play_pending_track_change
= true;
1435 current_track_counter
++;
1441 DEBUGF("MPEG_PREV\n");
1443 if (!playlist_check(-1))
1446 /* stop the current stream */
1447 end_current_track();
1449 /* Open the next file */
1450 if (new_file(-1) < 0) {
1451 DEBUGF("No more files to play\n");
1454 check_playlist_end(-1);
1455 current_track_counter
++;
1457 /* Make it read more data */
1459 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1461 /* Tell the file loading code that we want to
1462 start playing as soon as we have some data */
1463 play_pending
= true;
1464 play_pending_track_change
= true;
1467 current_track_counter
++;
1472 case MPEG_FF_REWIND
: {
1473 struct mp3entry
*id3
= audio_current_track();
1474 unsigned int oldtime
= id3
->elapsed
;
1475 unsigned int newtime
= (unsigned int)ev
.data
;
1476 int curpos
, newpos
, diffpos
;
1477 DEBUGF("MPEG_FF_REWIND\n");
1479 id3
->elapsed
= newtime
;
1481 newpos
= audio_get_file_pos();
1484 id3
->elapsed
= oldtime
;
1489 curpos
= lseek(mpeg_file
, 0, SEEK_CUR
);
1491 curpos
= id3
->filesize
;
1493 if (num_tracks_in_memory() > 1)
1495 /* We have started loading other tracks that need to be
1497 struct trackdata
*track
;
1500 while((track
= get_trackdata(i
++)))
1502 curpos
+= track
->id3
.filesize
;
1506 diffpos
= curpos
- newpos
;
1508 if(!filling
&& diffpos
>= 0 && diffpos
< audiobuflen
)
1510 int unplayed_space_left
, unswapped_space_left
;
1512 /* We are changing to a position that's already in
1513 memory, so we just move the DMA read pointer. */
1514 audiobuf_read
= audiobuf_write
- diffpos
;
1515 if (audiobuf_read
< 0)
1517 audiobuf_read
+= audiobuflen
;
1520 unplayed_space_left
= get_unplayed_space();
1521 unswapped_space_left
= get_unswapped_space();
1523 /* If unswapped_space_left is larger than
1524 unplayed_space_left, it means that the swapwrite pointer
1525 hasn't yet advanced up to the new location of the read
1526 pointer. We just move it, there is no need to swap
1527 data that won't be played anyway. */
1529 if (unswapped_space_left
> unplayed_space_left
)
1531 DEBUGF("Moved swapwrite\n");
1532 audiobuf_swapwrite
= audiobuf_read
;
1533 play_pending
= true;
1536 if (mpeg_file
>=0 && unplayed_space_left
< low_watermark
)
1538 /* We need to load more data before starting */
1540 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1541 play_pending
= true;
1545 /* resume will start at new position */
1546 last_dma_chunk_size
=
1547 MIN(0x2000, get_unplayed_space_current_song());
1548 mp3_play_data(audiobuf
+ audiobuf_read
,
1549 last_dma_chunk_size
, transfer_end
);
1550 dma_underrun
= false;
1555 /* Move to the new position in the file and start
1559 if (num_tracks_in_memory() > 1)
1561 /* We have to reload the current track */
1563 remove_all_non_current_tags();
1564 generate_unbuffer_events();
1570 mpeg_file
= open(id3
->path
, O_RDONLY
);
1573 id3
->elapsed
= oldtime
;
1578 if(-1 == lseek(mpeg_file
, newpos
, SEEK_SET
))
1580 id3
->elapsed
= oldtime
;
1585 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1587 /* Tell the file loading code that we want to start playing
1588 as soon as we have some data */
1589 play_pending
= true;
1592 id3
->offset
= newpos
;
1597 case MPEG_FLUSH_RELOAD
: {
1598 int numtracks
= num_tracks_in_memory();
1599 bool reload_track
= false;
1603 /* Reset the buffer */
1604 audiobuf_write
= get_trackdata(1)->mempos
;
1606 /* Reset swapwrite unless we're still swapping current
1608 if (get_unplayed_space() <= get_playable_space())
1609 audiobuf_swapwrite
= audiobuf_write
;
1612 remove_all_non_current_tags();
1613 generate_unbuffer_events();
1615 reload_track
= true;
1617 else if (numtracks
== 1 && mpeg_file
< 0)
1619 reload_track
= true;
1622 if(reload_track
&& new_file(1) >= 0)
1624 /* Tell ourselves that we want more data */
1626 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1632 case MPEG_NEED_DATA
:
1633 free_space_left
= audiobuf_read
- audiobuf_write
;
1635 /* We interpret 0 as "empty buffer" */
1636 if(free_space_left
<= 0)
1637 free_space_left
+= audiobuflen
;
1639 unplayed_space_left
= audiobuflen
- free_space_left
;
1641 /* Make sure that we don't fill the entire buffer */
1642 free_space_left
-= MPEG_HIGH_WATER
;
1644 if (ev
.data
== GENERATE_UNBUFFER_EVENTS
)
1645 generate_unbuffer_events();
1647 /* do we have any more buffer space to fill? */
1648 if(free_space_left
<= 0)
1652 generate_postbuffer_events();
1657 /* Read small chunks while we are below the low water mark */
1658 if(unplayed_space_left
< low_watermark
)
1659 amount_to_read
= MIN(MPEG_LOW_WATER_CHUNKSIZE
,
1662 amount_to_read
= free_space_left
;
1664 /* Don't read more than until the end of the buffer */
1665 amount_to_read
= MIN(audiobuflen
- audiobuf_write
,
1667 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1668 amount_to_read
= MIN(0x40000, amount_to_read
);
1670 amount_to_read
= MIN(0x100000, amount_to_read
);
1673 /* Read as much mpeg data as we can fit in the buffer */
1678 len
= read(mpeg_file
, audiobuf
+ audiobuf_write
,
1683 DEBUGF("time: %d\n", t2
- t1
);
1684 DEBUGF("R: %x\n", len
);
1686 /* Now make sure that we don't feed the MAS with ID3V1
1688 if (len
< amount_to_read
)
1691 static const unsigned char tag
[] = "TAG";
1693 int tagptr
= audiobuf_write
+ len
- 128;
1695 /* Really rare case: entire potential tag wasn't
1696 read in this call AND audiobuf_write < 128 */
1698 tagptr
+= audiobuflen
;
1700 for(i
= 0;i
< 3;i
++)
1702 if(tagptr
>= audiobuflen
)
1703 tagptr
-= audiobuflen
;
1705 if(audiobuf
[tagptr
] != tag
[i
])
1716 /* Skip id3v1 tag */
1717 DEBUGF("Skipping ID3v1 tag\n");
1720 /* In the very rare case when the entire tag
1721 wasn't read in this read() len will be < 0.
1722 Take care of this when changing the write
1727 audiobuf_write
+= len
;
1729 if (audiobuf_write
< 0)
1730 audiobuf_write
+= audiobuflen
;
1732 if(audiobuf_write
>= audiobuflen
)
1738 /* Tell ourselves that we want more data */
1739 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1745 DEBUGF("MPEG read error\n");
1753 /* No more data to play */
1754 DEBUGF("No more files to play\n");
1759 /* Tell ourselves that we want more data */
1760 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1766 case MPEG_TRACK_CHANGE
:
1771 case SYS_USB_CONNECTED
:
1776 /* Tell the USB thread that we are safe */
1777 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1778 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1780 /* Wait until the USB cable is extracted again */
1781 usb_wait_for_disconnect(&mpeg_queue
);
1783 #endif /* !USB_NONE */
1785 #if CONFIG_CODEC == MAS3587F
1786 case MPEG_INIT_RECORDING
:
1788 init_recording_done
= true;
1790 #endif /* CONFIG_CODEC == MAS3587F */
1794 playlist_update_resume_info(audio_current_track());
1797 #if CONFIG_CODEC == MAS3587F
1801 queue_wait(&mpeg_queue
, &ev
);
1805 if (is_prerecording
)
1809 /* Go back prerecord_count seconds in the buffer */
1810 startpos
= prerecord_index
- prerecord_count
;
1812 startpos
+= prerecording_max_seconds
;
1814 /* Read the position data from the prerecord buffer */
1815 frame_count_start
= prerecord_buffer
[startpos
].framecount
;
1816 startpos
= prerecord_buffer
[startpos
].mempos
;
1818 DEBUGF("Start looking at address %x (%x)\n",
1819 audiobuf
+startpos
, startpos
);
1821 saved_header
= mpeg_get_last_header();
1823 mem_find_next_frame(startpos
, &offset
, 1800,
1826 audiobuf_read
= startpos
+ offset
;
1827 if(audiobuf_read
>= audiobuflen
)
1828 audiobuf_read
-= audiobuflen
;
1830 DEBUGF("New audiobuf_read address: %x (%x)\n",
1831 audiobuf
+audiobuf_read
, audiobuf_read
);
1833 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1834 num_rec_bytes
= get_unsaved_space();
1835 set_irq_level(level
);
1839 frame_count_start
= 0;
1841 audiobuf_read
= MPEG_RESERVED_HEADER_SPACE
;
1842 audiobuf_write
= MPEG_RESERVED_HEADER_SPACE
;
1846 DEBUGF("Recording...\n");
1849 /* Wait until at least one frame is encoded and get the
1850 frame header, for later use by the Xing header
1853 saved_header
= mpeg_get_last_header();
1855 /* delayed until buffer is saved, don't open yet */
1856 strcpy(delayed_filename
, recording_filename
);
1862 DEBUGF("MPEG_STOP\n");
1866 /* Save the remaining data in the buffer */
1867 save_endpos
= audiobuf_write
;
1868 saving_status
= STOP_RECORDING
;
1869 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1872 case MPEG_STOP_DONE
:
1873 DEBUGF("MPEG_STOP_DONE\n");
1883 for(i
= 0;i
< 512;i
++)
1885 DEBUGF("%d - %d us (%d bytes)\n",
1887 (timing_info
[i
*2+1] & 0xffff) *
1889 timing_info
[i
*2+1] >> 16);
1896 start_prerecording();
1898 mpeg_stop_done
= true;
1902 /* Bail out when a more important save is happening */
1903 if (saving_status
> NEW_FILE
)
1906 /* Make sure we have at least one complete frame
1907 in the buffer. If we haven't recorded a single
1908 frame within 200ms, the MAS is probably not recording
1909 anything, and we bail out. */
1910 amount_to_save
= get_unsaved_space();
1911 if (amount_to_save
< 1800)
1914 amount_to_save
= get_unsaved_space();
1917 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1918 &frame_count_end
, 1);
1920 last_rec_time
= current_tick
- record_start_time
;
1921 record_start_time
= current_tick
;
1923 pause_start_time
= record_start_time
;
1925 /* capture all values at one point */
1926 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1927 save_endpos
= audiobuf_write
;
1928 last_rec_bytes
= num_rec_bytes
;
1930 set_irq_level(level
);
1932 if (amount_to_save
>= 1800)
1934 /* Now find a frame boundary to split at */
1935 save_endpos
-= 1800;
1936 if (save_endpos
< 0)
1937 save_endpos
+= audiobuflen
;
1939 rc
= mem_find_next_frame(save_endpos
, &offset
, 1800,
1941 if (!rc
) /* No header found, save whole buffer */
1944 save_endpos
+= offset
;
1945 if (save_endpos
>= audiobuflen
)
1946 save_endpos
-= audiobuflen
;
1948 last_rec_bytes
+= offset
- 1800;
1949 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1950 num_rec_bytes
+= 1800 - offset
;
1951 set_irq_level(level
);
1954 saving_status
= NEW_FILE
;
1955 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1958 case MPEG_SAVE_DATA
:
1959 if (saving_status
== BUFFER_FULL
)
1960 save_endpos
= audiobuf_write
;
1962 if (mpeg_file
< 0) /* delayed file open */
1964 mpeg_file
= open(delayed_filename
, O_WRONLY
|O_CREAT
);
1967 panicf("recfile: %d", mpeg_file
);
1970 amount_to_save
= save_endpos
- audiobuf_read
;
1971 if (amount_to_save
< 0)
1972 amount_to_save
+= audiobuflen
;
1974 amount_to_save
= MIN(amount_to_save
,
1975 audiobuflen
- audiobuf_read
);
1976 #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */
1977 amount_to_save
= MIN(0x40000, amount_to_save
);
1979 amount_to_save
= MIN(0x100000, amount_to_save
);
1981 rc
= write(mpeg_file
, audiobuf
+ audiobuf_read
,
1985 if (errno
== ENOSPC
)
1987 mpeg_errno
= AUDIOERR_DISK_FULL
;
1989 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1990 /* will close the file */
1994 panicf("rec wrt: %d", rc
);
1997 audiobuf_read
+= amount_to_save
;
1998 if (audiobuf_read
>= audiobuflen
)
2001 if (audiobuf_read
== save_endpos
) /* all saved */
2003 switch (saving_status
)
2006 rc
= fsync(mpeg_file
);
2008 panicf("rec fls: %d", rc
);
2013 /* Close the current file */
2014 rc
= close(mpeg_file
);
2016 panicf("rec cls: %d", rc
);
2021 /* copy new filename */
2022 strcpy(delayed_filename
, recording_filename
);
2024 frame_count_start
= frame_count_end
;
2027 case STOP_RECORDING
:
2028 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
2029 /* will close the file */
2035 saving_status
= NOT_SAVING
;
2037 else /* tell ourselves to save the next chunk */
2038 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
2042 case MPEG_PRERECORDING_TICK
:
2043 if(!is_prerecording
)
2046 /* Store the write pointer every second */
2047 prerecord_buffer
[prerecord_index
].mempos
= audiobuf_write
;
2048 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
2049 &prerecord_buffer
[prerecord_index
].framecount
, 1);
2051 /* Wrap if necessary */
2052 if(++prerecord_index
== prerecording_max_seconds
)
2053 prerecord_index
= 0;
2055 /* Update the number of seconds recorded */
2056 if(prerecord_count
< prerecording_max_seconds
)
2060 case MPEG_INIT_PLAYBACK
:
2061 /* Stop the prerecording */
2065 init_playback_done
= true;
2068 case MPEG_PAUSE_RECORDING
:
2072 case MPEG_RESUME_RECORDING
:
2076 case SYS_USB_CONNECTED
:
2077 /* We can safely go to USB mode if no recording
2079 if((!is_recording
|| is_prerecording
) && mpeg_stop_done
)
2081 /* Even if we aren't recording, we still call this
2082 function, to put the MAS in monitoring mode,
2086 /* Tell the USB thread that we are safe */
2087 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2088 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
2090 /* Wait until the USB cable is extracted again */
2091 usb_wait_for_disconnect(&mpeg_queue
);
2096 #endif /* CONFIG_CODEC == MAS3587F */
2099 #endif /* !SIMULATOR */
2101 void mpeg_id3_options(bool _v1first
)
2106 struct mp3entry
* audio_current_track()
2110 #else /* !SIMULATOR */
2111 if(num_tracks_in_memory())
2112 return &get_trackdata(0)->id3
;
2115 #endif /* !SIMULATOR */
2118 struct mp3entry
* audio_next_track()
2122 #else /* !SIMULATOR */
2123 if(num_tracks_in_memory() > 1)
2124 return &get_trackdata(1)->id3
;
2127 #endif /* !SIMULATOR */
2130 bool audio_has_changed_track(void)
2132 if(last_track_counter
!= current_track_counter
)
2134 last_track_counter
= current_track_counter
;
2140 #if CONFIG_CODEC == MAS3587F
2142 void audio_init_playback(void)
2144 init_playback_done
= false;
2145 queue_post(&mpeg_queue
, MPEG_INIT_PLAYBACK
, 0);
2147 while(!init_playback_done
)
2152 /****************************************************************************
2153 * Recording functions
2154 ***************************************************************************/
2155 void audio_init_recording(unsigned int buffer_offset
)
2157 buffer_offset
= buffer_offset
;
2158 init_recording_done
= false;
2159 queue_post(&mpeg_queue
, MPEG_INIT_RECORDING
, 0);
2161 while(!init_recording_done
)
2165 static void init_recording(void)
2177 /* Init the recording variables */
2178 is_recording
= false;
2179 is_prerecording
= false;
2181 mpeg_stop_done
= true;
2185 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2186 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
2188 panicf("mas_ctrl_w: %d", rc
);
2190 /* Stop the current application */
2192 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2195 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2198 /* Perform black magic as described by the data sheet */
2199 if((mas_version_code
& 0x0fff) == 0x0102)
2201 DEBUGF("Performing MAS black magic for B2 version\n");
2202 mas_writereg(0xa3, 0x98);
2203 mas_writereg(0x94, 0xfffff);
2205 mas_writemem(MAS_BANK_D1
, 0, &val
, 1);
2206 mas_writereg(0xa3, 0x90);
2209 /* Enable A/D Converters */
2210 shadow_codec_reg0
= 0xcccd;
2211 mas_codec_writereg(0x0, shadow_codec_reg0
);
2213 /* Copy left channel to right (mono mode) */
2214 mas_codec_writereg(8, 0x8000);
2216 /* ADC scale 0%, DSP scale 100%
2217 We use the DSP output for monitoring, because it works with all
2218 sources including S/PDIF */
2219 mas_codec_writereg(6, 0x0000);
2220 mas_codec_writereg(7, 0x4000);
2223 shadow_soft_mute
= 0;
2224 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2226 #ifdef HAVE_SPDIF_OUT
2227 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2229 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2231 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
2233 /* Set Demand mode, monitoring OFF and validate all settings */
2234 shadow_io_control_main
= 0x125;
2235 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2237 /* Start the encoder application */
2239 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2242 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2243 } while(!(val
& 0x40));
2245 /* We have started the recording application with monitoring OFF.
2246 This is because we want to record at least one frame to fill the DMA
2247 buffer, because the silly MAS will not negate EOD until at least one
2248 DMA transfer has taken place.
2249 Now let's wait for some data to be encoded. */
2252 /* Now set it to Monitoring mode as default, saves power */
2253 shadow_io_control_main
= 0x525;
2254 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2256 /* Wait until the DSP has accepted the settings */
2259 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2263 mpeg_mode
= MPEG_ENCODER
;
2265 DEBUGF("MAS Recording application started\n");
2267 /* At this point, all settings are the reset MAS defaults, next thing is to
2268 call mpeg_set_recording_options(). */
2271 void audio_record(const char *filename
)
2275 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2276 recording_filename
[MAX_PATH
- 1] = 0;
2278 queue_post(&mpeg_queue
, MPEG_RECORD
, 0);
2281 void audio_pause_recording(void)
2283 queue_post(&mpeg_queue
, MPEG_PAUSE_RECORDING
, 0);
2286 void audio_resume_recording(void)
2288 queue_post(&mpeg_queue
, MPEG_RESUME_RECORDING
, 0);
2291 static void prepend_header(void)
2296 /* Make room for header */
2297 audiobuf_read
-= MPEG_RESERVED_HEADER_SPACE
;
2298 if(audiobuf_read
< 0)
2300 /* Clear the bottom half */
2301 memset(audiobuf
, 0, audiobuf_read
+ MPEG_RESERVED_HEADER_SPACE
);
2303 /* And the top half */
2304 audiobuf_read
+= audiobuflen
;
2305 memset(audiobuf
+ audiobuf_read
, 0, audiobuflen
- audiobuf_read
);
2309 memset(audiobuf
+ audiobuf_read
, 0, MPEG_RESERVED_HEADER_SPACE
);
2311 /* Copy the empty ID3 header */
2312 startpos
= audiobuf_read
;
2313 for(i
= 0; i
< sizeof(empty_id3_header
); i
++)
2315 audiobuf
[startpos
++] = empty_id3_header
[i
];
2316 if(startpos
== audiobuflen
)
2321 static void update_header(void)
2324 unsigned long frames
;
2326 if (last_rec_bytes
> 0)
2328 /* Create the Xing header */
2329 fd
= open(delayed_filename
, O_RDWR
);
2331 panicf("rec upd: %d (%s)", fd
, recording_filename
);
2333 frames
= frame_count_end
- frame_count_start
;
2334 /* If the number of recorded frames has reached 0x7ffff,
2335 we can no longer trust it */
2336 if (frame_count_end
== 0x7ffff)
2339 /* saved_header is saved right before stopping the MAS */
2340 framelen
= create_xing_header(fd
, 0, last_rec_bytes
, xing_buffer
,
2341 frames
, last_rec_time
* (1000/HZ
),
2342 saved_header
, NULL
, false);
2344 lseek(fd
, MPEG_RESERVED_HEADER_SPACE
- framelen
, SEEK_SET
);
2345 write(fd
, xing_buffer
, framelen
);
2350 static void start_prerecording(void)
2354 DEBUGF("Starting prerecording\n");
2356 prerecord_index
= 0;
2357 prerecord_count
= 0;
2358 prerecord_timeout
= current_tick
+ HZ
;
2359 memset(prerecord_buffer
, 0, sizeof(prerecord_buffer
));
2362 is_prerecording
= true;
2364 /* Stop monitoring and start the encoder */
2365 shadow_io_control_main
&= ~(1 << 10);
2366 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2367 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2369 /* Wait until the DSP has accepted the settings */
2372 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2375 is_recording
= true;
2376 saving_status
= NOT_SAVING
;
2378 demand_irq_enable(true);
2381 static void start_recording(void)
2387 /* This will make the IRQ handler start recording
2388 for real, i.e send MPEG_SAVE_DATA messages when
2389 the buffer is full */
2390 is_prerecording
= false;
2394 /* If prerecording is off, we need to stop the monitoring
2395 and start the encoder */
2396 shadow_io_control_main
&= ~(1 << 10);
2397 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2398 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2400 /* Wait until the DSP has accepted the settings */
2403 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2407 is_recording
= true;
2408 saving_status
= NOT_SAVING
;
2411 /* Store the current time */
2413 record_start_time
= current_tick
- prerecord_count
* HZ
;
2415 record_start_time
= current_tick
;
2417 pause_start_time
= 0;
2419 demand_irq_enable(true);
2422 static void pause_recording(void)
2424 pause_start_time
= current_tick
;
2426 /* Set the pause bit */
2427 shadow_soft_mute
|= 2;
2428 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2433 static void resume_recording(void)
2437 /* Clear the pause bit */
2438 shadow_soft_mute
&= ~2;
2439 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2441 /* Compensate for the time we have been paused */
2442 if(pause_start_time
)
2445 current_tick
- (pause_start_time
- record_start_time
);
2446 pause_start_time
= 0;
2450 static void stop_recording(void)
2454 /* Let it finish the last frame */
2459 demand_irq_enable(false);
2461 is_recording
= false;
2462 is_prerecording
= false;
2464 last_rec_bytes
= num_rec_bytes
;
2465 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
, &frame_count_end
, 1);
2466 last_rec_time
= current_tick
- record_start_time
;
2468 /* Start monitoring */
2469 shadow_io_control_main
|= (1 << 10);
2470 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2471 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2473 /* Wait until the DSP has accepted the settings */
2476 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2482 void audio_set_recording_options(struct audio_recording_options
*options
)
2486 is_mpeg1
= (options
->rec_frequency
< 3)?true:false;
2488 rec_version_index
= is_mpeg1
?3:2;
2489 rec_frequency_index
= options
->rec_frequency
% 3;
2491 shadow_encoder_control
= (options
->rec_quality
<< 17) |
2492 (rec_frequency_index
<< 10) |
2493 ((is_mpeg1
?1:0) << 9) |
2494 (((options
->rec_channels
* 2 + 1) & 3) << 6) |
2495 (1 << 5) /* MS-stereo */ |
2496 (1 << 2) /* Is an original */;
2497 mas_writemem(MAS_BANK_D0
, MAS_D0_ENCODER_CONTROL
, &shadow_encoder_control
,1);
2499 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control
);
2501 shadow_soft_mute
= options
->rec_editable
?4:0;
2502 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
,1);
2504 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute
);
2506 shadow_io_control_main
= ((1 << 10) | /* Monitoring ON */
2507 ((options
->rec_source
< 2)?1:2) << 8) | /* Input select */
2508 (1 << 5) | /* SDO strobe invert */
2509 ((is_mpeg1
?0:1) << 3) |
2510 (1 << 2) | /* Inverted SIBC clock signal */
2512 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
,1);
2514 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2516 if(options
->rec_source
== AUDIO_SRC_MIC
)
2518 /* Copy left channel to right (mono mode) */
2519 mas_codec_writereg(8, 0x8000);
2523 /* Stereo input mode */
2524 mas_codec_writereg(8, 0);
2527 prerecording_max_seconds
= options
->rec_prerecord_time
;
2528 if(prerecording_max_seconds
)
2530 prerecording
= true;
2531 start_prerecording();
2535 prerecording
= false;
2536 is_prerecording
= false;
2537 is_recording
= false;
2541 /* If use_mic is true, the left gain is used */
2542 void audio_set_recording_gain(int left
, int right
, int type
)
2544 /* Enable both left and right A/D */
2545 shadow_codec_reg0
= (left
<< 12) |
2548 (type
==AUDIO_GAIN_MIC
?0x0008:0) | /* Connect left A/D to mic */
2550 mas_codec_writereg(0x0, shadow_codec_reg0
);
2553 #if CONFIG_TUNER & S1A0903X01
2554 /* Get the (unpitched) MAS PLL frequency, for avoiding FM interference with the
2555 * Samsung tuner. Zero means unknown. Currently handles recording from analog
2557 int mpeg_get_mas_pllfreq(void)
2559 if (mpeg_mode
!= MPEG_ENCODER
)
2562 if (rec_frequency_index
== 0) /* 44.1 kHz / 22.05 kHz */
2567 #endif /* CONFIG_TUNER & S1A0903X01 */
2569 /* try to make some kind of beep, also in recording mode */
2570 void audio_beep(int duration
)
2572 long starttick
= current_tick
;
2574 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2575 * While this is still audible even without an external signal,
2576 * it doesn't affect the (pre-)recording. */
2577 mas_codec_writereg(0, shadow_codec_reg0
^ 1);
2578 mas_codec_writereg(0, shadow_codec_reg0
);
2581 while (current_tick
- starttick
< duration
);
2584 void audio_new_file(const char *filename
)
2588 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2589 recording_filename
[MAX_PATH
- 1] = 0;
2591 queue_post(&mpeg_queue
, MPEG_NEW_FILE
, 0);
2594 unsigned long audio_recorded_time(void)
2597 return prerecord_count
* HZ
;
2602 return pause_start_time
- record_start_time
;
2604 return current_tick
- record_start_time
;
2610 unsigned long audio_num_recorded_bytes(void)
2619 index
= prerecord_index
- prerecord_count
;
2621 index
+= prerecording_max_seconds
;
2623 num_bytes
= audiobuf_write
- prerecord_buffer
[index
].mempos
;
2625 num_bytes
+= audiobuflen
;
2630 return num_rec_bytes
;
2636 #else /* SIMULATOR */
2638 /* dummies coming up */
2640 void audio_init_playback(void)
2644 unsigned long audio_recorded_time(void)
2649 void audio_beep(int duration
)
2654 void audio_pause_recording(void)
2658 void audio_resume_recording(void)
2662 unsigned long audio_num_recorded_bytes(void)
2667 void audio_record(const char *filename
)
2672 void audio_new_file(const char *filename
)
2678 void audio_set_recording_gain(int left
, int right
, int type
)
2685 void audio_init_recording(unsigned int buffer_offset
)
2688 (void)buffer_offset
;
2690 void audio_set_recording_options(struct audio_recording_options
*options
)
2695 #endif /* SIMULATOR */
2696 #endif /* CONFIG_CODEC == MAS3587F */
2698 void audio_play(long offset
)
2707 trackname
= playlist_peek( steps
);
2710 if(mp3info(&taginfo
, trackname
, v1first
)) {
2711 /* bad mp3, move on */
2712 if(++steps
> playlist_amount())
2716 #ifdef HAVE_MPEG_PLAY
2717 real_mpeg_play(trackname
);
2719 playlist_next(steps
);
2720 taginfo
.offset
= offset
;
2721 set_elapsed(&taginfo
);
2726 #else /* !SIMULATOR */
2729 queue_post(&mpeg_queue
, MPEG_PLAY
, offset
);
2730 #endif /* !SIMULATOR */
2735 void audio_stop(void)
2740 struct trackdata
*track
= get_trackdata(0);
2741 prev_track_elapsed
= track
->id3
.elapsed
;
2743 mpeg_stop_done
= false;
2744 queue_post(&mpeg_queue
, MPEG_STOP
, 0);
2745 while(!mpeg_stop_done
)
2747 #else /* SIMULATOR */
2751 #endif /* SIMULATOR */
2755 void audio_stop_recording(void)
2760 void audio_pause(void)
2763 queue_post(&mpeg_queue
, MPEG_PAUSE
, 0);
2764 #else /* SIMULATOR */
2768 #endif /* SIMULATOR */
2771 void audio_resume(void)
2774 queue_post(&mpeg_queue
, MPEG_RESUME
, 0);
2775 #else /* SIMULATOR */
2779 #endif /* SIMULATOR */
2782 void audio_next(void)
2785 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2786 queue_post(&mpeg_queue
, MPEG_NEXT
, 0);
2787 #else /* SIMULATOR */
2793 file
= playlist_peek(steps
);
2796 if(mp3info(&taginfo
, file
, v1first
)) {
2797 if(++steps
> playlist_amount())
2801 index
= playlist_next(steps
);
2802 taginfo
.index
= index
;
2803 current_track_counter
++;
2808 #endif /* SIMULATOR */
2811 void audio_prev(void)
2814 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2815 queue_post(&mpeg_queue
, MPEG_PREV
, 0);
2816 #else /* SIMULATOR */
2822 file
= playlist_peek(steps
);
2825 if(mp3info(&taginfo
, file
, v1first
)) {
2829 index
= playlist_next(steps
);
2830 taginfo
.index
= index
;
2831 current_track_counter
++;
2836 #endif /* SIMULATOR */
2839 void audio_ff_rewind(long newtime
)
2842 queue_post(&mpeg_queue
, MPEG_FF_REWIND
, newtime
);
2843 #else /* SIMULATOR */
2845 #endif /* SIMULATOR */
2848 void audio_flush_and_reload_tracks(void)
2851 queue_post(&mpeg_queue
, MPEG_FLUSH_RELOAD
, 0);
2852 #endif /* !SIMULATOR*/
2855 int audio_status(void)
2860 ret
|= AUDIO_STATUS_PLAY
;
2863 ret
|= AUDIO_STATUS_PAUSE
;
2865 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2866 if(is_recording
&& !is_prerecording
)
2867 ret
|= AUDIO_STATUS_RECORD
;
2870 ret
|= AUDIO_STATUS_PRERECORD
;
2871 #endif /* CONFIG_CODEC == MAS3587F */
2874 ret
|= AUDIO_STATUS_ERROR
;
2879 unsigned int audio_error(void)
2884 void audio_error_clear(void)
2890 static void mpeg_thread(void)
2892 struct mp3entry
* id3
;
2895 id3
= audio_current_track();
2901 if (id3
->elapsed
>=id3
->length
)
2907 #endif /* SIMULATOR */
2909 void audio_init(void)
2912 track_buffer_callback
= NULL
;
2913 track_unbuffer_callback
= NULL
;
2916 audiobuflen
= audiobufend
- audiobuf
;
2917 queue_init(&mpeg_queue
, true);
2918 #endif /* !SIMULATOR */
2919 create_thread(mpeg_thread
, mpeg_stack
,
2920 sizeof(mpeg_stack
), mpeg_thread_name
IF_PRIO(, PRIORITY_SYSTEM
)
2921 IF_COP(, CPU
, false));
2923 memset(trackdata
, sizeof(trackdata
), 0);
2925 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2926 if (HW_MASK
& PR_ACTIVE_HIGH
)
2927 and_b(~0x08, &PADRH
);
2930 #endif /* CONFIG_CODEC == MAS3587F */
2938 #endif /* CONFIG_CODEC != SWCODEC */