summaryrefslogtreecommitdiff
path: root/src/class/audio/audio_host.h
diff options
context:
space:
mode:
authorZhang, Zhenjiang <[email protected]>2026-07-21 11:23:27 +0800
committerZhang, Zhenjiang <[email protected]>2026-07-21 11:23:27 +0800
commite9578eb103a90d5ab059a067b2e17ca1ddcedee5 (patch)
treec3a4419e7497d57892086e84072404b6455a0478 /src/class/audio/audio_host.h
parent786eef5fd29d0a1ba46eda1e907399aee5af16d0 (diff)
Refactor TUH_AUDIO API and simplify multi-AS interface support
This commit refactors the TUH_AUDIO (USB Audio Host) class driver to simplify its public API and improve multi-AS (Audio Streaming) interface support. The changes are focused on three files: the core driver (audio_host.c/h) and the example application (audio_app.c). Key changes in src/class/audio/audio_host.h: - Remove tuh_audio_descriptor_cb_t and tuh_audio_mount_cb_t structures. The mount callback no longer passes a large descriptor-info struct; applications query per-AS info via tuh_audio_as_get_info(). - Add tuh_audio_get_dev_addr() and tuh_audio_get_feature_unit_id() accessors to retrieve device address and feature-unit ID from an interface index. - Simplify control-transfer APIs by replacing (daddr, itf_num, unit_id) parameters with a single idx parameter: tuh_audio_set_sampling_freq(idx, as_idx, ...) tuh_audio_get_sampling_freq(idx, as_idx, ...) tuh_audio_feature_unit_set(idx, control_selector, channel, ...) tuh_audio_feature_unit_get(idx, control_selector, channel, ...) - Add synchronous wrapper APIs using TU_API_SYNC macro: tuh_audio_get_sampling_freq_sync() tuh_audio_set_sampling_freq_sync() tuh_audio_feature_unit_set_sync() tuh_audio_feature_unit_get_sync() - Update isochronous endpoint APIs to use (idx, as_idx) instead of (daddr, idx): tuh_audio_receive(idx, as_idx, buffer, len) tuh_audio_send(idx, as_idx, buffer, len) - Remove tuh_audio_descriptor_cb() weak callback. - Update tuh_audio_mount_cb() signature from mount_cb(param) to no param. - Update tuh_audio_rx_cb()/tuh_audio_tx_cb() first parameter from idx to dev_addr for consistency with other class drivers. Key changes in src/class/audio/audio_host.c: - Delete tuh_audio_descriptor_cb weak stub. - Refactor get_idx_by_ep_addr() to iterate all AS interfaces per device instead of relying on single ep_in/ep_out fields. - Add audioh_get_ep_addr_by_dir() helper to find an endpoint address by direction across multiple AS interfaces. - Simplify audioh_close() cleanup: remove now-removed single-endpoint fields (ep_in, ep_out) and rely on tu_memclr(p_audio->as, ...). - Update audioh_xfer_cb() to pass dev_addr (not idx) to rx/tx callbacks, matching the new callback signature. - Simplify audioh_open(): remove descriptor-callback emission and the temporary desc_cb structure; store only ac_itf_num instead of bInterfaceNumber + iInterface + as_interface_num. - Rename local descriptor pointers for clarity: desc_input_terminal (was desc_it) desc_output_terminal (was desc_ot) Key changes in examples/host/audio_host/src/audio_app.c: - Remove now-unnecessary globals: audio_ep_in, audio_ep_out, audio_ac_itf, audio_feature_unit_id. - Initialize audio_dev_addr, audio_idx, audiostream_in_idx, audiostream_out_idx to 0xFF (TUSB_INDEX_INVALID_8) instead of 0. - Update print_as_interfaces() to use tuh_audio_as_get_count() and tuh_audio_as_get_info() instead of accessing mount_cb_data. - Update all callback signatures and API calls to match the new driver API.
Diffstat (limited to 'src/class/audio/audio_host.h')
-rw-r--r--src/class/audio/audio_host.h163
1 files changed, 65 insertions, 98 deletions
diff --git a/src/class/audio/audio_host.h b/src/class/audio/audio_host.h
index 5c5a8b3df..aafd58f43 100644
--- a/src/class/audio/audio_host.h
+++ b/src/class/audio/audio_host.h
@@ -17,14 +17,15 @@ extern "C" {
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
+// Maximum number of Audio interfaces per Audio device
#ifndef CFG_TUH_AUDIO_MAX
#define CFG_TUH_AUDIO_MAX 1
#endif
-
+// Maximum number of Audio Streaming interfaces per Audio device
#ifndef CFG_TUH_AUDIO_MAX_SAM_FREQ
#define CFG_TUH_AUDIO_MAX_SAM_FREQ 5
#endif
-
+// Maximum number of Audio Streaming interfaces per Audio device
#ifndef CFG_TUH_AUDIO_MAX_AS
#define CFG_TUH_AUDIO_MAX_AS 4
#endif
@@ -33,18 +34,18 @@ extern "C" {
// AS Interface Info (per-interface independent storage)
//--------------------------------------------------------------------+
typedef struct {
- uint8_t interface_num; // AS interface number
- uint8_t alt_setting; // Current alt setting
- uint8_t ep_addr; // Endpoint address
- uint16_t ep_size; // Max packet size
- uint8_t ep_dir; // TUSB_DIR_IN or TUSB_DIR_OUT
+ uint8_t interface_num; // AS interface number
+ uint8_t alt_setting; // Current alt setting
+ uint8_t ep_addr; // Endpoint address
+ uint16_t ep_size; // Max packet size
+ uint8_t ep_dir; // TUSB_DIR_IN or TUSB_DIR_OUT
// Format info
- uint8_t format_type;
- uint8_t num_channels;
- uint8_t sub_frame_size;
- uint8_t bit_resolution;
- uint8_t sam_freq_type;
+ uint8_t format_type;
+ uint8_t num_channels;
+ uint8_t sub_frame_size;
+ uint8_t bit_resolution;
+ uint8_t sam_freq_type;
uint32_t sam_freq[CFG_TUH_AUDIO_MAX_SAM_FREQ];
uint32_t sam_freq_lower;
uint32_t sam_freq_upper;
@@ -59,72 +60,15 @@ typedef struct {
#endif
//--------------------------------------------------------------------+
-// Descriptor Information
-//--------------------------------------------------------------------+
-// Information about parsed UAC 1.0 descriptors passed to the application
-// during enumeration (via tuh_audio_descriptor_cb)
-typedef struct {
- // Audio Control Interface descriptor
- const tusb_desc_interface_t *desc_ac_interface;
-
- // Audio Streaming Interface descriptor (alt setting 0)
- const tusb_desc_interface_t *desc_as_interface;
-
- // Audio Streaming Interface alt setting (with endpoints)
- const tusb_desc_interface_t *desc_as_interface_alt;
-
- // Format Type descriptor
- const uint8_t *desc_format_type;
-
- // Class-Specific AS Interface (AS General) descriptor
- const uint8_t *desc_cs_as_general;
-
- // Standard Isochronous Endpoint descriptor (IN)
- const tusb_desc_endpoint_t *desc_ep_in;
-
- // Standard Isochronous Endpoint descriptor (OUT)
- const tusb_desc_endpoint_t *desc_ep_out;
-
- // Audio function information
- uint8_t ac_interface_num; // Audio Control interface number
- uint8_t as_interface_num; // Audio Streaming interface number
- uint8_t alt_setting; // Current alt setting with endpoints
-} tuh_audio_descriptor_cb_t;
-
-typedef struct {
- uint8_t daddr;
- uint8_t bInterfaceNumber;
- uint8_t bAltSetting;
-
- // Terminal info (from Audio Control Interface)
- uint16_t input_terminal_type; // wTerminalType of Input Terminal (0x0201 = Mic, etc.)
- uint8_t input_terminal_id; // bTerminalID of Input Terminal
- uint8_t input_terminal_channels; // bNrChannels of Input Terminal
- uint16_t output_terminal_type; // wTerminalType of Output Terminal (0x0301 = Speaker, etc.)
- uint8_t output_terminal_id; // bTerminalID of Output Terminal
-
- // Feature Unit info
- uint8_t feature_unit_id; // bUnitID of Feature Unit (0 = none)
- uint8_t feature_unit_source_id; // bSourceID of Feature Unit
-
- // Endpoint info
- uint8_t ep_in;
- uint8_t ep_out;
- uint16_t ep_in_size;
- uint16_t ep_out_size;
-
- // Multi-AS support (per AS interface independent storage)
- uint8_t as_count;
- tuh_audio_as_info_t as_info[CFG_TUH_AUDIO_MAX_AS];
-} tuh_audio_mount_cb_t;
-
-//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
// Check if Audio interface is mounted
bool tuh_audio_mounted(uint8_t idx);
-
+// Get device address of Audio interface
+uint8_t tuh_audio_get_dev_addr(uint8_t idx);
+// Get Feature Unit ID
+uint8_t tuh_audio_get_feature_unit_id(uint8_t idx);
// Get Interface index from device address + interface number
// return TUSB_INDEX_INVALID_8 (0xFF) if not found
uint8_t tuh_audio_itf_get_index(uint8_t daddr, uint8_t itf_num);
@@ -141,8 +85,8 @@ uint8_t tuh_audio_as_get_count(uint8_t idx);
bool tuh_audio_as_get_info(uint8_t idx, uint8_t as_idx, tuh_audio_as_info_t *info);
// Set Audio Streaming interface alternate setting (to enable/disable endpoints)
-bool tuh_audio_set_interface(uint8_t daddr, uint8_t itf_num, uint8_t alt_setting,
- tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+bool tuh_audio_set_interface(uint8_t daddr, uint8_t itf_num, uint8_t alt_setting, tuh_xfer_cb_t complete_cb,
+ uintptr_t user_data);
//--------------------------------------------------------------------+
// Control Endpoint API
@@ -150,54 +94,77 @@ bool tuh_audio_set_interface(uint8_t daddr, uint8_t itf_num, uint8_t alt_setting
// Set current sampling frequency on an isochronous endpoint (UAC 1.0)
// Sampling frequency is 3 bytes little-endian
-bool tuh_audio_set_sampling_freq(uint8_t daddr, uint8_t ep_addr, uint32_t sampling_freq,
- tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+// In multi-AS scenarios, pass the endpoint address from tuh_audio_as_get_info().
+bool tuh_audio_set_sampling_freq(uint8_t idx, uint8_t as_idx, uint32_t sampling_freq, tuh_xfer_cb_t complete_cb,
+ uintptr_t user_data);
// Get current sampling frequency from an isochronous endpoint (UAC 1.0)
-bool tuh_audio_get_sampling_freq(uint8_t daddr, uint8_t ep_addr, uint32_t *sampling_freq,
- tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+// In multi-AS scenarios, pass the endpoint address from tuh_audio_as_get_info().
+bool tuh_audio_get_sampling_freq(uint8_t idx, uint8_t as_idx, uint32_t *sampling_freq, tuh_xfer_cb_t complete_cb,
+ uintptr_t user_data);
// Set current/mute/volume etc. for a feature unit (UAC 1.0)
-bool tuh_audio_feature_unit_set(uint8_t daddr, uint8_t itf_num, uint8_t unit_id,
- uint8_t control_selector, uint8_t channel,
- uint16_t value, tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+bool tuh_audio_feature_unit_set(uint8_t idx, uint8_t control_selector, uint8_t channel, uint16_t value,
+ tuh_xfer_cb_t complete_cb, uintptr_t user_data);
// Get current/mute/volume etc. from a feature unit (UAC 1.0)
-bool tuh_audio_feature_unit_get(uint8_t daddr, uint8_t itf_num, uint8_t unit_id,
- uint8_t control_selector, uint8_t channel,
- void *buffer, uint8_t len,
- tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+bool tuh_audio_feature_unit_get(uint8_t idx, uint8_t control_selector, uint8_t channel, uint16_t *value,
+ tuh_xfer_cb_t complete_cb, uintptr_t user_data);
+
+//--------------------------------------------------------------------+
+// Control Request Sync API
+// Each Function will make a USB control transfer request to/from device the function will block until request is
+// complete. The function will return the transfer request result
+//--------------------------------------------------------------------+
+TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_audio_get_sampling_freq_sync(uint8_t idx, uint8_t as_idx,
+ uint32_t *sampling_freq) {
+ TU_API_SYNC(tuh_audio_get_sampling_freq, idx, as_idx, sampling_freq);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t tuh_audio_set_sampling_freq_sync(uint8_t idx, uint8_t as_idx,
+ uint32_t sampling_freq) {
+ TU_API_SYNC(tuh_audio_set_sampling_freq, idx, as_idx, sampling_freq);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t
+tuh_audio_feature_unit_set_sync(uint8_t idx, uint8_t control_selector, uint8_t channel, uint16_t value) {
+ TU_API_SYNC(tuh_audio_feature_unit_set, idx, control_selector, channel, value);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline tusb_xfer_result_t
+tuh_audio_feature_unit_get_sync(uint8_t idx, uint8_t control_selector, uint8_t channel, uint16_t *value) {
+ TU_API_SYNC(tuh_audio_feature_unit_get, idx, control_selector, channel, value);
+}
//--------------------------------------------------------------------+
// Interrupt/Isochronous Endpoint API
//--------------------------------------------------------------------+
-// Submit an isochronous transfer to receive audio data from IN endpoint
-bool tuh_audio_receive(uint8_t daddr, uint8_t idx, uint8_t *buffer, uint16_t len);
+// Submit an isochronous transfer to receive audio data from a default IN endpoint.
+// In multi-AS scenarios, endpoint selection is implementation-defined default behavior.
+// Use tuh_audio_as_get_info() when application needs explicit per-AS endpoint control.
+bool tuh_audio_receive(uint8_t idx, uint8_t as_idx, uint8_t *buffer, uint16_t len);
-// Submit an isochronous transfer to send audio data to OUT endpoint
-bool tuh_audio_send(uint8_t daddr, uint8_t idx, uint8_t *buffer, uint16_t len);
+// Submit an isochronous transfer to send audio data to a default OUT endpoint.
+// In multi-AS scenarios, endpoint selection is implementation-defined default behavior.
+// Use tuh_audio_as_get_info() when application needs explicit per-AS endpoint control.
+bool tuh_audio_send(uint8_t idx, uint8_t as_idx, uint8_t *buffer, uint16_t len);
//--------------------------------------------------------------------+
// Callbacks (Weak is optional)
//--------------------------------------------------------------------+
-// Invoked when Audio interface descriptor is detected during enumeration.
-// Application can copy/parse descriptor if needed.
-// Note: may be fired before tuh_audio_mount_cb(), therefore audio interface is not mounted/ready.
-void tuh_audio_descriptor_cb(uint8_t idx, const tuh_audio_descriptor_cb_t *desc_cb_data);
-
// Invoked when device with Audio interface is mounted
-void tuh_audio_mount_cb(uint8_t idx, const tuh_audio_mount_cb_t *mount_cb_data);
+void tuh_audio_mount_cb(uint8_t idx);
// Invoked when device with Audio interface is un-mounted
void tuh_audio_umount_cb(uint8_t idx);
// Invoked when an isochronous IN transfer is complete
-void tuh_audio_rx_cb(uint8_t idx, uint8_t ep_addr, uint16_t xferred_bytes);
+void tuh_audio_rx_cb(uint8_t dev_addr, uint8_t ep_addr, uint16_t xferred_bytes);
// Invoked when an isochronous OUT transfer is complete
-void tuh_audio_tx_cb(uint8_t idx, uint8_t ep_addr, uint16_t xferred_bytes);
+void tuh_audio_tx_cb(uint8_t dev_addr, uint8_t ep_addr, uint16_t xferred_bytes);
//--------------------------------------------------------------------+
// Internal Class Driver API