#include "Drv_mic.h" #include "ima_enc.h" #include "system.h" #undef INFO_HEADER #define INFO_HEADER "MIC" //#define TEST_AUDIO_PCM unsigned char micRecordbuf[RECORE_BUFFER_SIZE]; unsigned char gAdcCtrl; tMicCallback gfMicCb; unsigned char gadcEncodeBuf[ENCODE_OUTPUT_LEN+20]; IPC_DATA_FORMAT *gIpcDataPtr; MIC_CUR_VARIABLE sMicCurVariable; QUEUE_HEADER VoiceDecodeDataQueue; uint8_t VoiceDecodeDataQueueBuffer[MIC_QUEUE_MAX*MIC_ADPCM_PACKET_LEN]; /******************************Queue Function Start***********************************/ /* * @method queue_init * @brief init queue struct. * @retval None */ bool queue_init(QUEUE_HEADER *pQheader, void *pMem, uint8_t unitLen, uint8_t len) { // printf("Queue initial\r\n"); if (pQheader == NULL || pMem == NULL || unitLen == 0 || len == 0) { return false; } pQheader->pRead = pMem; pQheader->pWrite = pMem; pQheader->pHead = pMem; pQheader->array_Len = len; pQheader->unit_Len = unitLen; pQheader->current_queue_len = 0; return true; } /* * @method queue_clear * @brief clear queue pointer. * @retval false or true. */ bool queue_clear(QUEUE_HEADER *pQheader) { if (pQheader == NULL) { return false; } pQheader->pRead = pQheader->pHead; pQheader->pWrite = pQheader->pHead; pQheader->current_queue_len = 0; return true; } void * Delete_Queue(QUEUE_HEADER *pQheader) { void *pTemp; if (queue_is_empty(pQheader)) { return NULL; } pTemp = pQheader->pRead; pQheader->pRead = (void *)(((unsigned char *)pQheader->pRead)+ pQheader->unit_Len); if ((uint8_t *)pQheader->pRead == ((uint8_t *)pQheader->pHead) + (pQheader->unit_Len*pQheader->array_Len)) { pQheader->pRead = pQheader->pHead; } pQheader->current_queue_len--; return pTemp; } bool queue_is_empty(QUEUE_HEADER *pQheader) { if (pQheader->current_queue_len == 0) { return true; } return false; } bool queue_is_full(QUEUE_HEADER *pQheader) { if (pQheader->current_queue_len == pQheader->array_Len) { return true; } return false; } bool Insert_Queue(QUEUE_HEADER *pQheader,void *pEle) { uint8_t i; //unsigned char * pTemp; if (queue_is_full(pQheader)) { return false; } memcpy(pQheader->pWrite,pEle,pQheader->unit_Len); pQheader->pWrite = (void *)(((uint8_t *)pQheader->pWrite)+pQheader->unit_Len); if ((uint8_t *)pQheader->pWrite == ((uint8_t *)pQheader->pHead) + (pQheader->unit_Len*pQheader->array_Len)) { pQheader->pWrite = pQheader->pHead; } pQheader->current_queue_len++; return true; } /******************************Queue Function End***********************************/ void Drv_adcdma_init(DRV_ADC_CONFIG *pAdcConfig) { unsigned short buffenEnd; int i,j; buffenEnd = ((unsigned short)((uint32_t)pAdcConfig->mDmaBuf + pAdcConfig->mDmaBufLen) & 0xFFFF); //mic bias HWRITE(0x8977,0x2a); HWRITE(0x8978,0xa0);// three bits means mic suply high HWRITE(0x8979,0xE0); HWRITE(0x897a,0x68); HWRITE(0x897b,0xa8); HWRITE(0x897c,0x55); HWRITE(0x897d,0x18); HWRITE(0x897e,0xF3); HWRITE(0x897f,0xE1); HWRITE(0x8980,0xFF); HWRITE(0x8981,0x30); HWRITE(0x897f,0xE3); HWRITE(0x897f,0xE1); HWRITE(0x897e,0xf3); HWRITE(0x897e,0xE3); HWRITE(0x897e,0xf3); gAdcCtrl = pAdcConfig->mAdcConfig; HWRITE(CORE_MIC_HPF_CTRL,0x10); HWRITEW(CORE_ADCD_SADDR, pAdcConfig->mDmaBuf); HWRITEW(CORE_ADCD_EADDR, buffenEnd-1); } void Drv_adc_enable(void) { for (int j =100*1000;j>0;j--);//mic need 320/7ms to wake HWRITE(CORE_ADCD_CTRL, DRV_ADC_ENABLE | gAdcCtrl); return; } unsigned short Drv_adc_getWptr(void) { return HREADW(CORE_ADCD_ADDR); } void Drv_adc_disable(void) { HWRITE(CORE_ADCD_CTRL, gAdcCtrl); return; } void DRV_Mic_Init(void) { DRV_ADC_CONFIG adcCfg; gIpcDataPtr = (IPC_DATA_FORMAT*)&gadcEncodeBuf; sMicCurVariable.mEndPtr =(unsigned char *)( ((int)micRecordbuf + RECORE_BUFFER_SIZE) ); memset(micRecordbuf, 0, RECORE_BUFFER_SIZE); sMicCurVariable.mMicEnable = MIC_DISABLE; sMicCurVariable.mReadBufPtr = micRecordbuf; sMicCurVariable.mReadPtr = micRecordbuf; adcCfg.mDmaBuf = micRecordbuf; adcCfg.mDmaBufLen = RECORE_BUFFER_SIZE; adcCfg.mAdcConfig = DRV_ADC_M0RAM_ENABLE; adcCfg.mAdcConfig = DRV_ADC_M0RAM_ENABLE|DRV_ADC_16K_FILTer; adcCfg.mChannelCfg = DRV_ADC_CHANNEL_DIFF_GPIO1213; adcCfg.mSampleDelay = 0; Drv_adcdma_init(&adcCfg); } void DRV_Mic_DeInit(void) { int len; len = (int)(sMicCurVariable.mReadBufPtr - sMicCurVariable.mEndPtr); memset(sMicCurVariable.mReadBufPtr, 0, len); return; } void DRV_Mic_sendEnable() { sMicCurVariable.mMicBleEnable= MIC_ENABLE; } void DRV_Mic_sendDisable() { sMicCurVariable.mMicBleEnable= MIC_DISABLE; } void DRV_Mic_Enable(void) { int len; if(sMicCurVariable.mMicEnable == MIC_ENABLE) return; sMicCurVariable.mMicEnable = MIC_ENABLE; sMicCurVariable.mReadPtr = sMicCurVariable.mReadBufPtr; Drv_adc_enable(); } void DRV_Mic_Disable(void) { sMicCurVariable.mMicEnable = MIC_DISABLE; Drv_adc_disable(); } MIC_STATUS_ENUM DRV_Mic_State(void) { return sMicCurVariable.mMicEnable; } void Drv_micQueueInit() { queue_init(&VoiceDecodeDataQueue, VoiceDecodeDataQueueBuffer,MIC_ADPCM_PACKET_LEN, MIC_QUEUE_MAX); } bool Drv_micQueueEmpty(QUEUE_HEADER *pQheader) { if (queue_is_empty(&VoiceDecodeDataQueue)){ //Lpm_unLockLpm(VOICE_LPM_FLAG); return true; } else return false; } void Drv_micClearQueue() { queue_clear(&VoiceDecodeDataQueue); } bool Drv_micInsertQueue(QUEUE_HEADER *pQheader,void *pEle) { if(Insert_Queue(pQheader,pEle)) return true; else return false; } void Drv_voiceDecodeDataSend() { while(IPC_TxBufferIsEnough(MIC_ADPCM_PACKET_LEN) && (!Drv_micQueueEmpty(&VoiceDecodeDataQueue))) { IPC_DATA_FORMAT *tmp=Delete_Queue(&VoiceDecodeDataQueue); (*gfMicCb)(tmp,ENCODE_OUTPUT_LEN); } } void DRV_Mic_multiply_2(s16 *data,int datalen) { for(int i=0;i32767)tmp=32767; if(tmp<-32768)tmp=-32768; *(data+i)=(s16)tmp; } } int DRV_Mic_Get_Buffer_Len() { int audioWPtr = HREADW(CORE_ADCD_ADDR) ; int audioRPtr = TO_16BIT_ADDR(sMicCurVariable.mReadPtr); int audioBufferLen = (int)(sMicCurVariable.mEndPtr - sMicCurVariable.mReadBufPtr); if(audioRPtr <= audioWPtr) { return (audioWPtr - audioRPtr); } else { return (audioBufferLen - (audioRPtr - audioWPtr)); } } void DRV_Mic_Encode_ADC() { //check enable if (sMicCurVariable.mMicBleEnable == MIC_DISABLE) return; int audioWPtr = Drv_adc_getWptr(); //check mic adc buf int bufferLen = DRV_Mic_Get_Buffer_Len(); if (bufferLen != 0 && bufferLen >= ENCODE_PACKETS_LEN) { for (int i =0; iipcUnion.uBleData.data); while(!Drv_micInsertQueue(&VoiceDecodeDataQueue,gIpcDataPtr)) { Drv_voiceDecodeDataSend(); } Drv_voiceDecodeDataSend(); sMicCurVariable.mReadPtr+=ENCODE_INPUT_LEN; if (sMicCurVariable.mReadPtr == sMicCurVariable.mEndPtr){ sMicCurVariable.mReadPtr = sMicCurVariable.mReadBufPtr; } } } }