/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_StartRec(uint32_t frequency) { uint32_t byteswritten = 0; /* Initialize header file */ WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); haudio.ppcm = 0; /* Write header file */ if(f_write(&wav_file, pHeaderBuff, 44, (void*)&byteswritten) == FR_OK) { if(byteswritten != 0) { BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR); BSP_AUDIO_IN_Record((uint16_t*)&haudio.pdm[0], AUDIO_IN_PDM_BUFFER_SIZE); if(haudio.in.state == AUDIO_RECORDER_SUSPENDED) { osThreadResume(AudioThreadId); } haudio.in.state = AUDIO_RECORDER_RECORDING; haudio.in.fptr = byteswritten; return AUDIO_RECORDER_ERROR_NONE; } } return AUDIO_RECORDER_ERROR_IO; }
/** * @brief Play audio stream * @param frequency: Audio frequency used to play the audio stream. * @retval Audio state. */ AUDIO_RECORDER_ErrorTypdef AUDIO_RECORDER_StartRec(uint32_t frequency) { uint32_t byteswritten = 0; /* Initialize header file */ WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); /* Write header file */ if(f_write(&wav_file, pHeaderBuff, 44, (void*)&byteswritten) == FR_OK) { if(byteswritten != 0) { BSP_AUDIO_IN_Init(INPUT_DEVICE_DIGITAL_MICROPHONE_2, haudio.in.volume, DEFAULT_AUDIO_IN_FREQ); BSP_AUDIO_IN_Record((uint16_t*)&haudio.buff[0], AUDIO_IN_BUFFER_SIZE/2); if(haudio.in.state == AUDIO_RECORDER_SUSPENDED) { osThreadResume(AudioThreadId); } haudio.in.state = AUDIO_RECORDER_RECORDING; haudio.in.fptr = byteswritten; return AUDIO_RECORDER_ERROR_NONE; } } return AUDIO_RECORDER_ERROR_IO; }
/** * @brief Starts Audio streaming. * @param None * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_REC_Start(void) { uint32_t byteswritten = 0; uint8_t str[FILEMGR_FILE_NAME_SIZE + 20]; uwVolume = 100; /* Create a new file system */ if(f_open(&WavFile, REC_WAVE_NAME, FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) { /* Initialize header file */ WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); /* Write header file */ if(f_write(&WavFile, pHeaderBuff, 44, (void*)&byteswritten) == FR_OK) { AudioState = AUDIO_STATE_PRERECORD; BSP_LCD_SetTextColor(LCD_COLOR_WHITE); sprintf((char *)str, "Recording file: %s", (char *)REC_WAVE_NAME); BSP_LCD_ClearStringLine(4); BSP_LCD_DisplayStringAtLine(4, str); BSP_LCD_SetTextColor(LCD_COLOR_CYAN); sprintf((char *)str, "Sample rate : %d Hz", (int)DEFAULT_AUDIO_IN_FREQ); BSP_LCD_ClearStringLine(6); BSP_LCD_DisplayStringAtLine(6, str); sprintf((char *)str, "Channels number : %d", (int)DEFAULT_AUDIO_IN_CHANNEL_NBR); BSP_LCD_ClearStringLine(7); BSP_LCD_DisplayStringAtLine(7, str); sprintf((char *)str, "Volume : %d ", (int)uwVolume); BSP_LCD_ClearStringLine(7); BSP_LCD_DisplayStringAtLine(7, str); sprintf((char *)str, "File Size :"); BSP_LCD_ClearStringLine(8); BSP_LCD_DisplayStringAtLine(8, str); AUDIO_REC_DisplayButtons(); BSP_LCD_DisplayStringAt(250, LINE(14), (uint8_t *)" [RECORD]", LEFT_MODE); { if(byteswritten != 0) { BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR); BSP_AUDIO_IN_Record((uint16_t*)&BufferCtl.pdm_buff[0], AUDIO_IN_PDM_BUFFER_SIZE); BufferCtl.fptr = byteswritten; BufferCtl.pcm_ptr = 0; BufferCtl.offset = 0; BufferCtl.wr_state = BUFFER_EMPTY; return AUDIO_ERROR_NONE; } } } } return AUDIO_ERROR_IO; }
/** * @brief Update the recorded data. * @param None * @retval None */ void WaveRecorderProcess(void) { /* Current size of the recorded buffer */ uint32_t byteswritten = 0; WaveCounter = 0; LEDsState = LEDS_OFF; /* Remove Wave file if it exists on USB Flash Disk */ f_unlink(REC_WAVE_NAME); /* Open the file to write on it */ if((AppliState == APPLICATION_IDLE) || (f_open(&WavFile, REC_WAVE_NAME, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)) { while(1) { /* Toggle LED5 in infinite loop to signal that: USB Flash Disk is not connected/removed or an issue has occurred when creating/opening Wave file */ BSP_LED_Toggle(LED5); } } else { WaveRecStatus = 1; } /* Initialize header file */ WavProcess_EncInit(DEFAULT_AUDIO_IN_FREQ, pHeaderBuff); /* Write the header Wave */ f_write(&WavFile, pHeaderBuff, 44, (void *)&byteswritten); /* Increment the Wave counter */ BufferCtl.fptr = byteswritten; BufferCtl.offset = BUFFER_OFFSET_NONE; BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR); BSP_AUDIO_IN_Record((uint16_t*)&InternalBuffer[0], INTERNAL_BUFF_SIZE); /* Reset the time recording base variable */ TimeRecBase = 0; ITCounter = 0; LEDsState = LED3_TOGGLE; while(AppliState != APPLICATION_IDLE) { /* Wait for the recording time */ if(TimeRecBase <= DEFAULT_TIME_REC) { /* Check if there are Data to write in Usb Key */ if(AUDIODataReady == 1) { /* write buffer in file */ res = f_write(&WavFile, (uint8_t*)(WrBuffer+AUDIOBuffOffset), WR_BUFFER_SIZE, (void*)&byteswritten); if(res != FR_OK) { Error_Handler(); } BufferCtl.fptr += byteswritten; AUDIODataReady = 0; } /* User button pressed */ if(CmdIndex != CMD_RECORD) { /* Stop Audio Recording */ WaveRecorderStop(); /* Switch Command Index to Play */ CmdIndex = CMD_PLAY; /* Toggoling LED6 to signal Play */ LEDsState = LED6_TOGGLE; break; } } else /* End of recording time DEFAULT_TIME_REC */ { /* Stop Audio Recording */ WaveRecorderStop(); /* Change Command Index to Stop */ CmdIndex = CMD_STOP; /* Toggoling LED4 to signal Stop */ LEDsState = LED4_TOGGLE; AUDIODataReady = 0; break; } } /* Update the data length in the header of the recorded Wave */ f_lseek(&WavFile, 0); /* Parse the wav file header and extract required information */ WavProcess_HeaderUpdate(pHeaderBuff, &WaveFormat); f_write(&WavFile, pHeaderBuff, 44, (void*)&byteswritten); /* Close file and unmount MyFilesystem */ f_close (&WavFile); f_mount(NULL, 0, 1); /* Change Command Index to Play */ CmdIndex = CMD_PLAY; }
/** * @brief Test Audio Hardware. * The main objective of this test is to check the hardware connection of the * Audio peripheral. * @param None * @retval None */ void AudioRecord_Test(void) { BufferCtl.offset = BUFFER_OFFSET_NONE; if(BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) != AUDIO_OK) { /* Record Error */ Error_Handler(); } /* Turn ON LED3: start record */ BSP_LED_On(LED3); /* Start the record */ if (BSP_AUDIO_IN_Record((uint16_t*)&InternalBuffer[0], INTERNAL_BUFF_SIZE) != AUDIO_OK) { /* Record Error */ Error_Handler(); } BufferCtl.fptr = 0; AUDIODataReady = 0; /* Wait for the data to be ready with PCM form */ while (AUDIODataReady != 2) { if(BufferCtl.offset == BUFFER_OFFSET_HALF) { /* PDM to PCM data convert */ BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[0], (uint16_t*)&RecBuf[0]); /* Copy PCM data in internal buffer */ memcpy((uint16_t*)&WrBuffer[ITCounter * (PCM_OUT_SIZE*2)], RecBuf, PCM_OUT_SIZE*4); BufferCtl.offset = BUFFER_OFFSET_NONE; if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*4))-1) { AUDIODataReady = 1; AUDIOBuffOffset = 0; ITCounter++; } else if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1) { AUDIODataReady = 2; AUDIOBuffOffset = WR_BUFFER_SIZE/2; ITCounter = 0; } else { ITCounter++; } } if(BufferCtl.offset == BUFFER_OFFSET_FULL) { /* PDM to PCM data convert */ BSP_AUDIO_IN_PDMToPCM((uint16_t*)&InternalBuffer[INTERNAL_BUFF_SIZE/2], (uint16_t*)&RecBuf[0]); /* Copy PCM data in internal buffer */ memcpy((uint16_t*)&WrBuffer[ITCounter * (PCM_OUT_SIZE*2)], RecBuf, PCM_OUT_SIZE*4); BufferCtl.offset = BUFFER_OFFSET_NONE; if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*4))-1) { AUDIODataReady = 1; AUDIOBuffOffset = 0; ITCounter++; } else if(ITCounter == (WR_BUFFER_SIZE/(PCM_OUT_SIZE*2))-1) { AUDIODataReady = 2; AUDIOBuffOffset = WR_BUFFER_SIZE/2; ITCounter = 0; } else { ITCounter++; } } }; /* Stop audio record */ if (BSP_AUDIO_IN_Stop() != AUDIO_OK) { /* Record Error */ Error_Handler(); } /* Turn OFF LED3: record stopped */ BSP_LED_Off(LED3); /* Turn ON LED6: play recorded file */ BSP_LED_On(LED6); /* Play in the loop the recorded file */ /* Set variable to indicate play from record buffer */ AudioTest = 1; /* Set variable used to stop player before starting */ UserPressButton = 0; /* Initialize audio IN at REC_FREQ */ BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_AUTO, 70, DEFAULT_AUDIO_IN_FREQ); /* Set the total number of data to be played */ AudioTotalSize = AUDIODATA_SIZE * WR_BUFFER_SIZE; /* Update the remaining number of data to be played */ AudioRemSize = 0; /* Update the WrBuffer audio pointer position */ CurrentPos = (uint16_t *)(WrBuffer); /* Play the recorded buffer */ BSP_AUDIO_OUT_Play(WrBuffer , AudioTotalSize); while(!UserPressButton) { } /* Stop Player before close Test */ if (BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW) != AUDIO_OK) { /* Audio Stop error */ Error_Handler(); } }
/** * @brief Audio Play demo * @param None * @retval None */ void AudioRec_demo (void) { uint16_t NbRecord_done = 0; uint8_t FreqStr[256] = {0}; AudioRec_State = REC_NONE_STATE; buffer_ctl.rec_length = 0; /* Initialize AudioRecFullBuff at the address of the audio_play reader */ AudioRecFullBuff_addr = AUDIO_REC_START_ADDR; AudioRec_SetHint(); #ifdef JOYSTICK /* Initialize Joystick */ if (BSP_JOY_Init(JOY_MODE_GPIO) != IO_OK) { BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)"ERROR", CENTER_MODE); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 80, (uint8_t *)"Joystick cannot be initialized", CENTER_MODE); } #endif /* Initialize Audio Recorder */ if (BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) == AUDIO_OK) { AudioRec_State = REC_RESET_STATE; BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)" AUDIO RECORD INIT OK ", CENTER_MODE); } else { AudioRec_State = REC_ERROR_STATE; BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)" AUDIO RECORD INIT FAIL", CENTER_MODE); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 80, (uint8_t *)" Try to reset board ", CENTER_MODE); } /* Infinite loop */ while (buffer_ctl.rec_length < AUDIO_REC_TOTAL_SIZE) { BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_BLUE); if (buffer_ctl.it_state == TRANSFER_HALF) { /* PDM to PCM data convert */ BSP_AUDIO_IN_PDMToPCM((uint16_t*)&buffer_ctl.pdm_buff[0], &buffer_ctl.pcm_buff[buffer_ctl.pcm_ptr]); buffer_ctl.pcm_ptr+= AUDIO_IN_PDM_BUFFER_SIZE/4/2; if(buffer_ctl.pcm_ptr == AUDIO_IN_PCM_BUFFER_SIZE/2) { buffer_ctl.wr_state = BUFFER_FULL; buffer_ctl.offset = 0; } if(buffer_ctl.pcm_ptr >= AUDIO_IN_PCM_BUFFER_SIZE) { buffer_ctl.wr_state = BUFFER_FULL; buffer_ctl.offset = AUDIO_IN_PCM_BUFFER_SIZE/2; buffer_ctl.pcm_ptr = 0; } buffer_ctl.it_state = TRANSFER_NONE; } if (buffer_ctl.it_state == TRANSFER_FULL) { /* PDM to PCM data convert */ if (BSP_AUDIO_IN_PDMToPCM((uint16_t*)&buffer_ctl.pdm_buff[INTERNAL_BUFF_SIZE/2], &buffer_ctl.pcm_buff[buffer_ctl.pcm_ptr]) == 0) { buffer_ctl.pcm_ptr+= AUDIO_IN_PDM_BUFFER_SIZE/4/2; if(buffer_ctl.pcm_ptr == AUDIO_IN_PCM_BUFFER_SIZE/2) { buffer_ctl.wr_state = BUFFER_FULL; buffer_ctl.offset = 0; } if(buffer_ctl.pcm_ptr >= AUDIO_IN_PCM_BUFFER_SIZE) { buffer_ctl.wr_state = BUFFER_FULL; buffer_ctl.offset = AUDIO_IN_PCM_BUFFER_SIZE/2; buffer_ctl.pcm_ptr = 0; } } buffer_ctl.it_state = TRANSFER_NONE; NbRecord_done++; } /* PCM buffer is full, copy it into the record_file */ if (buffer_ctl.wr_state == BUFFER_FULL) { memcpy((uint32_t *)AudioRecFullBuff_addr, (uint8_t*)(buffer_ctl.pcm_buff + buffer_ctl.offset), AUDIO_IN_PCM_BUFFER_SIZE); AudioRecFullBuff_addr += AUDIO_IN_PCM_BUFFER_SIZE; buffer_ctl.rec_length += AUDIO_IN_PCM_BUFFER_SIZE; buffer_ctl.wr_state = BUFFER_EMPTY; } #ifdef JOYSTICK /* Get the Joystick State */ JoyState = BSP_JOY_GetState(); switch (JoyState) { case JOY_SEL: #endif if (AudioRec_State == REC_RESET_STATE) { /* Display the state on the screen */ BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_BLUE); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 80, (uint8_t *)" RECORDING... ", CENTER_MODE); /* Start Recording */ buffer_ctl.rec_length = 0; buffer_ctl.wr_state = BUFFER_EMPTY; buffer_ctl.it_state = TRANSFER_NONE; BSP_AUDIO_IN_Record((uint16_t*)&buffer_ctl.pdm_buff[0], INTERNAL_BUFF_SIZE); AudioRec_State = RECORD_ONGOING; } #ifdef JOYSTICK break; default: break; } #endif if (CheckForUserInput() > 0) { /* Stop recorder and exit the test (go to next test) */ BSP_AUDIO_IN_Stop(); return; } } /* Stop recorder once buffer_ctl.rec_length < AUDIO_REC_TOTAL_SIZE*/ BSP_AUDIO_IN_Stop(); BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_BLUE); sprintf((char*)FreqStr, "RECORDING DONE, %d frames, START PLAYBACK", NbRecord_done); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 65, (uint8_t *)FreqStr, CENTER_MODE); NbRecord_done = buffer_ctl.rec_length / (DEFAULT_AUDIO_IN_FREQ * DEFAULT_AUDIO_IN_CHANNEL_NBR * 2); sprintf((char*)FreqStr, "Elapsed_time: %d frames", NbRecord_done); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 45, (uint8_t *)FreqStr, CENTER_MODE); /* -----------Start Playback -------------- */ /* Initialize audio IN at REC_FREQ*/ if(BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, 95, DEFAULT_AUDIO_IN_FREQ/2) == 0) { BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)" AUDIO CODEC OK ", CENTER_MODE); } else { BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)" AUDIO CODEC FAIL ", CENTER_MODE); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 80, (uint8_t *)" Try to reset board ", CENTER_MODE); } /* Play the recorded buffer*/ if(AUDIO_Play_Start((uint32_t *)AUDIO_REC_START_ADDR, (uint32_t)AUDIO_REC_TOTAL_SIZE) == 0) { BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)" AUDIO PLAYBACK OK ", CENTER_MODE); } else { BSP_LCD_SetBackColor(LCD_COLOR_WHITE); BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)" AUDIO PLAYBACK FAIL ", CENTER_MODE); } BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 25, (uint8_t *)"PLAYBACK DONE", CENTER_MODE); while (1) { /* Toggle LED4 */ BSP_LED_Toggle(LED4); /* Insert 100 ms delay */ HAL_Delay(100); if (CheckForUserInput() > 0) { /* Set LED4 */ BSP_LED_On(LED4); /* Stop recorder */ BSP_AUDIO_IN_Stop(); /* Stop Player before close Test */ BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); return; } } }