summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasterPhi <[email protected]>2021-07-01 11:39:15 +0200
committerMasterPhi <[email protected]>2021-07-04 15:46:11 +0200
commit5b7795be4be83daa0a1575a47299af1a89348bc0 (patch)
tree62aa0df84c9fb38dac411f504dec56bc63e0218e
parent204f3152cb486b8de3817bf940efd4593c8bfd07 (diff)
Add 24bit loopback in example.
-rw-r--r--examples/device/uac2_headset/src/main.c58
-rw-r--r--examples/device/uac2_headset/src/tusb_config.h3
-rw-r--r--examples/device/uac2_headset/src/usb_descriptors.h6
3 files changed, 54 insertions, 13 deletions
diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c
index e119ee2c8..c9e79a543 100644
--- a/examples/device/uac2_headset/src/main.c
+++ b/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;
}
}
diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h
index e97f4c470..642e52551 100644
--- a/examples/device/uac2_headset/src/tusb_config.h
+++ b/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
diff --git a/examples/device/uac2_headset/src/usb_descriptors.h b/examples/device/uac2_headset/src/usb_descriptors.h
index 4fae25831..d9510ea4f 100644
--- a/examples/device/uac2_headset/src/usb_descriptors.h
+++ b/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\