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)!!
Committer:
Daniel_Lee
Date:
Fri Jan 31 07:55:52 2020 +0000
Revision:
3:5809b93aa2b7
Parent:
2:897f21ef78e3
Added mbed_app.json for baudrate 115200

Who changed what in which revision?

UserRevisionLine numberNew contents of line
arostm 0:adbe8684bb7c 1 #include "mbed.h"
Daniel_Lee 2:897f21ef78e3 2 #include "stm32f413h_discovery_audio.h"
Daniel_Lee 2:897f21ef78e3 3
Daniel_Lee 2:897f21ef78e3 4 static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize);
Daniel_Lee 2:897f21ef78e3 5
Daniel_Lee 2:897f21ef78e3 6 #define SCRATCH_BUFF_SIZE 1024
Daniel_Lee 2:897f21ef78e3 7 #define RECORD_BUFFER_SIZE 4096
Daniel_Lee 2:897f21ef78e3 8
Daniel_Lee 2:897f21ef78e3 9 typedef enum {
Daniel_Lee 2:897f21ef78e3 10 BUFFER_OFFSET_NONE = 0,
Daniel_Lee 2:897f21ef78e3 11 BUFFER_OFFSET_HALF = 1,
Daniel_Lee 2:897f21ef78e3 12 BUFFER_OFFSET_FULL = 2,
Daniel_Lee 2:897f21ef78e3 13 } BUFFER_StateTypeDef;
Daniel_Lee 2:897f21ef78e3 14
Daniel_Lee 2:897f21ef78e3 15 volatile uint32_t audio_rec_buffer_state = BUFFER_OFFSET_NONE;
Daniel_Lee 2:897f21ef78e3 16 int32_t Scratch[SCRATCH_BUFF_SIZE];
Daniel_Lee 2:897f21ef78e3 17
Daniel_Lee 2:897f21ef78e3 18 /* Buffer containing the PCM samples coming from the microphone */
Daniel_Lee 2:897f21ef78e3 19 int16_t RecordBuffer[RECORD_BUFFER_SIZE];
Daniel_Lee 2:897f21ef78e3 20
Daniel_Lee 2:897f21ef78e3 21 /* Buffer used to stream the recorded PCM samples towards the audio codec. */
Daniel_Lee 2:897f21ef78e3 22 int16_t PlaybackBuffer[RECORD_BUFFER_SIZE];
bcostm 1:1025d8dcf8ec 23
arostm 0:adbe8684bb7c 24 int main()
arostm 0:adbe8684bb7c 25 {
Daniel_Lee 2:897f21ef78e3 26 printf("\n\nAUDIO LOOPBACK EXAMPLE FOR DISCO-F413H START:\n");
Daniel_Lee 2:897f21ef78e3 27
Daniel_Lee 2:897f21ef78e3 28 /* Initialize Audio Recorder with 2 microphone of DISCO-F413H to be used */
Daniel_Lee 2:897f21ef78e3 29 if (BSP_AUDIO_IN_Init(DEFAULT_AUDIO_IN_FREQ, DEFAULT_AUDIO_IN_BIT_RESOLUTION, DEFAULT_AUDIO_IN_CHANNEL_NBR) == AUDIO_ERROR) {
Daniel_Lee 2:897f21ef78e3 30 printf("BSP_AUDIO_IN_Init error\n");
Daniel_Lee 2:897f21ef78e3 31 }
Daniel_Lee 2:897f21ef78e3 32 printf("Audio init done..\n");
arostm 0:adbe8684bb7c 33
Daniel_Lee 2:897f21ef78e3 34 /* Allocate scratch buffers */
Daniel_Lee 2:897f21ef78e3 35 if (BSP_AUDIO_IN_AllocScratch (Scratch, SCRATCH_BUFF_SIZE) == AUDIO_ERROR) {
Daniel_Lee 2:897f21ef78e3 36 printf("BSP_AUDIO_IN_AllocScratch error\n");
Daniel_Lee 2:897f21ef78e3 37 }
Daniel_Lee 2:897f21ef78e3 38 printf("Audio buffer init done..\n");
Daniel_Lee 2:897f21ef78e3 39
Daniel_Lee 2:897f21ef78e3 40 /* Start Recording */
Daniel_Lee 2:897f21ef78e3 41 if (BSP_AUDIO_IN_Record((uint16_t*)&RecordBuffer[0], RECORD_BUFFER_SIZE) == AUDIO_ERROR) {
Daniel_Lee 2:897f21ef78e3 42 printf("BSP_AUDIO_IN_Record error\n");
Daniel_Lee 2:897f21ef78e3 43 }
Daniel_Lee 2:897f21ef78e3 44 printf("Audio in(Microphone U16, U17) recording start..\n");
bcostm 1:1025d8dcf8ec 45
Daniel_Lee 2:897f21ef78e3 46 /* Initialize the audio device*/
Daniel_Lee 2:897f21ef78e3 47 if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, 50, DEFAULT_AUDIO_IN_FREQ) == AUDIO_ERROR) {
Daniel_Lee 2:897f21ef78e3 48 printf("BSP_AUDIO_OUT_Init error\n");
Daniel_Lee 2:897f21ef78e3 49 }
Daniel_Lee 2:897f21ef78e3 50 printf("Audio out init done..\n");
Daniel_Lee 2:897f21ef78e3 51
Daniel_Lee 2:897f21ef78e3 52 /* Play the recorded buffer */
Daniel_Lee 2:897f21ef78e3 53 if (BSP_AUDIO_OUT_Play((uint16_t *) &PlaybackBuffer[0], 2*RECORD_BUFFER_SIZE) == AUDIO_ERROR) {
Daniel_Lee 2:897f21ef78e3 54 printf("BSP_AUDIO_OUT_Play error\n");
Daniel_Lee 2:897f21ef78e3 55 }
Daniel_Lee 2:897f21ef78e3 56 printf("Start loopback (Mic -> Audio Jack)!!\n");
Daniel_Lee 2:897f21ef78e3 57
Daniel_Lee 2:897f21ef78e3 58 audio_rec_buffer_state = BUFFER_OFFSET_NONE;
bcostm 1:1025d8dcf8ec 59
Daniel_Lee 2:897f21ef78e3 60 while (1) {
Daniel_Lee 2:897f21ef78e3 61 /* 1st or 2nd half of the record buffer ready for being copied to the playback buffer */
Daniel_Lee 2:897f21ef78e3 62 if(audio_rec_buffer_state != BUFFER_OFFSET_NONE) {
Daniel_Lee 2:897f21ef78e3 63 /* Copy half of the record buffer to the playback buffer */
Daniel_Lee 2:897f21ef78e3 64 if(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
Daniel_Lee 2:897f21ef78e3 65 CopyBuffer(&PlaybackBuffer[0], &RecordBuffer[0], RECORD_BUFFER_SIZE/2);
Daniel_Lee 2:897f21ef78e3 66
Daniel_Lee 2:897f21ef78e3 67 } else { /* if(audio_rec_buffer_state == BUFFER_OFFSET_FULL)*/
Daniel_Lee 2:897f21ef78e3 68 CopyBuffer(&PlaybackBuffer[RECORD_BUFFER_SIZE/2], &RecordBuffer[RECORD_BUFFER_SIZE/2], RECORD_BUFFER_SIZE/2);
Daniel_Lee 2:897f21ef78e3 69 }
Daniel_Lee 2:897f21ef78e3 70
Daniel_Lee 2:897f21ef78e3 71 /* Wait for next data */
Daniel_Lee 2:897f21ef78e3 72 audio_rec_buffer_state = BUFFER_OFFSET_NONE;
Daniel_Lee 2:897f21ef78e3 73 }
arostm 0:adbe8684bb7c 74 }
arostm 0:adbe8684bb7c 75 }
Daniel_Lee 2:897f21ef78e3 76
Daniel_Lee 2:897f21ef78e3 77 /*-------------------------------------------------------------------------------------
Daniel_Lee 2:897f21ef78e3 78 Callbacks implementation:
Daniel_Lee 2:897f21ef78e3 79 the callbacks API are defined __weak in the stm32f413h_discovery_audio.c file
Daniel_Lee 2:897f21ef78e3 80 and their implementation should be done in the user code if they are needed.
Daniel_Lee 2:897f21ef78e3 81 Below some examples of callback implementations.
Daniel_Lee 2:897f21ef78e3 82 -------------------------------------------------------------------------------------*/
Daniel_Lee 2:897f21ef78e3 83 /**
Daniel_Lee 2:897f21ef78e3 84 * @brief Manages the DMA Transfer complete interrupt.
Daniel_Lee 2:897f21ef78e3 85 * @param None
Daniel_Lee 2:897f21ef78e3 86 * @retval None
Daniel_Lee 2:897f21ef78e3 87 */
Daniel_Lee 2:897f21ef78e3 88 void BSP_AUDIO_IN_TransferComplete_CallBack(void)
Daniel_Lee 2:897f21ef78e3 89 {
Daniel_Lee 2:897f21ef78e3 90 audio_rec_buffer_state = BUFFER_OFFSET_FULL;
Daniel_Lee 2:897f21ef78e3 91 }
Daniel_Lee 2:897f21ef78e3 92
Daniel_Lee 2:897f21ef78e3 93 /**
Daniel_Lee 2:897f21ef78e3 94 * @brief Manages the DMA Half Transfer complete interrupt.
Daniel_Lee 2:897f21ef78e3 95 * @param None
Daniel_Lee 2:897f21ef78e3 96 * @retval None
Daniel_Lee 2:897f21ef78e3 97 */
Daniel_Lee 2:897f21ef78e3 98 void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
Daniel_Lee 2:897f21ef78e3 99 {
Daniel_Lee 2:897f21ef78e3 100 audio_rec_buffer_state = BUFFER_OFFSET_HALF;
Daniel_Lee 2:897f21ef78e3 101 }
Daniel_Lee 2:897f21ef78e3 102
Daniel_Lee 2:897f21ef78e3 103 /**
Daniel_Lee 2:897f21ef78e3 104 * @brief Audio IN Error callback function.
Daniel_Lee 2:897f21ef78e3 105 * @param None
Daniel_Lee 2:897f21ef78e3 106 * @retval None
Daniel_Lee 2:897f21ef78e3 107 */
Daniel_Lee 2:897f21ef78e3 108 void BSP_AUDIO_IN_Error_CallBack(void)
Daniel_Lee 2:897f21ef78e3 109 {
Daniel_Lee 2:897f21ef78e3 110 printf("BSP_AUDIO_IN_Error_CallBack\n");
Daniel_Lee 2:897f21ef78e3 111 }
Daniel_Lee 2:897f21ef78e3 112
Daniel_Lee 2:897f21ef78e3 113
Daniel_Lee 2:897f21ef78e3 114 /**
Daniel_Lee 2:897f21ef78e3 115 * @brief Copy content of pbuffer2 to pbuffer1
Daniel_Lee 2:897f21ef78e3 116 * @param1 BufferOut
Daniel_Lee 2:897f21ef78e3 117 * @param2 BufferIn
Daniel_Lee 2:897f21ef78e3 118 * @param3 Size
Daniel_Lee 2:897f21ef78e3 119 * @retval None
Daniel_Lee 2:897f21ef78e3 120 */
Daniel_Lee 2:897f21ef78e3 121 static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize)
Daniel_Lee 2:897f21ef78e3 122 {
Daniel_Lee 2:897f21ef78e3 123 uint32_t i = 0;
Daniel_Lee 2:897f21ef78e3 124 for(i = 0; i < BufferSize; i++) {
Daniel_Lee 2:897f21ef78e3 125 pbuffer1[i] = pbuffer2[i];
Daniel_Lee 2:897f21ef78e3 126 }
Daniel_Lee 2:897f21ef78e3 127 }