/** * @brief Initializes wave recording. * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. * @param BitRes: Audio frequency to be configured for the I2S peripheral. * @param ChnlNbr: Audio frequency to be configured for the I2S peripheral. * @retval AUDIO_OK if correct communication, else wrong communication */ uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr) { RCC_PeriphCLKInitTypeDef rccclkinit; /* Enable PLLI2S clock */ HAL_RCCEx_GetPeriphCLKConfig(&rccclkinit); /* PLLI2S_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ if ((AudioFreq & 0x7) == 0) { /* Audio frequency multiple of 8 (8/16/32/48/96/192)*/ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 192 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 192/6 = 32 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 192; rccclkinit.PLLI2S.PLLI2SR = 6; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } else { /* Other Frequency (11.025/22.500/44.100) */ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 290 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 290/2 = 145 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 290; rccclkinit.PLLI2S.PLLI2SR = 2; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } /* Configure the PDM library */ PDMDecoder_Init(AudioFreq, ChnlNbr); /* Configure the I2S2 */ I2S2_Init(AudioFreq); /* Return AUDIO_OK when all operations are correctly done */ return AUDIO_OK; }
//播放某个WAV文件 //fname:wav文件路径. //返回值: //KEY0_PRES:下一曲 //KEY1_PRES:上一曲 //其他:错误 u8 wav_play_song(u8* fname) { u8 key; u8 t=0; u8 res; u32 fillnum; audiodev.file=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); audiodev.i2sbuf1=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE); audiodev.i2sbuf2=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE); audiodev.tbuf=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE); if(audiodev.file&&audiodev.i2sbuf1&&audiodev.i2sbuf2&&audiodev.tbuf) { res=wav_decode_init(fname,&wavctrl);//得到文件的信息 if(res==0)//解析文件成功 { if(wavctrl.bps==16) { WM8978_I2S_Cfg(2,0); //飞利浦标准,16位数据长度 I2S2_Init(0,2,0,0); //飞利浦标准,主机发送,时钟低电平有效,16位帧长度 }else if(wavctrl.bps==24) { WM8978_I2S_Cfg(2,2); //飞利浦标准,24位数据长度 I2S2_Init(0,2,0,2); //飞利浦标准,主机发送,时钟低电平有效,24位扩展帧长度 } I2S2_SampleRate_Set(wavctrl.samplerate);//设置采样率 I2S2_TX_DMA_Init(audiodev.i2sbuf1,audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE/2); //配置TX DMA i2s_tx_callback=wav_i2s_dma_tx_callback; //回调函数指wav_i2s_dma_callback audio_stop(); res=f_open(audiodev.file,(TCHAR*)fname,FA_READ); //打开文件 if(res==0) { f_lseek(audiodev.file, wavctrl.datastart); //跳过文件头 fillnum=wav_buffill(audiodev.i2sbuf1,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps); fillnum=wav_buffill(audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps); audio_start(); while(res==0) { while(wavtransferend==0);//等待wav传输完成; wavtransferend=0; if(fillnum!=WAV_I2S_TX_DMA_BUFSIZE)//播放结束? { res=KEY0_PRES; break; } if(wavwitchbuf)fillnum=wav_buffill(audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);//填充buf2 else fillnum=wav_buffill(audiodev.i2sbuf1,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);//填充buf1 while(1) { key=KEY_Scan(0); if(key==WKUP_PRES)//暂停 { if(audiodev.status&0X01)audiodev.status&=~(1<<0); else audiodev.status|=0X01; } if(key==KEY2_PRES||key==KEY0_PRES)//下一曲/上一曲 { res=key; break; } wav_get_curtime(audiodev.file,&wavctrl);//得到总时间和当前播放的时间 audio_msg_show(wavctrl.totsec,wavctrl.cursec,wavctrl.bitrate); t++; if(t==20) { t=0; LED0=!LED0; } if((audiodev.status&0X01)==0)delay_ms(10); else break; } } audio_stop(); }else res=0XFF; }else res=0XFF; }else res=0XFF; myfree(SRAMIN,audiodev.tbuf); //释放内存 myfree(SRAMIN,audiodev.i2sbuf1);//释放内存 myfree(SRAMIN,audiodev.i2sbuf2);//释放内存 myfree(SRAMIN,audiodev.file); //释放内存 return res; }