⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audiobuffer.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************** * * audiobuffer.c * * CVS ID:   $Id: audiobuffer.c,v 1.64 2007/11/15 14:40:33 marcucci Exp $ * Author:   Raffaele Belardi [RB] - STM * Date:     $Date: 2007/11/15 14:40:33 $ * Revision: $Revision: 1.64 $ *  * Description: *  * API for AudioBuffer access *  *************************************************** *  * COPYRIGHT (C) ST Microelectronics  2005 *            All Rights Reserved * *************************************************** * *  \brief        Audio buffer * *  \par          Change History: * * - BB060926a    Fixed CD exchange (WUT74-18-102531) * ****************************************************************************** * * STM CVS Log: * * $Log: audiobuffer.c,v $ * Revision 1.64  2007/11/15 14:40:33  marcucci * Fix for USB Stop * * Revision 1.63  2007/11/09 08:47:26  marcucci * Modification to allow patching of  FIQ interrupt procedure * * Revision 1.62  2007/10/22 08:29:42  marcucci * More robust waiting for DMA complete & correct start_dma0_xfer() prcedure * * Revision 1.61  2007/06/29 13:17:57  belardi * Removed unused variable * * Revision 1.60  2007/06/04 09:57:31  marcucci * Solve Wrong H/W detection of DMA Xfer complete * * Revision 1.59  2006/11/25 08:11:01  belardi * Ununsed function removal to free code space * * Revision 1.58  2006/11/20 13:58:08  marcucci * Understand if it is Compressed or Not Compressed by the CIF_CONF.field.SRC bit * * Revision 1.57  2006/11/07 08:44:39  chlapik * perform repeat of last xfer also in case of entering pause mode * * Revision 1.56  2006/11/06 15:37:59  chlapik * fixed bug - pause_active variable can be changed in CTR and also in DEC task, DEC task has lower priority, so we must use disable/enable scheduling for protection * * Revision 1.55  2006/11/02 12:10:33  chlapik * - checked all global variables used by DMA CH0 interrupt and DEC or CTR task - disable/enable scheduling/interrupts used for protection * - functions AudioBufferResetPosition() and ResetAudioBuffer() check if DMA xfer is not active, only then do the modification of AB variables * - CDDA - repeat of last xfer: * 		- mark AB element used for repeat xfer as not empty in order that DEC doesn't reconfigure SRC, DMA, OIF * 		- after repeated xfer is finished, if new data available, start DMA xfer again, but set source address correctly, not one from previous xfer * * Revision 1.54  2006/10/09 13:36:07  belardi * Merge of m8_cav2_cm80507 - created new AudioBufferResetPosition() function * * Revision 1.53  2006/09/18 09:55:21  belardi * Corrected CVS keyword usage * * Revision 1.52  2006/09/18 09:23:01  belardi * Added Log CVS keyword into file header * * ***************************************************/#include "configuration.h"#include "debug.h"#include "gendef.h"#include "osal.h"#include "hwinit.h"#include "decoder_task.h"#include "audiobuffer.h"#include "controller.h"#include <stdio.h>#include <string.h> //O.K. memset,...//#include <stdlib.h> // O.K. malloc//#include "lld_uart.h"#include "hwreg.h"  //[OK] for SRC init#include "srvchn.h" // [RB] for oif_init()#include "utility.h"//volatile uint8 val1;//volatile uint8 val2;//volatile uint8 val3;//volatile uint8 val;volatile uint8 src_restart_done;#define __SECTION(x,y) __attribute__((section(x),y))eDecoderSampleRate CurrentSampleRateConverterFrequency;#if (HAVE_SHOCK_MEMORY!=0)//__SECTION("audio_buffer",zero_init) AudioBufferElement AudioBuffer[AudioBufferElements]; [MM]uint32 AudioBufferElements;                           //[MM]AudioBufferElement *AudioBuffer;                      //[MM]//__attribute__((section("audio_buffer"),zero_init)) AudioBufferElement AudioBuffer[AudioBufferElements];//__attribute__((section("audio_buffer"),zero_init)) AudioBufferData data[AUDIO_BUFFER_ELEMENT_LENGTH];#else /*HAVE_SHOCK_MEMORY*/AudioBufferElement AudioBuffer[AudioBufferElements];#endif /*HAVE_SHOCK_MEMORY*/short g_AudioBufferWriteTo;volatile short g_AudioBufferReadFrom;short g_AudioBufferReadFrom_Prev; //[MM] 11/08/2006volatile int DMAunderflow = 0;int Activate_Mute = 0;            //[MM] 11/08/2006//uint32 absolute_outcnt; //[OK] number of decoded samples of currently decoded files//uint32 relative_outcnt; //[OK] number of decoded samples from last time updatevolatile int g_ABempty;  // number of empty AB elementsextern t_fileType CurrentFileType;extern t_fileType PreviousFileType;extern volatile uint8 pause_active;volatile t_position AB_lastplay_position;volatile t_position AB_current_position;volatile uint16 AB_lastplay_bitrate;volatile uint16 AB_current_bitrate;volatile uint8  dma_ch0_fiq;extern void (*fiq_hdl)(void);t_XItem AB_GetPlayedXfile(void){  // used only by Controller  return AB_lastplay_position.xfile;}uint32 AB_GetPlayedOffset(void){  // used only by Controller  // offset is in real bytes  return AB_lastplay_position.offset;}t_position AB_GetPlayedPosition(void){  // used only by Controller  // offset is in real bytes  return AB_lastplay_position;}#if 0 // [RB] unusedt_position AB_GetCurrentPosition(void){  // used only by Controller  // offset is in real bytes  return AB_current_position;}#endifuint16 AB_GetPlayedBitrate(void){  return AB_lastplay_bitrate;}#if 0 // [RB] unuseduint16 AB_GetCurrentBitrate(void){ return AB_current_bitrate;}#endifvoid start_dma0_xfer(void){  // Sample rate Converter send a DMA request as soon as unmute becames   // Active. DMA should be enabled first.  AB_current_position = AudioBuffer[g_AudioBufferReadFrom].Position;   AB_current_bitrate = AudioBuffer[g_AudioBufferReadFrom].Bitrate;    // Interrupts already disabled before calling it    enable_DMA0();  mute_off();}/******************************************************************************//* Function:  dma_ch0_isr_fiq                                          *//*                                                                            *//*! \brief    DMA interrupt handler  *  \param    void *  \return   void *  \remark   This interrupt handler is attached to the FIQ. For performance *            reason, the FIQ is not processed by the OS. *            As a consequence, OS primitives are not available in this irq handler. *            Since it is necessary to send a signal to a OS task when the SRC event *            happens, we also connect the event to the IRQ, which is a normal OS interrupt, *            and do the signal processing from there. *            In practice, the SRC interupt line is connected to both the FIQ and the IRQ *            lines of the ARM7. *//******************************************************************************/ // ARM7 call dma_ch0_isr_fiq on FIQ and this procedure call a procedure by // means of a function pointer put in RAM_A to make it patchable. // This pointer (fiq_hdl) is initilaized in mymain() function __irq void dma_ch0_isr_fiq(void) {  (*fiq_hdl)();   EIC_FIR.field.dma0_fiq_ip = 1; }void dma_ch0_isr_fiq_hdl(void) {      // After Tranfer Event Interrupt the DMA is disabled !!!    uint32 AudioDataLength;    //extern volatile int DMAunderflow;    tDecoderTime_event *pout_time_event;       DMA_STATUS_UNION  dma_status;       dma_status = DMA_STATUS;    dma_ch0_fiq = 0;       if(dma_status.field.int0)    {      //dma_ch2_status |= 0x01;      DMA_CLR.field.sic0 = 1;            if (Activate_Mute == 1)      {         // we went to mute because of underflow (and repeated the last transfer - correct mute)        // check if while repeating the last transfer new data are available                Activate_Mute = 0;        g_ABempty++;        AudioBuffer[g_AudioBufferReadFrom_Prev].status = abEmpty;                if (AudioBufferRead(&AudioDataLength) != NULL)        { // there are decoded data ready to be played#if (1 == HAVE_SHOCK_MEMORY)          if(ADPCM_ON == cap_config.adpcm)          {            if((AudioBuffer[g_AudioBufferReadFrom].data[1] & 0xFF) == 0x55)            {              OIF_SOFT_RST.field.adpcm_blockend_rst = 1;            }          }#endif                                              DMA_MAX0 = AudioDataLength*4;	      DMA_SOURCE_HI0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom].data) >> 16);	      DMA_SOURCE_LO0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom].data) & 0xFFFF);          		                if(!pause_active)                  {            start_dma0_xfer();          }          else          { //pause requested, don't start DMA            pause_active = 2;          }          }        else        {          DMAunderflow = 1;        }        }      else      {		      AudioBuffer[g_AudioBufferReadFrom].status = abEmpty;		      if ((AudioBuffer[g_AudioBufferReadFrom].TimeEvent.subcode.event_type)			  & (CAPTURE_EVENT_SUBCODE_REL_TIME | CAPTURE_EVENT_SUBCODE_BEGIN_OF_SONG))			  {			    pout_time_event = (tDecoderTime_event *) pevent_get_out(DECODER_TIME_EVENT);			    *pout_time_event = AudioBuffer[g_AudioBufferReadFrom].TimeEvent;			    event_set_out(DECODER_TIME_EVENT);      // copy to event_out			  }			  			  // de-emphasis			  // The bit 4 of the Control/ADDR byte of Subcode must be Checked for CDDA			  // CDDA == event_subcode = 1              // De-enphasis must be enabled if this bit is set to 1.			  if ((AudioBuffer[g_AudioBufferReadFrom].TimeEvent.subcode.q_subcode.q_cadr & 0x10)			   && (AudioBuffer[g_AudioBufferReadFrom].TimeEvent.subcode.event_subcode))			  {			    enable_DeEmphasis();			  }  			  else			  { // CDDA without deemphasis or CD-ROM			    disable_DeEmphasis();               }                            g_AudioBufferReadFrom_Prev = g_AudioBufferReadFrom;		      g_AudioBufferReadFrom = (g_AudioBufferReadFrom+1)%AudioBufferElements;		     		      g_ABempty++; // increment number of empty AB elements		          		      DMA_SOURCE_HI0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom].data) >> 16);		      DMA_SOURCE_LO0 = ((uint32)(AudioBuffer[g_AudioBufferReadFrom].data) & 0xFFFF);		      AB_lastplay_position = AB_current_position;		      AB_lastplay_bitrate = AB_current_bitrate;			  if (AudioBufferRead(&AudioDataLength) != NULL)		      {#if (1 == HAVE_SHOCK_MEMORY)                  if((CurrentFileType == ft_Audio) && (ADPCM_ON == cap_config.adpcm))                  {                    if((AudioBuffer[g_AudioBufferReadFrom].data[1] & 0xFF) == 0x55)                    {                      OIF_SOFT_RST.field.adpcm_blockend_rst = 1;                    }                  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -