فهرست منبع

Add 24bit loopback in example.

MasterPhi 4 سال پیش
والد
کامیت
5b7795be4b

+ 45 - 13
examples/device/uac2_headset/src/main.c

@@ -38,7 +38,7 @@
 const uint32_t sample_rates[]       = {44100, 48000, 88200, 96000};
 uint32_t       current_sample_rate  = 44100;
 
-#define N_SAMPLE_RATES  (sizeof(sample_rates) / 4)
+#define N_SAMPLE_RATES  TU_ARRAY_SIZE(sample_rates)
 
 /* Blink pattern
  * - 25 ms   : streaming data
@@ -78,11 +78,16 @@ int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];       // +1 for master chan
 int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];    // +1 for master channel 0
 
 // Buffer for microphone data
-int16_t mic_buf[1000];
+uint8_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ];
 // Buffer for speaker data
-int16_t spk_buf[1000];
+uint8_t spk_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ];
 // Speaker data size received in the last frame
 int spk_data_size;
+// Resolution per format
+const uint8_t resolutions_per_format[CFG_TUD_AUDIO_FUNC_1_N_FORMATS] = {CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX,
+                                                                        CFG_TUD_AUDIO_FUNC_1_FORMAT_2_RESOLUTION_RX};
+// Current resolution, update on format change
+uint8_t current_resolution;
 
 void led_blinking_task(void);
 void audio_task(void);
@@ -364,6 +369,13 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_reque
   if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt != 0)
       blink_interval_ms = BLINK_STREAMING;
 
+  // Clear buffer when streaming format is changed
+  spk_data_size = 0;
+  if(alt != 0)
+  {
+    current_resolution = resolutions_per_format[alt-1];
+  }
+
   return true;
 }
 
@@ -397,20 +409,40 @@ void audio_task(void)
 {
   // When new data arrived, copy data from speaker buffer, to microphone buffer
   // and send it over
+  // Only support speaker & headphone both have the same resolution
+  // If one is 16bit another is 24bit be care of LOUD noise !
   if (spk_data_size)
   {
-    int16_t *src = spk_buf;
-    int16_t *limit = spk_buf + spk_data_size / 2;
-    int16_t *dst = mic_buf;
-    while (src < limit)
+    if (current_resolution == 16)
     {
-      // Combine two channels into one
-      int32_t left = *src++;
-      int32_t right = *src++;
-      *dst++ = (int16_t)((left + right) / 2);
+      int16_t *src = (int16_t*)spk_buf;
+      int16_t *limit = (int16_t*)spk_buf + spk_data_size / 2;
+      int16_t *dst = (int16_t*)mic_buf;
+      while (src < limit)
+      {
+        // Combine two channels into one
+        int32_t left = *src++;
+        int32_t right = *src++;
+        *dst++ = (int16_t)((left + right) / 2);
+      }
+      tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2);
+      spk_data_size = 0;
+    }
+    else if (current_resolution == 24)
+    {
+      int32_t *src = (int32_t*)spk_buf;
+      int32_t *limit = (int32_t*)spk_buf + spk_data_size / 4;
+      int32_t *dst = (int32_t*)mic_buf;
+      while (src < limit)
+      {
+        // Combine two channels into one
+        int32_t left = (*src++);
+        int32_t right = (*src++);
+        *dst++ = (int32_t)((left + right) / 2) & 0xffffff00;
+      }
+      tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2);
+      spk_data_size = 0;
     }
-    tud_audio_write((uint8_t *)mic_buf, spk_data_size / 2);
-    spk_data_size = 0;
   }
 }
 

+ 3 - 0
examples/device/uac2_headset/src/tusb_config.h

@@ -96,6 +96,9 @@ extern "C" {
 
 #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN                                TUD_AUDIO_HEADSET_STEREO_DESC_LEN
 
+// How many formats are used, need to adjust USB descriptor if changed
+#define CFG_TUD_AUDIO_FUNC_1_N_FORMATS                               2
+
 // Audio format type I specifications
 #define CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE                         96000     // 24bit/96kHz is the best quality for full-speed, high-speed is needed beyond this
 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX                           1

+ 6 - 0
examples/device/uac2_headset/src/usb_descriptors.h

@@ -55,23 +55,29 @@ enum
     + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\
     + TUD_AUDIO_DESC_INPUT_TERM_LEN\
     + TUD_AUDIO_DESC_OUTPUT_TERM_LEN\
+    /* Interface 1, Alternate 0 */\
     + TUD_AUDIO_DESC_STD_AS_INT_LEN\
+    /* Interface 1, Alternate 0 */\
     + TUD_AUDIO_DESC_STD_AS_INT_LEN\
     + TUD_AUDIO_DESC_CS_AS_INT_LEN\
     + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\
     + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\
     + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\
+    /* Interface 1, Alternate 2 */\
     + TUD_AUDIO_DESC_STD_AS_INT_LEN\
     + TUD_AUDIO_DESC_CS_AS_INT_LEN\
     + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\
     + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\
     + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\
+    /* Interface 2, Alternate 0 */\
     + TUD_AUDIO_DESC_STD_AS_INT_LEN\
+    /* Interface 2, Alternate 1 */\
     + TUD_AUDIO_DESC_STD_AS_INT_LEN\
     + TUD_AUDIO_DESC_CS_AS_INT_LEN\
     + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\
     + TUD_AUDIO_DESC_STD_AS_ISO_EP_LEN\
     + TUD_AUDIO_DESC_CS_AS_ISO_EP_LEN\
+    /* Interface 2, Alternate 2 */\
     + TUD_AUDIO_DESC_STD_AS_INT_LEN\
     + TUD_AUDIO_DESC_CS_AS_INT_LEN\
     + TUD_AUDIO_DESC_TYPE_I_FORMAT_LEN\