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