AudioRecord
Dependencies: STM32L4xx_HAL_Driver CMSIS_DSP_401
audio_record.c
- Committer:
- EricLew
- Date:
- 2015-11-23
- Revision:
- 0:d4e5ad7ad71c
- Child:
- 1:1ae4b642c533
File content as of revision 0:d4e5ad7ad71c:
/* 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 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Buffer containing the PCM samples coming from the microphone */ static uint16_t RecordBuffer[RECORD_BUFFER_SIZE]; /* Buffer used to stream the recorded PCM samples towards the audio codec. */ static uint16_t PlaybackBuffer[RECORD_BUFFER_SIZE*2]; #define NB_SAMPLES_RATE 7 static uint32_t SamplesRates[NB_SAMPLES_RATE] = {BSP_AUDIO_FREQUENCY_48K, BSP_AUDIO_FREQUENCY_44K, BSP_AUDIO_FREQUENCY_32K, BSP_AUDIO_FREQUENCY_22K, BSP_AUDIO_FREQUENCY_16K, BSP_AUDIO_FREQUENCY_11K, BSP_AUDIO_FREQUENCY_8K}; /* 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 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(); } /* PCM samples recording loop */ while (AudioRecordExit != SET) { /* 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(); } /* Turn OFF LED5: stop record */ BSP_LED_Off(LED5); /* Reset AudioRecordExit flag */ AudioRecordExit = 0; /* 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; case BSP_AUDIO_FREQUENCY_44K: BSP_LCD_GLASS_DisplayString((uint8_t *)"44000"); break; case BSP_AUDIO_FREQUENCY_32K: BSP_LCD_GLASS_DisplayString((uint8_t *)"32000"); break; case BSP_AUDIO_FREQUENCY_22K: BSP_LCD_GLASS_DisplayString((uint8_t *)"22000"); break; case BSP_AUDIO_FREQUENCY_16K: BSP_LCD_GLASS_DisplayString((uint8_t *)"16000"); break; case BSP_AUDIO_FREQUENCY_11K: BSP_LCD_GLASS_DisplayString((uint8_t *)"11000"); break; case BSP_AUDIO_FREQUENCY_8K: BSP_LCD_GLASS_DisplayString((uint8_t *)"8000"); break; default: 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****/