void MakeConfigurationDescriptor(int32_t samplerate, int8_t channels, int8_t bits, int8_t samplebytes)
{
#if CONFIG_UAC_VERSION==CONFIG_UAC_VERSION10
// ---------------- Configuration Descriptor ----------------
uint8_t desc_configuration[] =
{
// Configuration Descriptor
0x09, TUSB_DESC_CONFIGURATION, // bLength, bDescriptorType (CONFIGURATION)
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP == 1
U16_BYTES(0x6D 9), // wTotalLength(109)
#else
U16_BYTES(0x6D), // wTotalLength(109)
#endif
0x02, // bNumInterfaces (AC AS)
0x01, // bConfigurationValue
0x00, // iConfiguration
0x80, // bmAttributes (Bus Powered)
0x32, // MaxPower (100mA)
// ===== Interface 0: Audio Control =====
0x09, 0x04, // bLength, bDescriptorType (INTERFACE)
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x00, // bNumEndpoints
0x01, // bInterfaceClass (Audio)
0x01, // bInterfaceSubClass (Audio Control)
0x00, // bInterfaceProtocol
0x00, // iInterface
// Audio Control Header
0x09, TUSB_DESC_CS_INTERFACE, 0x01, // bLength, bDescriptorType=CS_INTERFACE, HEADER
U16_BYTES(CONFIG_UAC_VERSION), // bcdADC = 1.00
U16_BYTES(0x27), // wTotalLength = 39 bytes
0x01, // bInCollection
0x01, // baInterfaceNr[1] = 1
// Input Terminal (USB Streaming)
0x0C, TUSB_DESC_CS_INTERFACE, 0x02, // bLength, CS_INTERFACE, INPUT_TERMINAL
UAC_ENTITY_INPUT_TERMINAL, // bTerminalID
U16_BYTES(AUDIO_TERM_TYPE_USB_STREAMING), // wTerminalType = USB Streaming
0x00, // bAssocTerminal
channels, // bNrChannels = 2
0x03, 0x00, // wChannelConfig = Left Right
0x00, // iChannelNames
0x00, // iTerminal
// Feature Unit (Mute Volume)
0x09, TUSB_DESC_CS_INTERFACE, 0x06, // bLength, CS_INTERFACE, FEATURE_UNIT
UAC_ENTITY_FEATURE_UNIT, // bUnitID
0x01, // bSourceID (Input Terminal)
0x01, // bControlSize
0x03, // bmaControls[master] (Mute Volume)
0x00, // bmaControls[channel 0]
0x00, // bmaControls[channel 1]
// Output Terminal (Speaker)
0x09, TUSB_DESC_CS_INTERFACE, 0x03, // bLength, CS_INTERFACE, OUTPUT_TERMINAL
UAC_ENTITY_OUTPUT_TERMINAL, // bTerminalID
U16_BYTES(AUDIO_TERM_TYPE_OUT_GENERIC_SPEAKER), // wTerminalType = Speaker
0x00, // bAssocTerminal
0x02, // bSourceID (Feature Unit)
0x04, // iTerminal → "PopoDAC Speaker"
// ===== Interface 1: Audio Streaming =====
// Alt0 (no endpoints)
0x09, TUSB_DESC_INTERFACE, // bLength, INTERFACE
0x01, // bInterfaceNumber
0x00, // bAlternateSetting
0x00, // bNumEndpoints
0x01, // bInterfaceClass (Audio)
AUDIO_SUBCLASS_STREAMING, // bInterfaceSubClass (Audio Streaming)
0x00, // bInterfaceProtocol
0x00, // iInterface
// Alt1 (with one OUT endpoint)
0x09, TUSB_DESC_INTERFACE, // bLength, INTERFACE
0x01, // bInterfaceNumber
0x01, // bAlternateSetting
(CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP==1?2:1), // bNumEndpoints(Out only or Out FB)
0x01, // bInterfaceClass (Audio)
AUDIO_SUBCLASS_STREAMING, // bInterfaceSubClass (Audio Streaming)
0x00, // bInterfaceProtocol
0x00, // iInterface
// AS General
0x07, TUSB_DESC_CS_INTERFACE, 0x01, // bLength, CS_INTERFACE, AS_GENERAL
UAC_ENTITY_INPUT_TERMINAL, // bTerminalLink (Input Terminal ID=1)
0x01, // bDelay
0x01, 0x00, // wFormatTag = PCM
// Format Type
0x0B, TUSB_DESC_CS_INTERFACE, 0x02, // bLength, CS_INTERFACE, FORMAT_TYPE
AUDIO20_FORMAT_TYPE_I, // bFormatType = FORMAT_TYPE_I
channels, // bNrChannels = 2
samplebytes, // bSubframeSize = 3 bytes
bits, // bBitResolution = 24
0x01, // bSamFreqType = 1 (Discrete)
U24_TO_U8S_LE(samplerate), // tSamFreq[1] = 96000 Hz
// Endpoint Descriptor (Isochronous OUT)
0x09, TUSB_DESC_ENDPOINT, // bLength, ENDPOINT
CFG_TUD_AUDIO_FUNC_1_EP_OUT, // bEndpointAddress = EP1 OUT
UAC_EP_OUT_ATTRIBUTE_USE, // bmAttributes = Isochronous, Adaptive, Data
U16_BYTES((samplerate*channels*samplebytes/1000)), // 576 bytes
0x01, // bInterval = 1
0x00, // bRefresh
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP == 1 // bSynchAddress
CFG_TUD_AUDIO_FUNC_1_EP_FB,
#else
0,
#endif
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP == 1
// Feedback Endpoint Descriptor
0x09, // bLength
TUSB_DESC_ENDPOINT, // bDescriptorType = ENDPOINT
CFG_TUD_AUDIO_FUNC_1_EP_FB, // bEndpointAddress = IN, EP2
UAC_EP_OUT_ATTRIBUTE_FEEEDBACK, // bmAttributes = Isochronous, Sync = Feedback, Usage = Data
0x03, 0x00, // wMaxPacketSize = 3 bytes (feedback reports are 3 bytes)
UAC_EXPLICIT_FB_INTERVAL/*0x01*/, // bInterval = 1 (1ms)
0x00, // bRefresh
0x00, // bSyncAddress = 0
#endif
// Class-Specific Audio Data Endpoint
0x07, TUSB_DESC_CS_ENDPOINT, 0x01, // bLength, CS_ENDPOINT, EP_GENERAL
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP == 1
AUDIO10_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, // bmAttributes
AUDIO10_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC, // bLockDelayUnits
U16_BYTES(0) // wLockDelay
#else
0x00,
0x00,
U16_BYTES(0) // wLockDelay
#endif
};
#else
(...UAC2 descriptor)
#endif
if (g_desc_configuration != NULL)
free(g_desc_configuration);
g_desc_configuration = malloc(sizeof(desc_configuration));
memcpy (g_desc_configuration, desc_configuration, sizeof(desc_configuration));
}