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)
If you connect a 5x Mems microphone, the Audio-in path (U16 and U17) going to be automatically changed to 5x Mems microphone.
- For more information, please see Audio input mechanism and API description
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@3:5809b93aa2b7, 2020-01-31 (annotated)
- 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?
User | Revision | Line number | New 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 | } |