AUDIO DISCO_F769NI audioloop basic example

Dependencies:   BSP_DISCO_F769NI

Committer:
Jerome Coutant
Date:
Fri Nov 22 16:02:58 2019 +0100
Revision:
2:db1aee306f50
Parent:
1:f849e36f029e
Update with STM32Cube_FW_F7_V1.15.0

Who changed what in which revision?

UserRevisionLine numberNew 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"
Jerome Coutant 2:db1aee306f50 4
jeromecoutant 0:284b9b17e99a 5 static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize);
Jerome Coutant 2:db1aee306f50 6
jeromecoutant 0:284b9b17e99a 7 #define SCRATCH_BUFF_SIZE 1024
jeromecoutant 0:284b9b17e99a 8 #define RECORD_BUFFER_SIZE 4096
Jerome Coutant 2:db1aee306f50 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;
Jerome Coutant 2:db1aee306f50 15
jeromecoutant 1:f849e36f029e 16 volatile uint32_t audio_rec_buffer_state = BUFFER_OFFSET_NONE;
jeromecoutant 0:284b9b17e99a 17 int32_t Scratch[SCRATCH_BUFF_SIZE];
Jerome Coutant 2:db1aee306f50 18
jeromecoutant 0:284b9b17e99a 19 /* Buffer containing the PCM samples coming from the microphone */
jeromecoutant 0:284b9b17e99a 20 int16_t RecordBuffer[RECORD_BUFFER_SIZE];
Jerome Coutant 2:db1aee306f50 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];
Jerome Coutant 2:db1aee306f50 24
jeromecoutant 0:284b9b17e99a 25 int main()
jeromecoutant 0:284b9b17e99a 26 {
jeromecoutant 0:284b9b17e99a 27 uint32_t audio_loop_back_init = RESET ;
Jerome Coutant 2:db1aee306f50 28
jeromecoutant 0:284b9b17e99a 29 printf("\n\nAUDIO LOOPBACK EXAMPLE FOR DISCO-F769NI START:\n");
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 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();
Jerome Coutant 2:db1aee306f50 46
jeromecoutant 0:284b9b17e99a 47 audio_rec_buffer_state = BUFFER_OFFSET_NONE;
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 73
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 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 }
Jerome Coutant 2:db1aee306f50 120
Jerome Coutant 2:db1aee306f50 121
jeromecoutant 0:284b9b17e99a 122 /**
jeromecoutant 0:284b9b17e99a 123 * @brief Copy content of pbuffer2 to pbuffer1
Jerome Coutant 2:db1aee306f50 124 * @param1 BufferOut
Jerome Coutant 2:db1aee306f50 125 * @param2 BufferIn
Jerome Coutant 2:db1aee306f50 126 * @param3 Size
jeromecoutant 0:284b9b17e99a 127 * @retval None
jeromecoutant 0:284b9b17e99a 128 */
jeromecoutant 0:284b9b17e99a 129 static void CopyBuffer(int16_t *pbuffer1, int16_t *pbuffer2, uint16_t BufferSize)
jeromecoutant 0:284b9b17e99a 130 {
jeromecoutant 0:284b9b17e99a 131 uint32_t i = 0;
jeromecoutant 0:284b9b17e99a 132 for(i = 0; i < BufferSize; i++) {
jeromecoutant 0:284b9b17e99a 133 pbuffer1[i] = pbuffer2[i];
jeromecoutant 0:284b9b17e99a 134 }
jeromecoutant 0:284b9b17e99a 135 }