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 playing
= false; /* We are playing an MP3 stream */
131 static bool is_playing
= false; /* We are (attempting to) playing MP3 files */
132 static bool paused
; /* playback is paused */
135 static char mpeg_stack
[DEFAULT_STACK_SIZE
];
136 static struct mp3entry taginfo
;
138 #else /* !SIMULATOR */
139 static struct event_queue mpeg_queue
;
140 static long mpeg_stack
[(DEFAULT_STACK_SIZE
+ 0x1000)/sizeof(long)];
142 static int audiobuflen
;
143 static int audiobuf_write
;
144 static int audiobuf_swapwrite
;
145 static int audiobuf_read
;
147 static int mpeg_file
;
149 static bool play_pending
; /* We are about to start playing */
150 static bool play_pending_track_change
; /* When starting play we're starting a new file */
151 static bool filling
; /* We are filling the buffer with data from disk */
152 static bool dma_underrun
; /* True when the DMA has stopped because of
153 slow disk reading (read error, shaking) */
154 static bool mpeg_stop_done
;
156 static int last_dma_tick
= 0;
157 static int last_dma_chunk_size
;
159 static long low_watermark
; /* Dynamic low watermark level */
160 static long low_watermark_margin
= 0; /* Extra time in seconds for watermark */
161 static long lowest_watermark_level
; /* Debug value to observe the buffer
163 #if CONFIG_CODEC == MAS3587F
164 static char recording_filename
[MAX_PATH
]; /* argument to thread */
165 static char delayed_filename
[MAX_PATH
]; /* internal copy of above */
167 static char xing_buffer
[MAX_XING_HEADER_SIZE
];
169 static bool init_recording_done
;
170 static bool init_playback_done
;
171 static bool prerecording
; /* True if prerecording is enabled */
172 static bool is_prerecording
; /* True if we are prerecording */
173 static bool is_recording
; /* We are recording */
176 NOT_SAVING
= 0, /* reasons to save data, sorted by importance */
182 static int rec_frequency_index
; /* For create_xing_header() calls */
183 static int rec_version_index
; /* For create_xing_header() calls */
185 struct prerecord_info
{
187 unsigned long framecount
;
190 static struct prerecord_info prerecord_buffer
[MPEG_MAX_PRERECORD_SECONDS
];
191 static int prerecord_index
; /* Current index in the prerecord buffer */
192 static int prerecording_max_seconds
; /* Max number of seconds to store */
193 static int prerecord_count
; /* Number of seconds in the prerecord buffer */
194 static int prerecord_timeout
; /* The tick count of the next prerecord data
197 unsigned long record_start_time
; /* Value of current_tick when recording
199 unsigned long pause_start_time
; /* Value of current_tick when pause was
201 static unsigned long last_rec_time
;
202 static unsigned long num_rec_bytes
;
203 static unsigned long last_rec_bytes
;
204 static unsigned long frame_count_start
;
205 static unsigned long frame_count_end
;
206 static unsigned long saved_header
= 0;
208 /* Shadow MAS registers */
209 unsigned long shadow_encoder_control
= 0;
210 #endif /* CONFIG_CODEC == MAS3587F */
212 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
213 unsigned long shadow_io_control_main
= 0;
214 unsigned long shadow_soft_mute
= 0;
215 unsigned shadow_codec_reg0
;
216 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
218 #ifdef HAVE_RECORDING
219 const unsigned char empty_id3_header
[] =
221 'I', 'D', '3', 0x03, 0x00, 0x00,
222 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
224 #endif /* HAVE_RECORDING */
227 static int get_unplayed_space(void);
228 static int get_playable_space(void);
229 static int get_unswapped_space(void);
230 #endif /* !SIMULATOR */
232 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
233 static void init_recording(void);
234 static void prepend_header(void);
235 static void update_header(void);
236 static void start_prerecording(void);
237 static void start_recording(void);
238 static void stop_recording(void);
239 static int get_unsaved_space(void);
240 static void pause_recording(void);
241 static void resume_recording(void);
242 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
246 static int num_tracks_in_memory(void)
248 return (track_write_idx
- track_read_idx
) & MAX_TRACK_ENTRIES_MASK
;
252 static void debug_tags(void)
256 for(i
= 0;i
< MAX_TRACK_ENTRIES
;i
++)
258 DEBUGF("%d - %s\n", i
, trackdata
[i
].id3
.path
);
260 DEBUGF("read: %d, write :%d\n", track_read_idx
, track_write_idx
);
261 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
263 #else /* !DEBUG_TAGS */
265 #endif /* !DEBUG_TAGS */
267 static void remove_current_tag(void)
269 if(num_tracks_in_memory() > 0)
271 /* First move the index, so nobody tries to access the tag */
272 track_read_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
277 DEBUGF("remove_current_tag: no tracks to remove\n");
281 static void remove_all_non_current_tags(void)
283 track_write_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
287 static void remove_all_tags(void)
289 track_write_idx
= track_read_idx
;
294 static struct trackdata
*get_trackdata(int offset
)
296 if(offset
>= num_tracks_in_memory())
299 return &trackdata
[(track_read_idx
+ offset
) & MAX_TRACK_ENTRIES_MASK
];
301 #endif /* !SIMULATOR */
303 /***********************************************************************/
304 /* audio event handling */
306 #define MAX_EVENT_HANDLERS 10
307 struct event_handlers_table
309 AUDIO_EVENT_HANDLER handler
;
312 static struct event_handlers_table event_handlers
[MAX_EVENT_HANDLERS
];
313 static int event_handlers_count
= 0;
315 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler
, unsigned short mask
)
317 if (event_handlers_count
< MAX_EVENT_HANDLERS
)
319 event_handlers
[event_handlers_count
].handler
= handler
;
320 event_handlers
[event_handlers_count
].mask
= mask
;
321 event_handlers_count
++;
325 /* dispatch calls each handler in the order registered and returns after some
326 handler actually handles the event (the event is assumed to no longer be valid
327 after this, due to the handler changing some condition); returns true if someone
328 handled the event, which is expected to cause the caller to skip its own handling
331 static bool audio_dispatch_event(unsigned short event
, unsigned long data
)
334 for(i
=0; i
< event_handlers_count
; i
++)
336 if ( event_handlers
[i
].mask
& event
)
338 int rc
= event_handlers
[i
].handler(event
, data
);
339 if ( rc
== AUDIO_EVENT_RC_HANDLED
)
347 /***********************************************************************/
349 static void set_elapsed(struct mp3entry
* id3
)
352 if ( id3
->has_toc
) {
353 /* calculate elapsed time using TOC */
355 unsigned int remainder
, plen
, relpos
, nextpos
;
357 /* find wich percent we're at */
358 for (i
=0; i
<100; i
++ )
360 if ( id3
->offset
< id3
->toc
[i
] * (id3
->filesize
/ 256) )
370 relpos
= id3
->toc
[i
];
374 nextpos
= id3
->toc
[i
+1];
381 remainder
= id3
->offset
- (relpos
* (id3
->filesize
/ 256));
383 /* set time for this percent (divide before multiply to prevent
384 overflow on long files. loss of precision is negligible on
386 id3
->elapsed
= i
* (id3
->length
/ 100);
388 /* calculate remainder time */
389 plen
= (nextpos
- relpos
) * (id3
->filesize
/ 256);
390 id3
->elapsed
+= (((remainder
* 100) / plen
) *
391 (id3
->length
/ 10000));
394 /* no TOC exists. set a rough estimate using average bitrate */
395 int tpk
= id3
->length
/ (id3
->filesize
/ 1024);
396 id3
->elapsed
= id3
->offset
/ 1024 * tpk
;
400 /* constant bitrate, use exact calculation */
401 id3
->elapsed
= id3
->offset
/ (id3
->bitrate
/ 8);
404 int audio_get_file_pos(void)
407 struct mp3entry
*id3
= audio_current_track();
413 /* Use the TOC to find the new position */
414 unsigned int percent
, remainder
;
415 int curtoc
, nexttoc
, plen
;
417 percent
= (id3
->elapsed
*100)/id3
->length
;
421 curtoc
= id3
->toc
[percent
];
424 nexttoc
= id3
->toc
[percent
+1];
428 pos
= (id3
->filesize
/256)*curtoc
;
430 /* Use the remainder to get a more accurate position */
431 remainder
= (id3
->elapsed
*100)%id3
->length
;
432 remainder
= (remainder
*100)/id3
->length
;
433 plen
= (nexttoc
- curtoc
)*(id3
->filesize
/256);
434 pos
+= (plen
/100)*remainder
;
438 /* No TOC exists, estimate the new position */
439 pos
= (id3
->filesize
/ (id3
->length
/ 1000)) *
440 (id3
->elapsed
/ 1000);
443 else if (id3
->bitrate
)
444 pos
= id3
->elapsed
* (id3
->bitrate
/ 8);
450 if (pos
>= (int)(id3
->filesize
- id3
->id3v1len
))
452 /* Don't seek right to the end of the file so that we can
453 transition properly to the next song */
454 pos
= id3
->filesize
- id3
->id3v1len
- 1;
456 else if (pos
< (int)id3
->first_frame_offset
)
458 /* skip past id3v2 tag and other leading garbage */
459 pos
= id3
->first_frame_offset
;
464 unsigned long mpeg_get_last_header(void)
468 #else /* !SIMULATOR */
469 unsigned long tmp
[2];
471 /* Read the frame data from the MAS and reconstruct it with the
472 frame sync and all */
473 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_STATUS_1
, tmp
, 2);
474 return 0xffe00000 | ((tmp
[0] & 0x7c00) << 6) | (tmp
[1] & 0xffff);
475 #endif /* !SIMULATOR */
478 void audio_set_track_buffer_event(void (*handler
)(struct mp3entry
*id3
,
481 track_buffer_callback
= handler
;
484 void audio_set_track_unbuffer_event(void (*handler
)(struct mp3entry
*id3
,
487 track_unbuffer_callback
= handler
;
490 void audio_set_track_changed_event(void (*handler
)(struct mp3entry
*id3
))
492 track_changed_callback
= handler
;
495 void audio_set_cuesheet_callback(bool (*handler
)(const char *filename
))
497 cuesheet_callback
= handler
;
501 /* Send callback events to notify about removing old tracks. */
502 static void generate_unbuffer_events(void)
506 int numentries
= MAX_TRACK_ENTRIES
- num_tracks_in_memory();
507 int cur_idx
= track_write_idx
;
509 for (i
= 0; i
< numentries
; i
++)
511 if (trackdata
[cur_idx
].event_sent
)
514 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
517 cur_idx
= track_write_idx
;
519 for (i
= 0; i
< numentries
; i
++)
521 /* Send an event to notify that track has finished. */
522 if (trackdata
[cur_idx
].event_sent
)
525 if (track_unbuffer_callback
)
526 track_unbuffer_callback(&trackdata
[cur_idx
].id3
,
528 trackdata
[cur_idx
].event_sent
= false;
530 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
534 /* Send callback events to notify about new tracks. */
535 static void generate_postbuffer_events(void)
539 int numentries
= num_tracks_in_memory();
540 int cur_idx
= track_read_idx
;
542 for (i
= 0; i
< numentries
; i
++)
544 if (!trackdata
[cur_idx
].event_sent
)
547 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
550 cur_idx
= track_read_idx
;
552 for (i
= 0; i
< numentries
; i
++)
554 if (!trackdata
[cur_idx
].event_sent
)
557 if (track_buffer_callback
)
558 track_buffer_callback(&trackdata
[cur_idx
].id3
,
560 trackdata
[cur_idx
].event_sent
= true;
562 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
566 static void recalculate_watermark(int bitrate
)
569 int time
= ata_spinup_time
;
571 /* A bitrate of 0 probably means empty VBR header. We play safe
572 and set a high threshold */
576 bytes_per_sec
= bitrate
* 1000 / 8;
580 /* No drive spins up faster than 3.5s */
585 low_watermark
= ((low_watermark_margin
* HZ
+ time
) *
590 low_watermark
= MPEG_LOW_WATER
;
594 #ifndef HAVE_FLASH_STORAGE
595 void audio_set_buffer_margin(int seconds
)
597 low_watermark_margin
= seconds
;
601 void audio_get_debugdata(struct audio_debug
*dbgdata
)
603 dbgdata
->audiobuflen
= audiobuflen
;
604 dbgdata
->audiobuf_write
= audiobuf_write
;
605 dbgdata
->audiobuf_swapwrite
= audiobuf_swapwrite
;
606 dbgdata
->audiobuf_read
= audiobuf_read
;
608 dbgdata
->last_dma_chunk_size
= last_dma_chunk_size
;
610 #if CONFIG_CPU == SH7034
611 dbgdata
->dma_on
= (SCR0
& 0x80) != 0;
613 dbgdata
->playing
= playing
;
614 dbgdata
->play_pending
= play_pending
;
615 dbgdata
->is_playing
= is_playing
;
616 dbgdata
->filling
= filling
;
617 dbgdata
->dma_underrun
= dma_underrun
;
619 dbgdata
->unplayed_space
= get_unplayed_space();
620 dbgdata
->playable_space
= get_playable_space();
621 dbgdata
->unswapped_space
= get_unswapped_space();
623 dbgdata
->low_watermark_level
= low_watermark
;
624 dbgdata
->lowest_watermark_level
= lowest_watermark_level
;
628 static void dbg_timer_start(void)
630 /* We are using timer 2 */
632 TSTR
&= ~0x04; /* Stop the timer */
633 TSNC
&= ~0x04; /* No synchronization */
634 TMDR
&= ~0x44; /* Operate normally */
636 TCNT2
= 0; /* Start counting at 0 */
637 TCR2
= 0x03; /* Sysclock/8 */
639 TSTR
|= 0x04; /* Start timer 2 */
642 static int dbg_cnt2us(unsigned int cnt
)
644 return (cnt
* 10000) / (FREQ
/800);
648 static int get_unplayed_space(void)
650 int space
= audiobuf_write
- audiobuf_read
;
652 space
+= audiobuflen
;
656 static int get_playable_space(void)
658 int space
= audiobuf_swapwrite
- audiobuf_read
;
660 space
+= audiobuflen
;
664 static int get_unplayed_space_current_song(void)
668 if (num_tracks_in_memory() > 1)
670 space
= get_trackdata(1)->mempos
- audiobuf_read
;
674 space
= audiobuf_write
- audiobuf_read
;
678 space
+= audiobuflen
;
683 static int get_unswapped_space(void)
685 int space
= audiobuf_write
- audiobuf_swapwrite
;
687 space
+= audiobuflen
;
691 #if CONFIG_CODEC == MAS3587F
692 static int get_unsaved_space(void)
694 int space
= audiobuf_write
- audiobuf_read
;
696 space
+= audiobuflen
;
700 static void drain_dma_buffer(void)
706 while (PBDRH
& 0x80);
710 while (!(PBDRH
& 0x80));
715 static long timing_info_index
= 0;
716 static long timing_info
[1024];
719 void rec_tick (void) __attribute__ ((section (".icode")));
726 if(is_recording
&& (PBDRH
& 0x40))
729 timing_info
[timing_info_index
++] = current_tick
;
732 /* Note: Although this loop is run in interrupt context, further
733 * optimisation will do no good. The MAS would then deliver bad
734 * frames occasionally, as observed in extended experiments. */
736 while (PBDRH
& 0x40) /* We try to read as long as EOD is high */
738 xor_b(0x08, &PADRH
); /* Set PR active, independent of polarity */
741 while (PBDRH
& 0x80) /* Wait until /RTW becomes active */
743 if (--delay
<= 0) /* Bail out if we have to wait too long */
744 { /* i.e. the MAS doesn't want to talk to us */
745 xor_b(0x08, &PADRH
); /* Set PR inactive */
746 goto transfer_end
; /* and get out of here */
750 data
= *(unsigned char *)0x04000000; /* read data byte */
752 xor_b(0x08, &PADRH
); /* Set PR inactive */
754 audiobuf
[audiobuf_write
++] = data
;
756 if (audiobuf_write
>= audiobuflen
)
764 timing_info
[timing_info_index
++] = TCNT2
+ (i
<< 16);
765 timing_info_index
&= 0x3ff;
772 if(TIME_AFTER(current_tick
, prerecord_timeout
))
774 prerecord_timeout
= current_tick
+ HZ
;
775 queue_post(&mpeg_queue
, MPEG_PRERECORDING_TICK
, 0);
780 /* Signal to save the data if we are running out of buffer
782 if (audiobuflen
- get_unsaved_space() < MPEG_RECORDING_LOW_WATER
783 && saving_status
== NOT_SAVING
)
785 saving_status
= BUFFER_FULL
;
786 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
791 #endif /* CONFIG_CODEC == MAS3587F */
793 void playback_tick(void)
795 struct trackdata
*ptd
= get_trackdata(0);
798 ptd
->id3
.elapsed
+= (current_tick
- last_dma_tick
) * 1000 / HZ
;
799 last_dma_tick
= current_tick
;
800 audio_dispatch_event(AUDIO_EVENT_POS_REPORT
,
801 (unsigned long)ptd
->id3
.elapsed
);
805 static void reset_mp3_buffer(void)
809 audiobuf_swapwrite
= 0;
810 lowest_watermark_level
= audiobuflen
;
813 /* DMA transfer end interrupt callback */
814 static void transfer_end(unsigned char** ppbuf
, size_t* psize
)
816 if(playing
&& !paused
)
818 int unplayed_space_left
;
819 int space_until_end_of_buffer
;
820 int track_offset
= 1;
821 struct trackdata
*track
;
823 audiobuf_read
+= last_dma_chunk_size
;
824 if(audiobuf_read
>= audiobuflen
)
827 /* First, check if we are on a track boundary */
828 if (num_tracks_in_memory() > 1)
830 if (audiobuf_read
== get_trackdata(track_offset
)->mempos
)
832 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
834 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
840 unplayed_space_left
= get_unplayed_space();
842 space_until_end_of_buffer
= audiobuflen
- audiobuf_read
;
844 if(!filling
&& unplayed_space_left
< low_watermark
)
847 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
850 if(unplayed_space_left
)
852 last_dma_chunk_size
= MIN(0x2000, unplayed_space_left
);
853 last_dma_chunk_size
= MIN(last_dma_chunk_size
,
854 space_until_end_of_buffer
);
856 /* several tracks loaded? */
857 track
= get_trackdata(track_offset
);
860 /* will we move across the track boundary? */
861 if (( audiobuf_read
< track
->mempos
) &&
862 ((audiobuf_read
+last_dma_chunk_size
) >
865 /* Make sure that we end exactly on the boundary */
866 last_dma_chunk_size
= track
->mempos
- audiobuf_read
;
870 *psize
= last_dma_chunk_size
& 0xffff;
871 *ppbuf
= audiobuf
+ audiobuf_read
;
872 track
= get_trackdata(0);
874 track
->id3
.offset
+= last_dma_chunk_size
;
876 /* Update the watermark debug level */
877 if(unplayed_space_left
< lowest_watermark_level
)
878 lowest_watermark_level
= unplayed_space_left
;
882 /* Check if the end of data is because of a hard disk error.
883 If there is an open file handle, we are still playing music.
884 If not, the last file has been loaded, and the file handle is
888 /* Update the watermark debug level */
889 if(unplayed_space_left
< lowest_watermark_level
)
890 lowest_watermark_level
= unplayed_space_left
;
892 DEBUGF("DMA underrun.\n");
897 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
899 DEBUGF("No more MP3 data. Stopping.\n");
900 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
904 *psize
= 0; /* no more transfer */
909 static struct trackdata
*add_track_to_tag_list(const char *filename
)
911 struct trackdata
*track
;
913 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES
)
915 DEBUGF("Tag memory is full\n");
919 track
= &trackdata
[track_write_idx
];
921 /* grab id3 tag of new file and
922 remember where in memory it starts */
923 if(mp3info(&track
->id3
, filename
))
928 track
->mempos
= audiobuf_write
;
929 track
->id3
.elapsed
= 0;
930 #ifdef HAVE_LCD_BITMAP
931 if (track
->id3
.title
)
932 lcd_getstringsize(track
->id3
.title
, NULL
, NULL
);
933 if (track
->id3
.artist
)
934 lcd_getstringsize(track
->id3
.artist
, NULL
, NULL
);
935 if (track
->id3
.album
)
936 lcd_getstringsize(track
->id3
.album
, NULL
, NULL
);
938 if (cuesheet_callback
)
939 if (cuesheet_callback(filename
))
940 track
->id3
.cuesheet_type
= 1;
942 track_write_idx
= (track_write_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
947 static int new_file(int steps
)
949 int max_steps
= playlist_amount();
952 struct trackdata
*track
;
954 /* Find out how many steps to advance. The load_ahead_index field tells
955 us how many playlist entries it had to skip to get to a valid one.
956 We add those together to find out where to start. */
957 if(steps
> 0 && num_tracks_in_memory() > 1)
959 /* Begin with the song after the currently playing one */
961 while((track
= get_trackdata(i
++)))
963 start
+= track
->load_ahead_index
;
970 trackname
= playlist_peek( start
+ steps
);
974 DEBUGF("Loading %s\n", trackname
);
976 mpeg_file
= open(trackname
, O_RDONLY
);
978 DEBUGF("Couldn't open file: %s\n",trackname
);
986 struct trackdata
*track
= add_track_to_tag_list(trackname
);
1000 /* skip past id3v2 tag */
1002 track
->id3
.first_frame_offset
,
1004 track
->id3
.index
= steps
;
1005 track
->load_ahead_index
= steps
;
1006 track
->id3
.offset
= 0;
1009 /* Average bitrate * 1.5 */
1010 recalculate_watermark(
1011 (track
->id3
.bitrate
* 3) / 2);
1013 recalculate_watermark(
1014 track
->id3
.bitrate
);
1019 /* Bail out if no file could be opened */
1020 if(abs(steps
) > max_steps
)
1022 } while ( mpeg_file
< 0 );
1027 static void stop_playing(void)
1029 struct trackdata
*track
;
1031 /* Stop the current stream */
1036 track
= get_trackdata(0);
1038 prev_track_elapsed
= track
->id3
.elapsed
;
1044 generate_unbuffer_events();
1048 static void end_current_track(void) {
1049 struct trackdata
*track
;
1051 play_pending
= false;
1053 mp3_play_pause(false);
1055 track
= get_trackdata(0);
1057 prev_track_elapsed
= track
->id3
.elapsed
;
1061 generate_unbuffer_events();
1067 /* Is this a really the end of playback or is a new playlist starting */
1068 static void check_playlist_end(int direction
)
1070 /* Use the largest possible step size to account for skipped tracks */
1071 int steps
= playlist_amount();
1076 if (playlist_next(steps
) < 0)
1080 static void update_playlist(void)
1082 if (num_tracks_in_memory() > 0)
1084 struct trackdata
*track
= get_trackdata(0);
1085 track
->id3
.index
= playlist_next(track
->id3
.index
);
1089 /* End of playlist? */
1090 check_playlist_end(1);
1093 playlist_update_resume_info(audio_current_track());
1096 static void track_change(void)
1098 DEBUGF("Track change\n");
1100 struct trackdata
*track
= get_trackdata(0);
1101 prev_track_elapsed
= track
->id3
.elapsed
;
1103 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1106 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1108 if (num_tracks_in_memory() > 0)
1110 remove_current_tag();
1111 if (track_changed_callback
)
1112 track_changed_callback(audio_current_track());
1116 current_track_counter
++;
1119 unsigned long audio_prev_elapsed(void)
1121 return prev_track_elapsed
;
1125 void hexdump(const unsigned char *buf
, int len
)
1129 for(i
= 0;i
< len
;i
++)
1131 if(i
&& (i
& 15) == 0)
1135 DEBUGF("%02x ", buf
[i
]);
1141 static void start_playback_if_ready(void)
1145 playable_space
= audiobuf_swapwrite
- audiobuf_read
;
1146 if(playable_space
< 0)
1147 playable_space
+= audiobuflen
;
1149 /* See if we have started playing yet. If not, do it. */
1150 if(play_pending
|| dma_underrun
)
1152 /* If the filling has stopped, and we still haven't reached
1153 the watermark, the file must be smaller than the
1154 watermark. We must still play it. */
1155 if((playable_space
>= MPEG_PLAY_PENDING_THRESHOLD
) ||
1156 !filling
|| dma_underrun
)
1159 if (play_pending
) /* don't do this when recovering from DMA underrun */
1161 generate_postbuffer_events(); /* signal first track as buffered */
1162 if (play_pending_track_change
)
1164 play_pending_track_change
= false;
1165 if(track_changed_callback
)
1166 track_changed_callback(audio_current_track());
1168 play_pending
= false;
1172 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1173 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1174 dma_underrun
= false;
1178 last_dma_tick
= current_tick
;
1179 mp3_play_pause(true);
1182 /* Tell ourselves that we need more data */
1183 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1188 static bool swap_one_chunk(void)
1190 int free_space_left
;
1193 free_space_left
= get_unswapped_space();
1195 if(free_space_left
== 0 && !play_pending
)
1198 /* Swap in larger chunks when the user is waiting for the playback
1199 to start, or when there is dangerously little playable data left */
1201 amount_to_swap
= MIN(MPEG_PLAY_PENDING_SWAPSIZE
, free_space_left
);
1204 if(get_playable_space() < low_watermark
)
1205 amount_to_swap
= MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE
,
1208 amount_to_swap
= MIN(MPEG_SWAP_CHUNKSIZE
, free_space_left
);
1211 if(audiobuf_write
< audiobuf_swapwrite
)
1212 amount_to_swap
= MIN(audiobuflen
- audiobuf_swapwrite
,
1215 amount_to_swap
= MIN(audiobuf_write
- audiobuf_swapwrite
,
1218 bitswap(audiobuf
+ audiobuf_swapwrite
, amount_to_swap
);
1220 audiobuf_swapwrite
+= amount_to_swap
;
1221 if(audiobuf_swapwrite
>= audiobuflen
)
1223 audiobuf_swapwrite
= 0;
1229 static void mpeg_thread(void)
1231 static int pause_tick
= 0;
1232 static unsigned int pause_track
= 0;
1233 struct queue_event ev
;
1235 int free_space_left
;
1236 int unplayed_space_left
;
1240 #if CONFIG_CODEC == MAS3587F
1242 int save_endpos
= 0;
1246 #endif /* CONFIG_CODEC == MAS3587F */
1249 play_pending
= false;
1255 #if CONFIG_CODEC == MAS3587F
1256 if(mpeg_mode
== MPEG_DECODER
)
1258 #endif /* CONFIG_CODEC == MAS3587F */
1261 /* Swap if necessary, and don't block on the queue_wait() */
1262 if(swap_one_chunk())
1264 queue_wait_w_tmo(&mpeg_queue
, &ev
, 0);
1268 /* periodically update resume info */
1269 queue_wait_w_tmo(&mpeg_queue
, &ev
, HZ
/2);
1273 DEBUGF("S R:%x W:%x SW:%x\n",
1274 audiobuf_read
, audiobuf_write
, audiobuf_swapwrite
);
1275 queue_wait(&mpeg_queue
, &ev
);
1278 start_playback_if_ready();
1283 DEBUGF("MPEG_PLAY\n");
1286 /* Silence the A/D input, it may be on because the radio
1288 mas_codec_writereg(6, 0x0000);
1289 #endif /* CONFIG_TUNER */
1291 /* Stop the current stream */
1293 end_current_track();
1295 if ( new_file(0) == -1 )
1302 start_offset
= (int)ev
.data
;
1304 /* mid-song resume? */
1306 struct mp3entry
* id3
= &get_trackdata(0)->id3
;
1307 lseek(mpeg_file
, start_offset
, SEEK_SET
);
1308 id3
->offset
= start_offset
;
1312 /* skip past id3v2 tag */
1314 get_trackdata(0)->id3
.first_frame_offset
,
1319 /* Make it read more data */
1321 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1323 /* Tell the file loading code that we want to start playing
1324 as soon as we have some data */
1325 play_pending
= true;
1326 play_pending_track_change
= true;
1329 current_track_counter
++;
1333 DEBUGF("MPEG_STOP\n");
1338 playlist_update_resume_info(audio_current_track());
1341 mpeg_stop_done
= true;
1345 DEBUGF("MPEG_PAUSE\n");
1346 /* Stop the current stream */
1348 playlist_update_resume_info(audio_current_track());
1351 pause_tick
= current_tick
;
1352 pause_track
= current_track_counter
;
1353 mp3_play_pause(false);
1357 DEBUGF("MPEG_RESUME\n");
1358 /* Continue the current stream */
1363 if ( current_track_counter
== pause_track
)
1364 last_dma_tick
+= current_tick
- pause_tick
;
1366 last_dma_tick
= current_tick
;
1368 mp3_play_pause(true);
1373 DEBUGF("MPEG_NEXT\n");
1374 /* is next track in ram? */
1375 if ( num_tracks_in_memory() > 1 ) {
1376 int unplayed_space_left
, unswapped_space_left
;
1378 /* stop the current stream */
1379 play_pending
= false;
1381 mp3_play_pause(false);
1384 audiobuf_read
= get_trackdata(0)->mempos
;
1385 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1386 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1387 dma_underrun
= false;
1388 last_dma_tick
= current_tick
;
1390 unplayed_space_left
= get_unplayed_space();
1391 unswapped_space_left
= get_unswapped_space();
1393 /* should we start reading more data? */
1394 if(!filling
&& (unplayed_space_left
< low_watermark
)) {
1396 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1397 play_pending
= true;
1398 } else if(unswapped_space_left
&&
1399 unswapped_space_left
> unplayed_space_left
) {
1400 /* Stop swapping the data from the previous file */
1401 audiobuf_swapwrite
= audiobuf_read
;
1402 play_pending
= true;
1406 mp3_play_pause(true);
1410 if (!playlist_check(1))
1413 /* stop the current stream */
1414 end_current_track();
1416 if (new_file(1) < 0) {
1417 DEBUGF("No more files to play\n");
1420 check_playlist_end(1);
1421 current_track_counter
++;
1423 /* Make it read more data */
1425 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1427 /* Tell the file loading code that we want
1428 to start playing as soon as we have some data */
1429 play_pending
= true;
1430 play_pending_track_change
= true;
1433 current_track_counter
++;
1439 DEBUGF("MPEG_PREV\n");
1441 if (!playlist_check(-1))
1444 /* stop the current stream */
1445 end_current_track();
1447 /* Open the next file */
1448 if (new_file(-1) < 0) {
1449 DEBUGF("No more files to play\n");
1452 check_playlist_end(-1);
1453 current_track_counter
++;
1455 /* Make it read more data */
1457 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1459 /* Tell the file loading code that we want to
1460 start playing as soon as we have some data */
1461 play_pending
= true;
1462 play_pending_track_change
= true;
1465 current_track_counter
++;
1470 case MPEG_FF_REWIND
: {
1471 struct mp3entry
*id3
= audio_current_track();
1472 unsigned int oldtime
= id3
->elapsed
;
1473 unsigned int newtime
= (unsigned int)ev
.data
;
1474 int curpos
, newpos
, diffpos
;
1475 DEBUGF("MPEG_FF_REWIND\n");
1477 id3
->elapsed
= newtime
;
1479 newpos
= audio_get_file_pos();
1482 id3
->elapsed
= oldtime
;
1487 curpos
= lseek(mpeg_file
, 0, SEEK_CUR
);
1489 curpos
= id3
->filesize
;
1491 if (num_tracks_in_memory() > 1)
1493 /* We have started loading other tracks that need to be
1495 struct trackdata
*track
;
1498 while((track
= get_trackdata(i
++)))
1500 curpos
+= track
->id3
.filesize
;
1504 diffpos
= curpos
- newpos
;
1506 if(!filling
&& diffpos
>= 0 && diffpos
< audiobuflen
)
1508 int unplayed_space_left
, unswapped_space_left
;
1510 /* We are changing to a position that's already in
1511 memory, so we just move the DMA read pointer. */
1512 audiobuf_read
= audiobuf_write
- diffpos
;
1513 if (audiobuf_read
< 0)
1515 audiobuf_read
+= audiobuflen
;
1518 unplayed_space_left
= get_unplayed_space();
1519 unswapped_space_left
= get_unswapped_space();
1521 /* If unswapped_space_left is larger than
1522 unplayed_space_left, it means that the swapwrite pointer
1523 hasn't yet advanced up to the new location of the read
1524 pointer. We just move it, there is no need to swap
1525 data that won't be played anyway. */
1527 if (unswapped_space_left
> unplayed_space_left
)
1529 DEBUGF("Moved swapwrite\n");
1530 audiobuf_swapwrite
= audiobuf_read
;
1531 play_pending
= true;
1534 if (mpeg_file
>=0 && unplayed_space_left
< low_watermark
)
1536 /* We need to load more data before starting */
1538 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1539 play_pending
= true;
1543 /* resume will start at new position */
1544 last_dma_chunk_size
=
1545 MIN(0x2000, get_unplayed_space_current_song());
1546 mp3_play_data(audiobuf
+ audiobuf_read
,
1547 last_dma_chunk_size
, transfer_end
);
1548 dma_underrun
= false;
1553 /* Move to the new position in the file and start
1557 if (num_tracks_in_memory() > 1)
1559 /* We have to reload the current track */
1561 remove_all_non_current_tags();
1562 generate_unbuffer_events();
1568 mpeg_file
= open(id3
->path
, O_RDONLY
);
1571 id3
->elapsed
= oldtime
;
1576 if(-1 == lseek(mpeg_file
, newpos
, SEEK_SET
))
1578 id3
->elapsed
= oldtime
;
1583 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1585 /* Tell the file loading code that we want to start playing
1586 as soon as we have some data */
1587 play_pending
= true;
1590 id3
->offset
= newpos
;
1595 case MPEG_FLUSH_RELOAD
: {
1596 int numtracks
= num_tracks_in_memory();
1597 bool reload_track
= false;
1601 /* Reset the buffer */
1602 audiobuf_write
= get_trackdata(1)->mempos
;
1604 /* Reset swapwrite unless we're still swapping current
1606 if (get_unplayed_space() <= get_playable_space())
1607 audiobuf_swapwrite
= audiobuf_write
;
1610 remove_all_non_current_tags();
1611 generate_unbuffer_events();
1613 reload_track
= true;
1615 else if (numtracks
== 1 && mpeg_file
< 0)
1617 reload_track
= true;
1620 if(reload_track
&& new_file(1) >= 0)
1622 /* Tell ourselves that we want more data */
1624 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1630 case MPEG_NEED_DATA
:
1631 free_space_left
= audiobuf_read
- audiobuf_write
;
1633 /* We interpret 0 as "empty buffer" */
1634 if(free_space_left
<= 0)
1635 free_space_left
+= audiobuflen
;
1637 unplayed_space_left
= audiobuflen
- free_space_left
;
1639 /* Make sure that we don't fill the entire buffer */
1640 free_space_left
-= MPEG_HIGH_WATER
;
1642 if (ev
.data
== GENERATE_UNBUFFER_EVENTS
)
1643 generate_unbuffer_events();
1645 /* do we have any more buffer space to fill? */
1646 if(free_space_left
<= 0)
1650 generate_postbuffer_events();
1655 /* Read small chunks while we are below the low water mark */
1656 if(unplayed_space_left
< low_watermark
)
1657 amount_to_read
= MIN(MPEG_LOW_WATER_CHUNKSIZE
,
1660 amount_to_read
= free_space_left
;
1662 /* Don't read more than until the end of the buffer */
1663 amount_to_read
= MIN(audiobuflen
- audiobuf_write
,
1665 #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */
1666 amount_to_read
= MIN(0x40000, amount_to_read
);
1668 amount_to_read
= MIN(0x100000, amount_to_read
);
1671 /* Read as much mpeg data as we can fit in the buffer */
1676 len
= read(mpeg_file
, audiobuf
+ audiobuf_write
,
1681 DEBUGF("time: %d\n", t2
- t1
);
1682 DEBUGF("R: %x\n", len
);
1684 /* Now make sure that we don't feed the MAS with ID3V1
1686 if (len
< amount_to_read
)
1689 static const unsigned char tag
[] = "TAG";
1691 int tagptr
= audiobuf_write
+ len
- 128;
1693 /* Really rare case: entire potential tag wasn't
1694 read in this call AND audiobuf_write < 128 */
1696 tagptr
+= audiobuflen
;
1698 for(i
= 0;i
< 3;i
++)
1700 if(tagptr
>= audiobuflen
)
1701 tagptr
-= audiobuflen
;
1703 if(audiobuf
[tagptr
] != tag
[i
])
1714 /* Skip id3v1 tag */
1715 DEBUGF("Skipping ID3v1 tag\n");
1718 /* In the very rare case when the entire tag
1719 wasn't read in this read() len will be < 0.
1720 Take care of this when changing the write
1725 audiobuf_write
+= len
;
1727 if (audiobuf_write
< 0)
1728 audiobuf_write
+= audiobuflen
;
1730 if(audiobuf_write
>= audiobuflen
)
1736 /* Tell ourselves that we want more data */
1737 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1743 DEBUGF("MPEG read error\n");
1751 /* No more data to play */
1752 DEBUGF("No more files to play\n");
1757 /* Tell ourselves that we want more data */
1758 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1764 case MPEG_TRACK_CHANGE
:
1769 case SYS_USB_CONNECTED
:
1774 /* Tell the USB thread that we are safe */
1775 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1776 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1778 /* Wait until the USB cable is extracted again */
1779 usb_wait_for_disconnect(&mpeg_queue
);
1781 #endif /* !USB_NONE */
1783 #if CONFIG_CODEC == MAS3587F
1784 case MPEG_INIT_RECORDING
:
1786 init_recording_done
= true;
1788 #endif /* CONFIG_CODEC == MAS3587F */
1792 playlist_update_resume_info(audio_current_track());
1795 #if CONFIG_CODEC == MAS3587F
1799 queue_wait(&mpeg_queue
, &ev
);
1803 if (is_prerecording
)
1807 /* Go back prerecord_count seconds in the buffer */
1808 startpos
= prerecord_index
- prerecord_count
;
1810 startpos
+= prerecording_max_seconds
;
1812 /* Read the position data from the prerecord buffer */
1813 frame_count_start
= prerecord_buffer
[startpos
].framecount
;
1814 startpos
= prerecord_buffer
[startpos
].mempos
;
1816 DEBUGF("Start looking at address %x (%x)\n",
1817 audiobuf
+startpos
, startpos
);
1819 saved_header
= mpeg_get_last_header();
1821 mem_find_next_frame(startpos
, &offset
, 1800,
1824 audiobuf_read
= startpos
+ offset
;
1825 if(audiobuf_read
>= audiobuflen
)
1826 audiobuf_read
-= audiobuflen
;
1828 DEBUGF("New audiobuf_read address: %x (%x)\n",
1829 audiobuf
+audiobuf_read
, audiobuf_read
);
1831 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1832 num_rec_bytes
= get_unsaved_space();
1833 set_irq_level(level
);
1837 frame_count_start
= 0;
1839 audiobuf_read
= MPEG_RESERVED_HEADER_SPACE
;
1840 audiobuf_write
= MPEG_RESERVED_HEADER_SPACE
;
1844 DEBUGF("Recording...\n");
1847 /* Wait until at least one frame is encoded and get the
1848 frame header, for later use by the Xing header
1851 saved_header
= mpeg_get_last_header();
1853 /* delayed until buffer is saved, don't open yet */
1854 strcpy(delayed_filename
, recording_filename
);
1860 DEBUGF("MPEG_STOP\n");
1864 /* Save the remaining data in the buffer */
1865 save_endpos
= audiobuf_write
;
1866 saving_status
= STOP_RECORDING
;
1867 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1870 case MPEG_STOP_DONE
:
1871 DEBUGF("MPEG_STOP_DONE\n");
1881 for(i
= 0;i
< 512;i
++)
1883 DEBUGF("%d - %d us (%d bytes)\n",
1885 (timing_info
[i
*2+1] & 0xffff) *
1887 timing_info
[i
*2+1] >> 16);
1894 start_prerecording();
1896 mpeg_stop_done
= true;
1900 /* Bail out when a more important save is happening */
1901 if (saving_status
> NEW_FILE
)
1904 /* Make sure we have at least one complete frame
1905 in the buffer. If we haven't recorded a single
1906 frame within 200ms, the MAS is probably not recording
1907 anything, and we bail out. */
1908 amount_to_save
= get_unsaved_space();
1909 if (amount_to_save
< 1800)
1912 amount_to_save
= get_unsaved_space();
1915 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1916 &frame_count_end
, 1);
1918 last_rec_time
= current_tick
- record_start_time
;
1919 record_start_time
= current_tick
;
1921 pause_start_time
= record_start_time
;
1923 /* capture all values at one point */
1924 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1925 save_endpos
= audiobuf_write
;
1926 last_rec_bytes
= num_rec_bytes
;
1928 set_irq_level(level
);
1930 if (amount_to_save
>= 1800)
1932 /* Now find a frame boundary to split at */
1933 save_endpos
-= 1800;
1934 if (save_endpos
< 0)
1935 save_endpos
+= audiobuflen
;
1937 rc
= mem_find_next_frame(save_endpos
, &offset
, 1800,
1939 if (!rc
) /* No header found, save whole buffer */
1942 save_endpos
+= offset
;
1943 if (save_endpos
>= audiobuflen
)
1944 save_endpos
-= audiobuflen
;
1946 last_rec_bytes
+= offset
- 1800;
1947 level
= set_irq_level(HIGHEST_IRQ_LEVEL
);
1948 num_rec_bytes
+= 1800 - offset
;
1949 set_irq_level(level
);
1952 saving_status
= NEW_FILE
;
1953 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1956 case MPEG_SAVE_DATA
:
1957 if (saving_status
== BUFFER_FULL
)
1958 save_endpos
= audiobuf_write
;
1960 if (mpeg_file
< 0) /* delayed file open */
1962 mpeg_file
= open(delayed_filename
, O_WRONLY
|O_CREAT
);
1965 panicf("recfile: %d", mpeg_file
);
1968 amount_to_save
= save_endpos
- audiobuf_read
;
1969 if (amount_to_save
< 0)
1970 amount_to_save
+= audiobuflen
;
1972 amount_to_save
= MIN(amount_to_save
,
1973 audiobuflen
- audiobuf_read
);
1974 #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */
1975 amount_to_save
= MIN(0x40000, amount_to_save
);
1977 amount_to_save
= MIN(0x100000, amount_to_save
);
1979 rc
= write(mpeg_file
, audiobuf
+ audiobuf_read
,
1983 if (errno
== ENOSPC
)
1985 mpeg_errno
= AUDIOERR_DISK_FULL
;
1987 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1988 /* will close the file */
1992 panicf("rec wrt: %d", rc
);
1995 audiobuf_read
+= amount_to_save
;
1996 if (audiobuf_read
>= audiobuflen
)
1999 if (audiobuf_read
== save_endpos
) /* all saved */
2001 switch (saving_status
)
2004 rc
= fsync(mpeg_file
);
2006 panicf("rec fls: %d", rc
);
2011 /* Close the current file */
2012 rc
= close(mpeg_file
);
2014 panicf("rec cls: %d", rc
);
2019 /* copy new filename */
2020 strcpy(delayed_filename
, recording_filename
);
2022 frame_count_start
= frame_count_end
;
2025 case STOP_RECORDING
:
2026 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
2027 /* will close the file */
2033 saving_status
= NOT_SAVING
;
2035 else /* tell ourselves to save the next chunk */
2036 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
2040 case MPEG_PRERECORDING_TICK
:
2041 if(!is_prerecording
)
2044 /* Store the write pointer every second */
2045 prerecord_buffer
[prerecord_index
].mempos
= audiobuf_write
;
2046 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
2047 &prerecord_buffer
[prerecord_index
].framecount
, 1);
2049 /* Wrap if necessary */
2050 if(++prerecord_index
== prerecording_max_seconds
)
2051 prerecord_index
= 0;
2053 /* Update the number of seconds recorded */
2054 if(prerecord_count
< prerecording_max_seconds
)
2058 case MPEG_INIT_PLAYBACK
:
2059 /* Stop the prerecording */
2063 init_playback_done
= true;
2066 case MPEG_PAUSE_RECORDING
:
2070 case MPEG_RESUME_RECORDING
:
2074 case SYS_USB_CONNECTED
:
2075 /* We can safely go to USB mode if no recording
2077 if((!is_recording
|| is_prerecording
) && mpeg_stop_done
)
2079 /* Even if we aren't recording, we still call this
2080 function, to put the MAS in monitoring mode,
2084 /* Tell the USB thread that we are safe */
2085 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2086 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
2088 /* Wait until the USB cable is extracted again */
2089 usb_wait_for_disconnect(&mpeg_queue
);
2094 #endif /* CONFIG_CODEC == MAS3587F */
2097 #endif /* !SIMULATOR */
2099 struct mp3entry
* audio_current_track()
2103 #else /* !SIMULATOR */
2104 if(num_tracks_in_memory())
2105 return &get_trackdata(0)->id3
;
2108 #endif /* !SIMULATOR */
2111 struct mp3entry
* audio_next_track()
2115 #else /* !SIMULATOR */
2116 if(num_tracks_in_memory() > 1)
2117 return &get_trackdata(1)->id3
;
2120 #endif /* !SIMULATOR */
2123 bool audio_has_changed_track(void)
2125 if(last_track_counter
!= current_track_counter
)
2127 last_track_counter
= current_track_counter
;
2133 #if CONFIG_CODEC == MAS3587F
2135 void audio_init_playback(void)
2137 init_playback_done
= false;
2138 queue_post(&mpeg_queue
, MPEG_INIT_PLAYBACK
, 0);
2140 while(!init_playback_done
)
2145 /****************************************************************************
2146 * Recording functions
2147 ***************************************************************************/
2148 void audio_init_recording(unsigned int buffer_offset
)
2150 buffer_offset
= buffer_offset
;
2151 init_recording_done
= false;
2152 queue_post(&mpeg_queue
, MPEG_INIT_RECORDING
, 0);
2154 while(!init_recording_done
)
2158 static void init_recording(void)
2170 /* Init the recording variables */
2171 is_recording
= false;
2172 is_prerecording
= false;
2174 mpeg_stop_done
= true;
2178 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2179 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
2181 panicf("mas_ctrl_w: %d", rc
);
2183 /* Stop the current application */
2185 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2188 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2191 /* Perform black magic as described by the data sheet */
2192 if((mas_version_code
& 0x0fff) == 0x0102)
2194 DEBUGF("Performing MAS black magic for B2 version\n");
2195 mas_writereg(0xa3, 0x98);
2196 mas_writereg(0x94, 0xfffff);
2198 mas_writemem(MAS_BANK_D1
, 0, &val
, 1);
2199 mas_writereg(0xa3, 0x90);
2202 /* Enable A/D Converters */
2203 shadow_codec_reg0
= 0xcccd;
2204 mas_codec_writereg(0x0, shadow_codec_reg0
);
2206 /* Copy left channel to right (mono mode) */
2207 mas_codec_writereg(8, 0x8000);
2209 /* ADC scale 0%, DSP scale 100%
2210 We use the DSP output for monitoring, because it works with all
2211 sources including S/PDIF */
2212 mas_codec_writereg(6, 0x0000);
2213 mas_codec_writereg(7, 0x4000);
2216 shadow_soft_mute
= 0;
2217 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2219 #ifdef HAVE_SPDIF_OUT
2220 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2222 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2224 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
2226 /* Set Demand mode, monitoring OFF and validate all settings */
2227 shadow_io_control_main
= 0x125;
2228 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2230 /* Start the encoder application */
2232 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2235 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2236 } while(!(val
& 0x40));
2238 /* We have started the recording application with monitoring OFF.
2239 This is because we want to record at least one frame to fill the DMA
2240 buffer, because the silly MAS will not negate EOD until at least one
2241 DMA transfer has taken place.
2242 Now let's wait for some data to be encoded. */
2245 /* Now set it to Monitoring mode as default, saves power */
2246 shadow_io_control_main
= 0x525;
2247 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2249 /* Wait until the DSP has accepted the settings */
2252 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2256 mpeg_mode
= MPEG_ENCODER
;
2258 DEBUGF("MAS Recording application started\n");
2260 /* At this point, all settings are the reset MAS defaults, next thing is to
2261 call mpeg_set_recording_options(). */
2264 void audio_record(const char *filename
)
2268 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2269 recording_filename
[MAX_PATH
- 1] = 0;
2271 queue_post(&mpeg_queue
, MPEG_RECORD
, 0);
2274 void audio_pause_recording(void)
2276 queue_post(&mpeg_queue
, MPEG_PAUSE_RECORDING
, 0);
2279 void audio_resume_recording(void)
2281 queue_post(&mpeg_queue
, MPEG_RESUME_RECORDING
, 0);
2284 static void prepend_header(void)
2289 /* Make room for header */
2290 audiobuf_read
-= MPEG_RESERVED_HEADER_SPACE
;
2291 if(audiobuf_read
< 0)
2293 /* Clear the bottom half */
2294 memset(audiobuf
, 0, audiobuf_read
+ MPEG_RESERVED_HEADER_SPACE
);
2296 /* And the top half */
2297 audiobuf_read
+= audiobuflen
;
2298 memset(audiobuf
+ audiobuf_read
, 0, audiobuflen
- audiobuf_read
);
2302 memset(audiobuf
+ audiobuf_read
, 0, MPEG_RESERVED_HEADER_SPACE
);
2304 /* Copy the empty ID3 header */
2305 startpos
= audiobuf_read
;
2306 for(i
= 0; i
< sizeof(empty_id3_header
); i
++)
2308 audiobuf
[startpos
++] = empty_id3_header
[i
];
2309 if(startpos
== audiobuflen
)
2314 static void update_header(void)
2317 unsigned long frames
;
2319 if (last_rec_bytes
> 0)
2321 /* Create the Xing header */
2322 fd
= open(delayed_filename
, O_RDWR
);
2324 panicf("rec upd: %d (%s)", fd
, recording_filename
);
2326 frames
= frame_count_end
- frame_count_start
;
2327 /* If the number of recorded frames has reached 0x7ffff,
2328 we can no longer trust it */
2329 if (frame_count_end
== 0x7ffff)
2332 /* saved_header is saved right before stopping the MAS */
2333 framelen
= create_xing_header(fd
, 0, last_rec_bytes
, xing_buffer
,
2334 frames
, last_rec_time
* (1000/HZ
),
2335 saved_header
, NULL
, false);
2337 lseek(fd
, MPEG_RESERVED_HEADER_SPACE
- framelen
, SEEK_SET
);
2338 write(fd
, xing_buffer
, framelen
);
2343 static void start_prerecording(void)
2347 DEBUGF("Starting prerecording\n");
2349 prerecord_index
= 0;
2350 prerecord_count
= 0;
2351 prerecord_timeout
= current_tick
+ HZ
;
2352 memset(prerecord_buffer
, 0, sizeof(prerecord_buffer
));
2355 is_prerecording
= true;
2357 /* Stop monitoring and start the encoder */
2358 shadow_io_control_main
&= ~(1 << 10);
2359 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2360 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2362 /* Wait until the DSP has accepted the settings */
2365 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2368 is_recording
= true;
2369 saving_status
= NOT_SAVING
;
2371 demand_irq_enable(true);
2374 static void start_recording(void)
2380 /* This will make the IRQ handler start recording
2381 for real, i.e send MPEG_SAVE_DATA messages when
2382 the buffer is full */
2383 is_prerecording
= false;
2387 /* If prerecording is off, we need to stop the monitoring
2388 and start the encoder */
2389 shadow_io_control_main
&= ~(1 << 10);
2390 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2391 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2393 /* Wait until the DSP has accepted the settings */
2396 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2400 is_recording
= true;
2401 saving_status
= NOT_SAVING
;
2404 /* Store the current time */
2406 record_start_time
= current_tick
- prerecord_count
* HZ
;
2408 record_start_time
= current_tick
;
2410 pause_start_time
= 0;
2412 demand_irq_enable(true);
2415 static void pause_recording(void)
2417 pause_start_time
= current_tick
;
2419 /* Set the pause bit */
2420 shadow_soft_mute
|= 2;
2421 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2426 static void resume_recording(void)
2430 /* Clear the pause bit */
2431 shadow_soft_mute
&= ~2;
2432 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2434 /* Compensate for the time we have been paused */
2435 if(pause_start_time
)
2438 current_tick
- (pause_start_time
- record_start_time
);
2439 pause_start_time
= 0;
2443 static void stop_recording(void)
2447 /* Let it finish the last frame */
2452 demand_irq_enable(false);
2454 is_recording
= false;
2455 is_prerecording
= false;
2457 last_rec_bytes
= num_rec_bytes
;
2458 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
, &frame_count_end
, 1);
2459 last_rec_time
= current_tick
- record_start_time
;
2461 /* Start monitoring */
2462 shadow_io_control_main
|= (1 << 10);
2463 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2464 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2466 /* Wait until the DSP has accepted the settings */
2469 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2475 void audio_set_recording_options(struct audio_recording_options
*options
)
2479 is_mpeg1
= (options
->rec_frequency
< 3)?true:false;
2481 rec_version_index
= is_mpeg1
?3:2;
2482 rec_frequency_index
= options
->rec_frequency
% 3;
2484 shadow_encoder_control
= (options
->rec_quality
<< 17) |
2485 (rec_frequency_index
<< 10) |
2486 ((is_mpeg1
?1:0) << 9) |
2487 (((options
->rec_channels
* 2 + 1) & 3) << 6) |
2488 (1 << 5) /* MS-stereo */ |
2489 (1 << 2) /* Is an original */;
2490 mas_writemem(MAS_BANK_D0
, MAS_D0_ENCODER_CONTROL
, &shadow_encoder_control
,1);
2492 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control
);
2494 shadow_soft_mute
= options
->rec_editable
?4:0;
2495 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
,1);
2497 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute
);
2499 shadow_io_control_main
= ((1 << 10) | /* Monitoring ON */
2500 ((options
->rec_source
< 2)?1:2) << 8) | /* Input select */
2501 (1 << 5) | /* SDO strobe invert */
2502 ((is_mpeg1
?0:1) << 3) |
2503 (1 << 2) | /* Inverted SIBC clock signal */
2505 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
,1);
2507 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2509 if(options
->rec_source
== AUDIO_SRC_MIC
)
2511 /* Copy left channel to right (mono mode) */
2512 mas_codec_writereg(8, 0x8000);
2516 /* Stereo input mode */
2517 mas_codec_writereg(8, 0);
2520 prerecording_max_seconds
= options
->rec_prerecord_time
;
2521 if(prerecording_max_seconds
)
2523 prerecording
= true;
2524 start_prerecording();
2528 prerecording
= false;
2529 is_prerecording
= false;
2530 is_recording
= false;
2534 /* If use_mic is true, the left gain is used */
2535 void audio_set_recording_gain(int left
, int right
, int type
)
2537 /* Enable both left and right A/D */
2538 shadow_codec_reg0
= (left
<< 12) |
2541 (type
==AUDIO_GAIN_MIC
?0x0008:0) | /* Connect left A/D to mic */
2543 mas_codec_writereg(0x0, shadow_codec_reg0
);
2546 #if CONFIG_TUNER & S1A0903X01
2547 /* Get the (unpitched) MAS PLL frequency, for avoiding FM interference with the
2548 * Samsung tuner. Zero means unknown. Currently handles recording from analog
2550 int mpeg_get_mas_pllfreq(void)
2552 if (mpeg_mode
!= MPEG_ENCODER
)
2555 if (rec_frequency_index
== 0) /* 44.1 kHz / 22.05 kHz */
2560 #endif /* CONFIG_TUNER & S1A0903X01 */
2562 /* try to make some kind of beep, also in recording mode */
2563 void audio_beep(int duration
)
2565 long starttick
= current_tick
;
2567 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2568 * While this is still audible even without an external signal,
2569 * it doesn't affect the (pre-)recording. */
2570 mas_codec_writereg(0, shadow_codec_reg0
^ 1);
2571 mas_codec_writereg(0, shadow_codec_reg0
);
2574 while (current_tick
- starttick
< duration
);
2577 void audio_new_file(const char *filename
)
2581 strncpy(recording_filename
, filename
, MAX_PATH
- 1);
2582 recording_filename
[MAX_PATH
- 1] = 0;
2584 queue_post(&mpeg_queue
, MPEG_NEW_FILE
, 0);
2587 unsigned long audio_recorded_time(void)
2590 return prerecord_count
* HZ
;
2595 return pause_start_time
- record_start_time
;
2597 return current_tick
- record_start_time
;
2603 unsigned long audio_num_recorded_bytes(void)
2612 index
= prerecord_index
- prerecord_count
;
2614 index
+= prerecording_max_seconds
;
2616 num_bytes
= audiobuf_write
- prerecord_buffer
[index
].mempos
;
2618 num_bytes
+= audiobuflen
;
2623 return num_rec_bytes
;
2629 #else /* SIMULATOR */
2631 /* dummies coming up */
2633 void audio_init_playback(void)
2637 unsigned long audio_recorded_time(void)
2642 void audio_beep(int duration
)
2647 void audio_pause_recording(void)
2651 void audio_resume_recording(void)
2655 unsigned long audio_num_recorded_bytes(void)
2660 void audio_record(const char *filename
)
2665 void audio_new_file(const char *filename
)
2671 void audio_set_recording_gain(int left
, int right
, int type
)
2678 void audio_init_recording(unsigned int buffer_offset
)
2681 (void)buffer_offset
;
2683 void audio_set_recording_options(struct audio_recording_options
*options
)
2688 #endif /* SIMULATOR */
2689 #endif /* CONFIG_CODEC == MAS3587F */
2691 void audio_play(long offset
)
2700 trackname
= playlist_peek( steps
);
2703 if(mp3info(&taginfo
, trackname
)) {
2704 /* bad mp3, move on */
2705 if(++steps
> playlist_amount())
2709 #ifdef HAVE_MPEG_PLAY
2710 real_mpeg_play(trackname
);
2712 playlist_next(steps
);
2713 taginfo
.offset
= offset
;
2714 set_elapsed(&taginfo
);
2719 #else /* !SIMULATOR */
2722 queue_post(&mpeg_queue
, MPEG_PLAY
, offset
);
2723 #endif /* !SIMULATOR */
2728 void audio_stop(void)
2733 struct trackdata
*track
= get_trackdata(0);
2734 prev_track_elapsed
= track
->id3
.elapsed
;
2736 mpeg_stop_done
= false;
2737 queue_post(&mpeg_queue
, MPEG_STOP
, 0);
2738 while(!mpeg_stop_done
)
2740 #else /* SIMULATOR */
2744 #endif /* SIMULATOR */
2748 void audio_stop_recording(void)
2753 void audio_pause(void)
2756 queue_post(&mpeg_queue
, MPEG_PAUSE
, 0);
2757 #else /* SIMULATOR */
2761 #endif /* SIMULATOR */
2764 void audio_resume(void)
2767 queue_post(&mpeg_queue
, MPEG_RESUME
, 0);
2768 #else /* SIMULATOR */
2772 #endif /* SIMULATOR */
2775 void audio_next(void)
2778 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2779 queue_post(&mpeg_queue
, MPEG_NEXT
, 0);
2780 #else /* SIMULATOR */
2786 file
= playlist_peek(steps
);
2789 if(mp3info(&taginfo
, file
)) {
2790 if(++steps
> playlist_amount())
2794 index
= playlist_next(steps
);
2795 taginfo
.index
= index
;
2796 current_track_counter
++;
2801 #endif /* SIMULATOR */
2804 void audio_prev(void)
2807 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2808 queue_post(&mpeg_queue
, MPEG_PREV
, 0);
2809 #else /* SIMULATOR */
2815 file
= playlist_peek(steps
);
2818 if(mp3info(&taginfo
, file
)) {
2822 index
= playlist_next(steps
);
2823 taginfo
.index
= index
;
2824 current_track_counter
++;
2829 #endif /* SIMULATOR */
2832 void audio_ff_rewind(long newtime
)
2835 queue_post(&mpeg_queue
, MPEG_FF_REWIND
, newtime
);
2836 #else /* SIMULATOR */
2838 #endif /* SIMULATOR */
2841 void audio_flush_and_reload_tracks(void)
2844 queue_post(&mpeg_queue
, MPEG_FLUSH_RELOAD
, 0);
2845 #endif /* !SIMULATOR*/
2848 int audio_status(void)
2853 ret
|= AUDIO_STATUS_PLAY
;
2856 ret
|= AUDIO_STATUS_PAUSE
;
2858 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2859 if(is_recording
&& !is_prerecording
)
2860 ret
|= AUDIO_STATUS_RECORD
;
2863 ret
|= AUDIO_STATUS_PRERECORD
;
2864 #endif /* CONFIG_CODEC == MAS3587F */
2867 ret
|= AUDIO_STATUS_ERROR
;
2872 unsigned int audio_error(void)
2877 void audio_error_clear(void)
2883 static void mpeg_thread(void)
2885 struct mp3entry
* id3
;
2888 id3
= audio_current_track();
2894 if (id3
->elapsed
>=id3
->length
)
2900 #endif /* SIMULATOR */
2902 void audio_init(void)
2905 track_buffer_callback
= NULL
;
2906 track_unbuffer_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
), 0, mpeg_thread_name
2914 IF_PRIO(, PRIORITY_SYSTEM
)
2917 memset(trackdata
, sizeof(trackdata
), 0);
2919 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2920 if (HW_MASK
& PR_ACTIVE_HIGH
)
2921 and_b(~0x08, &PADRH
);
2924 #endif /* CONFIG_CODEC == MAS3587F */
2932 #endif /* CONFIG_CODEC != SWCODEC */