STM32 usb HOST audio USB 音频设备 放音乐
闲来无事,折腾通过USBHOST 把本地的MP3 音频文件 发送给USB 音频设备 播放音乐。
1. 先把USB HOST 做成个USB U盘 通过MSC FATFS 往本地SD_NAND先存放音频文件,
2.再把USB HOST 驱动成 audio ,移植 软解码MP3HEX库。
3.移植USB HOST audio 相关驱动库,通过usbh_audio.c 分析整份代码过于繁琐,只需要保留枚举那部分代码即可,驱动操作可以自己封装相关的函数,4
typedef struct {uint8_t buff[AUDIT_SZIE+4];int32_t out_ptr;uint32_t in_ptr;
}Audio_BufferTypeDef;/* Private variables ---------------------------------------------------------*/
//static WAV_InfoTypedef WavInfo;
//static FIL WavFile;static Audio_BufferTypeDef BufferCtl;
static u32 pRdBufSize,halfSize;void AUDIO_Process(void)
{int32_t diff;USBH_StatusTypeDef Status = USBH_FAIL;switch(audio_state){case 0://if(Status ==USBH_OK)TRACE("sent cur:%d\n",10);// _HSetAur(&hUsbHostFS,10);// _HSetAur(&hUsbHostFS,5);_HSetAur(&hUsbHostFS,5);_HSetMirSpeak(&hUsbHostFS,0,1);// Mp3Reset();audio_state =1;break;case 1:Status = USBH_AUDIO_Play(&hUsbHostFS, &BufferCtl.buff[0],halfSize * GetMp3TotalFram(),48000,16,1);if(Status ==USBH_OK){audio_state ++;}break;case 2 :if((BufferCtl.out_ptr = USBH_AUDIO_GetOutOffset(&hUsbHostFS)) < 0) /* End of file */{ //audio_state ++;TRACE("sent all:%d\n",total);}else if(BufferCtl.out_ptr >= pRdBufSize ) /* End of buffer 4608 */{// TRACE("S:%d\n",BufferCtl.out_ptr);USBH_AUDIO_ChangeOutBuffer(&hUsbHostFS, &BufferCtl.buff[0]);}else {diff = BufferCtl.out_ptr - BufferCtl.in_ptr;if(diff < 0){diff = pRdBufSize + diff;}if(diff >= pRdBufSize /2 )//9216{BufferCtl.in_ptr += halfSize;if(BufferCtl.in_ptr >= pRdBufSize)//(AUDIO_BLOCK_SIZE * AUDIO_BLOCK_NBR)){BufferCtl.in_ptr = 0;}if(!CheckMP3Over()){// TRACE("in:%d\n",BufferCtl.in_ptr);halfSize = GetMP3Fram(&BufferCtl.buff[BufferCtl.in_ptr],1);}elseaudio_state = 3;}MP3ShowTimes();}break;case 3:Status = USBH_AUDIO_Stop(&hUsbHostFS);if(Status ==USBH_OK)audio_state ++;TRACE("err exit:%d\n",BufferCtl.in_ptr);break;default:break;}}void MX_USB_HOST_Process(void)
{int tx = 0;/* USB Host Background task */USBH_Process(&hUsbHostFS);if( Appli_state == APPLICATION_READY){AUDIO_Process();//AUDIO_Micr_Process();}if(!connected){TIM2->CNT = 0;TIM2->CR1|=0x01; //使能定时器2pRdBufSize = GetMP3Fram(&BufferCtl.buff[0],4);//AUDIO_BLOCK_SIZE * AUDIO_BLOCK_NBR);TIM2->CR1&=~0x01; //使能定时器2TRACE("mp3_run_us:%d\n",TIM2->CNT);BufferCtl.out_ptr = BufferCtl.in_ptr = 0;halfSize = pRdBufSize /4;TRACE("get byte:%d,%d\n",pRdBufSize,halfSize);connected = 1;}}
4.整个处理流程只需保留几个相关操作API,开始播放和停止播放,设置音量大小,因为usb 音频设备是单声道,对MP3解码的双通道 做 /2 处理