diff options
Diffstat (limited to 'apps/codecs/mpa.c')
-rw-r--r-- | apps/codecs/mpa.c | 142 |
1 files changed, 137 insertions, 5 deletions
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c index 7ac96fb8b2..c916aefcaa 100644 --- a/apps/codecs/mpa.c +++ b/apps/codecs/mpa.c | |||
@@ -25,13 +25,34 @@ | |||
25 | 25 | ||
26 | CODEC_HEADER | 26 | CODEC_HEADER |
27 | 27 | ||
28 | #if (CONFIG_CPU == PP5024 || CONFIG_CPU == PP5022 || CONFIG_CPU == PP5020 \ | ||
29 | || CONFIG_CPU == PP5002) && !defined(MPEGPLAYER) | ||
30 | #define MPA_SYNTH_ON_COP | ||
31 | #endif | ||
32 | |||
28 | struct mad_stream stream IBSS_ATTR; | 33 | struct mad_stream stream IBSS_ATTR; |
29 | struct mad_frame frame IBSS_ATTR; | 34 | struct mad_frame frame IBSS_ATTR; |
30 | struct mad_synth synth IBSS_ATTR; | 35 | struct mad_synth synth IBSS_ATTR; |
31 | 36 | ||
37 | #ifdef MPA_SYNTH_ON_COP | ||
38 | volatile short synth_running IBSS_ATTR; /*synthesis is running*/ | ||
39 | volatile short die IBSS_ATTR; /*thread should die*/ | ||
40 | |||
41 | #if (CONFIG_CPU == PP5024) || (CONFIG_CPU == PP5022) | ||
42 | mad_fixed_t sbsample_prev[2][36][32] IBSS_ATTR; | ||
43 | #else | ||
44 | mad_fixed_t sbsample_prev[2][36][32] SHAREDBSS_ATTR; | ||
45 | #endif | ||
46 | |||
47 | struct semaphore synth_done_sem IBSS_ATTR; | ||
48 | struct semaphore synth_pending_sem IBSS_ATTR; | ||
49 | #endif | ||
50 | |||
32 | #define INPUT_CHUNK_SIZE 8192 | 51 | #define INPUT_CHUNK_SIZE 8192 |
33 | 52 | ||
34 | mad_fixed_t mad_frame_overlap[2][32][18] IBSS_ATTR; | 53 | mad_fixed_t mad_frame_overlap[2][32][18] IBSS_ATTR; |
54 | mad_fixed_t sbsample[2][36][32] IBSS_ATTR; | ||
55 | |||
35 | unsigned char mad_main_data[MAD_BUFFER_MDLEN] IBSS_ATTR; | 56 | unsigned char mad_main_data[MAD_BUFFER_MDLEN] IBSS_ATTR; |
36 | /* TODO: what latency does layer 1 have? */ | 57 | /* TODO: what latency does layer 1 have? */ |
37 | int mpeg_latency[3] = { 0, 481, 529 }; | 58 | int mpeg_latency[3] = { 0, 481, 529 }; |
@@ -43,6 +64,14 @@ void init_mad(void) | |||
43 | ci->memset(&frame, 0, sizeof(struct mad_frame)); | 64 | ci->memset(&frame, 0, sizeof(struct mad_frame)); |
44 | ci->memset(&synth, 0, sizeof(struct mad_synth)); | 65 | ci->memset(&synth, 0, sizeof(struct mad_synth)); |
45 | 66 | ||
67 | #ifdef MPA_SYNTH_ON_COP | ||
68 | frame.sbsample_prev = &sbsample_prev; | ||
69 | #else | ||
70 | frame.sbsample_prev = &sbsample; | ||
71 | #endif | ||
72 | |||
73 | frame.sbsample=&sbsample; | ||
74 | |||
46 | mad_stream_init(&stream); | 75 | mad_stream_init(&stream); |
47 | mad_frame_init(&frame); | 76 | mad_frame_init(&frame); |
48 | mad_synth_init(&synth); | 77 | mad_synth_init(&synth); |
@@ -51,6 +80,8 @@ void init_mad(void) | |||
51 | ci->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap)); | 80 | ci->memset(mad_frame_overlap, 0, sizeof(mad_frame_overlap)); |
52 | frame.overlap = &mad_frame_overlap; | 81 | frame.overlap = &mad_frame_overlap; |
53 | stream.main_data = &mad_main_data; | 82 | stream.main_data = &mad_main_data; |
83 | |||
84 | |||
54 | } | 85 | } |
55 | 86 | ||
56 | int get_file_pos(int newtime) | 87 | int get_file_pos(int newtime) |
@@ -159,6 +190,90 @@ static void set_elapsed(struct mp3entry* id3) | |||
159 | } | 190 | } |
160 | } | 191 | } |
161 | 192 | ||
193 | #ifdef MPA_SYNTH_ON_COP | ||
194 | |||
195 | /* | ||
196 | * Run the synthesis filter on the COProcessor | ||
197 | */ | ||
198 | |||
199 | static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)/2] IBSS_ATTR; | ||
200 | |||
201 | static const unsigned char * const mad_synth_thread_name = "mp3dec"; | ||
202 | static struct thread_entry *mad_synth_thread_p; | ||
203 | |||
204 | |||
205 | static void mad_synth_thread(void){ | ||
206 | |||
207 | while(1){ | ||
208 | ci->semaphore_wait(&synth_pending_sem); | ||
209 | |||
210 | if(die){ | ||
211 | die=0; | ||
212 | invalidate_icache(); | ||
213 | return ; | ||
214 | } | ||
215 | synth_running = 1; | ||
216 | mad_synth_frame(&synth, &frame); | ||
217 | synth_running = 0; | ||
218 | ci->semaphore_release(&synth_done_sem); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | |||
223 | static int mad_synth_thread_wait_pcm(void){ | ||
224 | ci->semaphore_wait(&synth_done_sem); | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static void mad_synth_thread_ready(void){ | ||
229 | mad_fixed_t (*temp)[2][36][32]; | ||
230 | while(1){ | ||
231 | /*check if synth is currently running before changing its inputs! */ | ||
232 | if(!synth_running){ | ||
233 | /*circular buffer that holds 2 frames' samples*/ | ||
234 | temp=frame.sbsample; | ||
235 | frame.sbsample = frame.sbsample_prev; | ||
236 | frame.sbsample_prev=temp; | ||
237 | |||
238 | ci->semaphore_release(&synth_pending_sem); | ||
239 | return ; | ||
240 | } | ||
241 | ci->yield(); /*synth thread currently running, wait for it*/ | ||
242 | } | ||
243 | } | ||
244 | |||
245 | static int mad_synth_thread_create(void){ | ||
246 | synth_running=0; | ||
247 | die=0; | ||
248 | |||
249 | ci->semaphore_init(&synth_done_sem, 1, 0); | ||
250 | ci->semaphore_init(&synth_pending_sem, 1, 0); | ||
251 | |||
252 | mad_synth_thread_p = ci->create_thread(mad_synth_thread, | ||
253 | mad_synth_thread_stack, | ||
254 | sizeof(mad_synth_thread_stack), 0, | ||
255 | mad_synth_thread_name | ||
256 | IF_PRIO(, PRIORITY_PLAYBACK), COP); | ||
257 | |||
258 | if (mad_synth_thread_p == NULL) | ||
259 | return false; | ||
260 | |||
261 | return true; | ||
262 | |||
263 | } | ||
264 | #else | ||
265 | static void mad_synth_thread_ready(void){ | ||
266 | mad_synth_frame(&synth, &frame); | ||
267 | } | ||
268 | static int mad_synth_thread_create(void){ | ||
269 | return 0; | ||
270 | } | ||
271 | static int mad_synth_thread_wait_pcm(void){ | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | #endif | ||
276 | |||
162 | /* this is the codec entry point */ | 277 | /* this is the codec entry point */ |
163 | enum codec_status codec_main(void) | 278 | enum codec_status codec_main(void) |
164 | { | 279 | { |
@@ -180,8 +295,12 @@ enum codec_status codec_main(void) | |||
180 | /* Create a decoder instance */ | 295 | /* Create a decoder instance */ |
181 | 296 | ||
182 | ci->configure(DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS); | 297 | ci->configure(DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS); |
183 | 298 | ||
184 | next_track: | 299 | next_track: |
300 | |||
301 | /*does nothing on 1 processor systems*/ | ||
302 | mad_synth_thread_create(); | ||
303 | |||
185 | status = CODEC_OK; | 304 | status = CODEC_OK; |
186 | 305 | ||
187 | /* Reinitializing seems to be necessary to avoid playback quircks when seeking. */ | 306 | /* Reinitializing seems to be necessary to avoid playback quircks when seeking. */ |
@@ -300,6 +419,9 @@ next_track: | |||
300 | data (not the one just decoded above). When we exit the decoding | 419 | data (not the one just decoded above). When we exit the decoding |
301 | loop we will need to process the final frame that was decoded. */ | 420 | loop we will need to process the final frame that was decoded. */ |
302 | if (framelength > 0) { | 421 | if (framelength > 0) { |
422 | |||
423 | mad_synth_thread_wait_pcm(); | ||
424 | |||
303 | /* In case of a mono file, the second array will be ignored. */ | 425 | /* In case of a mono file, the second array will be ignored. */ |
304 | ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip], | 426 | ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip], |
305 | &synth.pcm.samples[1][samples_to_skip], | 427 | &synth.pcm.samples[1][samples_to_skip], |
@@ -308,8 +430,9 @@ next_track: | |||
308 | /* Only skip samples for the first frame added. */ | 430 | /* Only skip samples for the first frame added. */ |
309 | samples_to_skip = 0; | 431 | samples_to_skip = 0; |
310 | } | 432 | } |
311 | 433 | ||
312 | mad_synth_frame(&synth, &frame); | 434 | mad_synth_thread_ready(); |
435 | //mad_synth_frame(&synth, &frame); | ||
313 | 436 | ||
314 | /* Check if sample rate and stereo settings changed in this frame. */ | 437 | /* Check if sample rate and stereo settings changed in this frame. */ |
315 | if (frame.header.samplerate != current_frequency) { | 438 | if (frame.header.samplerate != current_frequency) { |
@@ -345,11 +468,20 @@ next_track: | |||
345 | 468 | ||
346 | /* Finish the remaining decoded frame. | 469 | /* Finish the remaining decoded frame. |
347 | Cut the required samples from the end. */ | 470 | Cut the required samples from the end. */ |
348 | if (framelength > stop_skip) | 471 | if (framelength > stop_skip){ |
472 | mad_synth_thread_wait_pcm(); | ||
349 | ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1], | 473 | ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1], |
350 | framelength - stop_skip); | 474 | framelength - stop_skip); |
351 | 475 | } | |
476 | #ifdef MPA_SYNTH_ON_COP | ||
477 | /*mop up COP thread*/ | ||
478 | die=1; | ||
479 | ci->semaphore_release(&synth_pending_sem); | ||
480 | ci->thread_wait(mad_synth_thread_p); | ||
481 | invalidate_icache(); | ||
352 | stream.error = 0; | 482 | stream.error = 0; |
483 | #endif | ||
484 | |||
353 | 485 | ||
354 | if (ci->request_next_track()) | 486 | if (ci->request_next_track()) |
355 | goto next_track; | 487 | goto next_track; |