From 804e54f9e59dc2b6442844d1194581e2b39c35b1 Mon Sep 17 00:00:00 2001 From: HiFiPHile Date: Wed, 26 Aug 2026 11:33:46 +0200 Subject: audio: preserve descriptor sample-rate entries Retain every valid discrete rate in descriptor order, including duplicate public tuples. Alternate settings remain independently selectable without disruptive validation or deduplication during enumeration. Signed-off-by: HiFiPHile --- src/class/audio/audio_host.c | 23 ---------------------- test/unit-test/test/host/audio/test_audio_host.c | 25 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/class/audio/audio_host.c b/src/class/audio/audio_host.c index 8caecf3d2..a28cad156 100644 --- a/src/class/audio/audio_host.c +++ b/src/class/audio/audio_host.c @@ -994,29 +994,6 @@ static const uint8_t *audioh_parse_as(audioh_interface_t *p_audio, const tusb_de itf_num, alt, ep->ep_size); continue; } - // Skip duplicate configurations already retained from another AS or from - // an earlier frequency entry in this descriptor. - bool duplicate = false; - for (uint8_t as_idx = 0; as_idx < stream->as_count && !duplicate; as_idx++) { - const audioh_as_config_t *existing = &stream->as[as_idx]; - if (existing->format == (uint8_t)format && existing->channels == num_channels) { - for (uint8_t rate_idx = 0; rate_idx < existing->sample_rate_count; rate_idx++) { - if (existing->sample_rate[rate_idx] == sample_rate) { - duplicate = true; - break; - } - } - } - } - for (uint8_t rate_idx = 0; rate_idx < as_config.sample_rate_count && !duplicate; rate_idx++) { - if (as_config.sample_rate[rate_idx] == sample_rate) { - duplicate = true; - } - } - if (duplicate) { - continue; - } - as_config.sample_rate[as_config.sample_rate_count++] = sample_rate; } diff --git a/test/unit-test/test/host/audio/test_audio_host.c b/test/unit-test/test/host/audio/test_audio_host.c index 62119f7be..0d7569090 100644 --- a/test/unit-test/test/host/audio/test_audio_host.c +++ b/test/unit-test/test/host/audio/test_audio_host.c @@ -396,7 +396,7 @@ static const uint8_t playback_with_two_frequencies[] = { TEST_UAC1_AS_ALT0, TEST_UAC1_AS_INTERFACE(1, 1), TEST_UAC1_AS_GENERAL(PLAYBACK_INPUT_TERM), - TEST_UAC1_FORMAT(2, 2, 16, 44100, 48000), + TEST_UAC1_FORMAT(2, 2, 16, 44100, 44100, 48000), TEST_UAC1_DATA_EP(0x01, TUSB_ISO_EP_ATT_ADAPTIVE, 384, 2), TEST_UAC1_CS_DATA_EP, }; @@ -479,7 +479,7 @@ static const uint8_t playback_with_two_alternates[] = { TEST_UAC1_CS_DATA_EP, TEST_UAC1_AS_INTERFACE(2, 1), TEST_UAC1_AS_GENERAL(PLAYBACK_INPUT_TERM), - TEST_UAC1_FORMAT(2, 2, 16, 96000), + TEST_UAC1_FORMAT(2, 2, 16, 48000, 96000), TEST_UAC1_DATA_EP(0x02, TUSB_ISO_EP_ATT_ADAPTIVE, 384, 1), TEST_UAC1_CS_DATA_EP, }; @@ -889,19 +889,34 @@ void test_audio_host_parses_discrete_frequencies_with_interval_greater_than_one( tuh_audio_stream_config_t config; mount_descriptors(playback_with_two_frequencies, sizeof(playback_with_two_frequencies)); - TEST_ASSERT_EQUAL_UINT8(2, tuh_audio_config_count(0, 0)); + TEST_ASSERT_EQUAL_UINT8(3, tuh_audio_config_count(0, 0)); TEST_ASSERT_TRUE(tuh_audio_config_get(0, 0, 0, &config)); TEST_ASSERT_EQUAL_UINT32(44100, config.sample_rate); TEST_ASSERT_TRUE(tuh_audio_config_get(0, 0, 1, &config)); + TEST_ASSERT_EQUAL_UINT32(44100, config.sample_rate); + TEST_ASSERT_TRUE(tuh_audio_config_get(0, 0, 2, &config)); TEST_ASSERT_EQUAL_UINT32(48000, config.sample_rate); - // Both public configurations share one AS mapping but retain their own rate. - TEST_ASSERT_TRUE(tuh_audio_configure(0, 0, 1)); + // All public configurations share one AS mapping and preserve descriptor order. + TEST_ASSERT_TRUE(tuh_audio_configure(0, 0, 2)); TEST_ASSERT_TRUE(tuh_audio_start(0, 0)); complete_interface_set(XFER_RESULT_SUCCESS); TEST_ASSERT_EQUAL_HEX8_ARRAY(((uint8_t[]){U24_TO_U8S_LE(48000)}), control_buffer, 3); } +void test_audio_host_retains_same_rate_in_different_alternate_settings(void) { + tuh_audio_stream_config_t config; + mount_descriptors(playback_with_two_alternates, sizeof(playback_with_two_alternates)); + + TEST_ASSERT_EQUAL_UINT8(3, tuh_audio_config_count(0, 0)); + TEST_ASSERT_TRUE(tuh_audio_config_get(0, 0, 0, &config)); + TEST_ASSERT_EQUAL_UINT32(48000, config.sample_rate); + TEST_ASSERT_TRUE(tuh_audio_config_get(0, 0, 1, &config)); + TEST_ASSERT_EQUAL_UINT32(48000, config.sample_rate); + TEST_ASSERT_TRUE(tuh_audio_config_get(0, 0, 2, &config)); + TEST_ASSERT_EQUAL_UINT32(96000, config.sample_rate); +} + void test_audio_host_keeps_supported_stream_when_other_as_format_is_unsupported(void) { open_descriptors(playback_with_unsupported_capture, sizeof(playback_with_unsupported_capture)); -- cgit v1.3.1