Several examples run on only mbed-os5.13.0 (not 5.14.0)
Dependencies: BD_SD_DISCO_F769NI BSP_DISCO_F769NI LCD_DISCO_F769NI TS_DISCO_F769NI USBHost_F769NI
z_example/8_audio.cpp@3:35ac9ee7d2d6, 2019-08-07 (annotated)
- Committer:
- kenjiArai
- Date:
- Wed Aug 07 05:39:01 2019 +0000
- Revision:
- 3:35ac9ee7d2d6
1st trial revision (Not finalized yet)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kenjiArai | 3:35ac9ee7d2d6 | 1 | // Original |
kenjiArai | 3:35ac9ee7d2d6 | 2 | // https://os.mbed.com/teams/ST/code/DISCO-F769NI_AUDIO_demo/ |
kenjiArai | 3:35ac9ee7d2d6 | 3 | // |
kenjiArai | 3:35ac9ee7d2d6 | 4 | // Modified by K.Arai |
kenjiArai | 3:35ac9ee7d2d6 | 5 | // July 23rd, 2019 |
kenjiArai | 3:35ac9ee7d2d6 | 6 | // |
kenjiArai | 3:35ac9ee7d2d6 | 7 | |
kenjiArai | 3:35ac9ee7d2d6 | 8 | #include "select_program.h" |
kenjiArai | 3:35ac9ee7d2d6 | 9 | //#define EXAMPLE_8_AUDIO |
kenjiArai | 3:35ac9ee7d2d6 | 10 | #ifdef EXAMPLE_8_AUDIO |
kenjiArai | 3:35ac9ee7d2d6 | 11 | |
kenjiArai | 3:35ac9ee7d2d6 | 12 | #include "mbed.h" |
kenjiArai | 3:35ac9ee7d2d6 | 13 | #include "stm32f769i_discovery.h" |
kenjiArai | 3:35ac9ee7d2d6 | 14 | #include "stm32f769i_discovery_audio.h" |
kenjiArai | 3:35ac9ee7d2d6 | 15 | |
kenjiArai | 3:35ac9ee7d2d6 | 16 | Serial pc(USBTX, USBRX, 115200); |
kenjiArai | 3:35ac9ee7d2d6 | 17 | |
kenjiArai | 3:35ac9ee7d2d6 | 18 | static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize); |
kenjiArai | 3:35ac9ee7d2d6 | 19 | |
kenjiArai | 3:35ac9ee7d2d6 | 20 | #define SCRATCH_BUFF_SIZE 1024 |
kenjiArai | 3:35ac9ee7d2d6 | 21 | #define RECORD_BUFFER_SIZE 4096 |
kenjiArai | 3:35ac9ee7d2d6 | 22 | |
kenjiArai | 3:35ac9ee7d2d6 | 23 | typedef enum { |
kenjiArai | 3:35ac9ee7d2d6 | 24 | BUFFER_OFFSET_NONE = 0, |
kenjiArai | 3:35ac9ee7d2d6 | 25 | BUFFER_OFFSET_HALF = 1, |
kenjiArai | 3:35ac9ee7d2d6 | 26 | BUFFER_OFFSET_FULL = 2, |
kenjiArai | 3:35ac9ee7d2d6 | 27 | } BUFFER_StateTypeDef; |
kenjiArai | 3:35ac9ee7d2d6 | 28 | |
kenjiArai | 3:35ac9ee7d2d6 | 29 | volatile uint32_t audio_rec_buffer_state = BUFFER_OFFSET_NONE; |
kenjiArai | 3:35ac9ee7d2d6 | 30 | int32_t Scratch[SCRATCH_BUFF_SIZE]; |
kenjiArai | 3:35ac9ee7d2d6 | 31 | |
kenjiArai | 3:35ac9ee7d2d6 | 32 | /* Buffer containing the PCM samples coming from the microphone */ |
kenjiArai | 3:35ac9ee7d2d6 | 33 | int16_t RecordBuffer[RECORD_BUFFER_SIZE]; |
kenjiArai | 3:35ac9ee7d2d6 | 34 | |
kenjiArai | 3:35ac9ee7d2d6 | 35 | /* Buffer used to stream the recorded PCM samples towards the audio codec. */ |
kenjiArai | 3:35ac9ee7d2d6 | 36 | int16_t PlaybackBuffer[RECORD_BUFFER_SIZE]; |
kenjiArai | 3:35ac9ee7d2d6 | 37 | |
kenjiArai | 3:35ac9ee7d2d6 | 38 | int main() |
kenjiArai | 3:35ac9ee7d2d6 | 39 | { |
kenjiArai | 3:35ac9ee7d2d6 | 40 | uint32_t audio_loop_back_init = RESET ; |
kenjiArai | 3:35ac9ee7d2d6 | 41 | |
kenjiArai | 3:35ac9ee7d2d6 | 42 | printf("\n\nAUDIO LOOPBACK EXAMPLE FOR DISCO-F769NI START:\n"); |
kenjiArai | 3:35ac9ee7d2d6 | 43 | |
kenjiArai | 3:35ac9ee7d2d6 | 44 | /* Initialize Audio Recorder with 4 channels to be used */ |
kenjiArai | 3:35ac9ee7d2d6 | 45 | if (BSP_AUDIO_IN_Init(BSP_AUDIO_FREQUENCY_44K, DEFAULT_AUDIO_IN_BIT_RESOLUTION, 2*DEFAULT_AUDIO_IN_CHANNEL_NBR) == AUDIO_ERROR) { |
kenjiArai | 3:35ac9ee7d2d6 | 46 | printf("BSP_AUDIO_IN_Init error\n"); |
kenjiArai | 3:35ac9ee7d2d6 | 47 | } |
kenjiArai | 3:35ac9ee7d2d6 | 48 | |
kenjiArai | 3:35ac9ee7d2d6 | 49 | /* Allocate scratch buffers */ |
kenjiArai | 3:35ac9ee7d2d6 | 50 | if (BSP_AUDIO_IN_AllocScratch (Scratch, SCRATCH_BUFF_SIZE) == AUDIO_ERROR) { |
kenjiArai | 3:35ac9ee7d2d6 | 51 | printf("BSP_AUDIO_IN_AllocScratch error\n"); |
kenjiArai | 3:35ac9ee7d2d6 | 52 | } |
kenjiArai | 3:35ac9ee7d2d6 | 53 | |
kenjiArai | 3:35ac9ee7d2d6 | 54 | /* Start Recording */ |
kenjiArai | 3:35ac9ee7d2d6 | 55 | if (BSP_AUDIO_IN_Record((uint16_t*)&RecordBuffer[0], RECORD_BUFFER_SIZE) == AUDIO_ERROR) { |
kenjiArai | 3:35ac9ee7d2d6 | 56 | printf("BSP_AUDIO_IN_Record error\n"); |
kenjiArai | 3:35ac9ee7d2d6 | 57 | } |
kenjiArai | 3:35ac9ee7d2d6 | 58 | uint8_t ChannelNumber = BSP_AUDIO_IN_GetChannelNumber(); |
kenjiArai | 3:35ac9ee7d2d6 | 59 | |
kenjiArai | 3:35ac9ee7d2d6 | 60 | audio_rec_buffer_state = BUFFER_OFFSET_NONE; |
kenjiArai | 3:35ac9ee7d2d6 | 61 | |
kenjiArai | 3:35ac9ee7d2d6 | 62 | while (1) { |
kenjiArai | 3:35ac9ee7d2d6 | 63 | /* 1st or 2nd half of the record buffer ready for being copied to the playbakc buffer */ |
kenjiArai | 3:35ac9ee7d2d6 | 64 | if(audio_rec_buffer_state != BUFFER_OFFSET_NONE) { |
kenjiArai | 3:35ac9ee7d2d6 | 65 | /* Copy half of the record buffer to the playback buffer */ |
kenjiArai | 3:35ac9ee7d2d6 | 66 | if(audio_rec_buffer_state == BUFFER_OFFSET_HALF) { |
kenjiArai | 3:35ac9ee7d2d6 | 67 | CopyBuffer(&PlaybackBuffer[0], &RecordBuffer[0], RECORD_BUFFER_SIZE/2); |
kenjiArai | 3:35ac9ee7d2d6 | 68 | if (audio_loop_back_init == RESET) { |
kenjiArai | 3:35ac9ee7d2d6 | 69 | /* Initialize the audio device*/ |
kenjiArai | 3:35ac9ee7d2d6 | 70 | if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, 70, BSP_AUDIO_FREQUENCY_44K) == AUDIO_ERROR) { |
kenjiArai | 3:35ac9ee7d2d6 | 71 | printf("BSP_AUDIO_OUT_Init error\n"); |
kenjiArai | 3:35ac9ee7d2d6 | 72 | } |
kenjiArai | 3:35ac9ee7d2d6 | 73 | if(ChannelNumber > 2) { |
kenjiArai | 3:35ac9ee7d2d6 | 74 | BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_0123); |
kenjiArai | 3:35ac9ee7d2d6 | 75 | } else { |
kenjiArai | 3:35ac9ee7d2d6 | 76 | BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); |
kenjiArai | 3:35ac9ee7d2d6 | 77 | } |
kenjiArai | 3:35ac9ee7d2d6 | 78 | |
kenjiArai | 3:35ac9ee7d2d6 | 79 | /* Play the recorded buffer */ |
kenjiArai | 3:35ac9ee7d2d6 | 80 | if (BSP_AUDIO_OUT_Play((uint16_t *) &PlaybackBuffer[0], 2*RECORD_BUFFER_SIZE) == AUDIO_ERROR) { |
kenjiArai | 3:35ac9ee7d2d6 | 81 | printf("BSP_AUDIO_OUT_Play error\n"); |
kenjiArai | 3:35ac9ee7d2d6 | 82 | } |
kenjiArai | 3:35ac9ee7d2d6 | 83 | /* Audio device is initialized only once */ |
kenjiArai | 3:35ac9ee7d2d6 | 84 | audio_loop_back_init = SET; |
kenjiArai | 3:35ac9ee7d2d6 | 85 | } |
kenjiArai | 3:35ac9ee7d2d6 | 86 | |
kenjiArai | 3:35ac9ee7d2d6 | 87 | |
kenjiArai | 3:35ac9ee7d2d6 | 88 | } else { /* if(audio_rec_buffer_state == BUFFER_OFFSET_FULL)*/ |
kenjiArai | 3:35ac9ee7d2d6 | 89 | CopyBuffer(&PlaybackBuffer[RECORD_BUFFER_SIZE/2], &RecordBuffer[RECORD_BUFFER_SIZE/2], RECORD_BUFFER_SIZE/2); |
kenjiArai | 3:35ac9ee7d2d6 | 90 | } |
kenjiArai | 3:35ac9ee7d2d6 | 91 | |
kenjiArai | 3:35ac9ee7d2d6 | 92 | /* Wait for next data */ |
kenjiArai | 3:35ac9ee7d2d6 | 93 | audio_rec_buffer_state = BUFFER_OFFSET_NONE; |
kenjiArai | 3:35ac9ee7d2d6 | 94 | } |
kenjiArai | 3:35ac9ee7d2d6 | 95 | } |
kenjiArai | 3:35ac9ee7d2d6 | 96 | } |
kenjiArai | 3:35ac9ee7d2d6 | 97 | |
kenjiArai | 3:35ac9ee7d2d6 | 98 | /*------------------------------------------------------------------------------------- |
kenjiArai | 3:35ac9ee7d2d6 | 99 | Callbacks implementation: |
kenjiArai | 3:35ac9ee7d2d6 | 100 | the callbacks API are defined __weak in the stm32f769i_discovery_audio.c file |
kenjiArai | 3:35ac9ee7d2d6 | 101 | and their implementation should be done in the user code if they are needed. |
kenjiArai | 3:35ac9ee7d2d6 | 102 | Below some examples of callback implementations. |
kenjiArai | 3:35ac9ee7d2d6 | 103 | -------------------------------------------------------------------------------------*/ |
kenjiArai | 3:35ac9ee7d2d6 | 104 | /** |
kenjiArai | 3:35ac9ee7d2d6 | 105 | * @brief Manages the DMA Transfer complete interrupt. |
kenjiArai | 3:35ac9ee7d2d6 | 106 | * @param None |
kenjiArai | 3:35ac9ee7d2d6 | 107 | * @retval None |
kenjiArai | 3:35ac9ee7d2d6 | 108 | */ |
kenjiArai | 3:35ac9ee7d2d6 | 109 | void BSP_AUDIO_IN_TransferComplete_CallBack(void) |
kenjiArai | 3:35ac9ee7d2d6 | 110 | { |
kenjiArai | 3:35ac9ee7d2d6 | 111 | audio_rec_buffer_state = BUFFER_OFFSET_FULL; |
kenjiArai | 3:35ac9ee7d2d6 | 112 | } |
kenjiArai | 3:35ac9ee7d2d6 | 113 | |
kenjiArai | 3:35ac9ee7d2d6 | 114 | /** |
kenjiArai | 3:35ac9ee7d2d6 | 115 | * @brief Manages the DMA Half Transfer complete interrupt. |
kenjiArai | 3:35ac9ee7d2d6 | 116 | * @param None |
kenjiArai | 3:35ac9ee7d2d6 | 117 | * @retval None |
kenjiArai | 3:35ac9ee7d2d6 | 118 | */ |
kenjiArai | 3:35ac9ee7d2d6 | 119 | void BSP_AUDIO_IN_HalfTransfer_CallBack(void) |
kenjiArai | 3:35ac9ee7d2d6 | 120 | { |
kenjiArai | 3:35ac9ee7d2d6 | 121 | audio_rec_buffer_state = BUFFER_OFFSET_HALF; |
kenjiArai | 3:35ac9ee7d2d6 | 122 | } |
kenjiArai | 3:35ac9ee7d2d6 | 123 | |
kenjiArai | 3:35ac9ee7d2d6 | 124 | /** |
kenjiArai | 3:35ac9ee7d2d6 | 125 | * @brief Audio IN Error callback function. |
kenjiArai | 3:35ac9ee7d2d6 | 126 | * @param None |
kenjiArai | 3:35ac9ee7d2d6 | 127 | * @retval None |
kenjiArai | 3:35ac9ee7d2d6 | 128 | */ |
kenjiArai | 3:35ac9ee7d2d6 | 129 | void BSP_AUDIO_IN_Error_CallBack(void) |
kenjiArai | 3:35ac9ee7d2d6 | 130 | { |
kenjiArai | 3:35ac9ee7d2d6 | 131 | printf("BSP_AUDIO_IN_Error_CallBack\n"); |
kenjiArai | 3:35ac9ee7d2d6 | 132 | } |
kenjiArai | 3:35ac9ee7d2d6 | 133 | |
kenjiArai | 3:35ac9ee7d2d6 | 134 | |
kenjiArai | 3:35ac9ee7d2d6 | 135 | /** |
kenjiArai | 3:35ac9ee7d2d6 | 136 | * @brief Copy content of pbuffer2 to pbuffer1 |
kenjiArai | 3:35ac9ee7d2d6 | 137 | * @param None |
kenjiArai | 3:35ac9ee7d2d6 | 138 | * @retval None |
kenjiArai | 3:35ac9ee7d2d6 | 139 | */ |
kenjiArai | 3:35ac9ee7d2d6 | 140 | static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize) |
kenjiArai | 3:35ac9ee7d2d6 | 141 | { |
kenjiArai | 3:35ac9ee7d2d6 | 142 | uint32_t i = 0; |
kenjiArai | 3:35ac9ee7d2d6 | 143 | for(i = 0; i < BufferSize; i++) { |
kenjiArai | 3:35ac9ee7d2d6 | 144 | pbuffer1[i] = pbuffer2[i]; |
kenjiArai | 3:35ac9ee7d2d6 | 145 | } |
kenjiArai | 3:35ac9ee7d2d6 | 146 | } |
kenjiArai | 3:35ac9ee7d2d6 | 147 | |
kenjiArai | 3:35ac9ee7d2d6 | 148 | #endif |