[STM32F1] 【有偿】关于MP3软解,使用内部DAC输出

[复制链接]
3023|12
 楼主| clvert 发表于 2018-5-25 15:59 | 显示全部楼层 |阅读模式
芯片是stm32f103ve,我手头有MP3软解代码,是用I2S外部音频芯片输出。想改为使用内部DAC输出,该如何改?求教!!
 楼主| clvert 发表于 2018-5-25 16:01 | 显示全部楼层
有意向的大神可以与我索要现有例程,压缩包太大上传不了
Ketose 发表于 2018-5-25 21:27 | 显示全部楼层
DAC输出质量很差。如果你不介意我可以试试。
戈卫东 发表于 2018-5-26 15:53 | 显示全部楼层
如果可以发一份给gwd1@live.cn
可能帮不上你,主要是我自己学学,谢谢了。如果搞定了我把代码帖这里。
 楼主| clvert 发表于 2018-5-28 13:56 | 显示全部楼层
Ketose 发表于 2018-5-25 21:27
DAC输出质量很差。如果你不介意我可以试试。

留个邮箱
 楼主| clvert 发表于 2018-5-28 13:57 | 显示全部楼层
戈卫东 发表于 2018-5-26 15:53
如果可以发一份给
可能帮不上你,主要是我自己学学,谢谢了。如果搞定了我把代码帖这里。 ...

已发
 楼主| clvert 发表于 2018-5-30 08:32 | 显示全部楼层
还有大神吗
Rospiers 发表于 2018-5-30 21:22 | 显示全部楼层
外部音频芯片是专用的,比内部DAC好
 楼主| clvert 发表于 2018-5-31 08:29 | 显示全部楼层
Rospiers 发表于 2018-5-30 21:22
外部音频芯片是专用的,比内部DAC好

是的,就是想搞一下自带DAC,试试效果。只是对自带DAC一直不熟悉,所以无从下手
 楼主| clvert 发表于 2018-6-5 14:31 | 显示全部楼层
还有大神吗
Ketose 发表于 2018-6-7 14:33 | 显示全部楼层
捉虫天师 发表于 2018-6-7 22:44 | 显示全部楼层
DAC分辨率不够吧
 楼主| clvert 发表于 2018-6-9 14:10 | 显示全部楼层

