AudioRecord
Dependencies: STM32L4xx_HAL_Driver CMSIS_DSP_401
Diff: audio_record.c
- Revision:
- 0:d4e5ad7ad71c
- Child:
- 1:1ae4b642c533
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audio_record.c Mon Nov 23 19:37:13 2015 +0000 @@ -0,0 +1,267 @@ + + +/* 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****/ +