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
);
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 filling
; /* We are filling the buffer with data from disk */
153 static bool dma_underrun
; /* True when the DMA has stopped because of
154 slow disk reading (read error, shaking) */
155 static bool mpeg_stop_done
;
157 static int last_dma_tick
= 0;
158 static int last_dma_chunk_size
;
160 static long low_watermark
; /* Dynamic low watermark level */
161 static long low_watermark_margin
; /* Extra time in seconds for watermark */
162 static long lowest_watermark_level
; /* Debug value to observe the buffer
164 #if CONFIG_CODEC == MAS3587F
165 static char recording_filename
[MAX_PATH
]; /* argument to thread */
166 static char delayed_filename
[MAX_PATH
]; /* internal copy of above */
168 static char xing_buffer
[MAX_XING_HEADER_SIZE
];
170 static bool init_recording_done
;
171 static bool init_playback_done
;
172 static bool prerecording
; /* True if prerecording is enabled */
173 static bool is_prerecording
; /* True if we are prerecording */
174 static bool is_recording
; /* We are recording */
177 NOT_SAVING
= 0, /* reasons to save data, sorted by importance */
183 static int rec_frequency_index
; /* For create_xing_header() calls */
184 static int rec_version_index
; /* For create_xing_header() calls */
186 struct prerecord_info
{
188 unsigned long framecount
;
191 static struct prerecord_info prerecord_buffer
[MPEG_MAX_PRERECORD_SECONDS
];
192 static int prerecord_index
; /* Current index in the prerecord buffer */
193 static int prerecording_max_seconds
; /* Max number of seconds to store */
194 static int prerecord_count
; /* Number of seconds in the prerecord buffer */
195 static int prerecord_timeout
; /* The tick count of the next prerecord data
198 unsigned long record_start_time
; /* Value of current_tick when recording
200 unsigned long pause_start_time
; /* Value of current_tick when pause was
202 static unsigned long last_rec_time
;
203 static unsigned long num_rec_bytes
;
204 static unsigned long last_rec_bytes
;
205 static unsigned long frame_count_start
;
206 static unsigned long frame_count_end
;
207 static unsigned long saved_header
= 0;
209 /* Shadow MAS registers */
210 unsigned long shadow_encoder_control
= 0;
211 #endif /* CONFIG_CODEC == MAS3587F */
213 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
214 unsigned long shadow_io_control_main
= 0;
215 unsigned long shadow_soft_mute
= 0;
216 unsigned shadow_codec_reg0
;
217 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
219 #ifdef HAVE_RECORDING
220 const unsigned char empty_id3_header
[] =
222 'I', 'D', '3', 0x03, 0x00, 0x00,
223 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
225 #endif /* HAVE_RECORDING */
228 static int get_unplayed_space(void);
229 static int get_playable_space(void);
230 static int get_unswapped_space(void);
231 #endif /* !SIMULATOR */
233 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
234 static void init_recording(void);
235 static void prepend_header(void);
236 static void update_header(void);
237 static void start_prerecording(void);
238 static void start_recording(void);
239 static void stop_recording(void);
240 static int get_unsaved_space(void);
241 static void pause_recording(void);
242 static void resume_recording(void);
243 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
247 static int num_tracks_in_memory(void)
249 return (track_write_idx
- track_read_idx
) & MAX_TRACK_ENTRIES_MASK
;
253 static void debug_tags(void)
257 for(i
= 0;i
< MAX_TRACK_ENTRIES
;i
++)
259 DEBUGF("%d - %s\n", i
, trackdata
[i
].id3
.path
);
261 DEBUGF("read: %d, write :%d\n", track_read_idx
, track_write_idx
);
262 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
264 #else /* !DEBUG_TAGS */
266 #endif /* !DEBUG_TAGS */
268 static void remove_current_tag(void)
270 if(num_tracks_in_memory() > 0)
272 /* First move the index, so nobody tries to access the tag */
273 track_read_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
278 DEBUGF("remove_current_tag: no tracks to remove\n");
282 static void remove_all_non_current_tags(void)
284 track_write_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
288 static void remove_all_tags(void)
290 track_write_idx
= track_read_idx
;
295 static struct trackdata
*get_trackdata(int offset
)
297 if(offset
>= num_tracks_in_memory())
300 return &trackdata
[(track_read_idx
+ offset
) & MAX_TRACK_ENTRIES_MASK
];
302 #endif /* !SIMULATOR */
304 /***********************************************************************/
305 /* audio event handling */
307 #define MAX_EVENT_HANDLERS 10
308 struct event_handlers_table
310 AUDIO_EVENT_HANDLER handler
;
313 static struct event_handlers_table event_handlers
[MAX_EVENT_HANDLERS
];
314 static int event_handlers_count
= 0;
316 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler
, unsigned short mask
)
318 if (event_handlers_count
< MAX_EVENT_HANDLERS
)
320 event_handlers
[event_handlers_count
].handler
= handler
;
321 event_handlers
[event_handlers_count
].mask
= mask
;
322 event_handlers_count
++;
326 /* dispatch calls each handler in the order registered and returns after some
327 handler actually handles the event (the event is assumed to no longer be valid
328 after this, due to the handler changing some condition); returns true if someone
329 handled the event, which is expected to cause the caller to skip its own handling
332 static bool audio_dispatch_event(unsigned short event
, unsigned long data
)
335 for(i
=0; i
< event_handlers_count
; i
++)
337 if ( event_handlers
[i
].mask
& event
)
339 int rc
= event_handlers
[i
].handler(event
, data
);
340 if ( rc
== AUDIO_EVENT_RC_HANDLED
)
348 /***********************************************************************/
350 static void set_elapsed(struct mp3entry
* id3
)
353 if ( id3
->has_toc
) {
354 /* calculate elapsed time using TOC */
356 unsigned int remainder
, plen
, relpos
, nextpos
;
358 /* find wich percent we're at */
359 for (i
=0; i
<100; i
++ )
361 if ( id3
->offset
< id3
->toc
[i
] * (id3
->filesize
/ 256) )
371 relpos
= id3
->toc
[i
];
375 nextpos
= id3
->toc
[i
+1];
382 remainder
= id3
->offset
- (relpos
* (id3
->filesize
/ 256));
384 /* set time for this percent (divide before multiply to prevent
385 overflow on long files. loss of precision is negligible on
387 id3
->elapsed
= i
* (id3
->length
/ 100);
389 /* calculate remainder time */
390 plen
= (nextpos
- relpos
) * (id3
->filesize
/ 256);
391 id3
->elapsed
+= (((remainder
* 100) / plen
) *
392 (id3
->length
/ 10000));
395 /* no TOC exists. set a rough estimate using average bitrate */
396 int tpk
= id3
->length
/ (id3
->filesize
/ 1024);
397 id3
->elapsed
= id3
->offset
/ 1024 * tpk
;
401 /* constant bitrate, use exact calculation */
402 id3
->elapsed
= id3
->offset
/ (id3
->bitrate
/ 8);
405 int audio_get_file_pos(void)
408 struct mp3entry
*id3
= audio_current_track();
414 /* Use the TOC to find the new position */
415 unsigned int percent
, remainder
;
416 int curtoc
, nexttoc
, plen
;
418 percent
= (id3
->elapsed
*100)/id3
->length
;
422 curtoc
= id3
->toc
[percent
];
425 nexttoc
= id3
->toc
[percent
+1];
429 pos
= (id3
->filesize
/256)*curtoc
;
431 /* Use the remainder to get a more accurate position */
432 remainder
= (id3
->elapsed
*100)%id3
->length
;
433 remainder
= (remainder
*100)/id3
->length
;
434 plen
= (nexttoc
- curtoc
)*(id3
->filesize
/256);
435 pos
+= (plen
/100)*remainder
;
439 /* No TOC exists, estimate the new position */
440 pos
= (id3
->filesize
/ (id3
->length
/ 1000)) *
441 (id3
->elapsed
/ 1000);
444 else if (id3
->bitrate
)
445 pos
= id3
->elapsed
* (id3
->bitrate
/ 8);
451 if (pos
>= (int)(id3
->filesize
- id3
->id3v1len
))
453 /* Don't seek right to the end of the file so that we can
454 transition properly to the next song */
455 pos
= id3
->filesize
- id3
->id3v1len
- 1;
457 else if (pos
< (int)id3
->first_frame_offset
)
459 /* skip past id3v2 tag and other leading garbage */
460 pos
= id3
->first_frame_offset
;
465 unsigned long mpeg_get_last_header(void)
469 #else /* !SIMULATOR */
470 unsigned long tmp
[2];
472 /* Read the frame data from the MAS and reconstruct it with the
473 frame sync and all */
474 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_STATUS_1
, tmp
, 2);
475 return 0xffe00000 | ((tmp
[0] & 0x7c00) << 6) | (tmp
[1] & 0xffff);
476 #endif /* !SIMULATOR */
479 void audio_set_track_buffer_event(void (*handler
)(struct mp3entry
*id3
,
482 track_buffer_callback
= handler
;
485 void audio_set_track_unbuffer_event(void (*handler
)(struct mp3entry
*id3
,
488 track_unbuffer_callback
= handler
;
491 void audio_set_track_changed_event(void (*handler
)(struct mp3entry
*id3
))
493 track_changed_callback
= handler
;
496 void audio_set_cuesheet_callback(bool (*handler
)(const char *filename
))
498 cuesheet_callback
= handler
;
502 /* Send callback events to notify about removing old tracks. */
503 static void generate_unbuffer_events(void)
507 int numentries
= MAX_TRACK_ENTRIES
- num_tracks_in_memory();
508 int cur_idx
= track_write_idx
;
510 for (i
= 0; i
< numentries
; i
++)
512 if (trackdata
[cur_idx
].event_sent
)
515 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
518 cur_idx
= track_write_idx
;
520 for (i
= 0; i
< numentries
; i
++)
522 /* Send an event to notify that track has finished. */
523 if (trackdata
[cur_idx
].event_sent
)
526 if (track_unbuffer_callback
)
527 track_unbuffer_callback(&trackdata
[cur_idx
].id3
,
529 trackdata
[cur_idx
].event_sent
= false;
531 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
535 /* Send callback events to notify about new tracks. */
536 static void generate_postbuffer_events(void)
540 int numentries
= num_tracks_in_memory();
541 int cur_idx
= track_read_idx
;
543 for (i
= 0; i
< numentries
; i
++)
545 if (!trackdata
[cur_idx
].event_sent
)
548 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
551 cur_idx
= track_read_idx
;
553 for (i
= 0; i
< numentries
; i
++)
555 if (!trackdata
[cur_idx
].event_sent
)
558 if (track_buffer_callback
)
559 track_buffer_callback(&trackdata
[cur_idx
].id3
,
561 trackdata
[cur_idx
].event_sent
= true;
563 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
567 static void recalculate_watermark(int bitrate
)
570 int time
= ata_spinup_time
;
572 /* A bitrate of 0 probably means empty VBR header. We play safe
573 and set a high threshold */
577 bytes_per_sec
= bitrate
* 1000 / 8;
581 /* No drive spins up faster than 3.5s */
586 low_watermark
= ((low_watermark_margin
* HZ
+ time
) *
591 low_watermark
= MPEG_LOW_WATER
;
595 void audio_set_buffer_margin(int seconds
)
597 low_watermark_margin
= seconds
;
600 void audio_get_debugdata(struct audio_debug
*dbgdata
)
602 dbgdata
->audiobuflen
= audiobuflen
;
603 dbgdata
->audiobuf_write
= audiobuf_write
;
604 dbgdata
->audiobuf_swapwrite
= audiobuf_swapwrite
;
605 dbgdata
->audiobuf_read
= audiobuf_read
;
607 dbgdata
->last_dma_chunk_size
= last_dma_chunk_size
;
609 #if CONFIG_CPU == SH7034
610 dbgdata
->dma_on
= (SCR0
& 0x80) != 0;
612 dbgdata
->playing
= playing
;
613 dbgdata
->play_pending
= play_pending
;
614 dbgdata
->is_playing
= is_playing
;
615 dbgdata
->filling
= filling
;
616 dbgdata
->dma_underrun
= dma_underrun
;
618 dbgdata
->unplayed_space
= get_unplayed_space();
619 dbgdata
->playable_space
= get_playable_space();
620 dbgdata
->unswapped_space
= get_unswapped_space();
622 dbgdata
->low_watermark_level
= low_watermark
;
623 dbgdata
->lowest_watermark_level
= lowest_watermark_level
;
627 static void dbg_timer_start(void)
629 /* We are using timer 2 */
631 TSTR
&= ~0x04; /* Stop the timer */
632 TSNC
&= ~0x04; /* No synchronization */
633 TMDR
&= ~0x44; /* Operate normally */
635 TCNT2
= 0; /* Start counting at 0 */
636 TCR2
= 0x03; /* Sysclock/8 */
638 TSTR
|= 0x04; /* Start timer 2 */
641 static int dbg_cnt2us(unsigned int cnt
)
643 return (cnt
* 10000) / (FREQ
/800);
647 static int get_unplayed_space(void)
649 int space
= audiobuf_write
- audiobuf_read
;
651 space
+= audiobuflen
;
655 static int get_playable_space(void)
657 int space
= audiobuf_swapwrite
- audiobuf_read
;
659 space
+= audiobuflen
;
663 static int get_unplayed_space_current_song(void)
667 if (num_tracks_in_memory() > 1)
669 space
= get_trackdata(1)->mempos
- audiobuf_read
;
673 space
= audiobuf_write
- audiobuf_read
;
677 space
+= audiobuflen
;
682 static int get_unswapped_space(void)
684 int space
= audiobuf_write
- audiobuf_swapwrite
;
686 space
+= audiobuflen
;
690 #if CONFIG_CODEC == MAS3587F
691 static int get_unsaved_space(void)
693 int space
= audiobuf_write
- audiobuf_read
;
695 space
+= audiobuflen
;
699 static void drain_dma_buffer(void)
705 while (PBDRH
& 0x80);
709 while (!(PBDRH
& 0x80));
714 static long timing_info_index
= 0;
715 static long timing_info
[1024];
718 void rec_tick (void) __attribute__ ((section (".icode")));
725 if(is_recording
&& (PBDRH
& 0x40))
728 timing_info
[timing_info_index
++] = current_tick
;
731 /* Note: Although this loop is run in interrupt context, further
732 * optimisation will do no good. The MAS would then deliver bad
733 * frames occasionally, as observed in extended experiments. */
735 while (PBDRH
& 0x40) /* We try to read as long as EOD is high */
737 xor_b(0x08, &PADRH
); /* Set PR active, independent of polarity */
740 while (PBDRH
& 0x80) /* Wait until /RTW becomes active */
742 if (--delay
<= 0) /* Bail out if we have to wait too long */
743 { /* i.e. the MAS doesn't want to talk to us */
744 xor_b(0x08, &PADRH
); /* Set PR inactive */
745 goto transfer_end
; /* and get out of here */
749 data
= *(unsigned char *)0x04000000; /* read data byte */
751 xor_b(0x08, &PADRH
); /* Set PR inactive */
753 audiobuf
[audiobuf_write
++] = data
;
755 if (audiobuf_write
>= audiobuflen
)
763 timing_info
[timing_info_index
++] = TCNT2
+ (i
<< 16);
764 timing_info_index
&= 0x3ff;
771 if(TIME_AFTER(current_tick
, prerecord_timeout
))
773 prerecord_timeout
= current_tick
+ HZ
;
774 queue_post(&mpeg_queue
, MPEG_PRERECORDING_TICK
, 0);
779 /* Signal to save the data if we are running out of buffer
781 if (audiobuflen
- get_unsaved_space() < MPEG_RECORDING_LOW_WATER
782 && saving_status
== NOT_SAVING
)
784 saving_status
= BUFFER_FULL
;
785 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
790 #endif /* CONFIG_CODEC == MAS3587F */
792 void playback_tick(void)
794 struct trackdata
*ptd
= get_trackdata(0);
797 ptd
->id3
.elapsed
+= (current_tick
- last_dma_tick
) * 1000 / HZ
;
798 last_dma_tick
= current_tick
;
799 audio_dispatch_event(AUDIO_EVENT_POS_REPORT
,
800 (unsigned long)ptd
->id3
.elapsed
);
804 static void reset_mp3_buffer(void)
808 audiobuf_swapwrite
= 0;
809 lowest_watermark_level
= audiobuflen
;
812 /* DMA transfer end interrupt callback */
813 static void transfer_end(unsigned char** ppbuf
, size_t* psize
)
815 if(playing
&& !paused
)
817 int unplayed_space_left
;
818 int space_until_end_of_buffer
;
819 int track_offset
= 1;
820 struct trackdata
*track
;
822 audiobuf_read
+= last_dma_chunk_size
;
823 if(audiobuf_read
>= audiobuflen
)
826 /* First, check if we are on a track boundary */
827 if (num_tracks_in_memory() > 1)
829 if (audiobuf_read
== get_trackdata(track_offset
)->mempos
)
831 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
833 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
839 unplayed_space_left
= get_unplayed_space();
841 space_until_end_of_buffer
= audiobuflen
- audiobuf_read
;
843 if(!filling
&& unplayed_space_left
< low_watermark
)
846 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
849 if(unplayed_space_left
)
851 last_dma_chunk_size
= MIN(0x2000, unplayed_space_left
);
852 last_dma_chunk_size
= MIN(last_dma_chunk_size
,
853 space_until_end_of_buffer
);
855 /* several tracks loaded? */
856 track
= get_trackdata(track_offset
);
859 /* will we move across the track boundary? */
860 if (( audiobuf_read
< track
->mempos
) &&
861 ((audiobuf_read
+last_dma_chunk_size
) >
864 /* Make sure that we end exactly on the boundary */
865 last_dma_chunk_size
= track
->mempos
- audiobuf_read
;
869 *psize
= last_dma_chunk_size
& 0xffff;
870 *ppbuf
= audiobuf
+ audiobuf_read
;
871 track
= get_trackdata(0);
873 track
->id3
.offset
+= last_dma_chunk_size
;
875 /* Update the watermark debug level */
876 if(unplayed_space_left
< lowest_watermark_level
)
877 lowest_watermark_level
= unplayed_space_left
;
881 /* Check if the end of data is because of a hard disk error.
882 If there is an open file handle, we are still playing music.
883 If not, the last file has been loaded, and the file handle is
887 /* Update the watermark debug level */
888 if(unplayed_space_left
< lowest_watermark_level
)
889 lowest_watermark_level
= unplayed_space_left
;
891 DEBUGF("DMA underrun.\n");
896 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
898 DEBUGF("No more MP3 data. Stopping.\n");
899 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
903 *psize
= 0; /* no more transfer */
908 static struct trackdata
*add_track_to_tag_list(const char *filename
)
910 struct trackdata
*track
;
912 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES
)
914 DEBUGF("Tag memory is full\n");
918 track
= &trackdata
[track_write_idx
];
920 /* grab id3 tag of new file and
921 remember where in memory it starts */
922 if(mp3info(&track
->id3
, filename
, v1first
))
927 track
->mempos
= audiobuf_write
;
928 track
->id3
.elapsed
= 0;
929 #ifdef HAVE_LCD_BITMAP
930 if (track
->id3
.title
)
931 lcd_getstringsize(track
->id3
.title
, NULL
, NULL
);
932 if (track
->id3
.artist
)
933 lcd_getstringsize(track
->id3
.artist
, NULL
, NULL
);
934 if (track
->id3
.album
)
935 lcd_getstringsize(track
->id3
.album
, NULL
, NULL
);
937 if (cuesheet_callback
)
938 if (cuesheet_callback(filename
))
939 track
->id3
.cuesheet_type
= 1;
941 track_write_idx
= (track_write_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
946 static int new_file(int steps
)
948 int max_steps
= playlist_amount();
951 struct trackdata
*track
;
953 /* Find out how many steps to advance. The load_ahead_index field tells
954 us how many playlist entries it had to skip to get to a valid one.
955 We add those together to find out where to start. */
956 if(steps
> 0 && num_tracks_in_memory() > 1)
958 /* Begin with the song after the currently playing one */
960 while((track
= get_trackdata(i
++)))
962 start
+= track
->load_ahead_index
;
969 trackname
= playlist_peek( start
+ steps
);
973 DEBUGF("Loading %s\n", trackname
);
975 mpeg_file
= open(trackname
, O_RDONLY
);
977 DEBUGF("Couldn't open file: %s\n",trackname
);
985 struct trackdata
*track
= add_track_to_tag_list(trackname
);
999 /* skip past id3v2 tag */
1001 track
->id3
.first_frame_offset
,
1003 track
->id3
.index
= steps
;
1004 track
->load_ahead_index
= steps
;
1005 track
->id3
.offset
= 0;
1008 /* Average bitrate * 1.5 */
1009 recalculate_watermark(
1010 (track
->id3
.bitrate
* 3) / 2);
1012 recalculate_watermark(
1013 track
->id3
.bitrate
);
1018 /* Bail out if no file could be opened */
1019 if(abs(steps
) > max_steps
)
1021 } while ( mpeg_file
< 0 );
1026 static void stop_playing(void)
1028 /* Stop the current stream */
1036 generate_unbuffer_events();
1040 /* Is this a really the end of playback or is a new playlist starting */
1041 static void check_playlist_end(int direction
)
1043 /* Use the largest possible step size to account for skipped tracks */
1044 int steps
= playlist_amount();
1049 if (playlist_next(steps
) < 0)
1053 static void update_playlist(void)
1055 if (num_tracks_in_memory() > 0)
1057 struct trackdata
*track
= get_trackdata(0);
1058 track
->id3
.index
= playlist_next(track
->id3
.index
);
1062 /* End of playlist? */
1063 check_playlist_end(1);
1066 playlist_update_resume_info(audio_current_track());
1069 static void track_change(void)
1071 DEBUGF("Track change\n");
1073 struct trackdata
*track
= get_trackdata(0);
1074 prev_track_elapsed
= track
->id3
.elapsed
;
1076 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1079 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1081 if (num_tracks_in_memory() > 0)
1083 remove_current_tag();
1084 if (track_changed_callback
)
1085 track_changed_callback(audio_current_track());
1089 current_track_counter
++;
1092 unsigned long audio_prev_elapsed(void)
1094 return prev_track_elapsed
;
1098 void hexdump(const unsigned char *buf
, int len
)
1102 for(i
= 0;i
< len
;i
++)
1104 if(i
&& (i
& 15) == 0)
1108 DEBUGF("%02x ", buf
[i
]);
1114 static void start_playback_if_ready(void)
1118 playable_space
= audiobuf_swapwrite
- audiobuf_read
;
1119 if(playable_space
< 0)
1120 playable_space
+= audiobuflen
;
1122 /* See if we have started playing yet. If not, do it. */
1123 if(play_pending
|| dma_underrun
)
1125 /* If the filling has stopped, and we still haven't reached
1126 the watermark, the file must be smaller than the
1127 watermark. We must still play it. */
1128 if((playable_space
>= MPEG_PLAY_PENDING_THRESHOLD
) ||
1129 !filling
|| dma_underrun
)
1132 if (play_pending
) /* don't do this when recovering from DMA underrun */
1134 generate_postbuffer_events(); /* signal first track as buffered */
1135 if (track_changed_callback
)
1136 track_changed_callback(audio_current_track());
1137 play_pending
= false;
1141 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1142 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1143 dma_underrun
= false;
1147 last_dma_tick
= current_tick
;
1148 mp3_play_pause(true);
1151 /* Tell ourselves that we need more data */
1152 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1157 static bool swap_one_chunk(void)
1159 int free_space_left
;
1162 free_space_left
= get_unswapped_space();
1164 if(free_space_left
== 0 && !play_pending
)
1167 /* Swap in larger chunks when the user is waiting for the playback
1168 to start, or when there is dangerously little playable data left */
1170 amount_to_swap
= MIN(MPEG_PLAY_PENDING_SWAPSIZE
, free_space_left
);
1173 if(get_playable_space() < low_watermark
)
1174 amount_to_swap
= MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE
,
1177 amount_to_swap
= MIN(MPEG_SWAP_CHUNKSIZE
, free_space_left
);
1180 if(audiobuf_write
< audiobuf_swapwrite
)
1181 amount_to_swap
= MIN(audiobuflen
- audiobuf_swapwrite
,
1184 amount_to_swap
= MIN(audiobuf_write
- audiobuf_swapwrite
,
1187 bitswap(audiobuf
+ audiobuf_swapwrite
, amount_to_swap
);
1189 audiobuf_swapwrite
+= amount_to_swap
;
1190 if(audiobuf_swapwrite
>= audiobuflen
)
1192 audiobuf_swapwrite
= 0;
1198 static void mpeg_thread(void)
1200 static int pause_tick
= 0;
1201 static unsigned int pause_track
= 0;
1204 int free_space_left
;
1205 int unplayed_space_left
;
1209 #if CONFIG_CODEC == MAS3587F
1211 int save_endpos
= 0;
1215 #endif /* CONFIG_CODEC == MAS3587F */
1218 play_pending
= false;
1224 #if CONFIG_CODEC == MAS3587F
1225 if(mpeg_mode
== MPEG_DECODER
)
1227 #endif /* CONFIG_CODEC == MAS3587F */
1230 /* Swap if necessary, and don't block on the queue_wait() */
1231 if(swap_one_chunk())
1233 queue_wait_w_tmo(&mpeg_queue
, &ev
, 0);
1237 /* periodically update resume info */
1238 queue_wait_w_tmo(&mpeg_queue
, &ev
, HZ
/2);
1242 DEBUGF("S R:%x W:%x SW:%x\n",
1243 audiobuf_read
, audiobuf_write
, audiobuf_swapwrite
);
1244 queue_wait(&mpeg_queue
, &ev
);
1247 start_playback_if_ready();
1252 DEBUGF("MPEG_PLAY\n");
1255 /* Silence the A/D input, it may be on because the radio
1257 mas_codec_writereg(6, 0x0000);
1258 #endif /* CONFIG_TUNER */
1260 /* Stop the current stream */
1261 play_pending
= false;
1264 mp3_play_pause(false);
1268 generate_unbuffer_events();
1273 if ( new_file(0) == -1 )
1280 start_offset
= (int)ev
.data
;
1282 /* mid-song resume? */
1284 struct mp3entry
* id3
= &get_trackdata(0)->id3
;
1285 lseek(mpeg_file
, start_offset
, SEEK_SET
);
1286 id3
->offset
= start_offset
;
1290 /* skip past id3v2 tag */
1292 get_trackdata(0)->id3
.first_frame_offset
,
1297 /* Make it read more data */
1299 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1301 /* Tell the file loading code that we want to start playing
1302 as soon as we have some data */
1303 play_pending
= true;
1306 current_track_counter
++;
1310 DEBUGF("MPEG_STOP\n");
1315 playlist_update_resume_info(audio_current_track());
1318 mpeg_stop_done
= true;
1322 DEBUGF("MPEG_PAUSE\n");
1323 /* Stop the current stream */
1325 playlist_update_resume_info(audio_current_track());
1328 pause_tick
= current_tick
;
1329 pause_track
= current_track_counter
;
1330 mp3_play_pause(false);
1334 DEBUGF("MPEG_RESUME\n");
1335 /* Continue the current stream */
1340 if ( current_track_counter
== pause_track
)
1341 last_dma_tick
+= current_tick
- pause_tick
;
1343 last_dma_tick
= current_tick
;
1345 mp3_play_pause(true);
1350 DEBUGF("MPEG_NEXT\n");
1351 /* is next track in ram? */
1352 if ( num_tracks_in_memory() > 1 ) {
1353 int unplayed_space_left
, unswapped_space_left
;
1355 /* stop the current stream */
1356 play_pending
= false;
1358 mp3_play_pause(false);
1361 audiobuf_read
= get_trackdata(0)->mempos
;
1362 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1363 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1364 dma_underrun
= false;
1365 last_dma_tick
= current_tick
;
1367 unplayed_space_left
= get_unplayed_space();
1368 unswapped_space_left
= get_unswapped_space();
1370 /* should we start reading more data? */
1371 if(!filling
&& (unplayed_space_left
< low_watermark
)) {
1373 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1374 play_pending
= true;
1375 } else if(unswapped_space_left
&&
1376 unswapped_space_left
> unplayed_space_left
) {
1377 /* Stop swapping the data from the previous file */
1378 audiobuf_swapwrite
= audiobuf_read
;
1379 play_pending
= true;
1383 mp3_play_pause(true);
1387 if (!playlist_check(1))
1390 /* stop the current stream */
1391 play_pending
= false;
1393 mp3_play_pause(false);
1397 generate_unbuffer_events();
1399 /* Open the next file */
1403 if (new_file(1) < 0) {
1404 DEBUGF("No more files to play\n");
1407 check_playlist_end(1);
1408 current_track_counter
++;
1410 /* Make it read more data */
1412 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1414 /* Tell the file loading code that we want
1415 to start playing as soon as we have some data */
1416 play_pending
= true;
1419 current_track_counter
++;
1425 DEBUGF("MPEG_PREV\n");
1427 if (!playlist_check(-1))
1430 /* stop the current stream */
1431 play_pending
= false;
1433 mp3_play_pause(false);
1437 generate_unbuffer_events();
1439 /* Open the next file */
1443 if (new_file(-1) < 0) {
1444 DEBUGF("No more files to play\n");
1447 check_playlist_end(-1);
1448 current_track_counter
++;
1450 /* Make it read more data */
1452 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1454 /* Tell the file loading code that we want to
1455 start playing as soon as we have some data */
1456 play_pending
= true;
1459 current_track_counter
++;
1464 case MPEG_FF_REWIND
: {
1465 struct mp3entry
*id3
= audio_current_track();
1466 unsigned int oldtime
= id3
->elapsed
;
1467 unsigned int newtime
= (unsigned int)ev
.data
;
1468 int curpos
, newpos
, diffpos
;
1469 DEBUGF("MPEG_FF_REWIND\n");
1471 id3
->elapsed
= newtime
;
1473 newpos
= audio_get_file_pos();
1476 id3
->elapsed
= oldtime
;
1481 curpos
= lseek(mpeg_file
, 0, SEEK_CUR
);
1483 curpos
= id3
->filesize
;
1485 if (num_tracks_in_memory() > 1)
1487 /* We have started loading other tracks that need to be
1489 struct trackdata
*track
;
1492 while((track
= get_trackdata(i
++)))
1494 curpos
+= track
->id3
.filesize
;
1498 diffpos
= curpos
- newpos
;
1500 if(!filling
&& diffpos
>= 0 && diffpos
< audiobuflen
)
1502 int unplayed_space_left
, unswapped_space_left
;
1504 /* We are changing to a position that's already in
1505 memory, so we just move the DMA read pointer. */
1506 audiobuf_read
= audiobuf_write
- diffpos
;
1507 if (audiobuf_read
< 0)
1509 audiobuf_read
+= audiobuflen
;
1512 unplayed_space_left
= get_unplayed_space();
1513 unswapped_space_left
= get_unswapped_space();
1515 /* If unswapped_space_left is larger than
1516 unplayed_space_left, it means that the swapwrite pointer
1517 hasn't yet advanced up to the new location of the read
1518 pointer. We just move it, there is no need to swap
1519 data that won't be played anyway. */
1521 if (unswapped_space_left
> unplayed_space_left
)
1523 DEBUGF("Moved swapwrite\n");
1524 audiobuf_swapwrite
= audiobuf_read
;
1525 play_pending
= true;
1528 if (mpeg_file
>=0 && unplayed_space_left
< low_watermark
)
1530 /* We need to load more data before starting */
1532 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1533 play_pending
= true;
1537 /* resume will start at new position */
1538 last_dma_chunk_size
=
1539 MIN(0x2000, get_unplayed_space_current_song());
1540 mp3_play_data(audiobuf
+ audiobuf_read
,
1541 last_dma_chunk_size
, transfer_end
);
1542 dma_underrun
= false;
1547 /* Move to the new position in the file and start
1551 if (num_tracks_in_memory() > 1)
1553 /* We have to reload the current track */
1555 remove_all_non_current_tags();
1556 generate_unbuffer_events();
1562 mpeg_file
= open(id3
->path
, O_RDONLY
);
1565 id3
->elapsed
= oldtime
;
1570 if(-1 == lseek(mpeg_file
, newpos
, SEEK_SET
))
1572 id3
->elapsed
= oldtime
;
1577 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1579 /* Tell the file loading code that we want to start playing
1580 as soon as we have some data */
1581 play_pending
= true;
1584 id3
->offset
= newpos
;
1589 case MPEG_FLUSH_RELOAD
: {
1590 int numtracks
= num_tracks_in_memory();
1591 bool reload_track
= false;
1595 /* Reset the buffer */
1596 audiobuf_write
= get_trackdata(1)->mempos
;
1598 /* Reset swapwrite unless we're still swapping current
1600 if (get_unplayed_space() <= get_playable_space())
1601 audiobuf_swapwrite
= audiobuf_write
;
1604 remove_all_non_current_tags();
1605 generate_unbuffer_events();
1607 reload_track
= true;
1609 else if (numtracks
== 1 && mpeg_file
< 0)
1611 reload_track
= true;
1614 if(reload_track
&& new_file(1) >= 0)
1616 /* Tell ourselves that we want more data */
1618 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1624 case MPEG_NEED_DATA
:
1625 free_space_left
= audiobuf_read
- audiobuf_write
;
1627 /* We interpret 0 as "empty buffer" */
1628 if(free_space_left
<= 0)
1629 free_space_left
+= audiobuflen
;
1631 unplayed_space_left
= audiobuflen
- free_space_left
;
1633 /* Make sure that we don't fill the entire buffer */
1634 free_space_left
-= MPEG_HIGH_WATER
;
1636 if (ev
.data
== GENERATE_UNBUFFER_EVENTS
)
1637 generate_unbuffer_events();
1639 /* do we have any more buffer space to fill? */
1640 if(free_space_left
<= 0)
1644 generate_postbuffer_events();
1649 /* Read small chunks while we are below the low water mark */
1650 if(unplayed_space_left
< low_watermark
)
1651 amount_to_read
= MIN(MPEG_LOW_WATER_CHUNKSIZE
,
1654 amount_to_read
= free_space_left
;
1656 /* Don't read more than until the end of the buffer */
1657 amount_to_read
= MIN(audiobuflen
- audiobuf_write
,
1659 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1660 amount_to_read
= MIN(0x40000, amount_to_read
);
1662 amount_to_read
= MIN(0x100000, amount_to_read
);
1665 /* Read as much mpeg data as we can fit in the buffer */
1670 len
= read(mpeg_file
, audiobuf
+ audiobuf_write
,
1675 DEBUGF("time: %d\n", t2
- t1
);
1676 DEBUGF("R: %x\n", len
);
1678 /* Now make sure that we don't feed the MAS with ID3V1
1680 if (len
< amount_to_read
)
1683 static const unsigned char tag
[] = "TAG";
1685 int tagptr
= audiobuf_write
+ len
- 128;
1687 /* Really rare case: entire potential tag wasn't
1688 read in this call AND audiobuf_write < 128 */
1690 tagptr
+= audiobuflen
;
1692 for(i
= 0;i
< 3;i
++)
1694 if(tagptr
>= audiobuflen
)
1695 tagptr
-= audiobuflen
;
1697 if(audiobuf
[tagptr
] != tag
[i
])
1708 /* Skip id3v1 tag */
1709 DEBUGF("Skipping ID3v1 tag\n");
1712 /* In the very rare case when the entire tag
1713 wasn't read in this read() len will be < 0.
1714 Take care of this when changing the write
1719 audiobuf_write
+= len
;
1721 if (audiobuf_write
< 0)
1722 audiobuf_write
+= audiobuflen
;
1724 if(audiobuf_write
>= audiobuflen
)
1730 /* Tell ourselves that we want more data */
1731 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1737 DEBUGF("MPEG read error\n");
1745 /* No more data to play */
1746 DEBUGF("No more files to play\n");
1751 /* Tell ourselves that we want more data */
1752 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1758 case MPEG_TRACK_CHANGE
:
1763 case SYS_USB_CONNECTED
:
1768 /* Tell the USB thread that we are safe */
1769 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1770 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1772 /* Wait until the USB cable is extracted again */
1773 usb_wait_for_disconnect(&mpeg_queue
);
1775 #endif /* !USB_NONE */
1777 #if CONFIG_CODEC == MAS3587F
1778 case MPEG_INIT_RECORDING
:
1780 init_recording_done
= true;
1782 #endif /* CONFIG_CODEC == MAS3587F */
1786 playlist_update_resume_info(audio_current_track());
1789 #if CONFIG_CODEC == MAS3587F
1793 queue_wait(&mpeg_queue
, &ev
);
1797 if (is_prerecording
)
1801 /* Go back prerecord_count seconds in the buffer */
1802 startpos
= prerecord_index
- prerecord_count
;
1804 startpos
+= prerecording_max_seconds
;
1806 /* Read the position data from the prerecord buffer */
1807 frame_count_start
= prerecord_buffer
[startpos
].framecount
;
1808 startpos
= prerecord_buffer
[startpos
].mempos
;
1810 DEBUGF("Start looking at address %x (%x)\n",
1811 audiobuf
+startpos
, startpos
);
1813 saved_header
= mpeg_get_last_header();
1815 mem_find_next_frame(startpos
, &offset
, 1800,
1818 audiobuf_read
= startpos
+ offset
;
1819 if(audiobuf_read
>= audiobuflen
)
1820 audiobuf_read
-= audiobuflen
;
1822 DEBUGF("New audiobuf_read address: %x (%x)\n",
1823 audiobuf
+audiobuf_read
, audiobuf_read
);
1825 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1826 num_rec_bytes
= get_unsaved_space();
1827 set_irq_level(level
);
1831 frame_count_start
= 0;
1833 audiobuf_read
= MPEG_RESERVED_HEADER_SPACE
;
1834 audiobuf_write
= MPEG_RESERVED_HEADER_SPACE
;
1838 DEBUGF("Recording...\n");
1841 /* Wait until at least one frame is encoded and get the
1842 frame header, for later use by the Xing header
1845 saved_header
= mpeg_get_last_header();
1847 /* delayed until buffer is saved, don't open yet */
1848 strcpy(delayed_filename
, recording_filename
);
1854 DEBUGF("MPEG_STOP\n");
1858 /* Save the remaining data in the buffer */
1859 save_endpos
= audiobuf_write
;
1860 saving_status
= STOP_RECORDING
;
1861 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1864 case MPEG_STOP_DONE
:
1865 DEBUGF("MPEG_STOP_DONE\n");
1875 for(i
= 0;i
< 512;i
++)
1877 DEBUGF("%d - %d us (%d bytes)\n",
1879 (timing_info
[i
*2+1] & 0xffff) *
1881 timing_info
[i
*2+1] >> 16);
1888 start_prerecording();
1890 mpeg_stop_done
= true;
1894 /* Bail out when a more important save is happening */
1895 if (saving_status
> NEW_FILE
)
1898 /* Make sure we have at least one complete frame
1899 in the buffer. If we haven't recorded a single
1900 frame within 200ms, the MAS is probably not recording
1901 anything, and we bail out. */
1902 amount_to_save
= get_unsaved_space();
1903 if (amount_to_save
< 1800)
1906 amount_to_save
= get_unsaved_space();
1909 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1910 &frame_count_end
, 1);
1912 last_rec_time
= current_tick
- record_start_time
;
1913 record_start_time
= current_tick
;
1915 pause_start_time
= record_start_time
;
1917 /* capture all values at one point */
1918 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1919 save_endpos
= audiobuf_write
;
1920 last_rec_bytes
= num_rec_bytes
;
1922 set_irq_level(level
);
1924 if (amount_to_save
>= 1800)
1926 /* Now find a frame boundary to split at */
1927 save_endpos
-= 1800;
1928 if (save_endpos
< 0)
1929 save_endpos
+= audiobuflen
;
1931 rc
= mem_find_next_frame(save_endpos
, &offset
, 1800,
1933 if (!rc
) /* No header found, save whole buffer */
1936 save_endpos
+= offset
;
1937 if (save_endpos
>= audiobuflen
)
1938 save_endpos
-= audiobuflen
;
1940 last_rec_bytes
+= offset
- 1800;
1941 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1942 num_rec_bytes
+= 1800 - offset
;
1943 set_irq_level(level
);
1946 saving_status
= NEW_FILE
;
1947 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1950 case MPEG_SAVE_DATA
:
1951 if (saving_status
== BUFFER_FULL
)
1952 save_endpos
= audiobuf_write
;
1954 if (mpeg_file
< 0) /* delayed file open */
1956 mpeg_file
= open(delayed_filename
, O_WRONLY
|O_CREAT
);
1959 panicf("recfile: %d", mpeg_file
);
1962 amount_to_save
= save_endpos
- audiobuf_read
;
1963 if (amount_to_save
< 0)
1964 amount_to_save
+= audiobuflen
;
1966 amount_to_save
= MIN(amount_to_save
,
1967 audiobuflen
- audiobuf_read
);
1968 #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */
1969 amount_to_save
= MIN(0x40000, amount_to_save
);
1971 amount_to_save
= MIN(0x100000, amount_to_save
);
1973 rc
= write(mpeg_file
, audiobuf
+ audiobuf_read
,
1977 if (errno
== ENOSPC
)
1979 mpeg_errno
= AUDIOERR_DISK_FULL
;
1981 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1982 /* will close the file */
1986 panicf("rec wrt: %d", rc
);
1989 audiobuf_read
+= amount_to_save
;
1990 if (audiobuf_read
>= audiobuflen
)
1993 if (audiobuf_read
== save_endpos
) /* all saved */
1995 switch (saving_status
)
1998 rc
= fsync(mpeg_file
);
2000 panicf("rec fls: %d", rc
);
2005 /* Close the current file */
2006 rc
= close(mpeg_file
);
2008 panicf("rec cls: %d", rc
);
2013 /* copy new filename */
2014 strcpy(delayed_filename
, recording_filename
);
2016 frame_count_start
= frame_count_end
;
2019 case STOP_RECORDING
:
2020 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
2021 /* will close the file */
2027 saving_status
= NOT_SAVING
;
2029 else /* tell ourselves to save the next chunk */
2030 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
2034 case MPEG_PRERECORDING_TICK
:
2035 if(!is_prerecording
)
2038 /* Store the write pointer every second */
2039 prerecord_buffer
[prerecord_index
].mempos
= audiobuf_write
;
2040 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
2041 &prerecord_buffer
[prerecord_index
].framecount
, 1);
2043 /* Wrap if necessary */
2044 if(++prerecord_index
== prerecording_max_seconds
)
2045 prerecord_index
= 0;
2047 /* Update the number of seconds recorded */
2048 if(prerecord_count
< prerecording_max_seconds
)
2052 case MPEG_INIT_PLAYBACK
:
2053 /* Stop the prerecording */
2057 init_playback_done
= true;
2060 case MPEG_PAUSE_RECORDING
:
2064 case MPEG_RESUME_RECORDING
:
2068 case SYS_USB_CONNECTED
:
2069 /* We can safely go to USB mode if no recording
2071 if((!is_recording
|| is_prerecording
) && mpeg_stop_done
)
2073 /* Even if we aren't recording, we still call this
2074 function, to put the MAS in monitoring mode,
2078 /* Tell the USB thread that we are safe */
2079 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2080 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
2082 /* Wait until the USB cable is extracted again */
2083 usb_wait_for_disconnect(&mpeg_queue
);
2088 #endif /* CONFIG_CODEC == MAS3587F */
2091 #endif /* !SIMULATOR */
2093 void mpeg_id3_options(bool _v1first
)
2098 struct mp3entry
* audio_current_track()
2102 #else /* !SIMULATOR */
2103 if(num_tracks_in_memory())
2104 return &get_trackdata(0)->id3
;
2107 #endif /* !SIMULATOR */
2110 struct mp3entry
* audio_next_track()
2114 #else /* !SIMULATOR */
2115 if(num_tracks_in_memory() > 1)
2116 return &get_trackdata(1)->id3
;
2119 #endif /* !SIMULATOR */
2122 bool audio_has_changed_track(void)
2124 if(last_track_counter
!= current_track_counter
)
2126 last_track_counter
= current_track_counter
;
2132 #if CONFIG_CODEC == MAS3587F
2134 void audio_init_playback(void)
2136 init_playback_done
= false;
2137 queue_post(&mpeg_queue
, MPEG_INIT_PLAYBACK
, 0);
2139 while(!init_playback_done
)
2144 /****************************************************************************
2145 * Recording functions
2146 ***************************************************************************/
2147 void audio_init_recording(unsigned int buffer_offset
)
2149 buffer_offset
= buffer_offset
;
2150 init_recording_done
= false;
2151 queue_post(&mpeg_queue
, MPEG_INIT_RECORDING
, 0);
2153 while(!init_recording_done
)
2157 static void init_recording(void)
2169 /* Init the recording variables */
2170 is_recording
= false;
2171 is_prerecording
= false;
2173 mpeg_stop_done
= true;
2177 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2178 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
2180 panicf("mas_ctrl_w: %d", rc
);
2182 /* Stop the current application */
2184 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2187 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2190 /* Perform black magic as described by the data sheet */
2191 if((mas_version_code
& 0x0fff) == 0x0102)
2193 DEBUGF("Performing MAS black magic for B2 version\n");
2194 mas_writereg(0xa3, 0x98);
2195 mas_writereg(0x94, 0xfffff);
2197 mas_writemem(MAS_BANK_D1
, 0, &val
, 1);
2198 mas_writereg(0xa3, 0x90);
2201 /* Enable A/D Converters */
2202 shadow_codec_reg0
= 0xcccd;
2203 mas_codec_writereg(0x0, shadow_codec_reg0
);
2205 /* Copy left channel to right (mono mode) */
2206 mas_codec_writereg(8, 0x8000);
2208 /* ADC scale 0%, DSP scale 100%
2209 We use the DSP output for monitoring, because it works with all
2210 sources including S/PDIF */
2211 mas_codec_writereg(6, 0x0000);
2212 mas_codec_writereg(7, 0x4000);
2215 shadow_soft_mute
= 0;
2216 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2218 #ifdef HAVE_SPDIF_OUT
2219 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2221 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2223 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
2225 /* Set Demand mode, monitoring OFF and validate all settings */
2226 shadow_io_control_main
= 0x125;
2227 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2229 /* Start the encoder application */
2231 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2234 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2235 } while(!(val
& 0x40));
2237 /* We have started the recording application with monitoring OFF.
2238 This is because we want to record at least one frame to fill the DMA
2239 buffer, because the silly MAS will not negate EOD until at least one
2240 DMA transfer has taken place.
2241 Now let's wait for some data to be encoded. */
2244 /* Now set it to Monitoring mode as default, saves power */
2245 shadow_io_control_main
= 0x525;
2246 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2248 /* Wait until the DSP has accepted the settings */
2251 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2255 mpeg_mode
= MPEG_ENCODER
;
2257 DEBUGF("MAS Recording application started\n");
2259 /* At this point, all settings are the reset MAS defaults, next thing is to
2260 call mpeg_set_recording_options(). */
2263 void audio_record(const char *filename
)
2267 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2268 recording_filename
[MAX_PATH
- 1] = 0;
2270 queue_post(&mpeg_queue
, MPEG_RECORD
, 0);
2273 void audio_pause_recording(void)
2275 queue_post(&mpeg_queue
, MPEG_PAUSE_RECORDING
, 0);
2278 void audio_resume_recording(void)
2280 queue_post(&mpeg_queue
, MPEG_RESUME_RECORDING
, 0);
2283 static void prepend_header(void)
2288 /* Make room for header */
2289 audiobuf_read
-= MPEG_RESERVED_HEADER_SPACE
;
2290 if(audiobuf_read
< 0)
2292 /* Clear the bottom half */
2293 memset(audiobuf
, 0, audiobuf_read
+ MPEG_RESERVED_HEADER_SPACE
);
2295 /* And the top half */
2296 audiobuf_read
+= audiobuflen
;
2297 memset(audiobuf
+ audiobuf_read
, 0, audiobuflen
- audiobuf_read
);
2301 memset(audiobuf
+ audiobuf_read
, 0, MPEG_RESERVED_HEADER_SPACE
);
2303 /* Copy the empty ID3 header */
2304 startpos
= audiobuf_read
;
2305 for(i
= 0; i
< sizeof(empty_id3_header
); i
++)
2307 audiobuf
[startpos
++] = empty_id3_header
[i
];
2308 if(startpos
== audiobuflen
)
2313 static void update_header(void)
2316 unsigned long frames
;
2318 if (last_rec_bytes
> 0)
2320 /* Create the Xing header */
2321 fd
= open(delayed_filename
, O_RDWR
);
2323 panicf("rec upd: %d (%s)", fd
, recording_filename
);
2325 frames
= frame_count_end
- frame_count_start
;
2326 /* If the number of recorded frames has reached 0x7ffff,
2327 we can no longer trust it */
2328 if (frame_count_end
== 0x7ffff)
2331 /* saved_header is saved right before stopping the MAS */
2332 framelen
= create_xing_header(fd
, 0, last_rec_bytes
, xing_buffer
,
2333 frames
, last_rec_time
* (1000/HZ
),
2334 saved_header
, NULL
, false);
2336 lseek(fd
, MPEG_RESERVED_HEADER_SPACE
- framelen
, SEEK_SET
);
2337 write(fd
, xing_buffer
, framelen
);
2342 static void start_prerecording(void)
2346 DEBUGF("Starting prerecording\n");
2348 prerecord_index
= 0;
2349 prerecord_count
= 0;
2350 prerecord_timeout
= current_tick
+ HZ
;
2351 memset(prerecord_buffer
, 0, sizeof(prerecord_buffer
));
2354 is_prerecording
= true;
2356 /* Stop monitoring and start the encoder */
2357 shadow_io_control_main
&= ~(1 << 10);
2358 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2359 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2361 /* Wait until the DSP has accepted the settings */
2364 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2367 is_recording
= true;
2368 saving_status
= NOT_SAVING
;
2370 demand_irq_enable(true);
2373 static void start_recording(void)
2379 /* This will make the IRQ handler start recording
2380 for real, i.e send MPEG_SAVE_DATA messages when
2381 the buffer is full */
2382 is_prerecording
= false;
2386 /* If prerecording is off, we need to stop the monitoring
2387 and start the encoder */
2388 shadow_io_control_main
&= ~(1 << 10);
2389 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2390 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2392 /* Wait until the DSP has accepted the settings */
2395 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2399 is_recording
= true;
2400 saving_status
= NOT_SAVING
;
2403 /* Store the current time */
2405 record_start_time
= current_tick
- prerecord_count
* HZ
;
2407 record_start_time
= current_tick
;
2409 pause_start_time
= 0;
2411 demand_irq_enable(true);
2414 static void pause_recording(void)
2416 pause_start_time
= current_tick
;
2418 /* Set the pause bit */
2419 shadow_soft_mute
|= 2;
2420 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2425 static void resume_recording(void)
2429 /* Clear the pause bit */
2430 shadow_soft_mute
&= ~2;
2431 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2433 /* Compensate for the time we have been paused */
2434 if(pause_start_time
)
2437 current_tick
- (pause_start_time
- record_start_time
);
2438 pause_start_time
= 0;
2442 static void stop_recording(void)
2446 /* Let it finish the last frame */
2451 demand_irq_enable(false);
2453 is_recording
= false;
2454 is_prerecording
= false;
2456 last_rec_bytes
= num_rec_bytes
;
2457 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
, &frame_count_end
, 1);
2458 last_rec_time
= current_tick
- record_start_time
;
2460 /* Start monitoring */
2461 shadow_io_control_main
|= (1 << 10);
2462 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2463 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2465 /* Wait until the DSP has accepted the settings */
2468 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2474 void audio_set_recording_options(struct audio_recording_options
*options
)
2478 is_mpeg1
= (options
->rec_frequency
< 3)?true:false;
2480 rec_version_index
= is_mpeg1
?3:2;
2481 rec_frequency_index
= options
->rec_frequency
% 3;
2483 shadow_encoder_control
= (options
->rec_quality
<< 17) |
2484 (rec_frequency_index
<< 10) |
2485 ((is_mpeg1
?1:0) << 9) |
2486 (((options
->rec_channels
* 2 + 1) & 3) << 6) |
2487 (1 << 5) /* MS-stereo */ |
2488 (1 << 2) /* Is an original */;
2489 mas_writemem(MAS_BANK_D0
, MAS_D0_ENCODER_CONTROL
, &shadow_encoder_control
,1);
2491 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control
);
2493 shadow_soft_mute
= options
->rec_editable
?4:0;
2494 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
,1);
2496 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute
);
2498 shadow_io_control_main
= ((1 << 10) | /* Monitoring ON */
2499 ((options
->rec_source
< 2)?1:2) << 8) | /* Input select */
2500 (1 << 5) | /* SDO strobe invert */
2501 ((is_mpeg1
?0:1) << 3) |
2502 (1 << 2) | /* Inverted SIBC clock signal */
2504 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
,1);
2506 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2508 if(options
->rec_source
== AUDIO_SRC_MIC
)
2510 /* Copy left channel to right (mono mode) */
2511 mas_codec_writereg(8, 0x8000);
2515 /* Stereo input mode */
2516 mas_codec_writereg(8, 0);
2519 prerecording_max_seconds
= options
->rec_prerecord_time
;
2520 if(prerecording_max_seconds
)
2522 prerecording
= true;
2523 start_prerecording();
2527 prerecording
= false;
2528 is_prerecording
= false;
2529 is_recording
= false;
2533 /* If use_mic is true, the left gain is used */
2534 void audio_set_recording_gain(int left
, int right
, int type
)
2536 /* Enable both left and right A/D */
2537 shadow_codec_reg0
= (left
<< 12) |
2540 (type
==AUDIO_GAIN_MIC
?0x0008:0) | /* Connect left A/D to mic */
2542 mas_codec_writereg(0x0, shadow_codec_reg0
);
2545 #if CONFIG_TUNER & S1A0903X01
2546 /* Get the (unpitched) MAS PLL frequency, for avoiding FM interference with the
2547 * Samsung tuner. Zero means unknown. Currently handles recording from analog
2549 int mpeg_get_mas_pllfreq(void)
2551 if (mpeg_mode
!= MPEG_ENCODER
)
2554 if (rec_frequency_index
== 0) /* 44.1 kHz / 22.05 kHz */
2559 #endif /* CONFIG_TUNER & S1A0903X01 */
2561 /* try to make some kind of beep, also in recording mode */
2562 void audio_beep(int duration
)
2564 long starttick
= current_tick
;
2566 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2567 * While this is still audible even without an external signal,
2568 * it doesn't affect the (pre-)recording. */
2569 mas_codec_writereg(0, shadow_codec_reg0
^ 1);
2570 mas_codec_writereg(0, shadow_codec_reg0
);
2573 while (current_tick
- starttick
< duration
);
2576 void audio_new_file(const char *filename
)
2580 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2581 recording_filename
[MAX_PATH
- 1] = 0;
2583 queue_post(&mpeg_queue
, MPEG_NEW_FILE
, 0);
2586 unsigned long audio_recorded_time(void)
2589 return prerecord_count
* HZ
;
2594 return pause_start_time
- record_start_time
;
2596 return current_tick
- record_start_time
;
2602 unsigned long audio_num_recorded_bytes(void)
2611 index
= prerecord_index
- prerecord_count
;
2613 index
+= prerecording_max_seconds
;
2615 num_bytes
= audiobuf_write
- prerecord_buffer
[index
].mempos
;
2617 num_bytes
+= audiobuflen
;
2622 return num_rec_bytes
;
2628 #else /* SIMULATOR */
2630 /* dummies coming up */
2632 void audio_init_playback(void)
2636 unsigned long audio_recorded_time(void)
2641 void audio_beep(int duration
)
2646 void audio_pause_recording(void)
2650 void audio_resume_recording(void)
2654 unsigned long audio_num_recorded_bytes(void)
2659 void audio_record(const char *filename
)
2664 void audio_new_file(const char *filename
)
2670 void audio_set_recording_gain(int left
, int right
, int type
)
2677 void audio_init_recording(unsigned int buffer_offset
)
2680 (void)buffer_offset
;
2682 void audio_set_recording_options(struct audio_recording_options
*options
)
2687 #endif /* SIMULATOR */
2688 #endif /* CONFIG_CODEC == MAS3587F */
2690 void audio_play(long offset
)
2699 trackname
= playlist_peek( steps
);
2702 if(mp3info(&taginfo
, trackname
, v1first
)) {
2703 /* bad mp3, move on */
2704 if(++steps
> playlist_amount())
2708 #ifdef HAVE_MPEG_PLAY
2709 real_mpeg_play(trackname
);
2711 playlist_next(steps
);
2712 taginfo
.offset
= offset
;
2713 set_elapsed(&taginfo
);
2718 #else /* !SIMULATOR */
2721 queue_post(&mpeg_queue
, MPEG_PLAY
, offset
);
2722 #endif /* !SIMULATOR */
2727 void audio_stop(void)
2732 struct trackdata
*track
= get_trackdata(0);
2733 prev_track_elapsed
= track
->id3
.elapsed
;
2735 mpeg_stop_done
= false;
2736 queue_post(&mpeg_queue
, MPEG_STOP
, 0);
2737 while(!mpeg_stop_done
)
2739 #else /* SIMULATOR */
2743 #endif /* SIMULATOR */
2747 void audio_stop_recording(void)
2752 void audio_pause(void)
2755 queue_post(&mpeg_queue
, MPEG_PAUSE
, 0);
2756 #else /* SIMULATOR */
2760 #endif /* SIMULATOR */
2763 void audio_resume(void)
2766 queue_post(&mpeg_queue
, MPEG_RESUME
, 0);
2767 #else /* SIMULATOR */
2771 #endif /* SIMULATOR */
2774 void audio_next(void)
2777 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2778 queue_post(&mpeg_queue
, MPEG_NEXT
, 0);
2779 #else /* SIMULATOR */
2785 file
= playlist_peek(steps
);
2788 if(mp3info(&taginfo
, file
, v1first
)) {
2789 if(++steps
> playlist_amount())
2793 index
= playlist_next(steps
);
2794 taginfo
.index
= index
;
2795 current_track_counter
++;
2800 #endif /* SIMULATOR */
2803 void audio_prev(void)
2806 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2807 queue_post(&mpeg_queue
, MPEG_PREV
, 0);
2808 #else /* SIMULATOR */
2814 file
= playlist_peek(steps
);
2817 if(mp3info(&taginfo
, file
, v1first
)) {
2821 index
= playlist_next(steps
);
2822 taginfo
.index
= index
;
2823 current_track_counter
++;
2828 #endif /* SIMULATOR */
2831 void audio_ff_rewind(long newtime
)
2834 queue_post(&mpeg_queue
, MPEG_FF_REWIND
, newtime
);
2835 #else /* SIMULATOR */
2837 #endif /* SIMULATOR */
2840 void audio_flush_and_reload_tracks(void)
2843 queue_post(&mpeg_queue
, MPEG_FLUSH_RELOAD
, 0);
2844 #endif /* !SIMULATOR*/
2847 int audio_status(void)
2852 ret
|= AUDIO_STATUS_PLAY
;
2855 ret
|= AUDIO_STATUS_PAUSE
;
2857 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2858 if(is_recording
&& !is_prerecording
)
2859 ret
|= AUDIO_STATUS_RECORD
;
2862 ret
|= AUDIO_STATUS_PRERECORD
;
2863 #endif /* CONFIG_CODEC == MAS3587F */
2866 ret
|= AUDIO_STATUS_ERROR
;
2871 unsigned int audio_error(void)
2876 void audio_error_clear(void)
2882 static void mpeg_thread(void)
2884 struct mp3entry
* id3
;
2887 id3
= audio_current_track();
2893 if (id3
->elapsed
>=id3
->length
)
2899 #endif /* SIMULATOR */
2901 void audio_init(void)
2904 track_buffer_callback
= NULL
;
2905 track_unbuffer_callback
= NULL
;
2906 track_changed_callback
= NULL
;
2909 audiobuflen
= audiobufend
- audiobuf
;
2910 queue_init(&mpeg_queue
, true);
2911 #endif /* !SIMULATOR */
2912 create_thread(mpeg_thread
, mpeg_stack
,
2913 sizeof(mpeg_stack
), mpeg_thread_name
IF_PRIO(, PRIORITY_SYSTEM
)
2914 IF_COP(, CPU
, false));
2916 memset(trackdata
, sizeof(trackdata
), 0);
2918 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2919 if (HW_MASK
& PR_ACTIVE_HIGH
)
2920 and_b(~0x08, &PADRH
);
2923 #endif /* CONFIG_CODEC == MAS3587F */
2931 #endif /* CONFIG_CODEC != SWCODEC */