AudioRecord
Dependencies: STM32L4xx_HAL_Driver CMSIS_DSP_401
audio_record.c
- Committer:
- EricLew
- Date:
- 2015-11-25
- Revision:
- 1:1ae4b642c533
- Parent:
- 0:d4e5ad7ad71c
- Child:
- 3:ec7e3c37fe80
File content as of revision 1:1ae4b642c533:
/* Includes ------------------------------------------------------------------*/ #include "main.h" /* Variable indicating which audio demo is currently running (playback v.s. record) */ Audio_DemoTypeDef AudioDemo = AUDIO_DEMO_NONE; /* Private typedef -----------------------------------------------------------*/ typedef enum { BUFFER_OFFSET_NONE = 0, BUFFER_OFFSET_HALF, BUFFER_OFFSET_FULL, } RecordBufferOffset_Typedef; /* Private define ------------------------------------------------------------*/ /* Size (in bytes) of the buffer containing the recorded PCM samples */ #define RECORD_BUFFER_SIZE (uint32_t)1024 //BUFFER SIZE IS THE SAME FOR BOTH RECORDINGS /* Buffer containing the PCM samples coming from the microphone */ static uint32_t RecordBuffer[RECORD_BUFFER_SIZE]; //RECORDING BUFFER FOR SAMPLE #0 static uint32_t RecordBuffer1[RECORD_BUFFER_SIZE];//RECORDING BUFFER FOR SAMPLE #1 /* Buffer used to stream the recorded PCM samples towards the audio codec. */ static uint16_t PlaybackBuffer[RECORD_BUFFER_SIZE*2]; //PLAYBACK BUFFER FOR SAMPLE#0 static uint16_t PlaybackBuffer1[RECORD_BUFFER_SIZE*2];//PLAYBACK BUFFER FOR SAMPLE#1 #define NB_SAMPLES_RATE 7 static uint32_t SamplesRates[NB_SAMPLES_RATE] = {BSP_AUDIO_FREQUENCY_48K}; //SAMPLE RATE IS THE SAME /* Information indicating which part of the recorded buffer is ready for audio loopback */ static RecordBufferOffset_Typedef RecordBufferOffset = BUFFER_OFFSET_NONE; /* Private function prototypes -----------------------------------------------*/ /* Display actuyel record sample rate */ static void SampleRateDisplay(uint8_t SampleRate); /* Record sample rate selection */ static void SampleRateSelection(void); /* Audio recorder callback functions */ static void AudioRecord_TransferComplete_CallBack(void); static void AudioRecord_HalfTransfer_CallBack(void); static void AudioRecord_Error_CallBack(void); /* Private functions ---------------------------------------------------------*/ /** * @brief Setup and start audio recording in loopback mode * @param None * @retval None */ void AudioRecord_demo(void) { /* Indicates which part of the payback buffer must be updated */ uint8_t transfer_range = 0; /* Flag indicating whether the audio codec has already been initialized */ uint32_t audio_loop_back_init = RESET ; /* Audio record demo is running */ AudioDemo = AUDIO_DEMO_RECORD; /* Turn off green LED5 */ BSP_LED_Off(LED5); /* Initialize record buffer offset */ RecordBufferOffset = BUFFER_OFFSET_NONE; /* Select the audio record sample rate */ SampleRateSelection(); //INITIALIZE RECORDING #0 /* Initialize audio input */ if (BSP_AUDIO_IN_Init(SamplesRates[SampleRateIndex], DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) != AUDIO_OK) { /* Record Error */ Error_Handler(); } /* Set Callback function pointers */ BSP_AUDIO_IN_RegisterCallbacks(AudioRecord_Error_CallBack, AudioRecord_HalfTransfer_CallBack, AudioRecord_TransferComplete_CallBack); /* Start the audio record */ if (BSP_AUDIO_IN_Record((uint16_t*)&RecordBuffer[0], RECORD_BUFFER_SIZE) != AUDIO_OK) { Error_Handler(); } uint32_t counter=0; //COUNTER IS REGISTER R4 /* PCM samples recording loop */ while (AudioRecordExit != SET) { if (counter==10000000) //Approximately 3 seconds of record time { AudioRecordExit=1; } else { counter=counter++; } /* 1st or 2nd half of the record buffer ready for being copied to the playback buffer */ if(RecordBufferOffset != BUFFER_OFFSET_NONE) { /* Copy half of the record buffer to the playback buffer */ if(RecordBufferOffset == BUFFER_OFFSET_HALF) { memcpy(&PlaybackBuffer[(RECORD_BUFFER_SIZE/2) * transfer_range], RecordBuffer, RECORD_BUFFER_SIZE); } else /* if(RecordBufferOffset == BUFFER_OFFSET_FULL)*/ { memcpy(&PlaybackBuffer[(RECORD_BUFFER_SIZE/2) * transfer_range], &RecordBuffer[RECORD_BUFFER_SIZE/2], RECORD_BUFFER_SIZE); } /* Wait for next data */ RecordBufferOffset = BUFFER_OFFSET_NONE; transfer_range = (transfer_range+1) % 4; } } /* Stop audio input */ if (BSP_AUDIO_IN_Stop() != AUDIO_OK) { Error_Handler(); } /* De-initialize audio input */ if (BSP_AUDIO_IN_DeInit() != AUDIO_OK) { Error_Handler(); } //END OF RECORDING #0 //INITIALIZE RECORDING #1 transfer_range = 0; /* Flag indicating whether the audio codec has already been initialized */ audio_loop_back_init = RESET ; /* Turn off green LED5 */ BSP_LED_Off(LED5); /* Initialize record buffer offset */ RecordBufferOffset = BUFFER_OFFSET_NONE; /* Initialize audio input */ if (BSP_AUDIO_IN_Init(SamplesRates[SampleRateIndex], DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) != AUDIO_OK) { /* Record Error */ Error_Handler(); } /* Set Callback function pointers */ BSP_AUDIO_IN_RegisterCallbacks(AudioRecord_Error_CallBack, AudioRecord_HalfTransfer_CallBack, AudioRecord_TransferComplete_CallBack); /* Start the audio record */ if (BSP_AUDIO_IN_Record((uint16_t*)&RecordBuffer1[0], RECORD_BUFFER_SIZE) != AUDIO_OK) { Error_Handler(); } AudioRecordExit = 0; //RESET AUDIO RECORD FLAG counter=0; //RESET COUNTER /* PCM samples recording loop */ //COPIED FROM ABOVE USE '1' WHEN REFERENCING VARIABLES while (AudioRecordExit != SET) { if (counter==10000000) //Approximately 3 seconds of record time { AudioRecordExit=1; //FLAG IS REGISTER R5 } else { counter=counter++; } /* 1st or 2nd half of the record buffer ready for being copied to the playback buffer */ if(RecordBufferOffset != BUFFER_OFFSET_NONE) { /* Copy half of the record buffer to the playback buffer */ if(RecordBufferOffset == BUFFER_OFFSET_HALF) { memcpy(&PlaybackBuffer1[(RECORD_BUFFER_SIZE/2) * transfer_range], RecordBuffer1, RECORD_BUFFER_SIZE); } else /* if(RecordBufferOffset == BUFFER_OFFSET_FULL)*/ { memcpy(&PlaybackBuffer1[(RECORD_BUFFER_SIZE/2) * transfer_range], &RecordBuffer1[RECORD_BUFFER_SIZE/2], RECORD_BUFFER_SIZE); } /* Wait for next data */ RecordBufferOffset = BUFFER_OFFSET_NONE; transfer_range = (transfer_range+1) % 4; } } /* Stop audio input */ if (BSP_AUDIO_IN_Stop() != AUDIO_OK) { Error_Handler(); } /* De-initialize audio input */ if (BSP_AUDIO_IN_DeInit() != AUDIO_OK) { Error_Handler(); } //END OF RECORDING #1 /* Turn OFF LED5: stop record */ BSP_LED_Off(LED5); /* Reset AudioRecordExit flag */ AudioRecordExit = 0; //COMPARISON ALGORITHM START /*arm_cfft_f32 ( const arm_cfft_instance_f32 * S, float32_t * p1, uint8_t ifftFlag, uint8_t bitReverseFlag ) */ /* Turn off green led */ AudioDemo = AUDIO_DEMO_NONE; } /** * @brief Display actual audio record sample rate on LCD * @param None * @retval None */ static void SampleRateDisplay(uint8_t SampleRate) { /* Clear the LCD glass */ BSP_LCD_GLASS_Clear(); /* Display actual audio record sample rate */ switch (SamplesRates[SampleRate]) { case BSP_AUDIO_FREQUENCY_48K: BSP_LCD_GLASS_DisplayString((uint8_t *)"48000"); break; } } /** * @brief Audio record sample rate selection * @param None * @retval None */ void SampleRateSelection(void) { /* Display actual audio record sample rate */ SampleRateDisplay(SampleRateIndex); /* Select audio record sample rate */ while (!AudioRecordSampleRateSelected) { if (AudioRecordSampleRateChange != 0) { SampleRateDisplay(SampleRateIndex); HAL_Delay(5); AudioRecordSampleRateChange = 0; } } AudioRecordSampleRateSelected = 0; } /** * @brief Callback function invoked when half of the PCM samples have been * DM Atransfered from the DFSDM channel. * @param None * @retval None */ void AudioRecord_TransferComplete_CallBack(void) { /* Toggle green LED */ BSP_LED_Toggle(LED5); RecordBufferOffset = BUFFER_OFFSET_FULL; } /** * @brief Callback function invoked when all the PCM samples have been * DMA transfered from the DFSDM channel. * @param None * @retval None */ void AudioRecord_HalfTransfer_CallBack(void) { RecordBufferOffset = BUFFER_OFFSET_HALF; } /** * @brief Callback function invoked when an error occured durint he DMA * transfer of the PCM samples from the DFSDM channel. * @param None * @retval None */ void AudioRecord_Error_CallBack(void) { /* Stop the program with an infinite loop */ Error_Handler(); } /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/