1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 #if CONFIG_CODEC != SWCODEC
39 #include "mp3_playback.h"
42 #include "appevents.h"
52 #endif /* !SIMULATOR */
53 #ifdef HAVE_LCD_BITMAP
57 #define MPEG_SWAP_CHUNKSIZE 0x2000
58 #define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
59 wouldn't be able to see the difference between
60 an empty buffer and a full one. */
61 #define MPEG_LOW_WATER 0x60000
62 #define MPEG_RECORDING_LOW_WATER 0x80000
63 #define MPEG_LOW_WATER_CHUNKSIZE 0x40000
64 #define MPEG_LOW_WATER_SWAP_CHUNKSIZE 0x10000
65 #if (CONFIG_STORAGE & STORAGE_MMC)
66 #define MPEG_PLAY_PENDING_THRESHOLD 0x20000
67 #define MPEG_PLAY_PENDING_SWAPSIZE 0x20000
69 #define MPEG_PLAY_PENDING_THRESHOLD 0x10000
70 #define MPEG_PLAY_PENDING_SWAPSIZE 0x10000
73 #define MPEG_MAX_PRERECORD_SECONDS 30
75 /* For ID3 info and VBR header */
76 #define MPEG_RESERVED_HEADER_SPACE (4096 + 576)
79 extern unsigned long mas_version_code
;
82 #if CONFIG_CODEC == MAS3587F
83 extern enum /* from mp3_playback.c */
88 #endif /* CONFIG_CODEC == MAS3587F */
90 extern char* playlist_peek(int steps
);
91 extern bool playlist_check(int steps
);
92 extern int playlist_next(int steps
);
93 extern int playlist_amount(void);
94 extern int playlist_update_resume_info(const struct mp3entry
* id3
);
102 #define MPEG_FF_REWIND 7
103 #define MPEG_FLUSH_RELOAD 8
104 #define MPEG_RECORD 9
105 #define MPEG_INIT_RECORDING 10
106 #define MPEG_INIT_PLAYBACK 11
107 #define MPEG_NEW_FILE 12
108 #define MPEG_PAUSE_RECORDING 13
109 #define MPEG_RESUME_RECORDING 14
110 #define MPEG_NEED_DATA 100
111 #define MPEG_TRACK_CHANGE 101
112 #define MPEG_SAVE_DATA 102
113 #define MPEG_STOP_DONE 103
114 #define MPEG_PRERECORDING_TICK 104
116 /* indicator for MPEG_NEED_DATA */
117 #define GENERATE_UNBUFFER_EVENTS 1
119 /* list of tracks in memory */
120 #define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
121 #define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
127 int load_ahead_index
;
130 static struct trackdata trackdata
[MAX_TRACK_ENTRIES
];
132 static unsigned int current_track_counter
= 0;
135 /* Play time of the previous track */
136 static unsigned long prev_track_elapsed
;
138 static int track_read_idx
= 0;
139 static int track_write_idx
= 0;
140 #endif /* !SIMULATOR */
142 /* Cuesheet support */
143 static struct cuesheet
*curr_cuesheet
= NULL
;
144 static bool checked_for_cuesheet
= false;
146 static const char mpeg_thread_name
[] = "mpeg";
147 static unsigned int mpeg_errno
;
149 static bool playing
= false; /* We are playing an MP3 stream */
150 static bool is_playing
= false; /* We are (attempting to) playing MP3 files */
151 static bool paused
; /* playback is paused */
154 static char mpeg_stack
[DEFAULT_STACK_SIZE
];
155 static struct mp3entry taginfo
;
157 #else /* !SIMULATOR */
158 static struct event_queue mpeg_queue
;
159 static long mpeg_stack
[(DEFAULT_STACK_SIZE
+ 0x1000)/sizeof(long)];
161 static int audiobuflen
;
162 static int audiobuf_write
;
163 static int audiobuf_swapwrite
;
164 static int audiobuf_read
;
166 static int mpeg_file
;
168 static bool play_pending
; /* We are about to start playing */
169 static bool play_pending_track_change
; /* When starting play we're starting a new file */
170 static bool filling
; /* We are filling the buffer with data from disk */
171 static bool dma_underrun
; /* True when the DMA has stopped because of
172 slow disk reading (read error, shaking) */
173 static bool mpeg_stop_done
;
175 static int last_dma_tick
= 0;
176 static int last_dma_chunk_size
;
178 static long low_watermark
; /* Dynamic low watermark level */
179 static long low_watermark_margin
= 0; /* Extra time in seconds for watermark */
180 static long lowest_watermark_level
; /* Debug value to observe the buffer
182 #if CONFIG_CODEC == MAS3587F
183 static char recording_filename
[MAX_PATH
]; /* argument to thread */
184 static char delayed_filename
[MAX_PATH
]; /* internal copy of above */
186 static char xing_buffer
[MAX_XING_HEADER_SIZE
];
188 static bool init_recording_done
;
189 static bool init_playback_done
;
190 static bool prerecording
; /* True if prerecording is enabled */
191 static bool is_prerecording
; /* True if we are prerecording */
192 static bool is_recording
; /* We are recording */
195 NOT_SAVING
= 0, /* reasons to save data, sorted by importance */
201 static int rec_frequency_index
; /* For create_xing_header() calls */
202 static int rec_version_index
; /* For create_xing_header() calls */
204 struct prerecord_info
{
206 unsigned long framecount
;
209 static struct prerecord_info prerecord_buffer
[MPEG_MAX_PRERECORD_SECONDS
];
210 static int prerecord_index
; /* Current index in the prerecord buffer */
211 static int prerecording_max_seconds
; /* Max number of seconds to store */
212 static int prerecord_count
; /* Number of seconds in the prerecord buffer */
213 static int prerecord_timeout
; /* The tick count of the next prerecord data
216 static unsigned long record_start_time
; /* Value of current_tick when recording
218 static unsigned long pause_start_time
; /* Value of current_tick when pause was
220 static unsigned long last_rec_time
;
221 static unsigned long num_rec_bytes
;
222 static unsigned long last_rec_bytes
;
223 static unsigned long frame_count_start
;
224 static unsigned long frame_count_end
;
225 static unsigned long saved_header
= 0;
227 /* Shadow MAS registers */
228 unsigned long shadow_encoder_control
= 0;
229 #endif /* CONFIG_CODEC == MAS3587F */
231 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
232 unsigned long shadow_io_control_main
= 0;
233 unsigned long shadow_soft_mute
= 0;
234 unsigned shadow_codec_reg0
;
235 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
237 #ifdef HAVE_RECORDING
238 static const unsigned char empty_id3_header
[] =
240 'I', 'D', '3', 0x03, 0x00, 0x00,
241 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
243 #endif /* HAVE_RECORDING */
246 static int get_unplayed_space(void);
247 static int get_playable_space(void);
248 static int get_unswapped_space(void);
249 #endif /* !SIMULATOR */
251 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
252 static void init_recording(void);
253 static void prepend_header(void);
254 static void update_header(void);
255 static void start_prerecording(void);
256 static void start_recording(void);
257 static void stop_recording(void);
258 static int get_unsaved_space(void);
259 static void pause_recording(void);
260 static void resume_recording(void);
261 #endif /* (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR) */
265 static int num_tracks_in_memory(void)
267 return (track_write_idx
- track_read_idx
) & MAX_TRACK_ENTRIES_MASK
;
271 static void debug_tags(void)
275 for(i
= 0;i
< MAX_TRACK_ENTRIES
;i
++)
277 DEBUGF("%d - %s\n", i
, trackdata
[i
].id3
.path
);
279 DEBUGF("read: %d, write :%d\n", track_read_idx
, track_write_idx
);
280 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
282 #else /* !DEBUG_TAGS */
284 #endif /* !DEBUG_TAGS */
286 static void remove_current_tag(void)
288 if(num_tracks_in_memory() > 0)
290 /* First move the index, so nobody tries to access the tag */
291 track_read_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
292 checked_for_cuesheet
= false;
297 DEBUGF("remove_current_tag: no tracks to remove\n");
301 static void remove_all_non_current_tags(void)
303 track_write_idx
= (track_read_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
307 static void remove_all_tags(void)
309 track_write_idx
= track_read_idx
;
314 static struct trackdata
*get_trackdata(int offset
)
316 if(offset
>= num_tracks_in_memory())
319 return &trackdata
[(track_read_idx
+ offset
) & MAX_TRACK_ENTRIES_MASK
];
321 #endif /* !SIMULATOR */
323 /***********************************************************************/
324 /* audio event handling */
326 #define MAX_EVENT_HANDLERS 10
327 struct event_handlers_table
329 AUDIO_EVENT_HANDLER handler
;
332 static struct event_handlers_table event_handlers
[MAX_EVENT_HANDLERS
];
333 static int event_handlers_count
= 0;
335 void audio_register_event_handler(AUDIO_EVENT_HANDLER handler
, unsigned short mask
)
337 if (event_handlers_count
< MAX_EVENT_HANDLERS
)
339 event_handlers
[event_handlers_count
].handler
= handler
;
340 event_handlers
[event_handlers_count
].mask
= mask
;
341 event_handlers_count
++;
345 /* dispatch calls each handler in the order registered and returns after some
346 handler actually handles the event (the event is assumed to no longer be valid
347 after this, due to the handler changing some condition); returns true if someone
348 handled the event, which is expected to cause the caller to skip its own handling
351 static bool audio_dispatch_event(unsigned short event
, unsigned long data
)
354 for(i
=0; i
< event_handlers_count
; i
++)
356 if ( event_handlers
[i
].mask
& event
)
358 int rc
= event_handlers
[i
].handler(event
, data
);
359 if ( rc
== AUDIO_EVENT_RC_HANDLED
)
367 /***********************************************************************/
369 static void set_elapsed(struct mp3entry
* id3
)
372 if ( id3
->has_toc
) {
373 /* calculate elapsed time using TOC */
375 unsigned int remainder
, plen
, relpos
, nextpos
;
377 /* find wich percent we're at */
378 for (i
=0; i
<100; i
++ )
380 if ( id3
->offset
< id3
->toc
[i
] * (id3
->filesize
/ 256) )
390 relpos
= id3
->toc
[i
];
394 nextpos
= id3
->toc
[i
+1];
401 remainder
= id3
->offset
- (relpos
* (id3
->filesize
/ 256));
403 /* set time for this percent (divide before multiply to prevent
404 overflow on long files. loss of precision is negligible on
406 id3
->elapsed
= i
* (id3
->length
/ 100);
408 /* calculate remainder time */
409 plen
= (nextpos
- relpos
) * (id3
->filesize
/ 256);
410 id3
->elapsed
+= (((remainder
* 100) / plen
) *
411 (id3
->length
/ 10000));
414 /* no TOC exists. set a rough estimate using average bitrate */
415 int tpk
= id3
->length
/ (id3
->filesize
/ 1024);
416 id3
->elapsed
= id3
->offset
/ 1024 * tpk
;
420 /* constant bitrate, use exact calculation */
421 id3
->elapsed
= id3
->offset
/ (id3
->bitrate
/ 8);
424 int audio_get_file_pos(void)
427 struct mp3entry
*id3
= audio_current_track();
433 /* Use the TOC to find the new position */
434 unsigned int percent
, remainder
;
435 int curtoc
, nexttoc
, plen
;
437 percent
= (id3
->elapsed
*100)/id3
->length
;
441 curtoc
= id3
->toc
[percent
];
444 nexttoc
= id3
->toc
[percent
+1];
448 pos
= (id3
->filesize
/256)*curtoc
;
450 /* Use the remainder to get a more accurate position */
451 remainder
= (id3
->elapsed
*100)%id3
->length
;
452 remainder
= (remainder
*100)/id3
->length
;
453 plen
= (nexttoc
- curtoc
)*(id3
->filesize
/256);
454 pos
+= (plen
/100)*remainder
;
458 /* No TOC exists, estimate the new position */
459 pos
= (id3
->filesize
/ (id3
->length
/ 1000)) *
460 (id3
->elapsed
/ 1000);
463 else if (id3
->bitrate
)
464 pos
= id3
->elapsed
* (id3
->bitrate
/ 8);
470 if (pos
>= (int)(id3
->filesize
- id3
->id3v1len
))
472 /* Don't seek right to the end of the file so that we can
473 transition properly to the next song */
474 pos
= id3
->filesize
- id3
->id3v1len
- 1;
476 else if (pos
< (int)id3
->first_frame_offset
)
478 /* skip past id3v2 tag and other leading garbage */
479 pos
= id3
->first_frame_offset
;
484 unsigned long mpeg_get_last_header(void)
488 #else /* !SIMULATOR */
489 unsigned long tmp
[2];
491 /* Read the frame data from the MAS and reconstruct it with the
492 frame sync and all */
493 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_STATUS_1
, tmp
, 2);
494 return 0xffe00000 | ((tmp
[0] & 0x7c00) << 6) | (tmp
[1] & 0xffff);
495 #endif /* !SIMULATOR */
499 /* Send callback events to notify about removing old tracks. */
500 static void generate_unbuffer_events(void)
503 int numentries
= MAX_TRACK_ENTRIES
- num_tracks_in_memory();
504 int cur_idx
= track_write_idx
;
506 for (i
= 0; i
< numentries
; i
++)
508 /* Send an event to notify that track has finished. */
509 send_event(PLAYBACK_EVENT_TRACK_FINISH
, &trackdata
[cur_idx
].id3
);
510 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
514 /* Send callback events to notify about new tracks. */
515 static void generate_postbuffer_events(void)
518 int numentries
= num_tracks_in_memory();
519 int cur_idx
= track_read_idx
;
521 for (i
= 0; i
< numentries
; i
++)
523 send_event(PLAYBACK_EVENT_TRACK_BUFFER
, &trackdata
[cur_idx
].id3
);
524 cur_idx
= (cur_idx
+ 1) & MAX_TRACK_ENTRIES_MASK
;
528 static void recalculate_watermark(int bitrate
)
531 int time
= storage_spinup_time();
533 /* A bitrate of 0 probably means empty VBR header. We play safe
534 and set a high threshold */
538 bytes_per_sec
= bitrate
* 1000 / 8;
542 /* No drive spins up faster than 3.5s */
547 low_watermark
= ((low_watermark_margin
* HZ
+ time
) *
552 low_watermark
= MPEG_LOW_WATER
;
556 #ifdef HAVE_DISK_STORAGE
557 void audio_set_buffer_margin(int setting
)
559 low_watermark_margin
= setting
; /* in seconds */
563 void audio_get_debugdata(struct audio_debug
*dbgdata
)
565 dbgdata
->audiobuflen
= audiobuflen
;
566 dbgdata
->audiobuf_write
= audiobuf_write
;
567 dbgdata
->audiobuf_swapwrite
= audiobuf_swapwrite
;
568 dbgdata
->audiobuf_read
= audiobuf_read
;
570 dbgdata
->last_dma_chunk_size
= last_dma_chunk_size
;
572 #if CONFIG_CPU == SH7034
573 dbgdata
->dma_on
= (SCR0
& 0x80) != 0;
575 dbgdata
->playing
= playing
;
576 dbgdata
->play_pending
= play_pending
;
577 dbgdata
->is_playing
= is_playing
;
578 dbgdata
->filling
= filling
;
579 dbgdata
->dma_underrun
= dma_underrun
;
581 dbgdata
->unplayed_space
= get_unplayed_space();
582 dbgdata
->playable_space
= get_playable_space();
583 dbgdata
->unswapped_space
= get_unswapped_space();
585 dbgdata
->low_watermark_level
= low_watermark
;
586 dbgdata
->lowest_watermark_level
= lowest_watermark_level
;
590 static void dbg_timer_start(void)
592 /* We are using timer 2 */
594 TSTR
&= ~0x04; /* Stop the timer */
595 TSNC
&= ~0x04; /* No synchronization */
596 TMDR
&= ~0x44; /* Operate normally */
598 TCNT2
= 0; /* Start counting at 0 */
599 TCR2
= 0x03; /* Sysclock/8 */
601 TSTR
|= 0x04; /* Start timer 2 */
604 static int dbg_cnt2us(unsigned int cnt
)
606 return (cnt
* 10000) / (FREQ
/800);
610 static int get_unplayed_space(void)
612 int space
= audiobuf_write
- audiobuf_read
;
614 space
+= audiobuflen
;
618 static int get_playable_space(void)
620 int space
= audiobuf_swapwrite
- audiobuf_read
;
622 space
+= audiobuflen
;
626 static int get_unplayed_space_current_song(void)
630 if (num_tracks_in_memory() > 1)
632 space
= get_trackdata(1)->mempos
- audiobuf_read
;
636 space
= audiobuf_write
- audiobuf_read
;
640 space
+= audiobuflen
;
645 static int get_unswapped_space(void)
647 int space
= audiobuf_write
- audiobuf_swapwrite
;
649 space
+= audiobuflen
;
653 #if CONFIG_CODEC == MAS3587F
654 static int get_unsaved_space(void)
656 int space
= audiobuf_write
- audiobuf_read
;
658 space
+= audiobuflen
;
662 static void drain_dma_buffer(void)
668 while (PBDRH
& 0x80);
672 while (!(PBDRH
& 0x80));
677 static long timing_info_index
= 0;
678 static long timing_info
[1024];
681 void rec_tick (void) __attribute__ ((section (".icode")));
688 if(is_recording
&& (PBDRH
& 0x40))
691 timing_info
[timing_info_index
++] = current_tick
;
694 /* Note: Although this loop is run in interrupt context, further
695 * optimisation will do no good. The MAS would then deliver bad
696 * frames occasionally, as observed in extended experiments. */
698 while (PBDRH
& 0x40) /* We try to read as long as EOD is high */
700 xor_b(0x08, &PADRH
); /* Set PR active, independent of polarity */
703 while (PBDRH
& 0x80) /* Wait until /RTW becomes active */
705 if (--delay
<= 0) /* Bail out if we have to wait too long */
706 { /* i.e. the MAS doesn't want to talk to us */
707 xor_b(0x08, &PADRH
); /* Set PR inactive */
708 goto transfer_end
; /* and get out of here */
712 data
= *(unsigned char *)0x04000000; /* read data byte */
714 xor_b(0x08, &PADRH
); /* Set PR inactive */
716 audiobuf
[audiobuf_write
++] = data
;
718 if (audiobuf_write
>= audiobuflen
)
726 timing_info
[timing_info_index
++] = TCNT2
+ (i
<< 16);
727 timing_info_index
&= 0x3ff;
734 if(TIME_AFTER(current_tick
, prerecord_timeout
))
736 prerecord_timeout
= current_tick
+ HZ
;
737 queue_post(&mpeg_queue
, MPEG_PRERECORDING_TICK
, 0);
742 /* Signal to save the data if we are running out of buffer
744 if (audiobuflen
- get_unsaved_space() < MPEG_RECORDING_LOW_WATER
745 && saving_status
== NOT_SAVING
)
747 saving_status
= BUFFER_FULL
;
748 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
753 #endif /* CONFIG_CODEC == MAS3587F */
755 void playback_tick(void)
757 struct trackdata
*ptd
= get_trackdata(0);
760 ptd
->id3
.elapsed
+= (current_tick
- last_dma_tick
) * 1000 / HZ
;
761 last_dma_tick
= current_tick
;
762 audio_dispatch_event(AUDIO_EVENT_POS_REPORT
,
763 (unsigned long)ptd
->id3
.elapsed
);
767 static void reset_mp3_buffer(void)
771 audiobuf_swapwrite
= 0;
772 lowest_watermark_level
= audiobuflen
;
775 /* DMA transfer end interrupt callback */
776 static void transfer_end(unsigned char** ppbuf
, size_t* psize
)
778 if(playing
&& !paused
)
780 int unplayed_space_left
;
781 int space_until_end_of_buffer
;
782 int track_offset
= 1;
783 struct trackdata
*track
;
785 audiobuf_read
+= last_dma_chunk_size
;
786 if(audiobuf_read
>= audiobuflen
)
789 /* First, check if we are on a track boundary */
790 if (num_tracks_in_memory() > 1)
792 if (audiobuf_read
== get_trackdata(track_offset
)->mempos
)
794 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
796 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
802 unplayed_space_left
= get_unplayed_space();
804 space_until_end_of_buffer
= audiobuflen
- audiobuf_read
;
806 if(!filling
&& unplayed_space_left
< low_watermark
)
809 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
812 if(unplayed_space_left
)
814 last_dma_chunk_size
= MIN(0x2000, unplayed_space_left
);
815 last_dma_chunk_size
= MIN(last_dma_chunk_size
,
816 space_until_end_of_buffer
);
818 /* several tracks loaded? */
819 track
= get_trackdata(track_offset
);
822 /* will we move across the track boundary? */
823 if (( audiobuf_read
< track
->mempos
) &&
824 ((audiobuf_read
+last_dma_chunk_size
) >
827 /* Make sure that we end exactly on the boundary */
828 last_dma_chunk_size
= track
->mempos
- audiobuf_read
;
832 *psize
= last_dma_chunk_size
& 0xffff;
833 *ppbuf
= audiobuf
+ audiobuf_read
;
834 track
= get_trackdata(0);
836 track
->id3
.offset
+= last_dma_chunk_size
;
838 /* Update the watermark debug level */
839 if(unplayed_space_left
< lowest_watermark_level
)
840 lowest_watermark_level
= unplayed_space_left
;
844 /* Check if the end of data is because of a hard disk error.
845 If there is an open file handle, we are still playing music.
846 If not, the last file has been loaded, and the file handle is
850 /* Update the watermark debug level */
851 if(unplayed_space_left
< lowest_watermark_level
)
852 lowest_watermark_level
= unplayed_space_left
;
854 DEBUGF("DMA underrun.\n");
859 if ( ! audio_dispatch_event(AUDIO_EVENT_END_OF_TRACK
, 0) )
861 DEBUGF("No more MP3 data. Stopping.\n");
862 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
866 *psize
= 0; /* no more transfer */
871 static struct trackdata
*add_track_to_tag_list(const char *filename
)
873 struct trackdata
*track
;
874 bool send_nid3_event
;
876 if(num_tracks_in_memory() >= MAX_TRACK_ENTRIES
)
878 DEBUGF("Tag memory is full\n");
882 track
= &trackdata
[track_write_idx
];
884 /* grab id3 tag of new file and
885 remember where in memory it starts */
886 if(mp3info(&track
->id3
, filename
))
891 track
->mempos
= audiobuf_write
;
892 track
->id3
.elapsed
= 0;
893 #ifdef HAVE_LCD_BITMAP
894 if (track
->id3
.title
)
895 lcd_getstringsize(track
->id3
.title
, NULL
, NULL
);
896 if (track
->id3
.artist
)
897 lcd_getstringsize(track
->id3
.artist
, NULL
, NULL
);
898 if (track
->id3
.album
)
899 lcd_getstringsize(track
->id3
.album
, NULL
, NULL
);
902 /* if this track is the next track then let the UI know it can get it */
903 send_nid3_event
= (track_write_idx
== track_read_idx
+ 1);
904 track_write_idx
= (track_write_idx
+1) & MAX_TRACK_ENTRIES_MASK
;
906 send_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE
, NULL
);
911 static int new_file(int steps
)
913 int max_steps
= playlist_amount();
916 struct trackdata
*track
;
918 /* Find out how many steps to advance. The load_ahead_index field tells
919 us how many playlist entries it had to skip to get to a valid one.
920 We add those together to find out where to start. */
921 if(steps
> 0 && num_tracks_in_memory() > 1)
923 /* Begin with the song after the currently playing one */
925 while((track
= get_trackdata(i
++)))
927 start
+= track
->load_ahead_index
;
934 trackname
= playlist_peek( start
+ steps
);
938 DEBUGF("Loading %s\n", trackname
);
940 mpeg_file
= open(trackname
, O_RDONLY
);
942 DEBUGF("Couldn't open file: %s\n",trackname
);
950 struct trackdata
*track
= add_track_to_tag_list(trackname
);
964 /* skip past id3v2 tag */
966 track
->id3
.first_frame_offset
,
968 track
->id3
.index
= steps
;
969 track
->load_ahead_index
= steps
;
970 track
->id3
.offset
= 0;
973 /* Average bitrate * 1.5 */
974 recalculate_watermark(
975 (track
->id3
.bitrate
* 3) / 2);
977 recalculate_watermark(
983 /* Bail out if no file could be opened */
984 if(abs(steps
) > max_steps
)
986 } while ( mpeg_file
< 0 );
991 static void stop_playing(void)
993 struct trackdata
*track
;
995 /* Stop the current stream */
1000 track
= get_trackdata(0);
1002 prev_track_elapsed
= track
->id3
.elapsed
;
1008 generate_unbuffer_events();
1012 static void end_current_track(void) {
1013 struct trackdata
*track
;
1015 play_pending
= false;
1017 mp3_play_pause(false);
1019 track
= get_trackdata(0);
1021 prev_track_elapsed
= track
->id3
.elapsed
;
1025 generate_unbuffer_events();
1031 /* Is this a really the end of playback or is a new playlist starting */
1032 static void check_playlist_end(int direction
)
1034 /* Use the largest possible step size to account for skipped tracks */
1035 int steps
= playlist_amount();
1040 if (playlist_next(steps
) < 0)
1044 static void update_playlist(void)
1046 if (num_tracks_in_memory() > 0)
1048 struct trackdata
*track
= get_trackdata(0);
1049 track
->id3
.index
= playlist_next(track
->id3
.index
);
1053 /* End of playlist? */
1054 check_playlist_end(1);
1057 playlist_update_resume_info(audio_current_track());
1060 static void track_change(void)
1062 DEBUGF("Track change\n");
1064 struct trackdata
*track
= get_trackdata(0);
1065 prev_track_elapsed
= track
->id3
.elapsed
;
1067 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
1070 #endif /* (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) */
1072 if (num_tracks_in_memory() > 0)
1074 remove_current_tag();
1077 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1080 current_track_counter
++;
1083 unsigned long audio_prev_elapsed(void)
1085 return prev_track_elapsed
;
1089 void hexdump(const unsigned char *buf
, int len
)
1093 for(i
= 0;i
< len
;i
++)
1095 if(i
&& (i
& 15) == 0)
1099 DEBUGF("%02x ", buf
[i
]);
1105 static void start_playback_if_ready(void)
1109 playable_space
= audiobuf_swapwrite
- audiobuf_read
;
1110 if(playable_space
< 0)
1111 playable_space
+= audiobuflen
;
1113 /* See if we have started playing yet. If not, do it. */
1114 if(play_pending
|| dma_underrun
)
1116 /* If the filling has stopped, and we still haven't reached
1117 the watermark, the file must be smaller than the
1118 watermark. We must still play it. */
1119 if((playable_space
>= MPEG_PLAY_PENDING_THRESHOLD
) ||
1120 !filling
|| dma_underrun
)
1123 if (play_pending
) /* don't do this when recovering from DMA underrun */
1125 generate_postbuffer_events(); /* signal first track as buffered */
1126 if (play_pending_track_change
)
1128 play_pending_track_change
= false;
1129 send_event(PLAYBACK_EVENT_TRACK_CHANGE
, audio_current_track());
1131 play_pending
= false;
1135 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1136 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1137 dma_underrun
= false;
1141 last_dma_tick
= current_tick
;
1142 mp3_play_pause(true);
1145 /* Tell ourselves that we need more data */
1146 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1151 static bool swap_one_chunk(void)
1153 int free_space_left
;
1156 free_space_left
= get_unswapped_space();
1158 if(free_space_left
== 0 && !play_pending
)
1161 /* Swap in larger chunks when the user is waiting for the playback
1162 to start, or when there is dangerously little playable data left */
1164 amount_to_swap
= MIN(MPEG_PLAY_PENDING_SWAPSIZE
, free_space_left
);
1167 if(get_playable_space() < low_watermark
)
1168 amount_to_swap
= MIN(MPEG_LOW_WATER_SWAP_CHUNKSIZE
,
1171 amount_to_swap
= MIN(MPEG_SWAP_CHUNKSIZE
, free_space_left
);
1174 if(audiobuf_write
< audiobuf_swapwrite
)
1175 amount_to_swap
= MIN(audiobuflen
- audiobuf_swapwrite
,
1178 amount_to_swap
= MIN(audiobuf_write
- audiobuf_swapwrite
,
1181 bitswap(audiobuf
+ audiobuf_swapwrite
, amount_to_swap
);
1183 audiobuf_swapwrite
+= amount_to_swap
;
1184 if(audiobuf_swapwrite
>= audiobuflen
)
1186 audiobuf_swapwrite
= 0;
1192 static void mpeg_thread(void)
1194 static int pause_tick
= 0;
1195 static unsigned int pause_track
= 0;
1196 struct queue_event ev
;
1198 int free_space_left
;
1199 int unplayed_space_left
;
1203 #if CONFIG_CODEC == MAS3587F
1205 int save_endpos
= 0;
1209 #endif /* CONFIG_CODEC == MAS3587F */
1212 play_pending
= false;
1218 #if CONFIG_CODEC == MAS3587F
1219 if(mpeg_mode
== MPEG_DECODER
)
1221 #endif /* CONFIG_CODEC == MAS3587F */
1224 /* Swap if necessary, and don't block on the queue_wait() */
1225 if(swap_one_chunk())
1227 queue_wait_w_tmo(&mpeg_queue
, &ev
, 0);
1231 /* periodically update resume info */
1232 queue_wait_w_tmo(&mpeg_queue
, &ev
, HZ
/2);
1236 DEBUGF("S R:%x W:%x SW:%x\n",
1237 audiobuf_read
, audiobuf_write
, audiobuf_swapwrite
);
1238 queue_wait(&mpeg_queue
, &ev
);
1241 start_playback_if_ready();
1246 DEBUGF("MPEG_PLAY\n");
1249 /* Silence the A/D input, it may be on because the radio
1251 mas_codec_writereg(6, 0x0000);
1252 #endif /* CONFIG_TUNER */
1254 /* Stop the current stream */
1256 end_current_track();
1258 if ( new_file(0) == -1 )
1265 start_offset
= (int)ev
.data
;
1267 /* mid-song resume? */
1269 struct mp3entry
* id3
= &get_trackdata(0)->id3
;
1270 lseek(mpeg_file
, start_offset
, SEEK_SET
);
1271 id3
->offset
= start_offset
;
1275 /* skip past id3v2 tag */
1277 get_trackdata(0)->id3
.first_frame_offset
,
1282 /* Make it read more data */
1284 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1286 /* Tell the file loading code that we want to start playing
1287 as soon as we have some data */
1288 play_pending
= true;
1289 play_pending_track_change
= true;
1292 current_track_counter
++;
1296 DEBUGF("MPEG_STOP\n");
1301 playlist_update_resume_info(audio_current_track());
1304 mpeg_stop_done
= true;
1308 DEBUGF("MPEG_PAUSE\n");
1309 /* Stop the current stream */
1311 playlist_update_resume_info(audio_current_track());
1314 pause_tick
= current_tick
;
1315 pause_track
= current_track_counter
;
1316 mp3_play_pause(false);
1320 DEBUGF("MPEG_RESUME\n");
1321 /* Continue the current stream */
1326 if ( current_track_counter
== pause_track
)
1327 last_dma_tick
+= current_tick
- pause_tick
;
1329 last_dma_tick
= current_tick
;
1331 mp3_play_pause(true);
1336 DEBUGF("MPEG_NEXT\n");
1337 /* is next track in ram? */
1338 if ( num_tracks_in_memory() > 1 ) {
1339 int unplayed_space_left
, unswapped_space_left
;
1341 /* stop the current stream */
1342 play_pending
= false;
1344 mp3_play_pause(false);
1347 audiobuf_read
= get_trackdata(0)->mempos
;
1348 last_dma_chunk_size
= MIN(0x2000, get_unplayed_space_current_song());
1349 mp3_play_data(audiobuf
+ audiobuf_read
, last_dma_chunk_size
, transfer_end
);
1350 dma_underrun
= false;
1351 last_dma_tick
= current_tick
;
1353 unplayed_space_left
= get_unplayed_space();
1354 unswapped_space_left
= get_unswapped_space();
1356 /* should we start reading more data? */
1357 if(!filling
&& (unplayed_space_left
< low_watermark
)) {
1359 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1360 play_pending
= true;
1361 } else if(unswapped_space_left
&&
1362 unswapped_space_left
> unplayed_space_left
) {
1363 /* Stop swapping the data from the previous file */
1364 audiobuf_swapwrite
= audiobuf_read
;
1365 play_pending
= true;
1369 mp3_play_pause(true);
1373 if (!playlist_check(1))
1376 /* stop the current stream */
1377 end_current_track();
1379 if (new_file(1) < 0) {
1380 DEBUGF("No more files to play\n");
1383 check_playlist_end(1);
1384 current_track_counter
++;
1386 /* Make it read more data */
1388 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1390 /* Tell the file loading code that we want
1391 to start playing as soon as we have some data */
1392 play_pending
= true;
1393 play_pending_track_change
= true;
1396 current_track_counter
++;
1402 DEBUGF("MPEG_PREV\n");
1404 if (!playlist_check(-1))
1407 /* stop the current stream */
1408 end_current_track();
1410 /* Open the next file */
1411 if (new_file(-1) < 0) {
1412 DEBUGF("No more files to play\n");
1415 check_playlist_end(-1);
1416 current_track_counter
++;
1418 /* Make it read more data */
1420 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1422 /* Tell the file loading code that we want to
1423 start playing as soon as we have some data */
1424 play_pending
= true;
1425 play_pending_track_change
= true;
1428 current_track_counter
++;
1433 case MPEG_FF_REWIND
: {
1434 struct mp3entry
*id3
= audio_current_track();
1435 unsigned int oldtime
= id3
->elapsed
;
1436 unsigned int newtime
= (unsigned int)ev
.data
;
1437 int curpos
, newpos
, diffpos
;
1438 DEBUGF("MPEG_FF_REWIND\n");
1440 id3
->elapsed
= newtime
;
1442 newpos
= audio_get_file_pos();
1445 id3
->elapsed
= oldtime
;
1450 curpos
= lseek(mpeg_file
, 0, SEEK_CUR
);
1452 curpos
= id3
->filesize
;
1454 if (num_tracks_in_memory() > 1)
1456 /* We have started loading other tracks that need to be
1458 struct trackdata
*track
;
1461 while((track
= get_trackdata(i
++)))
1463 curpos
+= track
->id3
.filesize
;
1467 diffpos
= curpos
- newpos
;
1469 if(!filling
&& diffpos
>= 0 && diffpos
< audiobuflen
)
1471 int unplayed_space_left
, unswapped_space_left
;
1473 /* We are changing to a position that's already in
1474 memory, so we just move the DMA read pointer. */
1475 audiobuf_read
= audiobuf_write
- diffpos
;
1476 if (audiobuf_read
< 0)
1478 audiobuf_read
+= audiobuflen
;
1481 unplayed_space_left
= get_unplayed_space();
1482 unswapped_space_left
= get_unswapped_space();
1484 /* If unswapped_space_left is larger than
1485 unplayed_space_left, it means that the swapwrite pointer
1486 hasn't yet advanced up to the new location of the read
1487 pointer. We just move it, there is no need to swap
1488 data that won't be played anyway. */
1490 if (unswapped_space_left
> unplayed_space_left
)
1492 DEBUGF("Moved swapwrite\n");
1493 audiobuf_swapwrite
= audiobuf_read
;
1494 play_pending
= true;
1497 if (mpeg_file
>=0 && unplayed_space_left
< low_watermark
)
1499 /* We need to load more data before starting */
1501 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, GENERATE_UNBUFFER_EVENTS
);
1502 play_pending
= true;
1506 /* resume will start at new position */
1507 last_dma_chunk_size
=
1508 MIN(0x2000, get_unplayed_space_current_song());
1509 mp3_play_data(audiobuf
+ audiobuf_read
,
1510 last_dma_chunk_size
, transfer_end
);
1511 dma_underrun
= false;
1516 /* Move to the new position in the file and start
1520 if (num_tracks_in_memory() > 1)
1522 /* We have to reload the current track */
1524 remove_all_non_current_tags();
1525 generate_unbuffer_events();
1531 mpeg_file
= open(id3
->path
, O_RDONLY
);
1534 id3
->elapsed
= oldtime
;
1539 if(-1 == lseek(mpeg_file
, newpos
, SEEK_SET
))
1541 id3
->elapsed
= oldtime
;
1546 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1548 /* Tell the file loading code that we want to start playing
1549 as soon as we have some data */
1550 play_pending
= true;
1553 id3
->offset
= newpos
;
1558 case MPEG_FLUSH_RELOAD
: {
1559 int numtracks
= num_tracks_in_memory();
1560 bool reload_track
= false;
1564 /* Reset the buffer */
1565 audiobuf_write
= get_trackdata(1)->mempos
;
1567 /* Reset swapwrite unless we're still swapping current
1569 if (get_unplayed_space() <= get_playable_space())
1570 audiobuf_swapwrite
= audiobuf_write
;
1573 remove_all_non_current_tags();
1574 generate_unbuffer_events();
1576 reload_track
= true;
1578 else if (numtracks
== 1 && mpeg_file
< 0)
1580 reload_track
= true;
1583 if(reload_track
&& new_file(1) >= 0)
1585 /* Tell ourselves that we want more data */
1587 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1593 case MPEG_NEED_DATA
:
1594 free_space_left
= audiobuf_read
- audiobuf_write
;
1596 /* We interpret 0 as "empty buffer" */
1597 if(free_space_left
<= 0)
1598 free_space_left
+= audiobuflen
;
1600 unplayed_space_left
= audiobuflen
- free_space_left
;
1602 /* Make sure that we don't fill the entire buffer */
1603 free_space_left
-= MPEG_HIGH_WATER
;
1605 if (ev
.data
== GENERATE_UNBUFFER_EVENTS
)
1606 generate_unbuffer_events();
1608 /* do we have any more buffer space to fill? */
1609 if(free_space_left
<= 0)
1613 generate_postbuffer_events();
1618 /* Read small chunks while we are below the low water mark */
1619 if(unplayed_space_left
< low_watermark
)
1620 amount_to_read
= MIN(MPEG_LOW_WATER_CHUNKSIZE
,
1623 amount_to_read
= free_space_left
;
1625 /* Don't read more than until the end of the buffer */
1626 amount_to_read
= MIN(audiobuflen
- audiobuf_write
,
1628 #if (CONFIG_STORAGE & STORAGE_MMC)
1629 /* MMC is slow, so don't read too large chunks */
1630 amount_to_read
= MIN(0x40000, amount_to_read
);
1632 amount_to_read
= MIN(0x100000, amount_to_read
);
1635 /* Read as much mpeg data as we can fit in the buffer */
1640 len
= read(mpeg_file
, audiobuf
+ audiobuf_write
,
1645 DEBUGF("time: %d\n", t2
- t1
);
1646 DEBUGF("R: %x\n", len
);
1648 /* Now make sure that we don't feed the MAS with ID3V1
1650 if (len
< amount_to_read
)
1653 static const unsigned char tag
[] = "TAG";
1655 int tagptr
= audiobuf_write
+ len
- 128;
1657 /* Really rare case: entire potential tag wasn't
1658 read in this call AND audiobuf_write < 128 */
1660 tagptr
+= audiobuflen
;
1662 for(i
= 0;i
< 3;i
++)
1664 if(tagptr
>= audiobuflen
)
1665 tagptr
-= audiobuflen
;
1667 if(audiobuf
[tagptr
] != tag
[i
])
1678 /* Skip id3v1 tag */
1679 DEBUGF("Skipping ID3v1 tag\n");
1682 /* In the very rare case when the entire tag
1683 wasn't read in this read() len will be < 0.
1684 Take care of this when changing the write
1689 audiobuf_write
+= len
;
1691 if (audiobuf_write
< 0)
1692 audiobuf_write
+= audiobuflen
;
1694 if(audiobuf_write
>= audiobuflen
)
1700 /* Tell ourselves that we want more data */
1701 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1707 DEBUGF("MPEG read error\n");
1715 /* No more data to play */
1716 DEBUGF("No more files to play\n");
1721 /* Tell ourselves that we want more data */
1722 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
1728 case MPEG_TRACK_CHANGE
:
1733 case SYS_USB_CONNECTED
:
1738 /* Tell the USB thread that we are safe */
1739 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1740 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
1742 /* Wait until the USB cable is extracted again */
1743 usb_wait_for_disconnect(&mpeg_queue
);
1745 #endif /* !USB_NONE */
1747 #if CONFIG_CODEC == MAS3587F
1748 case MPEG_INIT_RECORDING
:
1750 init_recording_done
= true;
1752 #endif /* CONFIG_CODEC == MAS3587F */
1756 playlist_update_resume_info(audio_current_track());
1759 #if CONFIG_CODEC == MAS3587F
1763 queue_wait(&mpeg_queue
, &ev
);
1767 if (is_prerecording
)
1771 /* Go back prerecord_count seconds in the buffer */
1772 startpos
= prerecord_index
- prerecord_count
;
1774 startpos
+= prerecording_max_seconds
;
1776 /* Read the position data from the prerecord buffer */
1777 frame_count_start
= prerecord_buffer
[startpos
].framecount
;
1778 startpos
= prerecord_buffer
[startpos
].mempos
;
1780 DEBUGF("Start looking at address %x (%x)\n",
1781 audiobuf
+startpos
, startpos
);
1783 saved_header
= mpeg_get_last_header();
1785 mem_find_next_frame(startpos
, &offset
, 1800,
1788 audiobuf_read
= startpos
+ offset
;
1789 if(audiobuf_read
>= audiobuflen
)
1790 audiobuf_read
-= audiobuflen
;
1792 DEBUGF("New audiobuf_read address: %x (%x)\n",
1793 audiobuf
+audiobuf_read
, audiobuf_read
);
1795 level
= disable_irq_save();
1796 num_rec_bytes
= get_unsaved_space();
1801 frame_count_start
= 0;
1803 audiobuf_read
= MPEG_RESERVED_HEADER_SPACE
;
1804 audiobuf_write
= MPEG_RESERVED_HEADER_SPACE
;
1808 DEBUGF("Recording...\n");
1811 /* Wait until at least one frame is encoded and get the
1812 frame header, for later use by the Xing header
1815 saved_header
= mpeg_get_last_header();
1817 /* delayed until buffer is saved, don't open yet */
1818 strcpy(delayed_filename
, recording_filename
);
1824 DEBUGF("MPEG_STOP\n");
1828 /* Save the remaining data in the buffer */
1829 save_endpos
= audiobuf_write
;
1830 saving_status
= STOP_RECORDING
;
1831 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1834 case MPEG_STOP_DONE
:
1835 DEBUGF("MPEG_STOP_DONE\n");
1845 for(i
= 0;i
< 512;i
++)
1847 DEBUGF("%d - %d us (%d bytes)\n",
1849 (timing_info
[i
*2+1] & 0xffff) *
1851 timing_info
[i
*2+1] >> 16);
1858 start_prerecording();
1860 mpeg_stop_done
= true;
1864 /* Bail out when a more important save is happening */
1865 if (saving_status
> NEW_FILE
)
1868 /* Make sure we have at least one complete frame
1869 in the buffer. If we haven't recorded a single
1870 frame within 200ms, the MAS is probably not recording
1871 anything, and we bail out. */
1872 amount_to_save
= get_unsaved_space();
1873 if (amount_to_save
< 1800)
1876 amount_to_save
= get_unsaved_space();
1879 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
1880 &frame_count_end
, 1);
1882 last_rec_time
= current_tick
- record_start_time
;
1883 record_start_time
= current_tick
;
1885 pause_start_time
= record_start_time
;
1887 /* capture all values at one point */
1888 level
= disable_irq_save();
1889 save_endpos
= audiobuf_write
;
1890 last_rec_bytes
= num_rec_bytes
;
1894 if (amount_to_save
>= 1800)
1896 /* Now find a frame boundary to split at */
1897 save_endpos
-= 1800;
1898 if (save_endpos
< 0)
1899 save_endpos
+= audiobuflen
;
1901 rc
= mem_find_next_frame(save_endpos
, &offset
, 1800,
1903 if (!rc
) /* No header found, save whole buffer */
1906 save_endpos
+= offset
;
1907 if (save_endpos
>= audiobuflen
)
1908 save_endpos
-= audiobuflen
;
1910 last_rec_bytes
+= offset
- 1800;
1911 level
= disable_irq_save();
1912 num_rec_bytes
+= 1800 - offset
;
1916 saving_status
= NEW_FILE
;
1917 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
1920 case MPEG_SAVE_DATA
:
1921 if (saving_status
== BUFFER_FULL
)
1922 save_endpos
= audiobuf_write
;
1924 if (mpeg_file
< 0) /* delayed file open */
1926 mpeg_file
= open(delayed_filename
, O_WRONLY
|O_CREAT
, 0666);
1929 panicf("recfile: %d", mpeg_file
);
1932 amount_to_save
= save_endpos
- audiobuf_read
;
1933 if (amount_to_save
< 0)
1934 amount_to_save
+= audiobuflen
;
1936 amount_to_save
= MIN(amount_to_save
,
1937 audiobuflen
- audiobuf_read
);
1938 #if (CONFIG_STORAGE & STORAGE_MMC)
1939 /* MMC is slow, so don't save too large chunks at once */
1940 amount_to_save
= MIN(0x40000, amount_to_save
);
1942 amount_to_save
= MIN(0x100000, amount_to_save
);
1944 rc
= write(mpeg_file
, audiobuf
+ audiobuf_read
,
1948 if (errno
== ENOSPC
)
1950 mpeg_errno
= AUDIOERR_DISK_FULL
;
1952 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1953 /* will close the file */
1957 panicf("rec wrt: %d", rc
);
1960 audiobuf_read
+= amount_to_save
;
1961 if (audiobuf_read
>= audiobuflen
)
1964 if (audiobuf_read
== save_endpos
) /* all saved */
1966 switch (saving_status
)
1969 rc
= fsync(mpeg_file
);
1971 panicf("rec fls: %d", rc
);
1976 /* Close the current file */
1977 rc
= close(mpeg_file
);
1979 panicf("rec cls: %d", rc
);
1984 /* copy new filename */
1985 strcpy(delayed_filename
, recording_filename
);
1987 frame_count_start
= frame_count_end
;
1990 case STOP_RECORDING
:
1991 queue_post(&mpeg_queue
, MPEG_STOP_DONE
, 0);
1992 /* will close the file */
1998 saving_status
= NOT_SAVING
;
2000 else /* tell ourselves to save the next chunk */
2001 queue_post(&mpeg_queue
, MPEG_SAVE_DATA
, 0);
2005 case MPEG_PRERECORDING_TICK
:
2006 if(!is_prerecording
)
2009 /* Store the write pointer every second */
2010 prerecord_buffer
[prerecord_index
].mempos
= audiobuf_write
;
2011 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
,
2012 &prerecord_buffer
[prerecord_index
].framecount
, 1);
2014 /* Wrap if necessary */
2015 if(++prerecord_index
== prerecording_max_seconds
)
2016 prerecord_index
= 0;
2018 /* Update the number of seconds recorded */
2019 if(prerecord_count
< prerecording_max_seconds
)
2023 case MPEG_INIT_PLAYBACK
:
2024 /* Stop the prerecording */
2028 init_playback_done
= true;
2031 case MPEG_PAUSE_RECORDING
:
2035 case MPEG_RESUME_RECORDING
:
2039 case SYS_USB_CONNECTED
:
2040 /* We can safely go to USB mode if no recording
2042 if((!is_recording
|| is_prerecording
) && mpeg_stop_done
)
2044 /* Even if we aren't recording, we still call this
2045 function, to put the MAS in monitoring mode,
2049 /* Tell the USB thread that we are safe */
2050 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
2051 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
2053 /* Wait until the USB cable is extracted again */
2054 usb_wait_for_disconnect(&mpeg_queue
);
2059 #endif /* CONFIG_CODEC == MAS3587F */
2062 #endif /* !SIMULATOR */
2064 struct mp3entry
* audio_current_track(void)
2067 struct mp3entry
*id3
= &taginfo
;
2068 #else /* !SIMULATOR */
2069 if(num_tracks_in_memory())
2071 struct mp3entry
*id3
= &get_trackdata(0)->id3
;
2073 if (!checked_for_cuesheet
&& curr_cuesheet
&& id3
->cuesheet
== NULL
)
2075 checked_for_cuesheet
= true; /* only check once per track */
2076 char cuepath
[MAX_PATH
];
2078 if (look_for_cuesheet_file(id3
->path
, cuepath
) &&
2079 parse_cuesheet(cuepath
, curr_cuesheet
))
2081 id3
->cuesheet
= curr_cuesheet
;
2082 cue_spoof_id3(curr_cuesheet
, id3
);
2090 #endif /* !SIMULATOR */
2093 struct mp3entry
* audio_next_track(void)
2097 #else /* !SIMULATOR */
2098 if(num_tracks_in_memory() > 1)
2099 return &get_trackdata(1)->id3
;
2102 #endif /* !SIMULATOR */
2105 #if CONFIG_CODEC == MAS3587F
2107 void audio_init_playback(void)
2109 init_playback_done
= false;
2110 queue_post(&mpeg_queue
, MPEG_INIT_PLAYBACK
, 0);
2112 while(!init_playback_done
)
2117 /****************************************************************************
2118 * Recording functions
2119 ***************************************************************************/
2120 void audio_init_recording(unsigned int buffer_offset
)
2122 buffer_offset
= buffer_offset
;
2123 init_recording_done
= false;
2124 queue_post(&mpeg_queue
, MPEG_INIT_RECORDING
, 0);
2126 while(!init_recording_done
)
2130 static void init_recording(void)
2142 /* Init the recording variables */
2143 is_recording
= false;
2144 is_prerecording
= false;
2146 mpeg_stop_done
= true;
2150 /* Enable the audio CODEC and the DSP core, max analog voltage range */
2151 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
2153 panicf("mas_ctrl_w: %d", rc
);
2155 /* Stop the current application */
2157 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2160 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2163 /* Perform black magic as described by the data sheet */
2164 if((mas_version_code
& 0x0fff) == 0x0102)
2166 DEBUGF("Performing MAS black magic for B2 version\n");
2167 mas_writereg(0xa3, 0x98);
2168 mas_writereg(0x94, 0xfffff);
2170 mas_writemem(MAS_BANK_D1
, 0, &val
, 1);
2171 mas_writereg(0xa3, 0x90);
2174 /* Enable A/D Converters */
2175 shadow_codec_reg0
= 0xcccd;
2176 mas_codec_writereg(0x0, shadow_codec_reg0
);
2178 /* Copy left channel to right (mono mode) */
2179 mas_codec_writereg(8, 0x8000);
2181 /* ADC scale 0%, DSP scale 100%
2182 We use the DSP output for monitoring, because it works with all
2183 sources including S/PDIF */
2184 mas_codec_writereg(6, 0x0000);
2185 mas_codec_writereg(7, 0x4000);
2188 shadow_soft_mute
= 0;
2189 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2191 #ifdef HAVE_SPDIF_OUT
2192 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
2194 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
2196 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
2198 /* Set Demand mode, monitoring OFF and validate all settings */
2199 shadow_io_control_main
= 0x125;
2200 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2202 /* Start the encoder application */
2204 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
2207 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
2208 } while(!(val
& 0x40));
2210 /* We have started the recording application with monitoring OFF.
2211 This is because we want to record at least one frame to fill the DMA
2212 buffer, because the silly MAS will not negate EOD until at least one
2213 DMA transfer has taken place.
2214 Now let's wait for some data to be encoded. */
2217 /* Now set it to Monitoring mode as default, saves power */
2218 shadow_io_control_main
= 0x525;
2219 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2221 /* Wait until the DSP has accepted the settings */
2224 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2228 mpeg_mode
= MPEG_ENCODER
;
2230 DEBUGF("MAS Recording application started\n");
2232 /* At this point, all settings are the reset MAS defaults, next thing is to
2233 call mpeg_set_recording_options(). */
2236 void audio_record(const char *filename
)
2240 strlcpy(recording_filename
, filename
, MAX_PATH
);
2242 queue_post(&mpeg_queue
, MPEG_RECORD
, 0);
2245 void audio_pause_recording(void)
2247 queue_post(&mpeg_queue
, MPEG_PAUSE_RECORDING
, 0);
2250 void audio_resume_recording(void)
2252 queue_post(&mpeg_queue
, MPEG_RESUME_RECORDING
, 0);
2255 static void prepend_header(void)
2260 /* Make room for header */
2261 audiobuf_read
-= MPEG_RESERVED_HEADER_SPACE
;
2262 if(audiobuf_read
< 0)
2264 /* Clear the bottom half */
2265 memset(audiobuf
, 0, audiobuf_read
+ MPEG_RESERVED_HEADER_SPACE
);
2267 /* And the top half */
2268 audiobuf_read
+= audiobuflen
;
2269 memset(audiobuf
+ audiobuf_read
, 0, audiobuflen
- audiobuf_read
);
2273 memset(audiobuf
+ audiobuf_read
, 0, MPEG_RESERVED_HEADER_SPACE
);
2275 /* Copy the empty ID3 header */
2276 startpos
= audiobuf_read
;
2277 for(i
= 0; i
< sizeof(empty_id3_header
); i
++)
2279 audiobuf
[startpos
++] = empty_id3_header
[i
];
2280 if(startpos
== audiobuflen
)
2285 static void update_header(void)
2288 unsigned long frames
;
2290 if (last_rec_bytes
> 0)
2292 /* Create the Xing header */
2293 fd
= open(delayed_filename
, O_RDWR
);
2295 panicf("rec upd: %d (%s)", fd
, recording_filename
);
2297 frames
= frame_count_end
- frame_count_start
;
2298 /* If the number of recorded frames has reached 0x7ffff,
2299 we can no longer trust it */
2300 if (frame_count_end
== 0x7ffff)
2303 /* saved_header is saved right before stopping the MAS */
2304 framelen
= create_xing_header(fd
, 0, last_rec_bytes
, xing_buffer
,
2305 frames
, last_rec_time
* (1000/HZ
),
2306 saved_header
, NULL
, false);
2308 lseek(fd
, MPEG_RESERVED_HEADER_SPACE
- framelen
, SEEK_SET
);
2309 write(fd
, xing_buffer
, framelen
);
2314 static void start_prerecording(void)
2318 DEBUGF("Starting prerecording\n");
2320 prerecord_index
= 0;
2321 prerecord_count
= 0;
2322 prerecord_timeout
= current_tick
+ HZ
;
2323 memset(prerecord_buffer
, 0, sizeof(prerecord_buffer
));
2326 is_prerecording
= true;
2328 /* Stop monitoring and start the encoder */
2329 shadow_io_control_main
&= ~(1 << 10);
2330 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2331 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2333 /* Wait until the DSP has accepted the settings */
2336 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2339 is_recording
= true;
2340 saving_status
= NOT_SAVING
;
2342 demand_irq_enable(true);
2345 static void start_recording(void)
2351 /* This will make the IRQ handler start recording
2352 for real, i.e send MPEG_SAVE_DATA messages when
2353 the buffer is full */
2354 is_prerecording
= false;
2358 /* If prerecording is off, we need to stop the monitoring
2359 and start the encoder */
2360 shadow_io_control_main
&= ~(1 << 10);
2361 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2362 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2364 /* Wait until the DSP has accepted the settings */
2367 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2371 is_recording
= true;
2372 saving_status
= NOT_SAVING
;
2375 /* Store the current time */
2377 record_start_time
= current_tick
- prerecord_count
* HZ
;
2379 record_start_time
= current_tick
;
2381 pause_start_time
= 0;
2383 demand_irq_enable(true);
2386 static void pause_recording(void)
2388 pause_start_time
= current_tick
;
2390 /* Set the pause bit */
2391 shadow_soft_mute
|= 2;
2392 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2397 static void resume_recording(void)
2401 /* Clear the pause bit */
2402 shadow_soft_mute
&= ~2;
2403 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
, 1);
2405 /* Compensate for the time we have been paused */
2406 if(pause_start_time
)
2409 current_tick
- (pause_start_time
- record_start_time
);
2410 pause_start_time
= 0;
2414 static void stop_recording(void)
2418 /* Let it finish the last frame */
2423 demand_irq_enable(false);
2425 is_recording
= false;
2426 is_prerecording
= false;
2428 last_rec_bytes
= num_rec_bytes
;
2429 mas_readmem(MAS_BANK_D0
, MAS_D0_MPEG_FRAME_COUNT
, &frame_count_end
, 1);
2430 last_rec_time
= current_tick
- record_start_time
;
2432 /* Start monitoring */
2433 shadow_io_control_main
|= (1 << 10);
2434 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
2435 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2437 /* Wait until the DSP has accepted the settings */
2440 mas_readmem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &val
,1);
2446 void audio_set_recording_options(struct audio_recording_options
*options
)
2450 is_mpeg1
= (options
->rec_frequency
< 3);
2452 rec_version_index
= is_mpeg1
?3:2;
2453 rec_frequency_index
= options
->rec_frequency
% 3;
2455 shadow_encoder_control
= (options
->rec_quality
<< 17) |
2456 (rec_frequency_index
<< 10) |
2457 ((is_mpeg1
?1:0) << 9) |
2458 (((options
->rec_channels
* 2 + 1) & 3) << 6) |
2459 (1 << 5) /* MS-stereo */ |
2460 (1 << 2) /* Is an original */;
2461 mas_writemem(MAS_BANK_D0
, MAS_D0_ENCODER_CONTROL
, &shadow_encoder_control
,1);
2463 DEBUGF("mas_writemem(MAS_BANK_D0, ENCODER_CONTROL, %x)\n", shadow_encoder_control
);
2465 #if CONFIG_TUNER & S1A0903X01
2466 /* Store the (unpitched) MAS PLL frequency. Used for avoiding FM
2467 interference with the Samsung tuner. */
2468 if (rec_frequency_index
)
2469 mas_store_pllfreq(24576000);
2471 mas_store_pllfreq(22579000);
2474 shadow_soft_mute
= options
->rec_editable
?4:0;
2475 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &shadow_soft_mute
,1);
2477 DEBUGF("mas_writemem(MAS_BANK_D0, SOFT_MUTE, %x)\n", shadow_soft_mute
);
2479 shadow_io_control_main
= ((1 << 10) | /* Monitoring ON */
2480 ((options
->rec_source
< 2)?1:2) << 8) | /* Input select */
2481 (1 << 5) | /* SDO strobe invert */
2482 ((is_mpeg1
?0:1) << 3) |
2483 (1 << 2) | /* Inverted SIBC clock signal */
2485 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
,1);
2487 DEBUGF("mas_writemem(MAS_BANK_D0, IO_CONTROL_MAIN, %x)\n", shadow_io_control_main
);
2489 if(options
->rec_source
== AUDIO_SRC_MIC
)
2491 /* Copy left channel to right (mono mode) */
2492 mas_codec_writereg(8, 0x8000);
2496 /* Stereo input mode */
2497 mas_codec_writereg(8, 0);
2500 prerecording_max_seconds
= options
->rec_prerecord_time
;
2501 if(prerecording_max_seconds
)
2503 prerecording
= true;
2504 start_prerecording();
2508 prerecording
= false;
2509 is_prerecording
= false;
2510 is_recording
= false;
2514 /* If use_mic is true, the left gain is used */
2515 void audio_set_recording_gain(int left
, int right
, int type
)
2517 /* Enable both left and right A/D */
2518 shadow_codec_reg0
= (left
<< 12) |
2521 (type
==AUDIO_GAIN_MIC
?0x0008:0) | /* Connect left A/D to mic */
2523 mas_codec_writereg(0x0, shadow_codec_reg0
);
2526 /* try to make some kind of beep, also in recording mode */
2527 void audio_beep(int duration
)
2529 long starttick
= current_tick
;
2531 { /* toggle bit 0 of codec register 0, toggling the DAC off & on.
2532 * While this is still audible even without an external signal,
2533 * it doesn't affect the (pre-)recording. */
2534 mas_codec_writereg(0, shadow_codec_reg0
^ 1);
2535 mas_codec_writereg(0, shadow_codec_reg0
);
2538 while (current_tick
- starttick
< duration
);
2541 void audio_new_file(const char *filename
)
2545 strlcpy(recording_filename
, filename
, MAX_PATH
);
2547 queue_post(&mpeg_queue
, MPEG_NEW_FILE
, 0);
2550 unsigned long audio_recorded_time(void)
2553 return prerecord_count
* HZ
;
2558 return pause_start_time
- record_start_time
;
2560 return current_tick
- record_start_time
;
2566 unsigned long audio_num_recorded_bytes(void)
2575 index
= prerecord_index
- prerecord_count
;
2577 index
+= prerecording_max_seconds
;
2579 num_bytes
= audiobuf_write
- prerecord_buffer
[index
].mempos
;
2581 num_bytes
+= audiobuflen
;
2586 return num_rec_bytes
;
2592 #else /* SIMULATOR */
2594 /* dummies coming up */
2596 void audio_init_playback(void)
2600 unsigned long audio_recorded_time(void)
2605 void audio_beep(int duration
)
2610 void audio_pause_recording(void)
2614 void audio_resume_recording(void)
2618 unsigned long audio_num_recorded_bytes(void)
2623 void audio_record(const char *filename
)
2628 void audio_new_file(const char *filename
)
2634 void audio_set_recording_gain(int left
, int right
, int type
)
2641 void audio_init_recording(unsigned int buffer_offset
)
2644 (void)buffer_offset
;
2646 void audio_set_recording_options(struct audio_recording_options
*options
)
2651 #endif /* SIMULATOR */
2652 #endif /* CONFIG_CODEC == MAS3587F */
2654 void audio_play(long offset
)
2663 trackname
= playlist_peek( steps
);
2666 if(mp3info(&taginfo
, trackname
)) {
2667 /* bad mp3, move on */
2668 if(++steps
> playlist_amount())
2672 #ifdef HAVE_MPEG_PLAY
2673 real_mpeg_play(trackname
);
2675 playlist_next(steps
);
2676 taginfo
.offset
= offset
;
2677 set_elapsed(&taginfo
);
2682 #else /* !SIMULATOR */
2685 queue_post(&mpeg_queue
, MPEG_PLAY
, offset
);
2686 #endif /* !SIMULATOR */
2691 void audio_stop(void)
2696 struct trackdata
*track
= get_trackdata(0);
2697 prev_track_elapsed
= track
->id3
.elapsed
;
2699 mpeg_stop_done
= false;
2700 queue_post(&mpeg_queue
, MPEG_STOP
, 0);
2701 while(!mpeg_stop_done
)
2703 #else /* SIMULATOR */
2707 #endif /* SIMULATOR */
2711 void audio_stop_recording(void)
2716 void audio_pause(void)
2719 queue_post(&mpeg_queue
, MPEG_PAUSE
, 0);
2720 #else /* SIMULATOR */
2724 #endif /* SIMULATOR */
2727 void audio_resume(void)
2730 queue_post(&mpeg_queue
, MPEG_RESUME
, 0);
2731 #else /* SIMULATOR */
2735 #endif /* SIMULATOR */
2738 void audio_next(void)
2741 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2742 queue_post(&mpeg_queue
, MPEG_NEXT
, 0);
2743 #else /* SIMULATOR */
2749 file
= playlist_peek(steps
);
2752 if(mp3info(&taginfo
, file
)) {
2753 if(++steps
> playlist_amount())
2757 index
= playlist_next(steps
);
2758 taginfo
.index
= index
;
2759 current_track_counter
++;
2764 #endif /* SIMULATOR */
2767 void audio_prev(void)
2770 queue_remove_from_head(&mpeg_queue
, MPEG_NEED_DATA
);
2771 queue_post(&mpeg_queue
, MPEG_PREV
, 0);
2772 #else /* SIMULATOR */
2778 file
= playlist_peek(steps
);
2781 if(mp3info(&taginfo
, file
)) {
2785 index
= playlist_next(steps
);
2786 taginfo
.index
= index
;
2787 current_track_counter
++;
2792 #endif /* SIMULATOR */
2795 void audio_ff_rewind(long newpos
)
2798 queue_post(&mpeg_queue
, MPEG_FF_REWIND
, newpos
);
2799 #else /* SIMULATOR */
2801 #endif /* SIMULATOR */
2804 void audio_flush_and_reload_tracks(void)
2807 queue_post(&mpeg_queue
, MPEG_FLUSH_RELOAD
, 0);
2808 #endif /* !SIMULATOR*/
2811 int audio_status(void)
2816 ret
|= AUDIO_STATUS_PLAY
;
2819 ret
|= AUDIO_STATUS_PAUSE
;
2821 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2822 if(is_recording
&& !is_prerecording
)
2823 ret
|= AUDIO_STATUS_RECORD
;
2826 ret
|= AUDIO_STATUS_PRERECORD
;
2827 #endif /* CONFIG_CODEC == MAS3587F */
2830 ret
|= AUDIO_STATUS_ERROR
;
2836 unsigned int audio_error(void)
2842 void audio_error_clear(void)
2848 static void mpeg_thread(void)
2850 struct mp3entry
* id3
;
2853 id3
= audio_current_track();
2859 if (id3
->elapsed
>=id3
->length
)
2865 #endif /* SIMULATOR */
2867 void audio_init(void)
2870 /* cuesheet support */
2871 if (global_settings
.cuesheet
)
2872 curr_cuesheet
= (struct cuesheet
*)buffer_alloc(sizeof(struct cuesheet
));
2875 audiobuflen
= audiobufend
- audiobuf
;
2876 queue_init(&mpeg_queue
, true);
2877 #endif /* !SIMULATOR */
2878 create_thread(mpeg_thread
, mpeg_stack
,
2879 sizeof(mpeg_stack
), 0, mpeg_thread_name
2880 IF_PRIO(, PRIORITY_SYSTEM
)
2883 memset(trackdata
, 0, sizeof(trackdata
));
2885 #if (CONFIG_CODEC == MAS3587F) && !defined(SIMULATOR)
2886 if (HW_MASK
& PR_ACTIVE_HIGH
)
2887 and_b(~0x08, &PADRH
);
2890 #endif /* CONFIG_CODEC == MAS3587F */
2896 #endif /* !SIMULATOR */
2900 #endif /* CONFIG_CODEC != SWCODEC */