diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class/audio/audio_host.c | 295 |
1 files changed, 152 insertions, 143 deletions
diff --git a/src/class/audio/audio_host.c b/src/class/audio/audio_host.c index 82d725329..ad2fd677f 100644 --- a/src/class/audio/audio_host.c +++ b/src/class/audio/audio_host.c @@ -874,8 +874,6 @@ bool audioh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin // Enumeration //--------------------------------------------------------------------+ - #define AUDIOH_MAX_AC_ENTITIES TUH_AUDIO_STREAM_DIRECTION_COUNT - typedef struct { uint8_t id; uint8_t source_id; @@ -896,13 +894,9 @@ typedef struct { } audioh_clock_info_t; typedef struct { - audioh_terminal_info_t terminal[AUDIOH_MAX_AC_ENTITIES]; - audioh_fu_info_t feature_unit[AUDIOH_MAX_AC_ENTITIES]; - audioh_clock_info_t clock[AUDIOH_MAX_AC_ENTITIES]; - uint8_t terminal_count; - uint8_t feature_unit_count; - uint8_t clock_count; -} audioh_ac_map_t; + const uint8_t *desc_start; + const uint8_t *desc_end; +} audioh_ac_desc_range_t; #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 static uint8_t audioh_uac2_control_access(uint32_t controls, uint8_t position) { @@ -923,156 +917,173 @@ static bool audioh_as_rate_fits(const audioh_interface_t *p_audio, const tuh_aud (stream->dir != TUSB_DIR_OUT || (packet_bytes <= epbuf_size && packet_bytes <= CFG_TUH_AUDIO_STREAM_BUFSIZE)); } -static void audioh_ac_terminal_add(audioh_ac_map_t *map, uint8_t id, uint8_t source_id, uint8_t clock_id, - tusb_dir_t stream_dir) { - if (map->terminal_count < TU_ARRAY_SIZE(map->terminal)) { - map->terminal[map->terminal_count++] = - (audioh_terminal_info_t){.id = id, .source_id = source_id, .clock_id = clock_id, .stream_dir = stream_dir}; - } -} - -static void audioh_ac_feature_unit_add(audioh_ac_map_t *map, uint8_t id, uint8_t source_id, uint8_t mute_access, - uint8_t volume_access) { - if ((mute_access != AUDIOH_CTRL_NONE || volume_access != AUDIOH_CTRL_NONE) && - map->feature_unit_count < TU_ARRAY_SIZE(map->feature_unit)) { - map->feature_unit[map->feature_unit_count++] = - (audioh_fu_info_t){.id = id, .source_id = source_id, .mute_access = mute_access, .volume_access = volume_access}; - } -} - -static const audioh_terminal_info_t *audioh_ac_terminal_find(const audioh_ac_map_t *map, uint8_t id) { - for (uint8_t i = 0; i < map->terminal_count; i++) { - if (map->terminal[i].id == id) { - return &map->terminal[i]; +static bool audioh_ac_entity_valid(const audioh_interface_t *p_audio, const uint8_t *p_desc) { + switch (p_audio->protocol) { + #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC1 + case AUDIO_INT_PROTOCOL_CODE_V1: { + switch (tu_desc_subtype(p_desc)) { + case AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL: + return TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio10_desc_input_terminal_t)); + case AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL: + return TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio10_desc_output_terminal_t)); + case AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT: { + TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= 7), false); + const uint8_t control_size = p_desc[5]; + return TUH_VALIDATE_BASIC(control_size > 0) && + TUH_VALIDATE_BASIC(control_size <= (uint8_t)(tu_desc_len(p_desc) - 7)); + } + default: + return true; + } } + #endif + #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 + case AUDIO_INT_PROTOCOL_CODE_V2: + switch (tu_desc_subtype(p_desc)) { + case AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL: + return TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio20_desc_input_terminal_t)); + case AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL: + return TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio20_desc_output_terminal_t)); + case AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT: + return TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= 10); + case AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE: + return TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio20_desc_clock_source_t)); + default: + return true; + } + #endif + default: + return false; } - return NULL; } +static bool audioh_ac_terminal_find(const audioh_interface_t *p_audio, const audioh_ac_desc_range_t *range, uint8_t id, + audioh_terminal_info_t *info) { + for (const uint8_t *p_desc = range->desc_start; p_desc < range->desc_end; p_desc = tu_desc_next(p_desc)) { + if (tu_desc_type(p_desc) != TUSB_DESC_CS_INTERFACE || tu_desc_len(p_desc) < 4 || p_desc[3] != id) { + continue; + } + switch (p_audio->protocol) { + #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC1 + case AUDIO_INT_PROTOCOL_CODE_V1: + if (tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL) { + const audio10_desc_input_terminal_t *terminal = (const audio10_desc_input_terminal_t *)p_desc; + if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { + *info = (audioh_terminal_info_t){.id = id, .stream_dir = TUSB_DIR_OUT}; + return true; + } + } else if (tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL) { + const audio10_desc_output_terminal_t *terminal = (const audio10_desc_output_terminal_t *)p_desc; + if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { + *info = (audioh_terminal_info_t){.id = id, .source_id = terminal->bSourceID, .stream_dir = TUSB_DIR_IN}; + return true; + } + } + break; + #endif #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 -static const audioh_clock_info_t *audioh_ac_clock_find(const audioh_ac_map_t *map, uint8_t id) { - for (uint8_t i = 0; i < map->clock_count; i++) { - if (map->clock[i].id == id) { - return &map->clock[i]; + case AUDIO_INT_PROTOCOL_CODE_V2: + if (tu_desc_subtype(p_desc) == AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL) { + const audio20_desc_input_terminal_t *terminal = (const audio20_desc_input_terminal_t *)p_desc; + if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { + *info = (audioh_terminal_info_t){.id = id, .clock_id = terminal->bCSourceID, .stream_dir = TUSB_DIR_OUT}; + return true; + } + } else if (tu_desc_subtype(p_desc) == AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL) { + const audio20_desc_output_terminal_t *terminal = (const audio20_desc_output_terminal_t *)p_desc; + if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { + *info = (audioh_terminal_info_t){.id = id, + .source_id = terminal->bSourceID, + .clock_id = terminal->bCSourceID, + .stream_dir = TUSB_DIR_IN}; + return true; + } + } + break; + #endif + default: + return false; } } - return NULL; + return false; } - #endif +static bool audioh_ac_feature_unit_parse(const audioh_interface_t *p_audio, const uint8_t *p_desc, + audioh_fu_info_t *info) { + if (tu_desc_type(p_desc) != TUSB_DESC_CS_INTERFACE) { + return false; + } + switch (p_audio->protocol) { #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC1 -static bool audioh_uac1_parse_ac_entity(audioh_ac_map_t *map, const uint8_t *p_desc) { - switch (tu_desc_subtype(p_desc)) { - case AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL: { - TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio10_desc_input_terminal_t)), false); - const audio10_desc_input_terminal_t *terminal = (const audio10_desc_input_terminal_t *)p_desc; - if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { - audioh_ac_terminal_add(map, terminal->bTerminalID, 0, 0, TUSB_DIR_OUT); + case AUDIO_INT_PROTOCOL_CODE_V1: + if (tu_desc_subtype(p_desc) == AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT) { + const uint8_t controls = p_desc[6]; + *info = (audioh_fu_info_t){.id = p_desc[3], + .source_id = p_desc[4], + .mute_access = (controls & AUDIO10_FU_CONTROL_BM_MUTE) ? AUDIOH_CTRL_READ_WRITE + : AUDIOH_CTRL_NONE, + .volume_access = (controls & AUDIO10_FU_CONTROL_BM_VOLUME) ? AUDIOH_CTRL_READ_WRITE + : AUDIOH_CTRL_NONE}; + return info->mute_access != AUDIOH_CTRL_NONE || info->volume_access != AUDIOH_CTRL_NONE; } break; - } - case AUDIO10_CS_AC_INTERFACE_OUTPUT_TERMINAL: { - TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio10_desc_output_terminal_t)), false); - const audio10_desc_output_terminal_t *terminal = (const audio10_desc_output_terminal_t *)p_desc; - if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { - audioh_ac_terminal_add(map, terminal->bTerminalID, terminal->bSourceID, 0, TUSB_DIR_IN); + #endif + #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 + case AUDIO_INT_PROTOCOL_CODE_V2: + if (tu_desc_subtype(p_desc) == AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT) { + const uint32_t controls = tu_le32toh(tu_unaligned_read32(&p_desc[5])); + *info = + (audioh_fu_info_t){.id = p_desc[3], + .source_id = p_desc[4], + .mute_access = audioh_uac2_control_access(controls, AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS), + .volume_access = + audioh_uac2_control_access(controls, AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS)}; + return info->mute_access != AUDIOH_CTRL_NONE || info->volume_access != AUDIOH_CTRL_NONE; } break; - } - case AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT: { - TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= 7), false); - const uint8_t control_size = p_desc[5]; - TU_VERIFY(TUH_VALIDATE_BASIC(control_size > 0), false); - TU_VERIFY(TUH_VALIDATE_BASIC(control_size <= (uint8_t)(tu_desc_len(p_desc) - 7)), false); - const uint8_t controls = p_desc[6]; - audioh_ac_feature_unit_add(map, p_desc[3], p_desc[4], - (controls & AUDIO10_FU_CONTROL_BM_MUTE) ? AUDIOH_CTRL_READ_WRITE : AUDIOH_CTRL_NONE, - (controls & AUDIO10_FU_CONTROL_BM_VOLUME) ? AUDIOH_CTRL_READ_WRITE : AUDIOH_CTRL_NONE); - break; - } + #endif default: break; } - return true; + return false; } - #endif #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 -static bool audioh_uac2_parse_ac_entity(audioh_ac_map_t *map, const uint8_t *p_desc) { - switch (tu_desc_subtype(p_desc)) { - case AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL: { - TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio20_desc_input_terminal_t)), false); - const audio20_desc_input_terminal_t *terminal = (const audio20_desc_input_terminal_t *)p_desc; - if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { - audioh_ac_terminal_add(map, terminal->bTerminalID, 0, terminal->bCSourceID, TUSB_DIR_OUT); - } - break; - } - case AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL: { - TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio20_desc_output_terminal_t)), false); - const audio20_desc_output_terminal_t *terminal = (const audio20_desc_output_terminal_t *)p_desc; - if (tu_le16toh(terminal->wTerminalType) == AUDIO_TERM_TYPE_USB_STREAMING) { - audioh_ac_terminal_add(map, terminal->bTerminalID, terminal->bSourceID, terminal->bCSourceID, TUSB_DIR_IN); - } - break; - } - case AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT: { - TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= 10), false); - const uint32_t controls = tu_le32toh(tu_unaligned_read32(&p_desc[5])); - audioh_ac_feature_unit_add(map, p_desc[3], p_desc[4], - audioh_uac2_control_access(controls, AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS), - audioh_uac2_control_access(controls, AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS)); - break; - } - case AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE: { - TU_VERIFY(TUH_VALIDATE_BASIC(tu_desc_len(p_desc) >= sizeof(audio20_desc_clock_source_t)), false); +static bool audioh_ac_clock_find(const audioh_ac_desc_range_t *range, uint8_t id, audioh_clock_info_t *info) { + for (const uint8_t *p_desc = range->desc_start; p_desc < range->desc_end; p_desc = tu_desc_next(p_desc)) { + if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && + tu_desc_subtype(p_desc) == AUDIO20_CS_AC_INTERFACE_CLOCK_SOURCE && p_desc[3] == id) { const audio20_desc_clock_source_t *clock = (const audio20_desc_clock_source_t *)p_desc; - if (map->clock_count < TU_ARRAY_SIZE(map->clock)) { - map->clock[map->clock_count++] = - (audioh_clock_info_t){.id = clock->bClockID, - .frequency_access = - audioh_uac2_control_access(clock->bmControls, AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS)}; - } - break; + *info = + (audioh_clock_info_t){.id = id, + .frequency_access = + audioh_uac2_control_access(clock->bmControls, AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS)}; + return true; } - default: - break; } - return true; + return false; } #endif -static bool audioh_parse_ac_entity(audioh_interface_t *p_audio, audioh_ac_map_t *map, const uint8_t *p_desc) { - switch (p_audio->protocol) { - #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC1 - case AUDIO_INT_PROTOCOL_CODE_V1: - return audioh_uac1_parse_ac_entity(map, p_desc); - #endif - #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 - case AUDIO_INT_PROTOCOL_CODE_V2: - return audioh_uac2_parse_ac_entity(map, p_desc); - #endif - default: - return false; - } -} - -static void audioh_link_feature_units(audioh_interface_t *p_audio, const audioh_ac_map_t *map) { +static void audioh_link_feature_units(audioh_interface_t *p_audio, const audioh_ac_desc_range_t *range) { for (uint8_t direction = TUSB_DIR_OUT; direction <= TUSB_DIR_IN; direction++) { tuh_audio_stream_t *stream = audioh_get_stream(p_audio, (tusb_dir_t)direction); if (stream == NULL || stream->as_count == 0) { continue; } - const audioh_terminal_info_t *terminal = audioh_ac_terminal_find(map, stream->as[0].terminal_id); - if (terminal == NULL || terminal->stream_dir != direction) { + audioh_terminal_info_t terminal; + if (!audioh_ac_terminal_find(p_audio, range, stream->as[0].terminal_id, &terminal) || + terminal.stream_dir != direction) { continue; } - for (uint8_t i = 0; i < map->feature_unit_count; i++) { - const audioh_fu_info_t *fu = &map->feature_unit[i]; - const bool linked = - (direction == TUSB_DIR_OUT) ? (fu->source_id == terminal->id) : (fu->id == terminal->source_id); + for (const uint8_t *p_desc = range->desc_start; p_desc < range->desc_end; p_desc = tu_desc_next(p_desc)) { + audioh_fu_info_t fu; + if (!audioh_ac_feature_unit_parse(p_audio, p_desc, &fu)) { + continue; + } + const bool linked = (direction == TUSB_DIR_OUT) ? (fu.source_id == terminal.id) : (fu.id == terminal.source_id); if (linked) { - audioh_stream_set_feature_unit(stream, fu->id, fu->mute_access, fu->volume_access); + audioh_stream_set_feature_unit(stream, fu.id, fu.mute_access, fu.volume_access); break; } } @@ -1170,17 +1181,17 @@ static bool audioh_parse_as_interface(audioh_interface_t *p_audio, const uint8_t } #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 -static int8_t audioh_uac2_rate_source_get(audioh_interface_t *p_audio, const audioh_ac_map_t *map, +static int8_t audioh_uac2_rate_source_get(audioh_interface_t *p_audio, const audioh_ac_desc_range_t *range, const audioh_terminal_info_t *terminal) { if (terminal->clock_id == 0) { return -1; } - const audioh_clock_info_t *clock = audioh_ac_clock_find(map, terminal->clock_id); - if (clock == NULL || clock->frequency_access == AUDIOH_CTRL_NONE) { + audioh_clock_info_t clock; + if (!audioh_ac_clock_find(range, terminal->clock_id, &clock) || clock.frequency_access == AUDIOH_CTRL_NONE) { return -1; } for (uint8_t i = 0; i < p_audio->rate_source_count; i++) { - if (p_audio->rate_source[i].control_id == clock->id) { + if (p_audio->rate_source[i].control_id == clock.id) { return (int8_t)i; } } @@ -1189,7 +1200,7 @@ static int8_t audioh_uac2_rate_source_get(audioh_interface_t *p_audio, const aud } const uint8_t idx = p_audio->rate_source_count++; p_audio->rate_source[idx] = - (audioh_rate_source_t){.control_id = clock->id, .frequency_access = clock->frequency_access}; + (audioh_rate_source_t){.control_id = clock.id, .frequency_access = clock.frequency_access}; return (int8_t)idx; } #endif @@ -1217,12 +1228,9 @@ static bool audioh_uac1_rates_store(const audioh_interface_t *p_audio, const tuh // Parse one Audio Streaming interface alternate setting and register its // supported configurations into the matching stream. Returns the descriptor // pointer of the next interface. -static const uint8_t *audioh_parse_as(audioh_interface_t *p_audio, const audioh_ac_map_t *ac_map, +static const uint8_t *audioh_parse_as(audioh_interface_t *p_audio, const audioh_ac_desc_range_t *ac_desc, const tusb_desc_interface_t *desc_itf, const uint8_t *p_desc, const uint8_t *desc_end) { - #if !(CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2) - (void)ac_map; - #endif TU_VERIFY(audioh_desc_valid(p_desc, desc_end, sizeof(tusb_desc_interface_t)), NULL); const uint8_t itf_num = desc_itf->bInterfaceNumber; @@ -1392,8 +1400,9 @@ static const uint8_t *audioh_parse_as(audioh_interface_t *p_audio, const audioh_ const audioh_ep_info_t *ep = &ep_info; tuh_audio_stream_t *stream = audioh_get_stream(p_audio, tu_edpt_dir(ep->ep_addr)); TU_ASSERT(stream != NULL, p_desc); - const audioh_terminal_info_t *terminal = audioh_ac_terminal_find(ac_map, class_info.terminal_id); - if (terminal == NULL || terminal->stream_dir != stream->dir) { + audioh_terminal_info_t terminal; + if (!audioh_ac_terminal_find(p_audio, ac_desc, class_info.terminal_id, &terminal) || + terminal.stream_dir != stream->dir) { TU_LOG_DRV(" AUDIO AS itf %u alt %u: terminal %u does not match endpoint direction\r\n", itf_num, alt, class_info.terminal_id); return p_desc; @@ -1439,7 +1448,7 @@ static const uint8_t *audioh_parse_as(audioh_interface_t *p_audio, const audioh_ #endif #if CFG_TUH_AUDIO_PROTOCOLS & TUH_AUDIO_PROTOCOL_UAC2 case AUDIO_INT_PROTOCOL_CODE_V2: { - const int8_t rate_source_idx = audioh_uac2_rate_source_get(p_audio, ac_map, terminal); + const int8_t rate_source_idx = audioh_uac2_rate_source_get(p_audio, ac_desc, &terminal); if (rate_source_idx < 0) { TU_LOG_DRV(" AUDIO AS itf %u alt %u: direct Clock Source not found\r\n", itf_num, alt); return p_desc; @@ -1514,9 +1523,8 @@ uint16_t audioh_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface TU_LOG_DRV("AUDIO opening AC Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr); - audioh_ac_map_t ac_map = {0}; - - p_desc = tu_desc_next(p_desc); + p_desc = tu_desc_next(p_desc); + audioh_ac_desc_range_t ac_desc = {.desc_start = p_desc}; while (p_desc < desc_end) { if (!audioh_desc_valid(p_desc, desc_end, 2)) { goto open_failed; @@ -1529,12 +1537,13 @@ uint16_t audioh_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface if (!audioh_desc_valid(p_desc, desc_end, 3)) { goto open_failed; } - if (!audioh_parse_ac_entity(p_audio, &ac_map, p_desc)) { + if (!audioh_ac_entity_valid(p_audio, p_desc)) { goto open_failed; } } p_desc = tu_desc_next(p_desc); } + ac_desc.desc_end = p_desc; // Parse the contiguous Audio Streaming interfaces of this audio function. while (p_desc < desc_end) { @@ -1558,13 +1567,13 @@ uint16_t audioh_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface TU_LOG_DRV(" Found AS Interface %u (alt = %u)\r\n", desc_interface->bInterfaceNumber, desc_interface->bAlternateSetting); - p_desc = audioh_parse_as(p_audio, &ac_map, desc_interface, p_desc, desc_end); + p_desc = audioh_parse_as(p_audio, &ac_desc, desc_interface, p_desc, desc_end); if (p_desc == NULL) { goto open_failed; } } - audioh_link_feature_units(p_audio, &ac_map); + audioh_link_feature_units(p_audio, &ac_desc); // UAC2 configurations receive their rates asynchronously during mount. // Release the tentative instance when no supported AS alternate was found. |
