From 2ba760a1c16dc096da9f96f20cf2443e3a1d8416 Mon Sep 17 00:00:00 2001
From: HiFiPhile <admin@hifiphile.com>
Date: Tue, 10 Oct 2023 18:24:47 +0200
Subject: [PATCH] Enhance audio_4_channel_mic example, plot 4 different waves
 for each channel.

---
 .../device/audio_4_channel_mic/src/main.c     | 43 +++++++++++--------
 .../audio_4_channel_mic/src/tusb_config.h     |  3 +-
 2 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c
index 94ac86d84..3b21b4ac6 100644
--- a/examples/device/audio_4_channel_mic/src/main.c
+++ b/examples/device/audio_4_channel_mic/src/main.c
@@ -34,17 +34,16 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include "arm_math.h"
 
 #include "bsp/board_api.h"
 #include "tusb.h"
+#include "tusb_config.h"
 
 //--------------------------------------------------------------------+
 // MACRO CONSTANT TYPEDEF PROTYPES
 //--------------------------------------------------------------------+
-
-#ifndef AUDIO_SAMPLE_RATE
-#define AUDIO_SAMPLE_RATE   48000
-#endif
+#define AUDIO_SAMPLE_RATE   CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE
 
 /* Blink pattern
  * - 250 ms  : device not mounted
@@ -70,7 +69,7 @@ uint8_t clkValid;
 audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; 			// Volume range state
 audio_control_range_4_n_t(1) sampleFreqRng; 						// Sample frequency range state
 
-// Audio test data
+// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2
 uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ/2];   // Ensure half word aligned
 
 void led_blinking_task(void);
@@ -400,7 +399,8 @@ bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, u
   (void) ep_in;
   (void) cur_alt_setting;
 
-  for (uint8_t cnt=0; cnt < CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; cnt++)
+  // Write buffer[0] (CH0-1) and buffer[1] (CH1-2) into FIFO
+  for (uint8_t cnt=0; cnt < 2; cnt++)
   {
     tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX);
   }
@@ -416,22 +416,27 @@ bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uin
   (void) ep_in;
   (void) cur_alt_setting;
 
-  uint16_t dataVal;
-
   // Generate dummy data
-  for (uint16_t cnt = 0; cnt < CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO; cnt++)
+  uint16_t * p_buff = i2s_dummy_buffer[0];
+  uint16_t dataVal = 1;
+  for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
   {
-    uint16_t * p_buff = i2s_dummy_buffer[cnt];              // 2 bytes per sample
-    dataVal = 1;
-    for (uint16_t cnt2 = 0; cnt2 < AUDIO_SAMPLE_RATE/1000; cnt2++)
-    {
-      for (uint8_t cnt3 = 0; cnt3 < CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX; cnt3++)
-      {
-        *p_buff++ = dataVal;
-      }
-      dataVal++;
-    }
+    // CH0 saw wave
+    *p_buff++ = dataVal;
+    // CH1 inverted saw wave
+    *p_buff++ = 60 + AUDIO_SAMPLE_RATE/1000 - dataVal;
+    dataVal++;
   }
+  p_buff = i2s_dummy_buffer[1];
+  for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
+  {
+    // CH3 square wave
+    *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 120:170;
+    // CH4 sinus wave
+    q15_t t = 0x7FFF * cnt / (AUDIO_SAMPLE_RATE/1000);
+    *p_buff++ = arm_sin_q15(t) / 1300 + 200;
+  }
+
   return true;
 }
 
diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h
index 5cf6d07c3..291ac4f79 100644
--- a/examples/device/audio_4_channel_mic/src/tusb_config.h
+++ b/examples/device/audio_4_channel_mic/src/tusb_config.h
@@ -103,6 +103,7 @@ extern "C" {
 //--------------------------------------------------------------------
 
 // Have a look into audio_device.h for all configurations
+#define CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE              48000
 
 #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN                 TUD_AUDIO_MIC_FOUR_CH_DESC_LEN
 
@@ -112,7 +113,7 @@ extern "C" {
 #define CFG_TUD_AUDIO_ENABLE_EP_IN                    1
 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX    2         // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX            4         // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
-#define CFG_TUD_AUDIO_EP_SZ_IN                        (48 + 1) * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX      // 48 Samples (48 kHz) x 2 Bytes/Sample x CFG_TUD_AUDIO_N_CHANNELS_TX Channels - the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error
+#define CFG_TUD_AUDIO_EP_SZ_IN                        TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
 #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX             CFG_TUD_AUDIO_EP_SZ_IN
 #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ          CFG_TUD_AUDIO_EP_SZ_IN