📄 audiobuffer.c
字号:
#endif DMA_MAX0 = AudioDataLength*4; if(!pause_active) { //pause not requested, start DMA AB_current_position = AudioBuffer[g_AudioBufferReadFrom].Position; AB_current_bitrate = AudioBuffer[g_AudioBufferReadFrom].Bitrate; enable_DMA0(); } else { //pause requested, don't start DMA mute_on(); pause_active = 2; if(!CIF_CONF.field.src) { // Not Compressed Audio - repeat last transfer to activate mute DMA_SOURCE_HI0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom_Prev].data) >> 16); //[MM] 11/08/2006 DMA_SOURCE_LO0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom_Prev].data) & 0xFFFF);//[MM] 11/08/2006 //DMA_MAX0 should not be re-initialized it has the value of the last Transfer enable_DMA0(); //[MM] 11/08/2006 Activate_Mute = 1; //[MM] 11/08/06 g_ABempty--; AudioBuffer[g_AudioBufferReadFrom_Prev].status = abDataReady; } } } else { mute_on(); if(!CIF_CONF.field.src) { // Not Compressed Audio - repeat last transfer to activate mute DMA_SOURCE_HI0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom_Prev].data) >> 16); //[MM] 11/08/2006 DMA_SOURCE_LO0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom_Prev].data) & 0xFFFF);//[MM] 11/08/2006 //DMA_MAX0 should not be re-initialized it has the value of the last Transfer enable_DMA0(); //[MM] 11/08/2006 Activate_Mute = 1; //[MM] 11/08/06 g_ABempty--; AudioBuffer[g_AudioBufferReadFrom_Prev].status = abDataReady; } else { // Compressed Audio DMAunderflow = 1; src_stop(); } } } } if(dma_status.field.err0) { DMA_CLR.field.sec0 = 1; } //EIC_FIR.field.dma0_fiq_ip = 1;} void dma_ch0_isr_irq(void){ event_set_dma0_xfer(READY); event_disable_scheduling(); event_out_shedule(DMA0_IRQ_XFER_EVENT); event_out_shedule(DECODER_TIME_EVENT); // copy to event_pending & wake event_enable_scheduling(); } void ReconfigureDMA_CH0(t_fileType FileType){ CIF_CONF.field.wr_en = 0; switch(FileType) { case ft_Audio: //uncompressed audio SetDMAChannel(DMA_CH0,CHITF_WR_CH); SetUpDMA(DMA_CH0, (uint32 *) NULL, // Source Address (uint32 *) &CIF_WRDATA, // Destination Address DMA_WORD_SIZE_IS_BYTE, // Source Word Size DMA_WORD_SIZE_IS_WORD, // Destination Word Size 0, // Number of Words DMA_BURST_IS_8_WORD, // Burst Size DMA_INCREMENT , // Source Inc DMA_NO_INCREMENT , // Peripheral Inc DMA_PERIPHERAL_IS_THE_DESTINATION, // Peripheral is Destination 0); // Mem 2 Mem Enable break; default: //compressed audio SetDMAChannel(DMA_CH0, SRC_DRE_CH); SetUpDMA(DMA_CH0, (uint32 *) NULL, // Source Address (uint32 *) &SRC_DIF, // Destination Address DMA_WORD_SIZE_IS_HALF_WORD, // Source Word Size DMA_WORD_SIZE_IS_HALF_WORD, // Destination Word Size 0, // Number of Words DMA_BURST_IS_4_WORD, // Burst Size DMA_INCREMENT , // Source Inc DMA_NO_INCREMENT , // Peripheral Inc DMA_PERIPHERAL_IS_THE_DESTINATION, // Peripheral is Destination 0); // Mem 2 Mem Enable break; }}void AudioBufferResetPosition(void) /* BB060926a */{ //wait till DMA xfer is finished //while(DMA_CTRL0.field.enable); while(dma_ch0_fiq); memset((void*)(&AB_lastplay_position),0,sizeof(t_position)); memset((void*)(&AB_current_position),0,sizeof(t_position)); AB_lastplay_bitrate = 0; AB_current_bitrate = 0;}void AudioBufferInit(void){ uint8 i; g_AudioBufferWriteTo = 0; g_AudioBufferReadFrom = 0; g_ABempty = AudioBufferElements; for (i = 0; i < AudioBufferElements ; i++) { AudioBuffer[i].status = abEmpty; } AudioBufferResetPosition(); /* BB060926a */ // *** INIT SRC *** // CurrentSampleRateConverterFrequency = kDecoderSampleRate_Undefined; src_init(); oif_init(); //[OK] - enable DAC and buffered path DMAunderflow = 1; }pAudioBufferData AudioBufferHaveSpace(eDecoderSampleRate SampleRate){ pAudioBufferData ret = NULL; DISABLE_INTERRUPTS(); if (SampleRate != CurrentSampleRateConverterFrequency) { // request that all AB elements are empty, to reconfigure SRC if (g_ABempty < AudioBufferElements) { goto exitf; } g_ABempty = AudioBufferElements; CurrentSampleRateConverterFrequency = SampleRate; // reconfigure SRC SRCSetFrequency(CurrentSampleRateConverterFrequency); } if (AudioBuffer[g_AudioBufferWriteTo].status == abEmpty) { ret = (AudioBuffer[g_AudioBufferWriteTo].data); } exitf: ENABLE_INTERRUPTS(); return ret;}void AudioBufferSetFull(uint32 num_samples, ElementFlagType ElementFlag, tDecoderTime_event *TimeEvent, t_position *Position){ AudioBuffer[g_AudioBufferWriteTo].ElementFlag = ElementFlag; AudioBuffer[g_AudioBufferWriteTo].status = abDataReady; AudioBuffer[g_AudioBufferWriteTo].DataLength = num_samples; AudioBuffer[g_AudioBufferWriteTo].TimeEvent = *TimeEvent; AudioBuffer[g_AudioBufferWriteTo].Position = *Position; AudioBuffer[g_AudioBufferWriteTo].Bitrate = GetCurrentBitRate(); DISABLE_INTERRUPTS(); g_ABempty--; // decrement number of empty AB elements if(DMAunderflow) { //DMA is stopped#if (DEBUG_INCLUDE_COUNTERS==1) extern uint32 countABUnderflows; // [RB] debug countABUnderflows++; // [RB] debug#endif DMAunderflow = 0; src_restart_done = 0; // start DMA set_DMA0((uint32*)(AudioBuffer[g_AudioBufferWriteTo].data),num_samples *4); event_disable_scheduling(); if(!pause_active) { //pause not requested, start DMA#if (1 == HAVE_SHOCK_MEMORY) if((CurrentFileType == ft_Audio) && (ADPCM_ON == cap_config.adpcm)) { OIF_SOFT_RST.field.adpcm_dec_rst = 1; }#endif //src_restart is set there if executed. //Point 1) start_dma0_xfer();#if (1 == HAVE_SHOCK_MEMORY) if(ADPCM_ON == cap_config.adpcm) { OIF_SOFT_RST.field.adpcm_dec_rst = 0; } #endif } else { //pause requested, don't start DMA pause_active = 2; } event_enable_scheduling(); if (CurrentFileType != ft_Audio) { //compressed audio // Don't execute SRC restart if already excuted in point // 1) if(0 == src_restart_done) { src_restart(); } } else { //CDDA enable_CIF(); } } ENABLE_INTERRUPTS(); if (AudioBuffer[g_AudioBufferWriteTo].ElementFlag == FT_FIRST) { AudioBuffer[g_AudioBufferWriteTo].ElementFlag = FT_MIDDLE; } g_AudioBufferWriteTo = (g_AudioBufferWriteTo+1)%AudioBufferElements; }void ResetAudioBuffer(void){ uint8 i; //At the end of a DMA Xfer the DMA_CTRL0.field.enable is set //to 0 before generation of FIQ interrupt. //In the previous version, the complete data song Transfer was checked //In the following way: // //while(DMA_CTRL0.field.enable); // //But it could happen that the the DMA_CTRL0.field.enable bit is checked to 0 //and then FIQ starts and the ResetAudioBuffer runs with a running FIQ. //This caused unrecoverable noise on Audio Output with CD DA. //wait till DMA xfer is finished #if 0 while(1) { val1 = DMA_CTRL0.field.enable; for(i = 0; i < 100; i++); val2 = DMA_CTRL0.field.enable; for(i = 0; i < 100; i++); val3 = DMA_CTRL0.field.enable; for(i = 0; i < 100; i++); val = val1 + val2 + val3; if(val == 0) { break; } } #endif while(dma_ch0_fiq); //wait till DMA xfer is finished g_AudioBufferWriteTo = 0; g_AudioBufferReadFrom = 0; g_ABempty = AudioBufferElements; for (i = 0; i < AudioBufferElements ; i++) { AudioBuffer[i].status = abEmpty; AudioBuffer[i].ElementFlag = FT_MIDDLE; } DMAunderflow = 1;}pAudioBufferData AudioBufferRead(uint32 *DataLength){ pAudioBufferData ret = NULL; if (AudioBuffer[g_AudioBufferReadFrom].status == abDataReady) { ret = (AudioBuffer[g_AudioBufferReadFrom].data); *DataLength = AudioBuffer[g_AudioBufferReadFrom].DataLength; // in Bytes } return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -