Initialized for DISCO_F413ZH audio example

Dependencies:   BSP_DISCO_F413ZH

This is a simple Audio loopback code for DISCO_F413ZH.

The base repository is https://os.mbed.com/teams/ST/code/BSP_DISCO_F413ZH/. I've added workaround patch for Audio-in and out(loopback) demo on DISCO_F413ZH board(Microphone U16, U17)

https://os.mbed.com/media/uploads/Daniel_Lee/img_9603.jpg

If you connect a 5x Mems microphone, the Audio-in path (U16 and U17) going to be automatically changed to 5x Mems microphone.

Testing

1. Import the application into your desktop

You can use Mbed CLI, Online Compiler, and Mbed Studio.

  • In case of Mbed CLI,

mbed import http://os.mbed.com/users/Daniel_Lee/code/DISCO_F413ZH-AUDIO-demo/

cd DISCO_F413ZH-AUDIO-demo
  • In case of Online Compiler and Mbed Studio, Please click 'Import into Compiler'

2. Compile and program

mbed compile -t <toolchain> -m <TARGET_BOARD>

(supported toolchains : GCC_ARM / ARM / IAR)

3. Download binary to a target board

4. Open a serial monitor on baudrate 115200 to see the output

AUDIO LOOPBACK EXAMPLE FOR DISCO-F413H START:
Audio init done..
Audio buffer init done..
Audio in(Microphone U16, U17) recording start..
Audio out init done..
Start loopback (Mic -> Audio Jack)!!

main.cpp

Committer:
Daniel_Lee
Date:
2020-01-31
Revision:
3:5809b93aa2b7
Parent:
2:897f21ef78e3

File content as of revision 3:5809b93aa2b7:

#include "mbed.h"
#include "stm32f413h_discovery_audio.h"

static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize);

#define SCRATCH_BUFF_SIZE  1024
#define RECORD_BUFFER_SIZE  4096

typedef enum {
    BUFFER_OFFSET_NONE = 0,
    BUFFER_OFFSET_HALF = 1,
    BUFFER_OFFSET_FULL = 2,
} BUFFER_StateTypeDef;

volatile uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
int32_t Scratch[SCRATCH_BUFF_SIZE];

/* Buffer containing the PCM samples coming from the microphone */
int16_t RecordBuffer[RECORD_BUFFER_SIZE];

/* Buffer used to stream the recorded PCM samples towards the audio codec. */
int16_t PlaybackBuffer[RECORD_BUFFER_SIZE];

int main()
{
    printf("\n\nAUDIO LOOPBACK EXAMPLE FOR DISCO-F413H START:\n");

    /* Initialize Audio Recorder with 2 microphone of DISCO-F413H to be used */
    if (BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) == AUDIO_ERROR) {
        printf("BSP_AUDIO_IN_Init error\n");
    }
    printf("Audio init done..\n");

    /* Allocate scratch buffers */
    if (BSP_AUDIO_IN_AllocScratch (Scratch, SCRATCH_BUFF_SIZE) == AUDIO_ERROR) {
        printf("BSP_AUDIO_IN_AllocScratch error\n");
    }
    printf("Audio buffer init done..\n");

    /* Start Recording */
    if (BSP_AUDIO_IN_Record((uint16_t*)&RecordBuffer[0], RECORD_BUFFER_SIZE) == AUDIO_ERROR) {
        printf("BSP_AUDIO_IN_Record error\n");
    }
    printf("Audio in(Microphone U16, U17) recording start..\n");

    /* Initialize the audio device*/
    if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, 50, DEFAULT_AUDIO_IN_FREQ) == AUDIO_ERROR) {
        printf("BSP_AUDIO_OUT_Init error\n");
    }
    printf("Audio out init done..\n");
 
    /* Play the recorded buffer */
    if (BSP_AUDIO_OUT_Play((uint16_t *) &PlaybackBuffer[0], 2*RECORD_BUFFER_SIZE) == AUDIO_ERROR) {
        printf("BSP_AUDIO_OUT_Play error\n");
    }
    printf("Start loopback (Mic -> Audio Jack)!!\n");
    
    audio_rec_buffer_state = BUFFER_OFFSET_NONE;

    while (1) {
        /* 1st or 2nd half of the record buffer ready for being copied to the playback buffer */
        if(audio_rec_buffer_state != BUFFER_OFFSET_NONE) {
            /* Copy half of the record buffer to the playback buffer */
            if(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
                CopyBuffer(&PlaybackBuffer[0], &RecordBuffer[0], RECORD_BUFFER_SIZE/2);
                
            } else { /* if(audio_rec_buffer_state == BUFFER_OFFSET_FULL)*/
                CopyBuffer(&PlaybackBuffer[RECORD_BUFFER_SIZE/2], &RecordBuffer[RECORD_BUFFER_SIZE/2], RECORD_BUFFER_SIZE/2);
            }

            /* Wait for next data */
            audio_rec_buffer_state = BUFFER_OFFSET_NONE;
        }
    }
}

/*-------------------------------------------------------------------------------------
       Callbacks implementation:
           the callbacks API are defined __weak in the stm32f413h_discovery_audio.c file
           and their implementation should be done in the user code if they are needed.
           Below some examples of callback implementations.
  -------------------------------------------------------------------------------------*/
/**
  * @brief Manages the DMA Transfer complete interrupt.
  * @param None
  * @retval None
  */
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
    audio_rec_buffer_state = BUFFER_OFFSET_FULL;
}

/**
  * @brief  Manages the DMA Half Transfer complete interrupt.
  * @param  None
  * @retval None
  */
void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
    audio_rec_buffer_state = BUFFER_OFFSET_HALF;
}

/**
  * @brief  Audio IN Error callback function.
  * @param  None
  * @retval None
  */
void BSP_AUDIO_IN_Error_CallBack(void)
{
    printf("BSP_AUDIO_IN_Error_CallBack\n");
}


/**
  * @brief  Copy content of pbuffer2 to pbuffer1
  * @param1 BufferOut
  * @param2 BufferIn
  * @param3 Size
  * @retval None
  */
static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize)
{
    uint32_t i = 0;
    for(i = 0; i < BufferSize; i++) {
        pbuffer1[i] = pbuffer2[i];
    }
}