这是我的工程,目前MP3文件信息可以正确读出,自带dac输出听着是那种规律的杂音。可以帮我看一下吗?

  1. #include "wave.h"
  2. #include "mp3.h"
  3. #include "string.h"
  4. #include "mp3dec.h"
  5. #include "wm8978.h"
  6. #include "i2s.h"


  7. //__align(8)
  8. //uint16_t Mp3DecodeBuf[DECODEBUFSIZE];
  9. short *Mp3DecodeBuf;

  10. FIL Mp3File;
  11. mp3Info Mp3Info;
  12. uint8_t* Readptr;        //MP3解码读指针
  13. int32_t ByteLeft;//buffer还剩余的有效数据
  14. uint8_t        InitMp3InfoFlag;
  15. HMP3Decoder Mp3Decoder;
  16. uint32_t DmaBufSize;


  17. /*==========================================================*/
  18. unsigned char DACbz_mp3;
  19. unsigned char CH_mp3;
  20. unsigned int DApc_mp3;
  21. unsigned char buffer_switch;
  22. HMP3Decoder hMP3Decoder;
  23. FIL f_MP3;
  24. //int16_t         *buffer1={0x00};
  25. //int16_t         *buffer2={0x00};
  26. short *buffer1;
  27. short *buffer2;


  28. void TIM3_IRQHandler(void)
  29. {                  
  30.         if(TIM3->SR&0X0001)//溢出中断
  31.         {
  32.                 if(CH_mp3==1)//单声道
  33.                 {
  34.                         if(buffer_switch==0)
  35.                         {
  36.                                 DAC->DHR12R1=(((uint16_t)buffer1[DApc_mp3]+0x8000)>>4);//*10/volume;
  37.                                 DAC->DHR12R2=(((uint16_t)buffer1[DApc_mp3]+0x8000)>>4);//*10/volume;
  38.                                 DApc_mp3++;
  39.                                 DAC->SWTRIGR|=0x03;//软件启动两个通道的转换   
  40.                         }
  41.                         else
  42.                         {
  43.                                 DAC->DHR12R1=(((uint16_t)buffer2[DApc_mp3]+0x8000)>>4);//*10/volume;
  44.                                 DAC->DHR12R2=(((uint16_t)buffer2[DApc_mp3]+0x8000)>>4);//*10/volume;
  45.                                 DApc_mp3++;
  46.                                 DAC->SWTRIGR|=0x03;//软件启动两个通道的转换
  47.                         }      
  48.                 }
  49.                 else //if(CH_mp3==2)//立体声    10110010  10110010
  50.                 {
  51.                         if(buffer_switch==0)
  52.                         {
  53.                                 DAC->DHR12R1=(((uint16_t)buffer1[DApc_mp3]+0x8000)>>4);//*10/volume;
  54.                                 DApc_mp3++;
  55.                                 DAC->DHR12R2=(((uint16_t)buffer1[DApc_mp3]+0x8000)>>4);//*10/volume;
  56.                                 DApc_mp3++;
  57.                                 DAC->SWTRIGR|=0x03;//软件启动两个通道的转换   
  58.                         }
  59.                         else
  60.                         {
  61.                                 DAC->DHR12R1=(((uint16_t)buffer2[DApc_mp3]+0x8000)>>4);//*10/volume;
  62.                                 DApc_mp3++;
  63.                                 DAC->DHR12R1=(((uint16_t)buffer2[DApc_mp3]+0x8000)>>4);//*10/volume;
  64.                                 DApc_mp3++;
  65.                                 DAC->SWTRIGR|=0x03;//软件启动两个通道的转换
  66.                         }
  67.                 }  
  68.                 if(DApc_mp3==2304)///    //1帧MP3输出2304数据
  69.                 {
  70.                         DApc_mp3=0;
  71.                         DACbz_mp3=1;
  72.                 }                             
  73.         }      
  74.         TIM3->SR&=~(1<<0);//清除中断标志位     
  75. }
  76. //设置NVIC分组
  77. //NVIC_Group:NVIC分组 0~4 总共5组
  78. //CHECK OK
  79. //091209
  80. void MY_NVIC_PriorityGroupConfig(unsigned char NVIC_Group)         
  81. {
  82.         uint32_t temp,temp1;          
  83.         temp1=(~NVIC_Group)&0x07;//取后三位
  84.         temp1<<=8;
  85.         temp=SCB->AIRCR;  //读取先前的设置
  86.         temp&=0X0000F8FF; //清空先前分组
  87.         temp|=0X05FA0000; //写入钥匙
  88.         temp|=temp1;          
  89.         SCB->AIRCR=temp;  //设置分组                                                        
  90. }
  91. //设置NVIC
  92. //NVIC_PreemptionPriority:抢占优先级
  93. //NVIC_SubPriority       :响应优先级
  94. //NVIC_Channel           :中断编号
  95. //NVIC_Group             :中断分组 0~4
  96. //注意优先级不能超过设定的组的范围!否则会有意想不到的错误
  97. //组划分:
  98. //组0:0位抢占优先级,4位响应优先级
  99. //组1:1位抢占优先级,3位响应优先级
  100. //组2:2位抢占优先级,2位响应优先级
  101. //组3:3位抢占优先级,1位响应优先级
  102. //组4:4位抢占优先级,0位响应优先级
  103. //NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先
  104. //CHECK OK
  105. //100329
  106. void MY_NVIC_Init(unsigned char NVIC_PreemptionPriority,unsigned char NVIC_SubPriority,unsigned char NVIC_Channel,unsigned char NVIC_Group)         
  107. {
  108.         uint32_t temp;       
  109.         unsigned char IPRADDR=NVIC_Channel/4;  //每组只能存4个,得到组地址
  110.         unsigned char IPROFFSET=NVIC_Channel%4;//在组内的偏移
  111.         IPROFFSET=IPROFFSET*8+4;    //得到偏移的确切位置
  112.         MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
  113.         temp=NVIC_PreemptionPriority<<(4-NVIC_Group);          
  114.         temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
  115.         temp&=0xf;//取低四位

  116.         if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;//使能中断位(要清除的话,相反操作就OK)
  117.         else NVIC->ISER[1]|=1<<(NVIC_Channel-32);   
  118.         NVIC->IP[IPRADDR]|=temp<<IPROFFSET;//设置响应优先级和抢断优先级                                                           
  119. }

  120. //通用定时器4中断初始化
  121. //这里始终选择为APB1的2倍,而APB1为36M
  122. //arr:自动重装值。
  123. //psc:时钟预分频数
  124. //这里使用的是定时器4!
  125. void Timer3_Init(unsigned int arr,unsigned int psc)
  126. {
  127.         RCC->APB1ENR|=1<<1;//TIM3时钟使能   
  128.         TIM3->ARR=arr;  //设定计数器自动重装值//刚好1ms   
  129.         TIM3->PSC=psc;  //预分频器7200,得到10Khz的计数时钟
  130.         //这两个东东要同时设置才可以使用中断
  131.         TIM3->DIER|=1<<0;   //允许更新中断                               
  132.         TIM3->DIER|=1<<6;   //允许触发中断
  133.                                                                               
  134.         TIM3->CR1|=0x01;    //使能定时器3
  135.           MY_NVIC_Init(1,3,0x1D,2);//抢占1,子优先级3,组2                                                                         
  136. }

  137. //DAC通道1输出初始化  要用双通道的还要加上DAC2的初始化
  138. /*void Dac1_Init(void)
  139. {
  140.         RCC->APB2ENR|=1<<2;    //使能PORTA时钟   
  141.         RCC->APB1ENR|=1<<29;   //使能DAC时钟   

  142.         GPIOA->CRL&=0XFFF0FFFF;
  143.         GPIOA->CRL|=0X00000000;//PA4 模拟输入(虽然是输入,但是STM32 内部会连接在DAC 模拟输出上
  144.         DAC->CR|=1<<0; //使能DAC1
  145.         DAC->CR|=0<<1; //DAC1输出缓存使能 BOFF1=0
  146.         DAC->CR|=0<<2; //不使用触发功能 TEN1=0
  147.         DAC->CR|=0<<3; //DAC TIM6 TRGO,不过要TEN1=1才行
  148.         DAC->CR|=0<<6; //不使用波形发生
  149.         DAC->CR|=0<<8; //屏蔽、幅值设置
  150.         DAC->CR|=0<<12; //DAC1 DMA不使能   
  151.         DAC->DHR12R1=0;
  152.         DAC->DHR12L1=0;
  153.         DAC->SWTRIGR|=0x01;//通道1软件启动转换
  154. }*/
  155. void DAC1_SetData(unsigned int data)
  156. {
  157.         DAC->DHR12R1=data;//通道1的12位右对齐数据
  158.         DAC->SWTRIGR|=0x01;//软件启动转换
  159. }

  160. void DAC2_SetData(unsigned int data)
  161. {
  162.         DAC->DHR12R2=data;//通道2的12位右对齐数据
  163.         DAC->SWTRIGR|=0x02;//软件启动转换
  164. }
  165. void Dac1_Init(void)//DAC channel1 Configuration
  166. {
  167.           unsigned int tmpreg1=0,tmpreg2=0;
  168.         RCC->APB2ENR|=1<<2;//使能PORTA时钟
  169.         RCC->APB1ENR|=0x20000000;//使能DAC时钟
  170.         GPIOA->CRL&=0XFF00FFFF;
  171.         GPIOA->CRL|=0X00440000;//PA4,5 浮空输入            

  172.           tmpreg1=DAC->CR;//Get the DAC CR value  
  173.           tmpreg1&=~(0x00000FFE<<0x00000000);//Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits  
  174.           tmpreg2=(0x0000003C|0x00000000|0x00000800|0x00000000);
  175.           tmpreg1|=tmpreg2<<0x00000000;//Calculate CR register value depending on DAC_Channel
  176.           DAC->CR=tmpreg1;//Write to DAC CR
  177.         DAC->CR|=0x00000001<<0x00000000;//DAC Channel1使能,PA4自动连接到DAC
  178.         DAC1_SetData(0x000);

  179.           tmpreg1=DAC->CR;//Get the DAC CR value  
  180.           tmpreg1&=~(0x00000FFE<<0x00000010);//Clear BOFFx, TENx, TSELx, WAVEx and MAMPx bits  
  181.           tmpreg2=(0x0000003C|0x00000000|0x00000800|0x00000000);
  182.           tmpreg1|=tmpreg2<<0x00000010;//Calculate CR register value depending on DAC_Channel
  183.           DAC->CR=tmpreg1;//Write to DAC CR
  184.         DAC->CR|=0x00000001<<0x00000010;//DAC Channel2使能,PA5自动连接到DAC
  185.         DAC2_SetData(0x000);
  186. }

  187. /************************************************************************************/
  188. /*
  189. * File Name  : Convert_Stereo  μ¥éùμàμ?á¢ì?éù×a??
  190. * Description    : I have do some modification in Subband() function due to the long time of
  191. *                  decode.Using PolyphaseMono() function which is used in decode mono mp3,to decode
  192. *                  Stereo,so must use this funtion to convert mono to Stereo.
  193. * Input          : Adress of buffer data
  194. * Output         : None
  195. * Return         : None
  196. */
  197. /************************************************************************************/
  198. void Convert_Stereo(short *buffer)
  199. {
  200.         int i,j,k=0;
  201.         for(i=0;i<(2304/64);i++)           //36
  202.         {
  203.                 for(j=31+i*64,k=j+32;j>=0+i*64;j--,k-=2)
  204.                 {
  205.                         buffer[k]=buffer[j];
  206.                         buffer[k-1]=buffer[j];
  207.                 }
  208.         }
  209. }

  210. /***********************************************************************************/
  211. /*
  212. * File Name  : Convert_Mono
  213. * Description    : ?o3?oóμ?μ¥éùμàMP3?a???÷μ??ò?ü£???ì?211152°?×?£??a??1|?ü*????±?μ¥éùμàμ?á¢ì?éù?£
  214. * Input          : Adress of buffer data
  215. * Output         : None
  216. * Return         : None
  217. */
  218. /***********************************************************************************/
  219. void Convert_Mono(short *buffer)
  220. {
  221.         int i;
  222.         for (i = 1152 - 1; i >= 0; i--)
  223.         {
  224.                 buffer[i * 2] = buffer[i];
  225.                 buffer[i * 2 + 1] = buffer[i];
  226.         }
  227. }
  228. /*void mp3play(void)//MP3播放,这个函数在压缩包里面有
  229. {
  230.         // int err;
  231.         uint32_t br;  
  232.         FRESULT res;
  233.         short  *Outpcmbuf;//输出数据指针
  234.         int bytesLeft;
  235.         unsigned char *readBuf;//输入数据缓存
  236.         unsigned char *readPtr;//读取数据指针
  237.        signed long offset;
  238.         unsigned char init;
  239.         Outpcmbuf=buffer1;
  240.         MP3FrameInfo mp3FrameInfo;
  241.         //LCD_Clear(WHITE);  //黑屏
  242.         hMP3Decoder=MP3InitDecoder();   //初始化解码器
  243.         Dac1_Init();   //用DAC播放   
  244.         res=f_open(&f_MP3,"0:/music/0001.MP3",FA_OPEN_EXISTING|FA_READ);//打开MP3文件
  245.         printf("res=%d\r\n", res);
  246.         bytesLeft=0;   //复位计数器
  247.         while(1)
  248.         {         
  249.                 res=f_read(&f_MP3,readBuf,4096,(UINT*)&br); //读出2048个字节       
  250.                 //printf("res=%d\r\n", res);
  251.                 //printf("br=%d\r\n", br);
  252.                 if(res!=FR_OK||br==0) break;       
  253.                 //printf("read mp3 success!\n");
  254.                 readPtr=readBuf;
  255.                 bytesLeft = br;        
  256.                 buffer_switch=0;   //双缓存切换标志
  257.                 init=0;     
  258.                 while(1)
  259.                 {     
  260.                         offset=MP3FindSyncWord(readPtr, bytesLeft);//寻找下一帧头 帧同步
  261.                         if(offset<0)break;
  262.                         //printf("MP3FindSyncWord success!\n");
  263.                         readPtr+=offset; //data start point
  264.                         bytesLeft-=offset; //in buffer
  265.                         MP3Decode(hMP3Decoder,&readPtr,&bytesLeft,Outpcmbuf,0);//解码
  266.                         //   err=MP3Decode(hMP3Decoder,&readPtr,&bytesLeft,Outpcmbuf,0);//解码
  267.                         if(bytesLeft<4096) //补充数据
  268.                         {
  269.                                 //printf("bytesLeft<4096!\n");
  270.                                 memmove(readBuf,readPtr,bytesLeft);
  271.                                 res=f_read(&f_MP3,readBuf+bytesLeft,4096-bytesLeft,(UINT*)&br);
  272.                                 if((res)||(br==0)) break;  
  273.                                 //printf("read mp3 success!\n");
  274.                                 if(br<4096-bytesLeft)
  275.                                 memset(readBuf+bytesLeft+br,0,4096-bytesLeft-br);
  276.                                 bytesLeft=4096;
  277.                                 readPtr=readBuf;               
  278.                         }

  279.                         MP3GetLastFrameInfo(hMP3Decoder, &mp3FrameInfo); //获得解码
  280.                         if(init==0)   //根据MP3帧信息初始化音频接口
  281.                         {
  282.                                 //printf("enter Timer4_Init!\n");
  283.                                 Timer3_Init(1000000/(mp3FrameInfo.samprate),71);//   1MHz的计数频率,产生和采样率一样的中断频率
  284.                                 CH_mp3=mp3FrameInfo.nChans;   //几声道      
  285.                                 //LCD_ShowNum(60+80,160,mp3FrameInfo.outputSamps,5,16); //打印=2304 //PCM 数据个数
  286.                                 init=1;//              //1帧MP3输出2304pcm数据
  287.                         }      
  288.                         if(mp3FrameInfo.nChans==1)Convert_Mono(Outpcmbuf);//单声道
  289.                         else Convert_Stereo(Outpcmbuf);//立体声
  290.                         while(!DACbz_mp3);        //等待转换完成
  291.                         DACbz_mp3=0;   //定时器中断会置1

  292.                         if(buffer_switch == 0)     //双缓存切换
  293.                         {
  294.                                 Outpcmbuf=buffer1;      
  295.                                 buffer_switch = 1;
  296.                         }
  297.                         else
  298.                         {   
  299.                                 Outpcmbuf=buffer2;
  300.                                 buffer_switch = 0;
  301.                         }
  302.                         //LED=!LED;
  303.                 }
  304.                 f_close(&f_MP3);//关闭文件   
  305.         }
  306.         TIM4->CR1&=~0x01;//关定时器,切歌时不产生噪音
  307.         DAC->CR&=0<<0; //关闭DAC1
  308. }
  309. ==========================================================*/



  310. uint8_t PlayMp3File(char* path)
  311. {
  312.         uint8_t res=0;
  313.         uint32_t br=0;
  314.         //uint32_t Mp3DataStart=0;
  315.         CloseFileFlag=0;
  316.         EndFileFlag=0;
  317.         FillBufFlag=0xFF;
  318.         //ID3V2_TagHead *TagHead;
  319.        
  320.        Mp3DecodeBuf=buffer1;
  321.         Mp3Decoder=MP3InitDecoder();
  322.         if(Mp3Decoder==0)
  323.         {
  324.                 printf("Init Mp3Decoder failed!\r\n");
  325.                 //res=4;
  326.                 //break;
  327.         }

  328.        
  329.         Dac1_Init();
  330.         res=f_open(&Mp3File,(TCHAR*)path,FA_READ);
  331.         while(1)
  332.         {
  333.                 if(res!=FR_OK)
  334.                 {
  335.                         printf("Open file failed!\r\n");
  336.                         res=1;
  337.                         break;
  338.                 }
  339.                 CloseFileFlag=1;
  340.                 res=f_read(&Mp3File,TempBuf,WAVEFILEBUFSIZE,&br);
  341.                 if(res!=FR_OK)
  342.                 {
  343.                         printf("Read file failed!\r\n");
  344.                         res=2;
  345.                         break;
  346.                 }
  347.                 /*TagHead=(ID3V2_TagHead*)TempBuf;
  348.                 //得到MP3数据的开始位置
  349.                 if(strncmp("ID3",(const char*)TagHead->id,3)==0)
  350.                 {
  351.                         Mp3Info.DataStart=((uint32_t)TagHead->size[0]<<21)|((uint32_t)TagHead->size[1]<<14)|((uint32_t)TagHead->size[2]<<7)|TagHead->size[3];
  352.                         f_lseek(&Mp3File,Mp3DataStart);
  353.                         res=f_read(&Mp3File,TempBuf,WAVEFILEBUFSIZE,&br);
  354.                         if(res!=FR_OK||br==0)
  355.                         {
  356.                                 printf("Read file failed!\r\n");
  357.                                 res=3;
  358.                                 break;
  359.                         }
  360.                 }
  361.                 Mp3Decoder=MP3InitDecoder();
  362.                 if(Mp3Decoder==0)
  363.                 {
  364.                         printf("Init Mp3Decoder failed!\r\n");
  365.                         res=4;
  366.                         break;
  367.                 }*/
  368.                 Readptr=TempBuf;
  369.                 ByteLeft=br;
  370.                 /*InitMp3InfoFlag=0;
  371.                 while(EndFileFlag==0)
  372.                 {
  373.                         res=FillMp3Buf(WaveFileBuf);
  374.                         if(res==0)
  375.                                 break;
  376.                 }
  377.                 res=My_I2S2_Init(Mp3Info.bitsPerSample,Mp3Info.samprate);
  378.                 printf("%d\r\n",res);
  379.                 DmaBufSize=Mp3Info.OutSamples*Mp3Info.bitsPerSample*4/(8*Mp3Info.nChans);
  380.                 printf("DmaBufSize=%d\r\n",DmaBufSize);*/
  381.                 FillMp3Buf(WaveFileBuf+DmaBufSize/2);
  382.                 //break;
  383.         }
  384.         /*if(res!=0)
  385.         {
  386.                 printf("res=%d\r\n",res);
  387.                 if(CloseFileFlag)
  388.                 {
  389.                         f_close(&Mp3File);
  390.                         CloseFileFlag=0;
  391.                 }
  392.                 MP3FreeDecoder(Mp3Decoder);               
  393.                 return res;
  394.         }
  395.         HAL_I2S_Transmit_DMA(&hi2s2,(uint16_t *)WaveFileBuf,DmaBufSize/2);
  396.         while(1)
  397.         {
  398.                 if(EndFileFlag==0)
  399.                 {
  400.                         if(FillBufFlag==0)
  401.                         {
  402.                                 FillMp3Buf(WaveFileBuf);
  403.                                 FillBufFlag=0xFF;
  404.                         }
  405.                         else
  406.                         if(FillBufFlag==1)
  407.                         {
  408.                                 FillMp3Buf(&WaveFileBuf[DmaBufSize/2]);
  409.                                 FillBufFlag=0xFF;
  410.                         }
  411.                 }
  412.                 else
  413.                 if(EndFileFlag==3)
  414.                 {
  415.                         HAL_I2S_DMAStop(&hi2s2);
  416.                         //printf("sr=%d\r\n",hi2s2.Instance->SR);
  417.                         //printf("cr2=%d\r\n",hi2s2.Instance->CR2);
  418.                         //printf("cfgr=%d\r\n",hi2s2.Instance->I2SCFGR);
  419.                         __HAL_I2S_ENABLE(&hi2s2);
  420.                         res=I2S_WaitFlagStateUntilTimeout(&hi2s2, I2S_FLAG_BSY, SET, 20);
  421.                         //printf("res=%d\r\n",res);
  422.                         __HAL_I2S_DISABLE(&hi2s2);
  423.                         //printf("sr=%d\r\n",hi2s2.Instance->SR);
  424.                         break;
  425.                 }
  426.         }
  427.         if(CloseFileFlag)*/
  428.                 f_close(&Mp3File);
  429.        
  430.         TIM4->CR1&=~0x01;//关定时器,切歌时不产生噪音
  431.         DAC->CR&=0<<0; //关闭DAC1

  432.         MP3FreeDecoder(Mp3Decoder);       
  433.         return 0;
  434. }


  435. uint32_t FillMp3Buf(uint8_t *Buf)
  436. {
  437.         uint32_t br=0;
  438.         int32_t Offset;
  439.         int32_t err=0;
  440.         //int32_t i;
  441.         uint16_t *PlayPtr;
  442.         //uint16_t *Mp3Ptr;
  443.         MP3FrameInfo Mp3FrameInfo;
  444.         int8_t init=0;
  445.         Offset=MP3FindSyncWord(Readptr,ByteLeft);        //在readptr位置,开始查找同步字符
  446.         if(Offset<0)                                                                                                                        //没有找到同步字符,跳出帧解码循环
  447.         {
  448.                 printf("Can not play the file!\r\n");
  449.                 return 1;
  450.         }
  451.         Readptr+=Offset;                                                                                                        //MP3读指针偏移到同步字符处.
  452.         ByteLeft-=Offset;                                                                                                        //buffer里面的有效数据个数,必须减去偏移量
  453.         //printf("ByteLeft=%d\r\n",ByteLeft);
  454.         if(ByteLeft<MAINBUF_SIZE*2)//当数组内容小于2倍MAINBUF_SIZE的时候,必须补充新的数据进来.
  455.         {
  456.                 memmove(TempBuf,Readptr,ByteLeft);//移动readptr所指向的数据到buffer里面,数据量大小为:bytesleft
  457.                 /*
  458.                 ReadBytesNum=WAVEFILEBUFSIZE-ByteLeft;
  459.                 if(ReadBytesNum%2)
  460.                         ReadBytesNum-=1;
  461.                 f_read(&Mp3File,TempBuf+ByteLeft,ReadBytesNum,&br);//补充余下的数据
  462.                 printf("rd=%d,br=%d\r\n",ReadBytesNum,br);
  463.                 if(br<ReadBytesNum)
  464.                 {
  465.                         memset(TempBuf+ByteLeft+br,0,WAVEFILEBUFSIZE-ByteLeft-br);
  466.                         //EndFileFlag=1;
  467.                 }
  468.                 ByteLeft=ByteLeft+ReadBytesNum;
  469.                 */
  470.                 f_read(&Mp3File,TempBuf+ByteLeft,WAVEFILEBUFSIZE-ByteLeft,&br);//补充余下的数据
  471.                 //printf("rd=%d,br=%d\r\n",WAVEFILEBUFSIZE-ByteLeft,br);
  472.                 if(br<WAVEFILEBUFSIZE-ByteLeft)
  473.                 {
  474.                         memset(TempBuf+ByteLeft+br,0,WAVEFILEBUFSIZE-ByteLeft-br);
  475.                         EndFileFlag=1;
  476.                 }
  477.                 ByteLeft=WAVEFILEBUFSIZE;
  478.                 Readptr=TempBuf;
  479.         }
  480.         err=MP3Decode(Mp3Decoder,&Readptr,&ByteLeft,Mp3DecodeBuf,0);//解码一帧MP3数据
  481.         //printf("Decode error:%d\r\n",err);
  482.         if(err!=0)
  483.         {
  484.                 printf("Decode error:%d\r\n",err);
  485.                 return 2;
  486.         }
  487.         if(InitMp3InfoFlag==0)
  488.         {
  489.                 MP3GetLastFrameInfo(Mp3Decoder,&Mp3FrameInfo);        //得到刚刚解码的MP3帧信息
  490.                 Mp3Info.bitsPerSample=Mp3FrameInfo.bitsPerSample;
  491.                 Mp3Info.nChans=Mp3FrameInfo.nChans;
  492.                 Mp3Info.OutSamples=Mp3FrameInfo.outputSamps;
  493.                 Mp3Info.samprate=Mp3FrameInfo.samprate;
  494.                 printf("bitsPerSample=%d\r\n",Mp3Info.bitsPerSample);
  495.                 printf("nChans=%d\r\n",Mp3Info.nChans);
  496.                 printf("OutSamples=%d\r\n",Mp3Info.OutSamples);
  497.                 printf("samprate=%d\r\n",Mp3Info.samprate);
  498.                 InitMp3InfoFlag=1;

  499.                         if(init==0)   //根据MP3帧信息初始化音频接口
  500.                         {
  501.                                 Timer3_Init(1000000/(Mp3Info.samprate),71);//   1MHz的计数频率,产生和采样率一样的中断频率
  502.                                 CH_mp3=Mp3Info.nChans;   //几声道      
  503.                                 init=1;//              //1帧MP3输出2304pcm数据
  504.                         }      
  505.                         if(Mp3Info.nChans==1)Convert_Mono(Mp3DecodeBuf);//单声道
  506.                         else Convert_Stereo(Mp3DecodeBuf);//立体声
  507.                         while(!DACbz_mp3);        //等待转换完成
  508.                         DACbz_mp3=0;   //定时器中断会置1

  509.                         if(buffer_switch == 0)     //双缓存切换
  510.                         {
  511.                                 Mp3DecodeBuf=buffer1;      
  512.                                 buffer_switch = 1;
  513.                         }
  514.                         else
  515.                         {   
  516.                                 Mp3DecodeBuf=buffer2;
  517.                                 buffer_switch = 0;
  518.                         }

  519.                
  520.                 if(Mp3Info.bitsPerSample!=16)
  521.                 {
  522.                         printf("Can not play the file!\r\n");
  523.                         return 3;
  524.                 }
  525.         }
  526.         //Mp3Ptr=Mp3DecodeBuf;
  527.         PlayPtr=(uint16_t*)Buf;
  528.         /*if(Mp3Info.nChans==2)
  529.         {
  530.                 for(i=0;i<Mp3Info.OutSamples;i++)
  531.                 {
  532.                         PlayPtr[i]=Mp3Ptr[i];
  533.                 }
  534.         }
  535.         else
  536.         {
  537.                 for(i=0;i<Mp3Info.OutSamples;i++)
  538.                 {
  539.                         PlayPtr[0]=Mp3Ptr[0];
  540.                         PlayPtr[1]=Mp3Ptr[0];
  541.                         PlayPtr+=2;
  542.                         Mp3Ptr+=1;
  543.                 }
  544.         }*/
  545.         return 0;
  546. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

111

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部