AudioRecord

Dependencies:   STM32L4xx_HAL_Driver CMSIS_DSP_401

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****/
+