summaryrefslogtreecommitdiff
path: root/firmware/mpeg.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/mpeg.c')
-rw-r--r--firmware/mpeg.c282
1 files changed, 136 insertions, 146 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index b1d1facc73..0406376e00 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -47,21 +47,23 @@
47#include "hwcompat.h" 47#include "hwcompat.h"
48#endif /* !SIMULATOR */ 48#endif /* !SIMULATOR */
49 49
50#ifndef SIMULATOR
51extern unsigned long mas_version_code;
52#endif
53
50#if CONFIG_HWCODEC == MAS3587F 54#if CONFIG_HWCODEC == MAS3587F
51static void init_recording(void); 55extern enum /* from mp3_playback.c */
52static void start_prerecording(void); 56{
53static void start_recording(void); 57 MPEG_DECODER,
54static void stop_recording(void); 58 MPEG_ENCODER
55static int get_unsaved_space(void); 59} mpeg_mode;
56static void pause_recording(void);
57static void resume_recording(void);
58#endif /* CONFIG_HWCODEC == MAS3587F */ 60#endif /* CONFIG_HWCODEC == MAS3587F */
59 61
60#ifndef SIMULATOR 62extern char* playlist_peek(int steps);
61static int get_unplayed_space(void); 63extern bool playlist_check(int steps);
62static int get_playable_space(void); 64extern int playlist_next(int steps);
63static int get_unswapped_space(void); 65extern int playlist_amount(void);
64#endif /* !SIMULATOR */ 66extern int playlist_update_resume_info(const struct mp3entry* id3);
65 67
66#define MPEG_PLAY 1 68#define MPEG_PLAY 1
67#define MPEG_STOP 2 69#define MPEG_STOP 2
@@ -82,20 +84,6 @@ static int get_unswapped_space(void);
82#define MPEG_SAVE_DATA 102 84#define MPEG_SAVE_DATA 102
83#define MPEG_STOP_DONE 103 85#define MPEG_STOP_DONE 103
84 86
85#if CONFIG_HWCODEC == MAS3587F
86extern enum /* from mp3_playback.c */
87{
88 MPEG_DECODER,
89 MPEG_ENCODER
90} mpeg_mode;
91#endif /* CONFIG_HWCODEC == MAS3587F */
92
93extern char* playlist_peek(int steps);
94extern bool playlist_check(int steps);
95extern int playlist_next(int steps);
96extern int playlist_amount(void);
97extern int playlist_update_resume_info(const struct mp3entry* id3);
98
99/* list of tracks in memory */ 87/* list of tracks in memory */
100#define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */ 88#define MAX_TRACK_ENTRIES (1<<4) /* Must be power of 2 */
101#define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1) 89#define MAX_TRACK_ENTRIES_MASK (MAX_TRACK_ENTRIES - 1)
@@ -109,26 +97,131 @@ struct trackdata
109 97
110static struct trackdata trackdata[MAX_TRACK_ENTRIES]; 98static struct trackdata trackdata[MAX_TRACK_ENTRIES];
111 99
112static bool v1first = false;
113
114static unsigned int current_track_counter = 0; 100static unsigned int current_track_counter = 0;
115static unsigned int last_track_counter = 0; 101static unsigned int last_track_counter = 0;
116 102
117#ifndef SIMULATOR 103#ifndef SIMULATOR
118
119static int track_read_idx = 0; 104static int track_read_idx = 0;
120static int track_write_idx = 0; 105static int track_write_idx = 0;
106#endif /* !SIMULATOR */
107
108static const char mpeg_thread_name[] = "mpeg";
109static unsigned int mpeg_errno;
110
111static bool v1first = false;
112
113static bool playing = false; /* We are playing an MP3 stream */
114static bool is_playing = false; /* We are (attempting to) playing MP3 files */
115static bool paused; /* playback is paused */
121 116
117#ifdef SIMULATOR
118static char mpeg_stack[DEFAULT_STACK_SIZE];
119static struct mp3entry taginfo;
120
121#else /* !SIMULATOR */
122static struct event_queue mpeg_queue;
123static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
124
125static int audiobuflen;
126static int audiobuf_write;
127static int audiobuf_swapwrite;
128static int audiobuf_read;
129
130static int mpeg_file;
131
132static bool play_pending; /* We are about to start playing */
133static bool filling; /* We are filling the buffer with data from disk */
134static bool dma_underrun; /* True when the DMA has stopped because of
135 slow disk reading (read error, shaking) */
136static bool mpeg_stop_done;
137
138static int last_dma_tick = 0;
139static int last_dma_chunk_size;
140
141static long low_watermark; /* Dynamic low watermark level */
142static long low_watermark_margin; /* Extra time in seconds for watermark */
143static long lowest_watermark_level; /* Debug value to observe the buffer
144 usage */
145#if CONFIG_HWCODEC == MAS3587F
146static char recording_filename[MAX_PATH]; /* argument to thread */
147static char delayed_filename[MAX_PATH]; /* internal copy of above */
148
149static bool init_recording_done;
150static bool init_playback_done;
151static bool prerecording; /* True if prerecording is enabled */
152static bool is_prerecording; /* True if we are prerecording */
153static bool is_recording; /* We are recording */
154static bool disable_xing_header; /* When splitting files */
155
156static enum {
157 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
158 BUFFER_FULL,
159 NEW_FILE,
160 STOP_RECORDING
161} saving_status;
162
163static int rec_frequency_index; /* For create_xing_header() calls */
164static int rec_version_index; /* For create_xing_header() calls */
165
166static int prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS];
167 /* Array of buffer indexes for each prerecorded second */
168static int prerecord_index; /* Current index in the prerecord buffer */
169static int prerecording_max_seconds; /* Max number of seconds to store */
170static int prerecord_count; /* Number of seconds in the prerecord buffer */
171static int prerecord_timeout; /* The tick count of the next prerecord data
172 store */
173
174unsigned long record_start_time; /* Value of current_tick when recording
175 was started */
176unsigned long pause_start_time; /* Value of current_tick when pause was
177 started */
178static unsigned long num_rec_bytes;
179static unsigned long num_recorded_frames;
180
181/* Shadow MAS registers */
182unsigned long shadow_encoder_control = 0;
183#endif /* CONFIG_HWCODEC == MAS3587F */
184
185#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
186unsigned long shadow_io_control_main = 0;
187unsigned long shadow_soft_mute = 0;
188unsigned shadow_codec_reg0;
189#endif /* (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
190
191#ifdef HAVE_RECORDING
192const unsigned char empty_id3_header[] =
193{
194 'I', 'D', '3', 0x03, 0x00, 0x00,
195 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
196};
197#endif /* HAVE_RECORDING */
198
199
200static int get_unplayed_space(void);
201static int get_playable_space(void);
202static int get_unswapped_space(void);
203#endif /* !SIMULATOR */
204
205#if CONFIG_HWCODEC == MAS3587F
206static void init_recording(void);
207static void start_prerecording(void);
208static void start_recording(void);
209static void stop_recording(void);
210static int get_unsaved_space(void);
211static void pause_recording(void);
212static void resume_recording(void);
213#endif /* CONFIG_HWCODEC == MAS3587F */
214
215
216#ifndef SIMULATOR
122static int num_tracks_in_memory(void) 217static int num_tracks_in_memory(void)
123{ 218{
124 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK; 219 return (track_write_idx - track_read_idx) & MAX_TRACK_ENTRIES_MASK;
125} 220}
126#endif /* !SIMULATOR */
127 221
128#ifndef SIMULATOR 222#ifdef DEBUG_TAGS
129static void debug_tags(void) 223static void debug_tags(void)
130{ 224{
131#ifdef DEBUG_TAGS
132 int i; 225 int i;
133 226
134 for(i = 0;i < MAX_TRACK_ENTRIES;i++) 227 for(i = 0;i < MAX_TRACK_ENTRIES;i++)
@@ -137,8 +230,10 @@ static void debug_tags(void)
137 } 230 }
138 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx); 231 DEBUGF("read: %d, write :%d\n", track_read_idx, track_write_idx);
139 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory()); 232 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
140#endif /* DEBUG_TAGS */
141} 233}
234#else /* !DEBUG_TAGS */
235#define debug_tags()
236#endif /* !DEBUG_TAGS */
142 237
143static void remove_current_tag(void) 238static void remove_current_tag(void)
144{ 239{
@@ -305,88 +400,8 @@ unsigned long mpeg_get_last_header(void)
305#endif /* !SIMULATOR */ 400#endif /* !SIMULATOR */
306} 401}
307 402
308static bool paused; /* playback is paused */
309
310static unsigned int mpeg_errno;
311
312#ifdef SIMULATOR
313static bool is_playing = false;
314static bool playing = false;
315#else /* !SIMULATOR */
316static int last_dma_tick = 0;
317
318extern unsigned long mas_version_code;
319
320static struct event_queue mpeg_queue;
321static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
322static const char mpeg_thread_name[] = "mpeg";
323
324static int audiobuflen;
325static int audiobuf_write;
326static int audiobuf_swapwrite;
327static int audiobuf_read;
328
329static int last_dma_chunk_size;
330
331static bool playing; /* We are playing an MP3 stream */
332static bool play_pending; /* We are about to start playing */
333static bool is_playing; /* We are (attempting to) playing MP3 files */
334static bool filling; /* We are filling the buffer with data from disk */
335static bool dma_underrun; /* True when the DMA has stopped because of
336 slow disk reading (read error, shaking) */
337static long low_watermark; /* Dynamic low watermark level */
338static long low_watermark_margin; /* Extra time in seconds for watermark */
339static long lowest_watermark_level; /* Debug value to observe the buffer
340 usage */
341#if CONFIG_HWCODEC == MAS3587F
342static bool is_recording; /* We are recording */
343unsigned long record_start_time; /* Value of current_tick when recording
344 was started */
345unsigned long pause_start_time; /* Value of current_tick when pause was
346 started */
347static enum {
348 NOT_SAVING = 0, /* reasons to save data, sorted by importance */
349 BUFFER_FULL,
350 NEW_FILE,
351 STOP_RECORDING
352} saving_status;
353
354static char recording_filename[MAX_PATH]; /* argument to thread */
355static char delayed_filename[MAX_PATH]; /* internal copy of above */
356static int rec_frequency_index; /* For create_xing_header() calls */
357static int rec_version_index; /* For create_xing_header() calls */
358static bool disable_xing_header; /* When splitting files */
359
360static bool prerecording; /* True if prerecording is enabled */
361static bool is_prerecording; /* True if we are prerecording */
362static int prerecord_buffer[MPEG_MAX_PRERECORD_SECONDS]; /* Array of buffer
363 indexes for each
364 prerecorded
365 second */
366static int prerecord_index; /* Current index in the prerecord buffer */
367static int prerecording_max_seconds; /* Max number of seconds to store */
368static int prerecord_count; /* Number of seconds in the prerecord buffer */
369static int prerecord_timeout; /* The tick count of the next prerecord data store */
370
371/* Shadow MAS registers */
372unsigned long shadow_encoder_control = 0;
373#endif /* CONFIG_HWCODEC == MAS3587F */
374
375#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
376unsigned long shadow_io_control_main = 0;
377unsigned long shadow_soft_mute = 0;
378unsigned shadow_codec_reg0;
379#endif /* (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
380
381static int mpeg_file;
382
383/* Synchronization variables */
384#if CONFIG_HWCODEC == MAS3587F
385static bool init_recording_done;
386static bool init_playback_done;
387#endif /* CONFIG_HWCODEC == MAS3587F */
388static bool mpeg_stop_done;
389 403
404#ifndef SIMULATOR
390static void recalculate_watermark(int bitrate) 405static void recalculate_watermark(int bitrate)
391{ 406{
392 int bytes_per_sec; 407 int bytes_per_sec;
@@ -518,15 +533,6 @@ static int get_unsaved_space(void)
518 space += audiobuflen; 533 space += audiobuflen;
519 return space; 534 return space;
520} 535}
521#endif /* CONFIG_HWCODEC == MAS3587F */
522
523#if CONFIG_HWCODEC == MAS3587F
524#ifdef DEBUG
525static long timing_info_index = 0;
526static long timing_info[1024];
527#endif /* DEBUG */
528static unsigned long num_rec_bytes;
529static unsigned long num_recorded_frames;
530 536
531static void drain_dma_buffer(void) 537static void drain_dma_buffer(void)
532{ 538{
@@ -542,6 +548,11 @@ static void drain_dma_buffer(void)
542 } 548 }
543} 549}
544 550
551#ifdef DEBUG
552static long timing_info_index = 0;
553static long timing_info[1024];
554#endif /* DEBUG */
555
545void rec_tick (void) __attribute__ ((section (".icode"))); 556void rec_tick (void) __attribute__ ((section (".icode")));
546void rec_tick(void) 557void rec_tick(void)
547{ 558{
@@ -984,14 +995,6 @@ static bool swap_one_chunk(void)
984 return true; 995 return true;
985} 996}
986 997
987#ifdef HAVE_RECORDING
988const unsigned char empty_id3_header[] =
989{
990 'I', 'D', '3', 0x03, 0x00, 0x00,
991 0x00, 0x00, 0x1f, 0x76 /* Size is 4096 minus 10 bytes for the header */
992};
993#endif /* HAVE_RECORDING */
994
995static void mpeg_thread(void) 998static void mpeg_thread(void)
996{ 999{
997 static int pause_tick = 0; 1000 static int pause_tick = 0;
@@ -1551,15 +1554,13 @@ static void mpeg_thread(void)
1551 is_playing = false; 1554 is_playing = false;
1552 paused = false; 1555 paused = false;
1553 stop_playing(); 1556 stop_playing();
1554#ifndef SIMULATOR //CHECKME 1557
1555
1556 /* Tell the USB thread that we are safe */ 1558 /* Tell the USB thread that we are safe */
1557 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n"); 1559 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
1558 usb_acknowledge(SYS_USB_CONNECTED_ACK); 1560 usb_acknowledge(SYS_USB_CONNECTED_ACK);
1559 1561
1560 /* Wait until the USB cable is extracted again */ 1562 /* Wait until the USB cable is extracted again */
1561 usb_wait_for_disconnect(&mpeg_queue); 1563 usb_wait_for_disconnect(&mpeg_queue);
1562#endif /* !SIMULATOR */
1563 break; 1564 break;
1564#endif /* !USB_NONE */ 1565#endif /* !USB_NONE */
1565 1566
@@ -1913,10 +1914,6 @@ static void mpeg_thread(void)
1913} 1914}
1914#endif /* !SIMULATOR */ 1915#endif /* !SIMULATOR */
1915 1916
1916#ifdef SIMULATOR
1917static struct mp3entry taginfo;
1918#endif /* SIMULATOR */
1919
1920void mpeg_id3_options(bool _v1first) 1917void mpeg_id3_options(bool _v1first)
1921{ 1918{
1922 v1first = _v1first; 1919 v1first = _v1first;
@@ -1969,11 +1966,7 @@ void audio_init_playback(void)
1969 1966
1970 1967
1971/**************************************************************************** 1968/****************************************************************************
1972 ** 1969 * Recording functions
1973 **
1974 ** Recording functions
1975 **
1976 **
1977 ***************************************************************************/ 1970 ***************************************************************************/
1978void mpeg_init_recording(void) 1971void mpeg_init_recording(void)
1979{ 1972{
@@ -2528,7 +2521,6 @@ void audio_stop(void)
2528 is_playing = false; 2521 is_playing = false;
2529 playing = false; 2522 playing = false;
2530#endif /* SIMULATOR */ 2523#endif /* SIMULATOR */
2531
2532} 2524}
2533 2525
2534void audio_pause(void) 2526void audio_pause(void)
@@ -2659,8 +2651,6 @@ void audio_error_clear(void)
2659} 2651}
2660 2652
2661#ifdef SIMULATOR 2653#ifdef SIMULATOR
2662static char mpeg_stack[DEFAULT_STACK_SIZE];
2663static const char mpeg_thread_name[] = "mpeg";
2664static void mpeg_thread(void) 2654static void mpeg_thread(void)
2665{ 2655{
2666 struct mp3entry* id3; 2656 struct mp3entry* id3;