AudioRecord

Dependencies:   STM32L4xx_HAL_Driver CMSIS_DSP_401

audio_record.c

Committer:
EricLew
Date:
2015-11-26
Revision:
3:ec7e3c37fe80
Parent:
1:1ae4b642c533

File content as of revision 3:ec7e3c37fe80:

/* 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 uint32_t PlaybackBuffer[2048]; //PLAYBACK BUFFER FOR SAMPLE#0
static uint32_t PlaybackBuffer1[2048];//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;
    
//  uint32_t fftLenReal=4096;
//  uint32_t ifftFlagR=0;
//  uint32_t bitReverseFlag=0;
//  
//  arm_rfft_init_q31   (arm_rfft_instance_q31, fftLenReal, ifftFlagR, bitReverseFlag)  
//  
//  
//  arm_rfft_q31    (   const arm_rfft_instance_q31 *   S, &PlaybackBuffer,
//q31_t *   pDst 
//) 
//  
    
    
    /* 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****/