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