Index: apps/codecs/mpa.c =================================================================== --- apps/codecs/mpa.c (revision 18341) +++ apps/codecs/mpa.c (working copy) @@ -25,6 +25,16 @@ CODEC_HEADER +/* +#define GPIO_SET_BITWISE(port, mask) \ + do { *(&port + (0x800/sizeof(long))) = (mask << 8) | mask; } while(0) + +#define GPIO_CLEAR_BITWISE(port, mask) \ + do { *(&port + (0x800/sizeof(long))) = mask << 8; } while(0) + +#define GPIOG_OUTPUT_VAL (*(volatile unsigned long *)(0x6000d0a8)) +*/ + struct mad_stream stream IBSS_ATTR; struct mad_frame frame IBSS_ATTR; struct mad_synth synth IBSS_ATTR; @@ -159,6 +169,109 @@ } } + + + + +/* + * Try running synth code on COP! + */ + +static int mad_synth_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)] + IBSS_ATTR; + +static const unsigned char * const mad_synth_thread_name = "mp3dec"; +static struct thread_entry *mad_synth_thread_p; + + +static void mad_synth_thread(void){ + + + //if threres a frame to synth, else sleep + while(1){ + if(frame.synth_pending){ + + + //GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, 0x80); + mad_synth_frame(&synth, &frame); + + //GPIO_CLEAR_BITWISE(GPIOG_OUTPUT_VAL, 0x80); + + + /*this is a terrible way to do this, but enough for now*/ + + frame.synth_pending = 0; + frame.synth_done=1; + invalidate_icache(); + }else if(frame.die){ + frame.die=0; + return ; + } else{ + ci->yield(); + } + } + +} + + +static int mad_synth_thread_wait_pcm(void){ + //check if pcm is ready + while(1){ + if(frame.synth_done){ + frame.synth_done=0; + + return 0; + }else{ + // if(frame.synth_pending){ + // GPIO_SET_BITWISE(GPIOG_OUTPUT_VAL, 0x80); + // } + ci->yield(); + + // GPIO_CLEAR_BITWISE(GPIOG_OUTPUT_VAL, 0x80); + // ci->yield(); + //invalidate_icache(); + + } + } +} + +static int mad_synth_thread_ready(void){ + //tell the synth thread we're ready to go + + frame.synth_pending=1; + return 0; + +} + +static int mad_synth_thread_create(void){ + frame.synth_done=0; + frame.synth_pending=0; + + mad_synth_thread_p = ci->create_thread(mad_synth_thread, mad_synth_thread_stack, + sizeof(mad_synth_thread_stack), 0, + mad_synth_thread_name IF_PRIO(, PRIORITY_PLAYBACK), COP); + + if (mad_synth_thread_p == NULL) + return false; + + return true; + +} + +static inline void mpa_synth_thread_quit(void) +{ + if (mad_synth_thread_p != NULL) { + //emu_thread_send_msg(SPC_EMU_QUIT, 0); + /* Wait for emu thread to be killed */ + ci->thread_wait(mad_synth_thread_p); + invalidate_icache(); + } +} + + + + + /* this is the codec entry point */ enum codec_status codec_main(void) { @@ -180,7 +293,10 @@ /* Create a decoder instance */ ci->configure(DSP_SET_SAMPLE_DEPTH, MAD_F_FRACBITS); - + + /*start a thread*/ + mad_synth_thread_create(); + next_track: status = CODEC_OK; @@ -300,6 +416,9 @@ data (not the one just decoded above). When we exit the decoding loop we will need to process the final frame that was decoded. */ if (framelength > 0) { + + mad_synth_thread_wait_pcm(); + /* In case of a mono file, the second array will be ignored. */ ci->pcmbuf_insert(&synth.pcm.samples[0][samples_to_skip], &synth.pcm.samples[1][samples_to_skip], @@ -308,9 +427,10 @@ /* Only skip samples for the first frame added. */ samples_to_skip = 0; } + + mad_synth_thread_ready(); + //mad_synth_frame(&synth, &frame); - mad_synth_frame(&synth, &frame); - /* Check if sample rate and stereo settings changed in this frame. */ if (frame.header.samplerate != current_frequency) { current_frequency = frame.header.samplerate; @@ -345,10 +465,11 @@ /* Finish the remaining decoded frame. Cut the required samples from the end. */ - if (framelength > stop_skip) + if (framelength > stop_skip){ + mad_synth_thread_wait_pcm(); ci->pcmbuf_insert(synth.pcm.samples[0], synth.pcm.samples[1], framelength - stop_skip); - +} stream.error = 0; if (ci->request_next_track()) Index: apps/codecs/libmad/mad.h =================================================================== --- apps/codecs/libmad/mad.h (revision 18341) +++ apps/codecs/libmad/mad.h (working copy) @@ -778,6 +778,10 @@ struct mad_frame { struct mad_header header; /* MPEG audio header */ + volatile short synth_done; /*synth is finished*/ + volatile short synth_pending; /*a frame is ready for synthesis*/ + volatile short die; /*thread should die*/ + int options; /* decoding options (from stream) */ mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */