From c11ac5844bdb91b0304e52f228ef388778c43cfd Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Thu, 21 Sep 2023 09:20:14 +0000 Subject: [PATCH 01/11] bluetooth: LE Audio multi-codec extensibility - unicast Bug: 308428217 Bug: 307258939 Test: m android.hardware.bluetooth.audio-update-api Change-Id: I9a40c24212cc36829a11b54977d313bef5e652ca --- .../hardware/bluetooth/audio/CodecInfo.aidl | 8 + .../audio/CodecSpecificCapabilitiesLtv.aidl | 83 ++++ .../audio/CodecSpecificConfigurationLtv.aidl | 101 +++++ .../bluetooth/audio/ConfigurationFlags.aidl | 45 ++ .../audio/IBluetoothAudioProvider.aidl | 108 +++++ .../audio/IBluetoothAudioProviderFactory.aidl | 1 + .../audio/LeAudioAseConfiguration.aidl | 50 +++ .../bluetooth/audio/LeAudioConfiguration.aidl | 11 + .../hardware/bluetooth/audio/MetadataLtv.aidl | 50 +++ .../android/hardware/bluetooth/audio/Phy.aidl | 41 ++ .../hardware/bluetooth/audio/CodecInfo.aidl | 37 ++ .../audio/CodecSpecificCapabilitiesLtv.aidl | 80 ++++ .../audio/CodecSpecificConfigurationLtv.aidl | 96 ++++ .../bluetooth/audio/ConfigurationFlags.aidl | 54 +++ .../audio/IBluetoothAudioProvider.aidl | 424 ++++++++++++++++++ .../audio/IBluetoothAudioProviderFactory.aidl | 16 +- .../audio/LeAudioAseConfiguration.aidl | 87 ++++ .../bluetooth/audio/LeAudioConfiguration.aidl | 34 +- .../hardware/bluetooth/audio/MetadataLtv.aidl | 44 ++ .../android/hardware/bluetooth/audio/Phy.aidl | 29 ++ 20 files changed, 1394 insertions(+), 5 deletions(-) create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl index 2ca9d9648b..2727d6e840 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecInfo.aidl @@ -49,7 +49,15 @@ parcelable CodecInfo { int outputDataPath = 1; boolean useControllerCodec = true; } + parcelable LeAudio { + android.hardware.bluetooth.audio.ChannelMode[] channelMode; + int[] samplingFrequencyHz; + int[] frameDurationUs; + int[] bitdepth; + @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags; + } union Transport { + android.hardware.bluetooth.audio.CodecInfo.LeAudio leAudio; android.hardware.bluetooth.audio.CodecInfo.A2dp a2dp; android.hardware.bluetooth.audio.CodecInfo.Hfp hfp; } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl new file mode 100644 index 0000000000..1049d983fb --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl @@ -0,0 +1,83 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +union CodecSpecificCapabilitiesLtv { + android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedSamplingFrequencies supportedSamplingFrequencies; + android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedFrameDurations supportedFrameDurations; + android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedAudioChannelCounts supportedAudioChannelCounts; + android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedOctetsPerCodecFrame supportedOctetsPerCodecFrame; + android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv.SupportedMaxCodecFramesPerSDU supportedMaxCodecFramesPerSDU; + parcelable SupportedSamplingFrequencies { + int bitmask; + const int HZ8000 = 0x0001; + const int HZ11025 = 0x0002; + const int HZ16000 = 0x0004; + const int HZ22050 = 0x0008; + const int HZ24000 = 0x0010; + const int HZ32000 = 0x0020; + const int HZ44100 = 0x0040; + const int HZ48000 = 0x0080; + const int HZ88200 = 0x0100; + const int HZ96000 = 0x0200; + const int HZ176400 = 0x0400; + const int HZ192000 = 0x0800; + const int HZ384000 = 0x1000; + } + parcelable SupportedFrameDurations { + int bitmask; + const int US7500 = 0x01; + const int US10000 = 0x02; + const int US7500PREFERRED = 0x10; + const int US10000PREFERRED = 0x20; + } + parcelable SupportedAudioChannelCounts { + int bitmask; + const int ONE = 0x01; + const int TWO = 0x02; + const int THREE = 0x04; + const int FOUR = 0x08; + const int FIVE = 0x10; + const int SIX = 0x20; + const int SEVEN = 0x40; + const int EIGHT = 0x80; + } + parcelable SupportedOctetsPerCodecFrame { + int minimum; + int maximum; + } + parcelable SupportedMaxCodecFramesPerSDU { + int value; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl new file mode 100644 index 0000000000..943d396aec --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl @@ -0,0 +1,101 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +union CodecSpecificConfigurationLtv { + android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.CodecFrameBlocksPerSDU codecFrameBlocksPerSDU; + android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.SamplingFrequency samplingFrequency; + android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.FrameDuration frameDuration; + android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.AudioChannelAllocation audioChannelAllocation; + android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv.OctetsPerCodecFrame octetsPerCodecFrame; + @Backing(type="byte") + enum SamplingFrequency { + HZ8000 = 0x01, + HZ11025 = 0x02, + HZ16000 = 0x03, + HZ22050 = 0x04, + HZ24000 = 0x05, + HZ32000 = 0x06, + HZ44100 = 0x07, + HZ48000 = 0x08, + HZ88200 = 0x09, + HZ96000 = 0x0A, + HZ176400 = 0x0B, + HZ192000 = 0x0C, + HZ384000 = 0x0D, + } + @Backing(type="byte") + enum FrameDuration { + US7500 = 0x00, + US10000 = 0x01, + } + parcelable AudioChannelAllocation { + int bitmask; + const int NOT_ALLOWED = 0x00000000; + const int FRONT_LEFT = 0x00000001; + const int FRONT_RIGHT = 0x00000002; + const int FRONT_CENTER = 0x00000004; + const int LOW_FREQUENCY_EFFECTS_1 = 0x00000008; + const int BACK_LEFT = 0x00000010; + const int BACK_RIGHT = 0x00000020; + const int FRONT_LEFT_OF_CENTER = 0x00000040; + const int FRONT_RIGHT_OF_CENTER = 0x00000080; + const int BACK_CENTER = 0x00000100; + const int LOW_FREQUENCY_EFFECTS_2 = 0x00000200; + const int SIDE_LEFT = 0x00000400; + const int SIDE_RIGHT = 0x00000800; + const int TOP_FRONT_LEFT = 0x00001000; + const int TOP_FRONT_RIGHT = 0x00002000; + const int TOP_FRONT_CENTER = 0x00004000; + const int TOP_CENTER = 0x00008000; + const int TOP_BACK_LEFT = 0x00010000; + const int TOP_BACK_RIGHT = 0x00020000; + const int TOP_SIDE_LEFT = 0x00040000; + const int TOP_SIDE_RIGHT = 0x00080000; + const int TOP_BACK_CENTER = 0x00100000; + const int BOTTOM_FRONT_CENTER = 0x00200000; + const int BOTTOM_FRONT_LEFT = 0x00400000; + const int BOTTOM_FRONT_RIGHT = 0x00800000; + const int FRONT_LEFT_WIDE = 0x01000000; + const int FRONT_RIGHT_WIDE = 0x02000000; + const int LEFT_SURROUND = 0x04000000; + const int RIGHT_SURROUND = 0x08000000; + } + parcelable OctetsPerCodecFrame { + int value; + } + parcelable CodecFrameBlocksPerSDU { + int value; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl new file mode 100644 index 0000000000..baf0a4e9f6 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/ConfigurationFlags.aidl @@ -0,0 +1,45 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable ConfigurationFlags { + int bitmask; + const int NONE = 0x0000; + const int LOSSLESS = 0x0001; + const int LOW_LATENCY = 0x0002; + const int ALLOW_ASYMMETRIC_CONFIGURATIONS = 0x0003; + const int SPATIAL_AUDIO = 0x0004; + const int PROVIDE_ASE_METADATA = 0x0005; + const int MONO_MIC_CONFIGURATION = 0x0006; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index ccf5524bf1..788e38f0e9 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -42,4 +42,112 @@ interface IBluetoothAudioProvider { void setLowLatencyModeAllowed(in boolean allowed); android.hardware.bluetooth.audio.A2dpStatus parseA2dpConfiguration(in android.hardware.bluetooth.audio.CodecId codecId, in byte[] configuration, out android.hardware.bluetooth.audio.CodecParameters codecParameters); @nullable android.hardware.bluetooth.audio.A2dpConfiguration getA2dpConfiguration(in List remoteA2dpCapabilities, in android.hardware.bluetooth.audio.A2dpConfigurationHint hint); + void setCodecPriority(in android.hardware.bluetooth.audio.CodecId codecId, int priority); + List getLeAudioAseConfiguration(in @nullable List remoteSinkAudioCapabilities, in @nullable List remoteSourceAudioCapabilities, in List requirements); + android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationPair getLeAudioAseQosConfiguration(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement qosRequirement); + android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(in android.hardware.bluetooth.audio.AudioContext context, in android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap); + void onSinkAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata); + void onSourceAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata); + @VintfStability + parcelable LeAudioDeviceCapabilities { + android.hardware.bluetooth.audio.CodecId codecId; + android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv[] codecSpecificCapabilities; + @nullable byte[] vendorCodecSpecificCapabilities; + @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata; + } + @VintfStability + parcelable LeAudioDataPathConfiguration { + int dataPathId; + android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration.DataPathConfiguration dataPathConfiguration; + android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration.IsoDataPathConfiguration isoDataPathConfiguration; + @VintfStability + parcelable IsoDataPathConfiguration { + android.hardware.bluetooth.audio.CodecId codecId; + boolean isTransparent; + int controllerDelayUs; + @nullable byte[] configuration; + } + @VintfStability + parcelable DataPathConfiguration { + @nullable byte[] configuration; + } + } + @VintfStability + parcelable LeAudioAseQosConfiguration { + int sduIntervalUs; + android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing; + android.hardware.bluetooth.audio.Phy[] phy; + int maxTransportLatencyMs; + int maxSdu; + int retransmissionNum; + } + @Backing(type="byte") @VintfStability + enum Packing { + SEQUENTIAL = 0x00, + INTERLEAVED = 0x01, + } + @Backing(type="byte") @VintfStability + enum Framing { + UNFRAMED = 0x00, + FRAMED = 0x01, + } + @VintfStability + parcelable LeAudioAseConfigurationSetting { + android.hardware.bluetooth.audio.AudioContext audioContext; + android.hardware.bluetooth.audio.IBluetoothAudioProvider.Packing packing; + @nullable List sinkAseConfiguration; + @nullable List sourceAseConfiguration; + @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags; + @VintfStability + parcelable AseDirectionConfiguration { + android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration; + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration qosConfiguration; + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration dataPathConfiguration; + } + } + @VintfStability + parcelable LeAudioConfigurationRequirement { + android.hardware.bluetooth.audio.AudioContext audioContext; + @nullable List sinkAseRequirement; + @nullable List sourceAseRequirement; + @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags; + @VintfStability + parcelable AseDirectionRequirement { + android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration; + } + } + @VintfStability + parcelable LeAudioAseQosConfigurationRequirement { + android.hardware.bluetooth.audio.AudioContext contextType; + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sinkAseQosRequirement; + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sourceAseQosRequirement; + @nullable android.hardware.bluetooth.audio.ConfigurationFlags[] flags; + @VintfStability + parcelable AseQosDirectionRequirement { + android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing; + android.hardware.bluetooth.audio.Phy[] preferredPhy; + int preferredRetransmissionNum; + int maxTransportLatencyMs; + int presentationDelayMinUs; + int presentationDelayMaxUs; + int preferredPresentationDelayMinUs; + int preferredPresentationDelayMaxUs; + android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration; + } + } + @VintfStability + parcelable LeAudioAseQosConfigurationPair { + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration sinkQosConfiguration; + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfiguration sourceQosConfiguration; + } + parcelable LeAudioDataPathConfigurationPair { + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration inputConfig; + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration outputConfig; + } + @Backing(type="byte") @VintfStability + enum AseState { + ENABLING = 0x00, + STREAMING = 0x01, + DISABLING = 0x02, + } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl index c806b0a001..edb79a3da0 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl @@ -41,5 +41,6 @@ interface IBluetoothAudioProviderFactory { parcelable ProviderInfo { String name; android.hardware.bluetooth.audio.CodecInfo[] codecInfos; + boolean supportsMultidirectionalCapabilities; } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl new file mode 100644 index 0000000000..bffc88b352 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl @@ -0,0 +1,50 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable LeAudioAseConfiguration { + android.hardware.bluetooth.audio.LeAudioAseConfiguration.TargetLatency targetLatency; + android.hardware.bluetooth.audio.Phy targetPhy; + @nullable android.hardware.bluetooth.audio.CodecId codecId; + android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv[] codecConfiguration; + @nullable byte[] vendorCodecConfiguration; + @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata; + @Backing(type="byte") @VintfStability + enum TargetLatency { + UNDEFINED = 0x00, + LOWER = 0x01, + BALANCED_LATENCY_RELIABILITY = 0x02, + HIGHER_RELIABILITY = 0x03, + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl index 2d9ebae9f4..25a9797daf 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl @@ -44,5 +44,16 @@ parcelable LeAudioConfiguration { char streamHandle; int audioChannelAllocation; boolean isStreamActive; + @nullable android.hardware.bluetooth.audio.LeAudioAseConfiguration aseConfiguration; + @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags; + @nullable android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap.BluetoothDeviceAddress bluetoothDeviceAddress; + parcelable BluetoothDeviceAddress { + byte[6] deviceAddress; + android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap.BluetoothDeviceAddress.DeviceAddressType deviceAddressType; + enum DeviceAddressType { + BLE_ADDRESS_PUBLIC = 0x00, + BLE_ADDRESS_RANDOM = 0x01, + } + } } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl new file mode 100644 index 0000000000..5e8a2ae25d --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/MetadataLtv.aidl @@ -0,0 +1,50 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +union MetadataLtv { + android.hardware.bluetooth.audio.MetadataLtv.PreferredAudioContexts preferredAudioContexts; + android.hardware.bluetooth.audio.MetadataLtv.StreamingAudioContexts streamingAudioContexts; + android.hardware.bluetooth.audio.MetadataLtv.VendorSpecific vendorSpecific; + parcelable PreferredAudioContexts { + android.hardware.bluetooth.audio.AudioContext values; + } + parcelable StreamingAudioContexts { + android.hardware.bluetooth.audio.AudioContext values; + } + parcelable VendorSpecific { + int companyId; + byte[] opaqueValue; + } +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl new file mode 100644 index 0000000000..bfeabcd5a5 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/Phy.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@Backing(type="byte") @VintfStability +enum Phy { + UNDEFINED = 0x00, + ONE_M = 0x01, + TWO_M = 0x02, + CODED = 0x03, +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl index 127cd7c93a..33f0c04307 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecInfo.aidl @@ -18,6 +18,7 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.ChannelMode; import android.hardware.bluetooth.audio.CodecId; +import android.hardware.bluetooth.audio.ConfigurationFlags; /** * General information about a Codec @@ -86,11 +87,47 @@ parcelable CodecInfo { boolean useControllerCodec = true; } + /** + * LE Audio Context + */ + parcelable LeAudio { + /** + * Channel configuration: Mono, Dual-Mono or Stereo + */ + ChannelMode[] channelMode; + + /** + * Supported sampling frequencies, in Hz. + */ + int[] samplingFrequencyHz; + + /* + * FrameDuration in microseconds. + */ + int[] frameDurationUs; + + /** + * - Fixed point resolution, basically 16, 24 or 32 bits by samples. + * The value 32 should be used for floating point representation. + * + * When the bitdepth is not an encoding/decoding parameter (don't take + * part in the interoperability), the `bitdepth` list shall have a + * single element indicating the bitdepth selected for the platform. + */ + int[] bitdepth; + + /** + * Additional configuration flags + */ + @nullable ConfigurationFlags flags; + } + /** * Specific informations, * depending on transport. */ union Transport { + LeAudio leAudio; A2dp a2dp; Hfp hfp; } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl new file mode 100644 index 0000000000..ceb90baf51 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificCapabilitiesLtv.aidl @@ -0,0 +1,80 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +/** + * Used to exchange generic remote device codec specific capabilities between + * the stack and the provider. As defined in Bluetooth Assigned Numbers, + * Sec. 6.12.4. + */ +@VintfStability +union CodecSpecificCapabilitiesLtv { + parcelable SupportedSamplingFrequencies { + const int HZ8000 = 0x0001; + const int HZ11025 = 0x0002; + const int HZ16000 = 0x0004; + const int HZ22050 = 0x0008; + const int HZ24000 = 0x0010; + const int HZ32000 = 0x0020; + const int HZ44100 = 0x0040; + const int HZ48000 = 0x0080; + const int HZ88200 = 0x0100; + const int HZ96000 = 0x0200; + const int HZ176400 = 0x0400; + const int HZ192000 = 0x0800; + const int HZ384000 = 0x1000; + + /* 16 bits wide bit mask */ + int bitmask; + } + parcelable SupportedFrameDurations { + const int US7500 = 0x01; + const int US10000 = 0x02; + // Bits 2-3 are RFU + const int US7500PREFERRED = 0x10; + const int US10000PREFERRED = 0x20; + + /* 8 bit wide bit mask */ + int bitmask; + } + parcelable SupportedAudioChannelCounts { + const int ONE = 0x01; + const int TWO = 0x02; + const int THREE = 0x04; + const int FOUR = 0x08; + const int FIVE = 0x10; + const int SIX = 0x20; + const int SEVEN = 0x40; + const int EIGHT = 0x80; + + /* 8 bit wide bit mask */ + int bitmask; + } + parcelable SupportedOctetsPerCodecFrame { + int minimum; + int maximum; + } + parcelable SupportedMaxCodecFramesPerSDU { + int value; + } + + SupportedSamplingFrequencies supportedSamplingFrequencies; + SupportedFrameDurations supportedFrameDurations; + SupportedAudioChannelCounts supportedAudioChannelCounts; + SupportedOctetsPerCodecFrame supportedOctetsPerCodecFrame; + SupportedMaxCodecFramesPerSDU supportedMaxCodecFramesPerSDU; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl new file mode 100644 index 0000000000..c099ebe108 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/CodecSpecificConfigurationLtv.aidl @@ -0,0 +1,96 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +/** + * Used to exchange generic remote device configuration between the stack and + * the provider. As defined in Bluetooth Assigned Numbers, Sec. 6.12.5. + */ +@VintfStability +union CodecSpecificConfigurationLtv { + @Backing(type="byte") + enum SamplingFrequency { + HZ8000 = 0x01, + HZ11025 = 0x02, + HZ16000 = 0x03, + HZ22050 = 0x04, + HZ24000 = 0x05, + HZ32000 = 0x06, + HZ44100 = 0x07, + HZ48000 = 0x08, + HZ88200 = 0x09, + HZ96000 = 0x0A, + HZ176400 = 0x0B, + HZ192000 = 0x0C, + HZ384000 = 0x0D, + } + + @Backing(type="byte") + enum FrameDuration { + US7500 = 0x00, + US10000 = 0x01, + } + + parcelable AudioChannelAllocation { + const int NOT_ALLOWED = 0x00000000; + const int FRONT_LEFT = 0x00000001; + const int FRONT_RIGHT = 0x00000002; + const int FRONT_CENTER = 0x00000004; + const int LOW_FREQUENCY_EFFECTS_1 = 0x00000008; + const int BACK_LEFT = 0x00000010; + const int BACK_RIGHT = 0x00000020; + const int FRONT_LEFT_OF_CENTER = 0x00000040; + const int FRONT_RIGHT_OF_CENTER = 0x00000080; + const int BACK_CENTER = 0x00000100; + const int LOW_FREQUENCY_EFFECTS_2 = 0x00000200; + const int SIDE_LEFT = 0x00000400; + const int SIDE_RIGHT = 0x00000800; + const int TOP_FRONT_LEFT = 0x00001000; + const int TOP_FRONT_RIGHT = 0x00002000; + const int TOP_FRONT_CENTER = 0x00004000; + const int TOP_CENTER = 0x00008000; + const int TOP_BACK_LEFT = 0x00010000; + const int TOP_BACK_RIGHT = 0x00020000; + const int TOP_SIDE_LEFT = 0x00040000; + const int TOP_SIDE_RIGHT = 0x00080000; + const int TOP_BACK_CENTER = 0x00100000; + const int BOTTOM_FRONT_CENTER = 0x00200000; + const int BOTTOM_FRONT_LEFT = 0x00400000; + const int BOTTOM_FRONT_RIGHT = 0x00800000; + const int FRONT_LEFT_WIDE = 0x01000000; + const int FRONT_RIGHT_WIDE = 0x02000000; + const int LEFT_SURROUND = 0x04000000; + const int RIGHT_SURROUND = 0x08000000; + + // Bit mask of Audio Locations + int bitmask; + } + + parcelable OctetsPerCodecFrame { + int value; + } + + parcelable CodecFrameBlocksPerSDU { + int value; + } + + CodecFrameBlocksPerSDU codecFrameBlocksPerSDU; + SamplingFrequency samplingFrequency; + FrameDuration frameDuration; + AudioChannelAllocation audioChannelAllocation; + OctetsPerCodecFrame octetsPerCodecFrame; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl new file mode 100644 index 0000000000..57c8be5b00 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/ConfigurationFlags.aidl @@ -0,0 +1,54 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +/** + * Coding fetures + */ +@VintfStability +parcelable ConfigurationFlags { + const int NONE = 0x0000; + /* + * Set for the lossless configurations + */ + const int LOSSLESS = 0x0001; + /* + * Set for the low latency configurations + */ + const int LOW_LATENCY = 0x0002; + /* + * When set, asymmetric configuration for SINK and SOURCE can be used. + * e.g. in GAMING mode stream for 32kHz and back channel for 16 kHz + */ + const int ALLOW_ASYMMETRIC_CONFIGURATIONS = 0x0003; + /* + * Set for the spatial audio configurations + */ + const int SPATIAL_AUDIO = 0x0004; + /* + * When set, BluetoothAudioProvider requests to receive ASE metadata. + * In such case onSinkAseMetadataChanged() and onSourceAseMetadataChanged + * will be called. + */ + const int PROVIDE_ASE_METADATA = 0x0005; + /* + * Set for mono microphone configurations + */ + const int MONO_MIC_CONFIGURATION = 0x0006; + + int bitmask; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index b5c8a31ce5..f5650181ab 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -21,11 +21,18 @@ import android.hardware.bluetooth.audio.A2dpConfigurationHint; import android.hardware.bluetooth.audio.A2dpRemoteCapabilities; import android.hardware.bluetooth.audio.A2dpStatus; import android.hardware.bluetooth.audio.AudioConfiguration; +import android.hardware.bluetooth.audio.AudioContext; import android.hardware.bluetooth.audio.BluetoothAudioStatus; import android.hardware.bluetooth.audio.CodecId; import android.hardware.bluetooth.audio.CodecParameters; +import android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv; +import android.hardware.bluetooth.audio.ConfigurationFlags; import android.hardware.bluetooth.audio.IBluetoothAudioPort; import android.hardware.bluetooth.audio.LatencyMode; +import android.hardware.bluetooth.audio.LeAudioAseConfiguration; +import android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap; +import android.hardware.bluetooth.audio.MetadataLtv; +import android.hardware.bluetooth.audio.Phy; import android.hardware.common.fmq.MQDescriptor; import android.hardware.common.fmq.SynchronizedReadWrite; @@ -124,4 +131,421 @@ interface IBluetoothAudioProvider { */ @nullable A2dpConfiguration getA2dpConfiguration( in List remoteA2dpCapabilities, in A2dpConfigurationHint hint); + + /** + * Set specific codec priority + * + * It should be assumed that the external module will start with all its + * integrated codecs priority 0 by default. + * + * @param codecId: codecId + * @param priority: 0 for no priority, -1 for codec disabled, + * from 1 to N, where 1 is highest. + */ + void setCodecPriority(in CodecId codecId, int priority); + + /** + * LE Audio device Capabilities - as defined in Bluetooth Published Audio + * Capabilities Service specification, v1.0.1, Sec. 3.1: "Sink PAC", and + * Sec. 3.3: "Source PAC". + */ + @VintfStability + parcelable LeAudioDeviceCapabilities { + /** + * Codec Identifier + */ + CodecId codecId; + /** + * Codec capabilities, packed as LTV. + */ + CodecSpecificCapabilitiesLtv[] codecSpecificCapabilities; + /** + * Vendor codec specific capabilities. + * + * This will not be parsed by the BT stack, but passed to the vendor + * module who can interpret this and based on that select the proper + * vendor specific codec configuration. + */ + @nullable byte[] vendorCodecSpecificCapabilities; + /** + * Audio capabilities metadata, packed as LTV. + */ + @nullable MetadataLtv[] metadata; + } + + @VintfStability + parcelable LeAudioDataPathConfiguration { + /** + * Vendor specific data path identifier + */ + int dataPathId; + + /** + * Used in the HCI_LE_Setup_ISO_Data_Path (0x006E). + * As defined in Bluetooth Core Specification Version + * 5.3, Vol 4, Part E, Sec. 7.8.109: "LE Setup ISO Data Path command". + */ + @VintfStability + parcelable IsoDataPathConfiguration { + /** + * Codec ID - Valid Codec Identifier matching the selected codec + */ + CodecId codecId; + /** + * Whether the transparent air mode should be set as a coding format + * in the HCI_LE_Setup_ISO_Data_Path command, indicating that the + * codec is not in the controller. + * + * If set to true, 0x03 (transparent air mode) will be used as a + * Codec_ID coding format and the `byte[] configuration` field shall + * remain empty. Otherwise the Codec_ID field will be set to + * according to BT specification (0xFF coding format, company ID, + * codec ID for vendor codecs, or according to Codec_ID identifiers + * defined in the Assigned Numbers for the non-vendor codecs). + */ + boolean isTransparent; + /** + * Controller delay (in microseconds) + */ + int controllerDelayUs; + /** + * Codec specific LE Audio ISO data path configuration + * must be null when codec ID is 0x03 transparent + */ + @nullable byte[] configuration; + } + + /** + * Used in HCI_Configure_Data_Path (0x0083) + * As defined in Bluetooth Core Specification Version + * 5.3, Vol 4, Part E, Sec. 7.3.101: "Configure Data Path command". + */ + @VintfStability + parcelable DataPathConfiguration { + /** + * Vendor specific data path configuration + */ + @nullable byte[] configuration; + } + /** + * Data path configuration + */ + DataPathConfiguration dataPathConfiguration; + /** + * ISO data path configuration + */ + IsoDataPathConfiguration isoDataPathConfiguration; + } + + /* All the LeAudioAseQosConfiguration parameters are defined by the + * Bluetooth Audio Stream Control Service specification v.1.0, Sec. 5: "ASE + * Control Operations". + */ + @VintfStability + parcelable LeAudioAseQosConfiguration { + /** + * SDU Interval (in microseconds) used in Set CIG Parameters command and + * Configure QoS. + */ + int sduIntervalUs; + /** + * Framing used in Set CIG Parameters command and Configure QoS + */ + Framing framing; + /** + * Phy used in Set CIG Parameters command and Configure QoS + */ + Phy[] phy; + /** + * Max transport latency (in milliseconds) used in Set CIG Parameters + * command and Configure QoS. + */ + int maxTransportLatencyMs; + /** + * Max SDU used in Set CIG Parameters command and Configure QoS + */ + int maxSdu; + /** + * Retransmission number used in Set CIG Parameters command and + * Configure QoS + */ + int retransmissionNum; + } + + /** + * Connected Isochronous Channel arrangement within the Connected + * Isochronous Group. As defined in Bluetooth Core Specification Version + * 5.3, Vol 4, Part E, Sec. 7.8.97. + */ + @VintfStability + @Backing(type="byte") + enum Packing { + SEQUENTIAL = 0x00, + INTERLEAVED = 0x01, + } + + /** + * Isochronous Data PDU framing parameter. As defined in Bluetooth Core + * Specification Version 5.3, Vol 4, Part E, Sec. 7.8.97. + */ + @VintfStability + @Backing(type="byte") + enum Framing { + UNFRAMED = 0x00, + FRAMED = 0x01, + } + + @VintfStability + parcelable LeAudioAseConfigurationSetting { + /** + * Audio Context that this configuration apply to + */ + AudioContext audioContext; + /** + * Sequential or interleave packing used in Set CIG Parameters command + */ + Packing packing; + + @VintfStability + parcelable AseDirectionConfiguration { + /** + * ASE configuration + */ + LeAudioAseConfiguration aseConfiguration; + /** + * QoS Configuration + */ + @nullable LeAudioAseQosConfiguration qosConfiguration; + /** + * Data path configuration + * If not provided, getLeAudioAseDatapathConfiguration() will be + * called during the configuration, increasing the stream + * establishment time (not recommended). + */ + @nullable LeAudioDataPathConfiguration dataPathConfiguration; + } + /** + * Sink ASEs configuration + */ + @nullable List sinkAseConfiguration; + /** + * Source ASEs configuration + */ + @nullable List sourceAseConfiguration; + /** + * Additional flags, used for configurations with special features + */ + @nullable ConfigurationFlags flags; + } + + /** + * ASE configuration requirements set by the BT stack. + */ + @VintfStability + parcelable LeAudioConfigurationRequirement { + /** + * Audio Contect that this requirements apply to + */ + AudioContext audioContext; + + @VintfStability + parcelable AseDirectionRequirement { + /** + * Optional ASE configurations requirements + * + * Note that the Host can set as many or as little parameters in + * the `aseConfiguration.codecConfiguration` field as needed, to + * closely or loosely specify the requirements. If any parameter + * is not specified, the offloader can choose it freely. The + * offloader should put all the specified parameters into the + * `aseConfiguration.codecConfiguration` field of the returned + * configuration to let the BT stack verify if the requirements + * were met. The mandatory requirement set by the BT stack will be + * the Audio Location. + */ + LeAudioAseConfiguration aseConfiguration; + } + /** + * Sink ASEs configuration setting + */ + @nullable List sinkAseRequirement; + /** + * Source ASEs configuration setting + */ + @nullable List sourceAseRequirement; + /** + * Additional flags, used to request configurations with special + * features + */ + @nullable ConfigurationFlags flags; + } + + /** + * Method that returns a proposed ASE configuration settings for each + * requested audio context type + * + * Note: _ENCODING session provides SINK ASE configuration + * and _DECODING session provides SOURCE ASE configuration unless + * BluetoothAudioProvider sets supportsMultidirectionalCapabilities to + * true in ProviderInfo. + * If supportsMultidirectionalCapabilities is set to true then the + * BluetoothStack expects to get configuration list for SINK and SOURCE + * on either _ENCODING or _DECODING session. + * + * @param remoteSinkAudioCapabilities List of remote sink capabilities + * supported by an active group devices. + * @param remoteSourceAudioCapabilities List of remote source capabilities + * supported by an active group devices. + * @param requirements ASE configuration requirements + * + * @return List + */ + List getLeAudioAseConfiguration( + in @nullable List remoteSinkAudioCapabilities, + in @nullable List remoteSourceAudioCapabilities, + in List requirements); + + @VintfStability + parcelable LeAudioAseQosConfigurationRequirement { + /** + * Audio Contect Type that this requirements apply to + */ + AudioContext contextType; + + /** + * QoS preferences received in Codec Configured ASE state. As defined in + * bluetooth service specification: Audio Stream Control Service" V1.0, + * Sec. 4.1 Audio Stream Endpoints, Table 4.3:"Additional_ASE_Parameters + * format when ASE_State = 0x01 (Codec Configured)". + */ + @VintfStability + parcelable AseQosDirectionRequirement { + /** + * Support for unframed Isochronous Adaptation Layer PDUs. + * When set to FRAMED, the unframed PDUs are not supported. + */ + Framing framing; + /** + * Preferred value for the PHY parameter to be written by the client + * for this ASE in the Config QoS operation + */ + Phy[] preferredPhy; + /** + * Preferred value for the Retransmission Number parameter to be + * written by the client for this ASE in the Config QoS operation. + */ + int preferredRetransmissionNum; + /** + * Preferred value for the Max Transport Latency parameter to be + * written by the client for this ASE in the Config QoS operation. + */ + int maxTransportLatencyMs; + /** + * Minimum server supported Presentation Delay (in microseconds) for + * an ASE. + */ + int presentationDelayMinUs; + /** + * Maximum server supported Presentation Delay (in microseconds) for + * an ASE. + */ + int presentationDelayMaxUs; + /** + * Preferred minimum Presentation Delay (in microseconds) for an + * ASE. + */ + int preferredPresentationDelayMinUs; + /** + * Preferred maximum Presentation Delay (in microseconds) for an + * ASE. + */ + int preferredPresentationDelayMaxUs; + + /** + * ASE configuration + */ + LeAudioAseConfiguration aseConfiguration; + } + /** + * Sink ASEs configuration setting + */ + @nullable AseQosDirectionRequirement sinkAseQosRequirement; + /** + * Source ASEs configuration setting + */ + @nullable AseQosDirectionRequirement sourceAseQosRequirement; + /** + * Additional configuration flags requirements + */ + @nullable ConfigurationFlags[] flags; + } + + /** + * A directional pair for QoS configuration. Either one or both directions + * can be set, depending on the audio context and the requirements provided + * to getLeAudioAseQosConfiguration(). + */ + @VintfStability + parcelable LeAudioAseQosConfigurationPair { + @nullable LeAudioAseQosConfiguration sinkQosConfiguration; + @nullable LeAudioAseQosConfiguration sourceQosConfiguration; + } + + /** + * Method that returns an ASE QoS configuration settings for the given ASE + * configuration,taking an ASE preferenced QoS parameters. It should be used + * to negotiaite the QoS parameters, when the initialy received QoS + * parameters are not within the boundaries received from the remote device + * after configuring the ASEs. + * + * @param qosRequirement ASE QoS configurations requirements + * + * @return LeAudioAseQosConfigurationPair + */ + LeAudioAseQosConfigurationPair getLeAudioAseQosConfiguration( + in LeAudioAseQosConfigurationRequirement qosRequirement); + + /** + * Audio data path configuration. + */ + parcelable LeAudioDataPathConfigurationPair { + /* Host to Controller data path */ + @nullable LeAudioDataPathConfiguration inputConfig; + /* Controller to Host data path */ + @nullable LeAudioDataPathConfiguration outputConfig; + } + + /** + * Used to get a data path configuration which dynamically depends on CIS + * connection handles in StreamMap. This is used if non-dynamic data path + * was not provided in LeAudioAseConfigurationSetting. Calling this during + * the unicast audio stream establishment might slightly delay the stream + * start. + */ + LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration( + in AudioContext context, in StreamMap[] streamMap); + + /* + * Audio Stream Endpoint state used to report Metadata changes on the remote + * device audio endpoints. + */ + @VintfStability + @Backing(type="byte") + enum AseState { + ENABLING = 0x00, + STREAMING = 0x01, + DISABLING = 0x02, + } + + /** + * Used to report metadata changes to the provider. This allows for a + * pseudo communication channel between the remote device and the provider, + * using the vendor specific metadata of the changing ASE state. + * It is used only when ASE is using configurations marked with the + * `PROVIDE_ASE_METADATA` flag. + */ + void onSinkAseMetadataChanged( + in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata); + void onSourceAseMetadataChanged( + in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata); } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl index b9cec2d38d..ea9c4e1709 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProviderFactory.aidl @@ -69,19 +69,33 @@ interface IBluetoothAudioProviderFactory { * General information relative to a provider * - An optional name * - A list of codec information + * - supportsMultidirectionalCapabilities if is set to false it means each + * session i.e. _ENCODING and _DECODING is responsible to provide + * configuration for a single direction: + * _ENCODING for SINK ASE + * _DECODING for SOURCE ASE + * + * If supportsMultidirectionalCapabilities is set to true, then either + * _ENCODING or _DECODING session can provide the configurations for either + * direction. */ @VintfStability parcelable ProviderInfo { String name; CodecInfo[] codecInfos; + boolean supportsMultidirectionalCapabilities; } /** * Get general information relative to a provider. * + * This can be called at any time, or just once during the BT stack + * initialization. + * * @param sessionType Hardware Offload provider (*_HARDWARE_OFFLOAD_*) * @return General information relative to the provider. - * The `null` value can be returned when the provider is not available + * The `null` value can be returned when the provider is not + * available */ @nullable ProviderInfo getProviderInfo(in SessionType sessionType); } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl new file mode 100644 index 0000000000..9fb2ecf99d --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.aidl @@ -0,0 +1,87 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +import android.hardware.bluetooth.audio.CodecId; +import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv; +import android.hardware.bluetooth.audio.MetadataLtv; +import android.hardware.bluetooth.audio.Phy; + +/** + * All the LeAudioAseConfiguration parameters are defined by the Bluetooth Audio + * Stream Control Service specification v.1.0, Sec. 5: "ASE Control Operations". + */ +@VintfStability +parcelable LeAudioAseConfiguration { + @VintfStability + @Backing(type="byte") + enum TargetLatency { + UNDEFINED = 0x00, + LOWER = 0x01, + BALANCED_LATENCY_RELIABILITY = 0x02, + HIGHER_RELIABILITY = 0x03, + } + + /** + * Target latency used in Configure Codec command - Can be UNDEFINED when + * used inside the AseDirectionRequirement, but shall not be UNDEFINED when + * used inside LeAudioAseConfigurationSetting. + */ + TargetLatency targetLatency; + + /** + * Target PHY used in Configure Codec command - Can be UNDEFINED when used + * inside the AseDirectionRequirement, but shall not be UNDEFINED when used + * inside LeAudioAseConfigurationSetting. + */ + Phy targetPhy; + + /** + * Codec ID - Can be Null when used inside the AseDirectionRequirement, but + * shall not be Null when used inside LeAudioAseConfigurationSetting. + */ + @nullable CodecId codecId; + + /** + * Codec configuration for ASE represented in the LTV types defined by + * Bluetooth SIG. Regardless of vendor specific configuration being used or + * not, this shall contain Bluetooth LTV types describing the common stream + * parameters, at least CodecSpecificConfigurationLtv.SamplingFrequency and + * CodecSpecificConfigurationLtv.AudioChannelAllocation. In addition, it + * should match aseConfiguration provided in LeAudioConfigurationRequirement + * as this will also be used to verify the requirements on the known LTV + * types. + */ + CodecSpecificConfigurationLtv[] codecConfiguration; + + /** + * Vendor specific codec configuration for ASE. + * + * This will not be parsed by the BT stack but will be written to the remote + * device as the codec specific configuration as part of the codec configure + * control point operation. If this is populated, only the + * `vendorCodecConfiguration` will be used for the ASE configuration, + * otherwise `codecConfiguration` will be used. The BT stack will not merge + * it with the codecConfiguration for any purpose. + */ + @nullable byte[] vendorCodecConfiguration; + + /** + * Metadata, packed as LTV - used to enable ASE. This is optional + */ + @nullable MetadataLtv[] metadata; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl index 7302aea255..db753ada96 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioConfiguration.aidl @@ -17,6 +17,8 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.ConfigurationFlags; +import android.hardware.bluetooth.audio.LeAudioAseConfiguration; import android.hardware.bluetooth.audio.LeAudioCodecConfiguration; @VintfStability @@ -29,16 +31,40 @@ parcelable LeAudioConfiguration { */ char streamHandle; /* - * Audio channel allocation is a bit field, each enabled bit means that given audio - * direction, i.e. "left", or "right" is used. Ordering of audio channels comes from the - * least significant bit to the most significant bit. The valus follows the Bluetooth SIG - * Audio Location assigned number. + * Audio channel allocation is a bit field, each enabled bit means that + * given audio direction, i.e. "left", or "right" is used. Ordering of + * audio channels comes from the least significant bit to the most + * significant bit. The valus follows the Bluetooth SIG Audio Location + * assigned number. */ int audioChannelAllocation; /* * The stream handle status */ boolean isStreamActive; + /* + * LE Audio device ASE configuration + */ + @nullable LeAudioAseConfiguration aseConfiguration; + /* + * Additional flags, used for configurations with special features + */ + @nullable ConfigurationFlags flags; + parcelable BluetoothDeviceAddress { + enum DeviceAddressType { + BLE_ADDRESS_PUBLIC = 0x00, + BLE_ADDRESS_RANDOM = 0x01, + } + /** + * Peer device address. It should be non zero when isStreamActive is true + */ + byte[6] deviceAddress; + /** + * Peer device address type. + */ + DeviceAddressType deviceAddressType; + } + @nullable BluetoothDeviceAddress bluetoothDeviceAddress; } CodecType codecType; StreamMap[] streamMap; diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl new file mode 100644 index 0000000000..b0befc15b9 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/MetadataLtv.aidl @@ -0,0 +1,44 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +import android.hardware.bluetooth.audio.AudioContext; + +/** + * Used to exchange generic metadata between the stack and the provider. + * As defined in Bluetooth Assigned Numbers, Sec. 6.12.6. + */ +@VintfStability +union MetadataLtv { + parcelable PreferredAudioContexts { + AudioContext values; + } + parcelable StreamingAudioContexts { + AudioContext values; + } + /* This is an opaque container for passing metadata between the provider and + * the remote device. It must not be interpreted by the BT stack. + */ + parcelable VendorSpecific { + int companyId; + byte[] opaqueValue; + } + + PreferredAudioContexts preferredAudioContexts; + StreamingAudioContexts streamingAudioContexts; + VendorSpecific vendorSpecific; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl new file mode 100644 index 0000000000..cbffdd5207 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/Phy.aidl @@ -0,0 +1,29 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +/** + * Used to exchange generic Phy parameter between the stack and the provider. + */ +@VintfStability +@Backing(type="byte") +enum Phy { + UNDEFINED = 0x00, + ONE_M = 0x01, + TWO_M = 0x02, + CODED = 0x03, +} From 8edc51bbbd4704fa8c4e66fadd72abd27acea426 Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Thu, 21 Sep 2023 12:37:58 +0000 Subject: [PATCH 02/11] bluetooth: LE Audio multi-codec extensibility - broadcast Bug: 308428217 Bug: 307258939 Test: m android.hardware.bluetooth.audio-update-api Change-Id: I50c07be7bd947f095824f3cf4630c0d640921f9a --- .../audio/IBluetoothAudioProvider.aidl | 42 ++++- .../audio/LeAudioBisConfiguration.aidl | 41 +++++ .../audio/LeAudioBroadcastConfiguration.aidl | 2 + .../audio/IBluetoothAudioProvider.aidl | 159 +++++++++++++++++- .../audio/LeAudioBisConfiguration.aidl | 65 +++++++ .../audio/LeAudioBroadcastConfiguration.aidl | 11 ++ 6 files changed, 318 insertions(+), 2 deletions(-) create mode 100644 bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl create mode 100644 bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index 788e38f0e9..f155634430 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -48,6 +48,8 @@ interface IBluetoothAudioProvider { android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(in android.hardware.bluetooth.audio.AudioContext context, in android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap); void onSinkAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata); void onSourceAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata); + android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationSetting getLeAudioBroadcastConfiguration(in @nullable List remoteSinkAudioCapabilities, in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationRequirement requirement); + android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration getLeAudioBroadcastDatapathConfiguration(in android.hardware.bluetooth.audio.AudioContext context, in android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap[] streamMap); @VintfStability parcelable LeAudioDeviceCapabilities { android.hardware.bluetooth.audio.CodecId codecId; @@ -121,7 +123,7 @@ interface IBluetoothAudioProvider { android.hardware.bluetooth.audio.AudioContext contextType; @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sinkAseQosRequirement; @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement.AseQosDirectionRequirement sourceAseQosRequirement; - @nullable android.hardware.bluetooth.audio.ConfigurationFlags[] flags; + @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags; @VintfStability parcelable AseQosDirectionRequirement { android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing; @@ -150,4 +152,42 @@ interface IBluetoothAudioProvider { STREAMING = 0x01, DISABLING = 0x02, } + @Backing(type="byte") @VintfStability + enum BroadcastQuality { + STANDARD, + HIGH, + } + @VintfStability + parcelable LeAudioBroadcastSubgroupConfigurationRequirement { + android.hardware.bluetooth.audio.AudioContext context; + android.hardware.bluetooth.audio.IBluetoothAudioProvider.BroadcastQuality quality; + int bisNumPerSubgroup; + } + @VintfStability + parcelable LeAudioBroadcastConfigurationRequirement { + List subgroupConfigurationRequirements; + } + @VintfStability + parcelable LeAudioSubgroupBisConfiguration { + int numBis; + android.hardware.bluetooth.audio.LeAudioBisConfiguration bisConfiguration; + } + @VintfStability + parcelable LeAudioBroadcastSubgroupConfiguration { + List bisConfigurations; + @nullable byte[] vendorCodecConfiguration; + } + @VintfStability + parcelable LeAudioBroadcastConfigurationSetting { + int sduIntervalUs; + int numBis; + int maxSduOctets; + int maxTransportLatencyMs; + int retransmitionNum; + android.hardware.bluetooth.audio.Phy[] phy; + android.hardware.bluetooth.audio.IBluetoothAudioProvider.Packing packing; + android.hardware.bluetooth.audio.IBluetoothAudioProvider.Framing framing; + @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration dataPathConfiguration; + List subgroupsConfigurations; + } } diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl new file mode 100644 index 0000000000..b09d34fec2 --- /dev/null +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl @@ -0,0 +1,41 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.bluetooth.audio; +@VintfStability +parcelable LeAudioBisConfiguration { + android.hardware.bluetooth.audio.CodecId codecId; + android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv[] codecConfiguration; + byte[] vendorCodecConfiguration; + @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata; +} diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl index 2945710c26..efd3b02818 100644 --- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl +++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl @@ -42,5 +42,7 @@ parcelable LeAudioBroadcastConfiguration { int audioChannelAllocation; android.hardware.bluetooth.audio.LeAudioCodecConfiguration leAudioCodecConfig; char pcmStreamId; + @nullable android.hardware.bluetooth.audio.LeAudioBisConfiguration bisConfiguration; + @nullable android.hardware.bluetooth.audio.ConfigurationFlags flags; } } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl index f5650181ab..2e16f4e33f 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl @@ -26,10 +26,13 @@ import android.hardware.bluetooth.audio.BluetoothAudioStatus; import android.hardware.bluetooth.audio.CodecId; import android.hardware.bluetooth.audio.CodecParameters; import android.hardware.bluetooth.audio.CodecSpecificCapabilitiesLtv; +import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv; import android.hardware.bluetooth.audio.ConfigurationFlags; import android.hardware.bluetooth.audio.IBluetoothAudioPort; import android.hardware.bluetooth.audio.LatencyMode; import android.hardware.bluetooth.audio.LeAudioAseConfiguration; +import android.hardware.bluetooth.audio.LeAudioBisConfiguration; +import android.hardware.bluetooth.audio.LeAudioBroadcastConfiguration.BroadcastStreamMap; import android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap; import android.hardware.bluetooth.audio.MetadataLtv; import android.hardware.bluetooth.audio.Phy; @@ -477,7 +480,7 @@ interface IBluetoothAudioProvider { /** * Additional configuration flags requirements */ - @nullable ConfigurationFlags[] flags; + @nullable ConfigurationFlags flags; } /** @@ -548,4 +551,158 @@ interface IBluetoothAudioProvider { in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata); void onSourceAseMetadataChanged( in AseState state, int cigId, int cisId, in @nullable MetadataLtv[] metadata); + + /** + * Broadcast quality index + */ + @VintfStability + @Backing(type="byte") + enum BroadcastQuality { + STANDARD, + HIGH, + } + + /** + * It is used in LeAudioBroadcastConfigurationRequirement + */ + @VintfStability + parcelable LeAudioBroadcastSubgroupConfigurationRequirement { + /** + * Streaming Audio Context for the given subgroup. + * This can serve as a hint for selecting the proper configuration by + * the offloader. + */ + AudioContext context; + /** + * Streaming Broadcast Audio Quality + */ + BroadcastQuality quality; + /** + * Number of BISes for the given subgroup + */ + int bisNumPerSubgroup; + } + + /** + * It is used in getLeAudioBroadcastConfiguration method + * If any group id is provided, the Provider should check Pacs capabilities + * of the group(s) and provide Broadcast configuration supported by the + * group. + */ + @VintfStability + parcelable LeAudioBroadcastConfigurationRequirement { + List subgroupConfigurationRequirements; + } + + /** + * Subgroup BIS configuration + * + */ + @VintfStability + parcelable LeAudioSubgroupBisConfiguration { + /** + * The number of BISes with the given configuration + */ + int numBis; + /** + * LE Audio BIS configuration for the `numBis` number of BISes + */ + LeAudioBisConfiguration bisConfiguration; + } + + /** + * Subgroup configuration with a list of BIS configurations + * + */ + @VintfStability + parcelable LeAudioBroadcastSubgroupConfiguration { + List bisConfigurations; + + /** + * Vendor specific codec configuration for all the BISes inside this + * subgroup. Only the vendor specific part is needed, since the BT stack + * can derive the common subgroup configuration by intersecting the LTV + * formatted configuration of every BIS inside the subgroup. + * This will not be parsed by the BT stack but will be set as the codec + * specific configuration for the ongoing audio stream at the subgroup + * level of the audio announcement,The remote device will receive this + * information when being configured for receiveing a brodcast audio + * stream. + */ + @nullable byte[] vendorCodecConfiguration; + } + + /** + * LeAudioBroadcastConfigurationSetting is a result of + * getLeAudioBroadcastConfiguration. It is used in HCI_LE_Create_BIG command + * and for creating the Broadcast Announcements. + * + */ + @VintfStability + parcelable LeAudioBroadcastConfigurationSetting { + /** + * SDU Interval (in microseconds) used in LE Create BIG command + */ + int sduIntervalUs; + /** + * Total number of BISes in the BIG + */ + int numBis; + /** + * Maximum size of an SDU in octets + */ + int maxSduOctets; + /** + * Maximum transport latency (in milliseconds) + */ + int maxTransportLatencyMs; + /** + * The number of times every PDU should be retransmitted + */ + int retransmitionNum; + /** + * A list of PHYs used for transmission of PDUs of BISes in the BIG. + */ + Phy[] phy; + /** + * The preferred method of arranging subevents of multiple BISes + */ + Packing packing; + /** + * format for sending BIS Data PDUs + */ + Framing framing; + + /** + * Data path configuration + * If not provided, getLeAudioBroadcastDatapathConfiguration() will be + * called during the configuration, increasing the stream establishment + * time (not recommended). + */ + @nullable LeAudioDataPathConfiguration dataPathConfiguration; + + /** + * A list of subgroup configurations in the broadcast. + */ + List subgroupsConfigurations; + } + + /** + * Get Broadcast configuration. Output of this function will be used + * in HCI_LE_Create_BIG (0x0068) command and also to create BIG INFO + * + */ + LeAudioBroadcastConfigurationSetting getLeAudioBroadcastConfiguration( + in @nullable List remoteSinkAudioCapabilities, + in LeAudioBroadcastConfigurationRequirement requirement); + + /** + * Used to get a data path configuration which dynamically depends on BIS + * handles in BroadcastStreamMap. This is used if non-dynamic data path was + * not provided in LeAudioBroadcastConfigurationSetting. Calling this during + * the broadcast audio stream establishment might slightly delay the stream + * start. + */ + LeAudioDataPathConfiguration getLeAudioBroadcastDatapathConfiguration( + in AudioContext context, in BroadcastStreamMap[] streamMap); } diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl new file mode 100644 index 0000000000..4d6cfde020 --- /dev/null +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBisConfiguration.aidl @@ -0,0 +1,65 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.bluetooth.audio; + +import android.hardware.bluetooth.audio.CodecId; +import android.hardware.bluetooth.audio.CodecSpecificConfigurationLtv; +import android.hardware.bluetooth.audio.MetadataLtv; + +/** + * LE Audio BIS configuration. This will be part of the streaming broadcast + * audio announcement advertised by the BT stack during the broadcast audio + * stream to inform the remote devices about the broadcast audio configuration. + * It will also be passed back to the vendor module as part of the currently + * active LeAudioBroadcastConfiguration for the encoder setup. + * As defined in Bluetooth Basic Audio Profile Specification, v.1.0.1, + * Sec. 3.7.2.2, Table 3.15, Level 3. + */ +@VintfStability +parcelable LeAudioBisConfiguration { + /** + * Codec ID + */ + CodecId codecId; + + /** + * Codec configuration for BIS or group of BISes represented in the LTV + * types defined by Bluetooht SIG. Regardless of vendor specific + * configuration being used or not, this shall contain Bluetooth LTV types + * describing the common stream parameters, at least + * CodecSpecificConfigurationLtv.SamplingFrequency and + * CodecSpecificConfigurationLtv.AudioChannelAllocation. + * This will also be used to verify the requirements on the known LTV types. + */ + CodecSpecificConfigurationLtv[] codecConfiguration; + + /** + * Vendor specific codec configuration. + * This will not be parsed by the BT stack but will be set as the codec + * specific configuration for the ongoing audio stream, encoded by the + * vendor module. The remote device will receive this information when being + * configured for receiveing a brodcast audio stream. If this is populated, + * only the `vendorCodecConfiguration` will be used when configuring the + * remote device, otherwise `codecConfiguration` will be used. + */ + byte[] vendorCodecConfiguration; + + /** + * Metadata for the particular BIS or group of BISes. This is optional. + */ + @nullable MetadataLtv[] metadata; +} diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl index 16503fb36a..da903731bc 100644 --- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl +++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/LeAudioBroadcastConfiguration.aidl @@ -17,6 +17,8 @@ package android.hardware.bluetooth.audio; import android.hardware.bluetooth.audio.CodecType; +import android.hardware.bluetooth.audio.ConfigurationFlags; +import android.hardware.bluetooth.audio.LeAudioBisConfiguration; import android.hardware.bluetooth.audio.LeAudioCodecConfiguration; @VintfStability @@ -39,6 +41,15 @@ parcelable LeAudioBroadcastConfiguration { * Pcm stream id to identify the source for given streamHandle. */ char pcmStreamId; + /* + * LE Audio BIS configuration + */ + @nullable LeAudioBisConfiguration bisConfiguration; + /* + * Additional flags, used to request configurations with special + * features + */ + @nullable ConfigurationFlags flags; } CodecType codecType; BroadcastStreamMap[] streamMap; From ccceb2f3b318dae08258889f8db01deaf0df1b6a Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Fri, 10 Nov 2023 09:55:22 +0000 Subject: [PATCH 03/11] LeAudio: Add empty audio provider implementation Empty implementation required for sucessfull build. Bug: 308428217 Bug: 307258939 Test: make Change-Id: I7ad578f3451edca89233652e331ef5d532925188 --- .../aidl/default/BluetoothAudioProvider.cpp | 114 ++++++++++++++++++ .../aidl/default/BluetoothAudioProvider.h | 60 +++++++++ 2 files changed, 174 insertions(+) diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp index b88e66aea0..bdba898a6a 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp @@ -187,6 +187,120 @@ ndk::ScopedAStatus BluetoothAudioProvider::getA2dpConfiguration( return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } +ndk::ScopedAStatus BluetoothAudioProvider::setCodecPriority( + const ::aidl::android::hardware::bluetooth::audio::CodecId& in_codecId, + int32_t in_priority) { + /* TODO: Implement */ + (void)in_codecId; + (void)in_priority; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseConfiguration( + const std::optional>>& in_remoteSinkAudioCapabilities, + const std::optional>>& in_remoteSourceAudioCapabilities, + const std::vector< + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioConfigurationRequirement>& in_requirements, + std::vector<::aidl::android::hardware::bluetooth::audio:: + IBluetoothAudioProvider::LeAudioAseConfigurationSetting>* + _aidl_return) { + /* TODO: Implement */ + (void)in_remoteSinkAudioCapabilities; + (void)in_remoteSourceAudioCapabilities; + (void)in_requirements; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseQosConfiguration( + const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioAseQosConfigurationRequirement& in_qosRequirement, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioAseQosConfigurationPair* _aidl_return) { + /* TODO: Implement */ + (void)in_qosRequirement; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseDatapathConfiguration( + const ::aidl::android::hardware::bluetooth::audio::AudioContext& in_context, + const std::vector<::aidl::android::hardware::bluetooth::audio:: + LeAudioConfiguration::StreamMap>& in_streamMap, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioDataPathConfigurationPair* _aidl_return) { + /* TODO: Implement */ + (void)in_context; + (void)in_streamMap; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ndk::ScopedAStatus BluetoothAudioProvider::onSinkAseMetadataChanged( + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + AseState in_state, + int32_t cigId, int32_t cisId, + const std::optional>>& + in_metadata) { + /* TODO: Implement */ + (void)in_state; + (void)cigId; + (void)cisId; + (void)in_metadata; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus BluetoothAudioProvider::onSourceAseMetadataChanged( + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + AseState in_state, + int32_t cigId, int32_t cisId, + const std::optional>>& + in_metadata) { + /* TODO: Implement */ + (void)in_state; + (void)cigId; + (void)cisId; + (void)in_metadata; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioBroadcastConfiguration( + const std::optional>>& in_remoteSinkAudioCapabilities, + const ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioBroadcastConfigurationRequirement& in_requirement, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioBroadcastConfigurationSetting* _aidl_return) { + /* TODO: Implement */ + (void)in_remoteSinkAudioCapabilities; + (void)in_requirement; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus +BluetoothAudioProvider::getLeAudioBroadcastDatapathConfiguration( + const ::aidl::android::hardware::bluetooth::audio::AudioContext& in_context, + const std::vector<::aidl::android::hardware::bluetooth::audio:: + LeAudioBroadcastConfiguration::BroadcastStreamMap>& + in_streamMap, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioDataPathConfiguration* _aidl_return) { + /* TODO: Implement */ + (void)in_context; + (void)in_streamMap; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + } // namespace audio } // namespace bluetooth } // namespace hardware diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h index 27ab13f50a..ca333941e3 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h @@ -49,6 +49,66 @@ class BluetoothAudioProvider : public BnBluetoothAudioProvider { ndk::ScopedAStatus updateAudioConfiguration( const AudioConfiguration& audio_config); ndk::ScopedAStatus setLowLatencyModeAllowed(bool allowed); + ndk::ScopedAStatus setCodecPriority( + const ::aidl::android::hardware::bluetooth::audio::CodecId& in_codecId, + int32_t in_priority) override; + ndk::ScopedAStatus getLeAudioAseConfiguration( + const std::optional>>& in_remoteSinkAudioCapabilities, + const std::optional>>& in_remoteSourceAudioCapabilities, + const std::vector< + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioConfigurationRequirement>& in_requirements, + std::vector<::aidl::android::hardware::bluetooth::audio:: + IBluetoothAudioProvider::LeAudioAseConfigurationSetting>* + _aidl_return) override; + ndk::ScopedAStatus getLeAudioAseQosConfiguration( + const ::aidl::android::hardware::bluetooth::audio:: + IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement& + in_qosRequirement, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioAseQosConfigurationPair* _aidl_return) override; + ndk::ScopedAStatus getLeAudioAseDatapathConfiguration( + const ::aidl::android::hardware::bluetooth::audio::AudioContext& + in_context, + const std::vector<::aidl::android::hardware::bluetooth::audio:: + LeAudioConfiguration::StreamMap>& in_streamMap, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioDataPathConfigurationPair* _aidl_return) override; + ndk::ScopedAStatus onSinkAseMetadataChanged( + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + AseState in_state, + int32_t cigId, int32_t cisId, + const std::optional>>& + in_metadata) override; + ndk::ScopedAStatus onSourceAseMetadataChanged( + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + AseState in_state, + int32_t cigId, int32_t cisId, + const std::optional>>& + in_metadata) override; + ndk::ScopedAStatus getLeAudioBroadcastConfiguration( + const std::optional>>& in_remoteSinkAudioCapabilities, + const ::aidl::android::hardware::bluetooth::audio:: + IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement& + in_requirement, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioBroadcastConfigurationSetting* _aidl_return) override; + ndk::ScopedAStatus getLeAudioBroadcastDatapathConfiguration( + const ::aidl::android::hardware::bluetooth::audio::AudioContext& + in_context, + const std::vector<::aidl::android::hardware::bluetooth::audio:: + LeAudioBroadcastConfiguration::BroadcastStreamMap>& + in_streamMap, + ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider:: + LeAudioDataPathConfiguration* _aidl_return) override; ndk::ScopedAStatus parseA2dpConfiguration( const CodecId& codec_id, const std::vector& configuration, From 6aeb5d7217abd27e0c59d916c9eec70f59207efe Mon Sep 17 00:00:00 2001 From: Bao Do Date: Mon, 11 Dec 2023 10:53:18 +0000 Subject: [PATCH 04/11] Add LE Audio getProviderInfo information Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/aidl/default Change-Id: Ieb03a1a3096dbeb6a4e2ac4774ece6d3ef3e33be --- .../aidl/default/BluetoothAudioProvider.h | 3 +- .../default/BluetoothAudioProviderFactory.cpp | 19 ++ .../aidl_session/BluetoothAudioCodecs.cpp | 27 +++ .../utils/aidl_session/BluetoothAudioCodecs.h | 3 + .../BluetoothLeAudioCodecsProvider.cpp | 195 +++++++++++++++--- .../BluetoothLeAudioCodecsProvider.h | 11 + 6 files changed, 225 insertions(+), 33 deletions(-) diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h index ca333941e3..5064869ca3 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h +++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h @@ -41,8 +41,7 @@ class BluetoothAudioProvider : public BnBluetoothAudioProvider { ndk::ScopedAStatus startSession( const std::shared_ptr& host_if, const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); + const std::vector& latency_modes, DataMQDesc* _aidl_return); ndk::ScopedAStatus endSession(); ndk::ScopedAStatus streamStarted(BluetoothAudioStatus status); ndk::ScopedAStatus streamSuspended(BluetoothAudioStatus status); diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp index 3a64c4d046..275cfec35f 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp +++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp @@ -37,6 +37,9 @@ namespace hardware { namespace bluetooth { namespace audio { +static const std::string kLeAudioOffloadProviderName = + "LE_AUDIO_OFFLOAD_HARDWARE_OFFLOAD_PROVIDER"; + BluetoothAudioProviderFactory::BluetoothAudioProviderFactory() {} ndk::ScopedAStatus BluetoothAudioProviderFactory::openProvider( @@ -158,6 +161,22 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo( provider_info.name = A2dpOffloadCodecFactory::GetInstance()->name; for (auto codec : A2dpOffloadCodecFactory::GetInstance()->codecs) provider_info.codecInfos.push_back(codec->info); + } else if (session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || + session_type == + SessionType:: + LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + std::vector db_codec_info = + BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type); + if (!db_codec_info.empty()) { + auto& provider_info = _aidl_return->emplace(); + provider_info.name = kLeAudioOffloadProviderName; + provider_info.codecInfos = db_codec_info; + *_aidl_return = provider_info; + } + return ndk::ScopedAStatus::ok(); } return ndk::ScopedAStatus::ok(); diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp index 6e15b3b93c..1524f5e3ac 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp @@ -97,6 +97,8 @@ const std::vector kDefaultOffloadA2dpCodecCapabilities = { {.codecType = CodecType::OPUS, .capabilities = {}}}; std::vector kDefaultOffloadLeAudioCapabilities; +std::unordered_map> + kDefaultOffloadLeAudioCodecInfoMap; template bool BluetoothAudioCodecs::ContainedInVector( @@ -411,6 +413,31 @@ BluetoothAudioCodecs::GetLeAudioOffloadCodecCapabilities( return kDefaultOffloadLeAudioCapabilities; } +std::vector BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo( + const SessionType& session_type) { + if (session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH && + session_type != + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + return std::vector(); + } + + if (kDefaultOffloadLeAudioCodecInfoMap.empty()) { + auto le_audio_offload_setting = + BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile(); + auto kDefaultOffloadLeAudioCodecInfoMap = + BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo( + le_audio_offload_setting); + } + auto codec_info_map_iter = + kDefaultOffloadLeAudioCodecInfoMap.find(session_type); + if (codec_info_map_iter == kDefaultOffloadLeAudioCodecInfoMap.end()) + return std::vector(); + return codec_info_map_iter->second; +} + } // namespace audio } // namespace bluetooth } // namespace hardware diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h index e3d657b497..01afb7a30a 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,8 @@ class BluetoothAudioCodecs { static std::vector GetLeAudioOffloadCodecCapabilities(const SessionType& session_type); + static std::vector GetLeAudioOffloadCodecInfo( + const SessionType& session_type); private: template diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp index 26da5fbe81..8c7a740cc2 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp @@ -14,6 +14,11 @@ * limitations under the License. */ +#include + +#include "aidl/android/hardware/bluetooth/audio/ChannelMode.h" +#include "aidl/android/hardware/bluetooth/audio/CodecId.h" +#include "aidl_android_hardware_bluetooth_audio_setting_enums.h" #define LOG_TAG "BTAudioCodecsProviderAidl" #include "BluetoothLeAudioCodecsProvider.h" @@ -50,6 +55,123 @@ BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile() { return le_audio_offload_setting; } +std::unordered_map> +BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo( + const std::optional& + le_audio_offload_setting) { + // Load from previous storage if present + if (!session_codecs_map_.empty()) return session_codecs_map_; + + isInvalidFileContent = true; + if (!le_audio_offload_setting.has_value()) return {}; + + // Load scenario, configuration, codec configuration and strategy + LoadConfigurationToMap(le_audio_offload_setting); + if (supported_scenarios_.empty() || configuration_map_.empty() || + codec_configuration_map_.empty() || strategy_configuration_map_.empty()) + return {}; + + // Map each configuration into a CodecInfo + std::unordered_map config_codec_info_map_; + + for (auto& p : configuration_map_) { + // Initialize new CodecInfo for the config + auto config_name = p.first; + if (config_codec_info_map_.count(config_name) == 0) + config_codec_info_map_[config_name] = CodecInfo(); + + // Getting informations from codecConfig and strategyConfig + const auto codec_config_name = p.second.getCodecConfiguration(); + const auto strategy_config_name = p.second.getStrategyConfiguration(); + const auto codec_configuration_map_iter = + codec_configuration_map_.find(codec_config_name); + if (codec_configuration_map_iter == codec_configuration_map_.end()) + continue; + const auto strategy_configuration_map_iter = + strategy_configuration_map_.find(strategy_config_name); + if (strategy_configuration_map_iter == strategy_configuration_map_.end()) + continue; + + const auto& codec_config = codec_configuration_map_iter->second; + const auto codec = codec_config.getCodec(); + const auto& strategy_config = strategy_configuration_map_iter->second; + const auto strategy_config_channel_count = + strategy_config.getChannelCount(); + + // Initiate information + auto& codec_info = config_codec_info_map_[config_name]; + switch (codec) { + case setting::CodecType::LC3: + codec_info.name = "LC3"; + codec_info.id = CodecId::Core::LC3; + break; + default: + codec_info.name = "UNDEFINE"; + codec_info.id = CodecId::make(); + break; + } + codec_info.transport = + CodecInfo::Transport::make(); + + // Mapping codec configuration information + auto& transport = + codec_info.transport.get(); + transport.samplingFrequencyHz.push_back( + codec_config.getSamplingFrequency()); + // Mapping octetsPerCodecFrame to bitdepth for easier comparison. + transport.bitdepth.push_back(codec_config.getOctetsPerCodecFrame()); + transport.frameDurationUs.push_back(codec_config.getFrameDurationUs()); + switch (strategy_config.getAudioLocation()) { + case setting::AudioLocation::MONO: + if (strategy_config_channel_count == 1) + transport.channelMode.push_back(ChannelMode::MONO); + else + transport.channelMode.push_back(ChannelMode::DUALMONO); + break; + case setting::AudioLocation::STEREO: + transport.channelMode.push_back(ChannelMode::STEREO); + break; + default: + transport.channelMode.push_back(ChannelMode::UNKNOWN); + break; + } + } + + // Goes through every scenario, deduplicate configuration + std::set encoding_config, decoding_config, broadcast_config; + for (auto& s : supported_scenarios_) { + if (s.hasEncode()) encoding_config.insert(s.getEncode()); + if (s.hasDecode()) decoding_config.insert(s.getDecode()); + if (s.hasBroadcast()) broadcast_config.insert(s.getBroadcast()); + } + + // Split by session types and add results + const auto encoding_path = + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; + const auto decoding_path = + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH; + const auto broadcast_path = + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH; + session_codecs_map_ = + std::unordered_map>(); + session_codecs_map_[encoding_path] = std::vector(); + session_codecs_map_[decoding_path] = std::vector(); + session_codecs_map_[broadcast_path] = std::vector(); + session_codecs_map_[encoding_path].reserve(encoding_config.size()); + session_codecs_map_[decoding_path].reserve(decoding_config.size()); + session_codecs_map_[broadcast_path].reserve(broadcast_config.size()); + for (auto& c : encoding_config) + session_codecs_map_[encoding_path].push_back(config_codec_info_map_[c]); + for (auto& c : decoding_config) + session_codecs_map_[decoding_path].push_back(config_codec_info_map_[c]); + for (auto& c : broadcast_config) + session_codecs_map_[broadcast_path].push_back(config_codec_info_map_[c]); + + isInvalidFileContent = session_codecs_map_.empty(); + + return session_codecs_map_; +} + std::vector BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities( const std::optional& @@ -58,6 +180,8 @@ BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities( return leAudioCodecCapabilities; } + isInvalidFileContent = true; + if (!le_audio_offload_setting.has_value()) { LOG(ERROR) << __func__ @@ -65,40 +189,13 @@ BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities( return {}; } - ClearLeAudioCodecCapabilities(); - isInvalidFileContent = true; - - std::vector supported_scenarios = - GetScenarios(le_audio_offload_setting); - if (supported_scenarios.empty()) { - LOG(ERROR) << __func__ << ": No scenarios in " - << kLeAudioCodecCapabilitiesFile; + LoadConfigurationToMap(le_audio_offload_setting); + if (supported_scenarios_.empty() || configuration_map_.empty() || + codec_configuration_map_.empty() || strategy_configuration_map_.empty()) return {}; - } - - UpdateConfigurationsToMap(le_audio_offload_setting); - if (configuration_map_.empty()) { - LOG(ERROR) << __func__ << ": No configurations in " - << kLeAudioCodecCapabilitiesFile; - return {}; - } - - UpdateCodecConfigurationsToMap(le_audio_offload_setting); - if (codec_configuration_map_.empty()) { - LOG(ERROR) << __func__ << ": No codec configurations in " - << kLeAudioCodecCapabilitiesFile; - return {}; - } - - UpdateStrategyConfigurationsToMap(le_audio_offload_setting); - if (strategy_configuration_map_.empty()) { - LOG(ERROR) << __func__ << ": No strategy configurations in " - << kLeAudioCodecCapabilitiesFile; - return {}; - } leAudioCodecCapabilities = - ComposeLeAudioCodecCapabilities(supported_scenarios); + ComposeLeAudioCodecCapabilities(supported_scenarios_); isInvalidFileContent = leAudioCodecCapabilities.empty(); return leAudioCodecCapabilities; @@ -109,6 +206,8 @@ void BluetoothLeAudioCodecsProvider::ClearLeAudioCodecCapabilities() { configuration_map_.clear(); codec_configuration_map_.clear(); strategy_configuration_map_.clear(); + session_codecs_map_.clear(); + supported_scenarios_.clear(); } std::vector BluetoothLeAudioCodecsProvider::GetScenarios( @@ -191,6 +290,40 @@ void BluetoothLeAudioCodecsProvider::UpdateStrategyConfigurationsToMap( } } +void BluetoothLeAudioCodecsProvider::LoadConfigurationToMap( + const std::optional& + le_audio_offload_setting) { + ClearLeAudioCodecCapabilities(); + + supported_scenarios_ = GetScenarios(le_audio_offload_setting); + if (supported_scenarios_.empty()) { + LOG(ERROR) << __func__ << ": No scenarios in " + << kLeAudioCodecCapabilitiesFile; + return; + } + + UpdateConfigurationsToMap(le_audio_offload_setting); + if (configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No configurations in " + << kLeAudioCodecCapabilitiesFile; + return; + } + + UpdateCodecConfigurationsToMap(le_audio_offload_setting); + if (codec_configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No codec configurations in " + << kLeAudioCodecCapabilitiesFile; + return; + } + + UpdateStrategyConfigurationsToMap(le_audio_offload_setting); + if (strategy_configuration_map_.empty()) { + LOG(ERROR) << __func__ << ": No strategy configurations in " + << kLeAudioCodecCapabilitiesFile; + return; + } +} + std::vector BluetoothLeAudioCodecsProvider::ComposeLeAudioCodecCapabilities( const std::vector& supported_scenarios) { diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h index 654e70cccf..5bf67e2f95 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h @@ -22,6 +22,8 @@ #include #include +#include "aidl/android/hardware/bluetooth/audio/CodecInfo.h" +#include "aidl/android/hardware/bluetooth/audio/SessionType.h" #include "aidl_android_hardware_bluetooth_audio_setting.h" namespace aidl { @@ -39,14 +41,20 @@ class BluetoothLeAudioCodecsProvider { const std::optional& le_audio_offload_setting); static void ClearLeAudioCodecCapabilities(); + static std::unordered_map> + GetLeAudioCodecInfo(const std::optional& + le_audio_offload_setting); private: + static inline std::vector supported_scenarios_; static inline std::unordered_map configuration_map_; static inline std::unordered_map codec_configuration_map_; static inline std::unordered_map strategy_configuration_map_; + static inline std::unordered_map> + session_codecs_map_; static std::vector GetScenarios( const std::optional& @@ -60,6 +68,9 @@ class BluetoothLeAudioCodecsProvider { static void UpdateStrategyConfigurationsToMap( const std::optional& le_audio_offload_setting); + static void LoadConfigurationToMap( + const std::optional& + le_audio_offload_setting); static std::vector ComposeLeAudioCodecCapabilities( From fbc99e05c6757e7e7d9a2aba04dbb324bf683786 Mon Sep 17 00:00:00 2001 From: Bao Do Date: Wed, 15 Nov 2023 03:21:03 +0000 Subject: [PATCH 05/11] Template and schemas for parsing LE Audio Set Configuration. Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/utils Change-Id: I20482faf20a41f04c39e1314db45a07cb5f9956b --- bluetooth/audio/utils/Android.bp | 81 +- .../aidl_session/BluetoothAudioCodecs.cpp | 7 + .../utils/aidl_session/BluetoothAudioCodecs.h | 7 + ...thLeAudioAseConfigurationSettingProvider.h | 125 + .../audio_set_configurations.fbs | 91 + .../audio_set_configurations.json | 11382 ++++++++++++++++ .../audio_set_scenarios.fbs | 36 + .../audio_set_scenarios.json | 304 + 8 files changed, 12032 insertions(+), 1 deletion(-) create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h create mode 100644 bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs create mode 100644 bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json create mode 100644 bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs create mode 100644 bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp index e7659a4750..16ee70a463 100644 --- a/bluetooth/audio/utils/Android.bp +++ b/bluetooth/audio/utils/Android.bp @@ -42,6 +42,7 @@ cc_library_shared { "aidl_session/BluetoothAudioSession.cpp", "aidl_session/HidlToAidlMiddleware.cpp", "aidl_session/BluetoothLeAudioCodecsProvider.cpp", + "aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp", ], export_include_dirs: ["aidl_session/"], header_libs: [ @@ -61,9 +62,13 @@ cc_library_shared { "liblog", "libhidlbase", "libxml2", + "libflatbuffers-cpp", ], generated_sources: ["le_audio_codec_capabilities"], - generated_headers: ["le_audio_codec_capabilities"], + generated_headers: [ + "le_audio_codec_capabilities", + "AIDLLeAudioSetConfigSchemas_h", + ], } cc_test { @@ -98,3 +103,77 @@ xsd_config { api_dir: "le_audio_codec_capabilities/schema", root_elements: ["leAudioOffloadSetting"], } + +genrule { + name: "AIDLLeAudioSetConfigSchemas_h", + tools: [ + "flatc", + ], + cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -o $(genDir) --cpp $(in) ", + srcs: [ + "le_audio_configuration_set/audio_set_configurations.fbs", + "le_audio_configuration_set/audio_set_scenarios.fbs", + ], + out: [ + "audio_set_configurations_generated.h", + "audio_set_scenarios_generated.h", + ], +} + +// Binary generation +genrule { + name: "AIDLLeAudioSetScenariosSchema_bfbs", + tools: [ + "flatc", + ], + cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -b --schema -o $(genDir) $(in) ", + srcs: [ + "le_audio_configuration_set/audio_set_scenarios.fbs", + ], + out: [ + "audio_set_scenarios.bfbs", + ], +} + +genrule { + name: "AIDLLeAudioSetConfigsSchema_bfbs", + tools: [ + "flatc", + ], + cmd: "$(location flatc) -I hardware/interfaces/bluetooth/audio/utils/ -b --schema -o $(genDir) $(in) ", + srcs: [ + "le_audio_configuration_set/audio_set_configurations.fbs", + ], + out: [ + "audio_set_configurations.bfbs", + ], +} + +// Add to prebuilt etc +prebuilt_etc { + name: "aidl_audio_set_scenarios_bfbs", + src: ":AIDLLeAudioSetScenariosSchema_bfbs", + filename: "aidl_audio_set_scenarios.bfbs", + sub_dir: "aidl/le_audio", +} + +prebuilt_etc { + name: "aidl_audio_set_scenarios_json", + src: "le_audio_configuration_set/audio_set_scenarios.json", + filename: "aidl_audio_set_scenarios.json", + sub_dir: "aidl/le_audio", +} + +prebuilt_etc { + name: "aidl_audio_set_configurations_bfbs", + src: ":AIDLLeAudioSetConfigsSchema_bfbs", + filename: "aidl_audio_set_configurations.bfbs", + sub_dir: "aidl/le_audio", +} + +prebuilt_etc { + name: "aidl_audio_set_configurations_json", + src: "le_audio_configuration_set/audio_set_configurations.json", + filename: "aidl_audio_set_configurations.json", + sub_dir: "aidl/le_audio", +} diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp index 1524f5e3ac..216e1692ff 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp @@ -32,6 +32,7 @@ #include #include +#include "BluetoothLeAudioAseConfigurationSettingProvider.h" #include "BluetoothLeAudioCodecsProvider.h" namespace aidl { @@ -438,6 +439,12 @@ std::vector BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo( return codec_info_map_iter->second; } +std::vector +BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() { + return AudioSetConfigurationProviderJson:: + GetLeAudioAseConfigurationSettings(); +} + } // namespace audio } // namespace bluetooth } // namespace hardware diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h index 01afb7a30a..057b9a72c8 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h +++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,9 @@ namespace hardware { namespace bluetooth { namespace audio { +using LeAudioAseConfigurationSetting = + IBluetoothAudioProvider::LeAudioAseConfigurationSetting; + class BluetoothAudioCodecs { public: static std::vector GetSoftwarePcmCapabilities(); @@ -50,6 +54,9 @@ class BluetoothAudioCodecs { static std::vector GetLeAudioOffloadCodecInfo( const SessionType& session_type); + static std::vector + GetLeAudioAseConfigurationSettings(); + private: template struct identity { diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h new file mode 100644 index 0000000000..ce91fca12b --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h @@ -0,0 +1,125 @@ + +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "audio_set_configurations_generated.h" +#include "audio_set_scenarios_generated.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +using LeAudioAseConfigurationSetting = + IBluetoothAudioProvider::LeAudioAseConfigurationSetting; +using AseDirectionConfiguration = IBluetoothAudioProvider:: + LeAudioAseConfigurationSetting::AseDirectionConfiguration; +using LeAudioAseQosConfiguration = + IBluetoothAudioProvider::LeAudioAseQosConfiguration; +using LeAudioDataPathConfiguration = + IBluetoothAudioProvider::LeAudioDataPathConfiguration; + +enum class CodecLocation { + HOST, + ADSP, + CONTROLLER, +}; + +class AudioSetConfigurationProviderJson { + public: + static std::vector + GetLeAudioAseConfigurationSettings(); + + private: + static void LoadAudioSetConfigurationProviderJson(); + + static const le_audio::CodecSpecificConfiguration* LookupCodecSpecificParam( + const flatbuffers::Vector>* flat_codec_specific_params, + le_audio::CodecSpecificLtvGenericTypes type); + + static void populateAudioChannelAllocation( + CodecSpecificConfigurationLtv::AudioChannelAllocation& + audio_channel_allocation, + uint32_t audio_location); + + static void populateConfigurationData( + LeAudioAseConfiguration& ase, + const flatbuffers::Vector< + flatbuffers::Offset>* + flat_codec_specific_params); + + static void populateAseConfiguration( + LeAudioAseConfiguration& ase, + const le_audio::AudioSetSubConfiguration* flat_subconfig, + const le_audio::QosConfiguration* qos_cfg); + + static void populateAseQosConfiguration( + LeAudioAseQosConfiguration& qos, + const le_audio::QosConfiguration* qos_cfg); + + static AseDirectionConfiguration SetConfigurationFromFlatSubconfig( + const le_audio::AudioSetSubConfiguration* flat_subconfig, + const le_audio::QosConfiguration* qos_cfg, CodecLocation location); + + static void processSubconfig( + const le_audio::AudioSetSubConfiguration* subconfig, + const le_audio::QosConfiguration* qos_cfg, + std::vector>& + directionAseConfiguration, + CodecLocation location); + + static void PopulateAseConfigurationFromFlat( + const le_audio::AudioSetConfiguration* flat_cfg, + std::vector* codec_cfgs, + std::vector* qos_cfgs, + CodecLocation location, + std::vector>& + sourceAseConfiguration, + std::vector>& + sinkAseConfiguration, + ConfigurationFlags& configurationFlags); + + static bool LoadConfigurationsFromFiles(const char* schema_file, + const char* content_file, + CodecLocation location); + + static bool LoadScenariosFromFiles(const char* schema_file, + const char* content_file); + + static bool LoadContent( + std::vector> + config_files, + std::vector> + scenario_files, + CodecLocation location); +}; + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs new file mode 100644 index 0000000000..bde467d775 --- /dev/null +++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.fbs @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +namespace aidl.android.hardware.bluetooth.audio.le_audio; +enum CodecSpecificLtvGenericTypes : byte { + SUPPORTED_SAMPLING_FREQUENCY = 0x01, + SUPPORTED_FRAME_DURATION = 0x02, + SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 0x03, + SUPPORTED_OCTETS_PER_CODEC_FRAME = 0x04, + SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 0x05, +} +/// Note: Holds either a single value (when `value_width == 0`) or multiple +/// values if `value.length()` is no-remainder divisible by the non-zero +/// `value_width`. +/// Note: Consider extending it with `flags` field, to hold additional info like +/// IsBitfield, IsRange, etc. if we need these type-specific validations. +table CompoundValue { + value: [ubyte] (required); + value_width: ubyte = 0; +} +table CodecSpecificConfiguration { + name: string; + type: ubyte (key); + compound_value: CompoundValue; +} +struct CodecId { + coding_format: ubyte; + vendor_company_id : ushort; + vendor_codec_id : ushort; +} +enum AudioSetConfigurationStrategy : byte { + MONO_ONE_CIS_PER_DEVICE = 0x00, + STEREO_TWO_CISES_PER_DEVICE = 0x01, + STEREO_ONE_CIS_PER_DEVICE = 0x02, +} +enum AudioSetConfigurationDirection : byte { + SINK = 0x01, + SOURCE = 0x02, +} +enum AudioSetConfigurationTargetLatency : byte { + LOW = 0x01, + BALANCED_RELIABILITY = 0x02, + HIGH_RELIABILITY = 0x03, +} +table AudioSetSubConfiguration { + device_cnt: ubyte; + ase_cnt: ubyte; + direction: AudioSetConfigurationDirection = SINK; + configuration_strategy: AudioSetConfigurationStrategy; + codec_id : CodecId (required); + codec_configuration: [CodecSpecificConfiguration] (required); +} +table CodecConfiguration { + name: string (key, required); + subconfigurations: [AudioSetSubConfiguration] (required); +} +table QosConfiguration { + name: string (key, required); + target_latency: AudioSetConfigurationTargetLatency = BALANCED_RELIABILITY; + retransmission_number: ubyte; + max_transport_latency : ushort; +} +/// Each set configration can contain multiple logical subconfigurations, which +/// all must be configurable with the current set of audio devices. For example, +/// one can define multiple output stream configurations with different +/// qualities, or assign different configurations to each stream direction. +table AudioSetConfiguration { + name: string (key, required); + codec_config_name: string (required); + qos_config_name: [string] (required); +} +table AudioSetConfigurations { + _comments_: [string]; + configurations: [AudioSetConfiguration] (required); + codec_configurations: [CodecConfiguration] (required); + qos_configurations: [QosConfiguration] (required); +} +root_type AudioSetConfigurations; diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json new file mode 100644 index 0000000000..404a48ac1b --- /dev/null +++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_configurations.json @@ -0,0 +1,11382 @@ +{ + "_comments_": [ + " == Audio Set Configurations == ", + " Contains: ", + " 1. configurations : ", + " Maps configuration name with codec and qos config to be used", + " 2. codec_configurations : ", + " Array of codec specific configurations", + " 3. qos_configurations : ", + " Array of QoS specific configurations", + " QoS configuration values are as per BAP spec 1.0", + " Example values which can be used as 'codec_configuration.type'", + " Codec Configuration parameter types:", + " SUPPORTED_SAMPLING_FREQUENCY = 1", + " SUPPORTED_FRAME_DURATION = 2", + " SUPPORTED_AUDIO_CHANNEL_ALLOCATION = 3", + " SUPPORTED_OCTETS_PER_CODEC_FRAME = 4", + " SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU = 5", + " Example values which can be used as 'codec_configuration.compound_value'", + " Codec Coding formats:", + " LC3 = 6", + " ASE Configuration strategies:", + " MONO_ONE_CIS_PER_DEVICE = 0", + " STEREO_TWO_CISES_PER_DEVICE = 1", + " STEREO_ONE_CIS_PER_DEVICE = 2", + " Sampling Frequencies: ", + " 8000Hz = 1", + " 11025Hz = 2", + " 16000Hz = 3", + " 22050Hz = 4", + " 24000Hz = 5", + " 32000Hz = 6", + " 44100Hz = 7", + " 48000Hz = 8", + " 88200Hz = 9", + " 96000Hz = 10", + " 176400Hz = 11", + " 192000Hz = 12", + " 384000Hz = 13", + " Frame Durations:", + " 7500us = 0", + " 10000us = 1" + ], + "configurations": [ + { + "name": "DualDev_OneChanStereoSnk_16_1_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_1_1", + "codec_config_name": "DualDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_1_2", + "codec_config_name": "DualDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_2_1", + "codec_config_name": "DualDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_2_2", + "codec_config_name": "DualDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_1_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_1_1", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_1_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_2_1", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_2_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_1_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_1_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_1_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_2_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_2_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_32_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_32_1_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_32_1", + "qos_config_name": [ + "QoS_Config_32_1_1" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_32_2_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_16_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_1_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_1_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanMonoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_2_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_2_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_2", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_2", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_1" + ] + }, + { + "name": "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_48_4", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_48_3", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_48_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_48_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_32_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_24_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1", + "qos_config_name": [ + "QoS_Config_16_1_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_1" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_16_2_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_24_1_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_24_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_24_1_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_24_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_24_1_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_24_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_24_2_2", + "codec_config_name": "DualDev_OneChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_24_2_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_24_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_24_2_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_24_2_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_24_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_24_2_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_24_2", + "qos_config_name": [ + "QoS_Config_24_2_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_24_2_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_24_2", + "qos_config_name": [ + "QoS_Config_24_2_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_32_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_32_1_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_32_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_32_1_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_32_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_32_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_32_1_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_32_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1", + "codec_config_name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_32_2_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_32_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_32_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_High_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_1", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_1" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_2", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_3_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_3_High_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_3_2", + "codec_config_name": "DualDev_OneChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_48_3_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_2_High_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_2_2", + "codec_config_name": "DualDev_OneChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_48_2_2" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_1_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_1_High_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_1_2", + "codec_config_name": "DualDev_OneChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_48_1_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_High_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_1", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_1" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_3_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_3_High_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_3_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_48_3_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_2_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_2_High_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_2_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_48_2_2" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_1_Low_Latency", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_1_High_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_1_2", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_48_1_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_High_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_1", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_1" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_3_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_3_High_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_3_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_3", + "qos_config_name": [ + "QoS_Config_48_3_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_2_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_2_High_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_2_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_2", + "qos_config_name": [ + "QoS_Config_48_2_2" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_1_Low_Latency", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_1_High_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_1_2", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_1", + "qos_config_name": [ + "QoS_Config_48_1_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_High_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_4", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_1", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_1" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_4", + "qos_config_name": [ + "QoS_Config_48_4_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_3_High_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_3", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_3_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_3", + "qos_config_name": [ + "QoS_Config_48_3_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_2_High_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_2", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_2_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_2", + "qos_config_name": [ + "QoS_Config_48_2_2" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_1_High_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_1_2", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_1", + "qos_config_name": [ + "QoS_Config_48_1_2" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_Low_Latency_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60oct_R3_L22_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1", + "qos_config_name": [ + "VND_QoS_Config_R3_L22" + ] + }, + { + "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1", + "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1", + "codec_config_name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1", + "qos_config_name": [ + "VND_QoS_Config_R15_L70" + ] + }, + { + "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1", + "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1", + "codec_config_name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1", + "qos_config_name": [ + "VND_QoS_Config_R15_L70" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1", + "qos_config_name": [ + "VND_QoS_Config_R15_L70" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1", + "qos_config_name": [ + "QoS_Config_High_Reliability" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1", + "qos_config_name": [ + "VND_QoS_Config_R5_L12" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_24_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_32_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_24_2_1_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_1_OneChanMonoSrc_16_2_Balanced_Reliability", + "codec_config_name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2", + "qos_config_name": [ + "QoS_Config_Low_Latency" + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability", + "codec_config_name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1", + "qos_config_name": [ + "VND_QoS_Config_R11_L40" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1", + "qos_config_name": [ + "VND_QoS_Config_R5_L12", + "VND_QoS_Config_R3_L12" + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1", + "codec_config_name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1", + "qos_config_name": [ + "QoS_Config_Balanced_Reliability" + ] + } + ], + "codec_configurations": [ + { + "name": "DualDev_OneChanStereoSnk_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_16_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SOURCE", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_32_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_32_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_32_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanMonoSnk_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 4, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 4, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_4", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_3", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 90, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_48_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_32_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_24_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 45, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 40, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSrc_16_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_3", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 90, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_3", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 90, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_3", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 90, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_3", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 90, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "VND_DualDev_OneChanStereoSnk_48khz_100octs_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "VND_SingleDev_OneChanStereoSnk_48khz_100octs_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 4, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 4, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 4, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 120, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 100, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_OneChanStereoSrc_32khz_60octs_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 8 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 75, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 3 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 30, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_24_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_24_1", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 45, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_24_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 45, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_24_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 45, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_24_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "MONO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 5 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 2, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 2, + "ase_cnt": 4, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + }, + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SOURCE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_TwoChanStereoSnk_32_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 1, + "direction": "SINK", + "configuration_strategy": "STEREO_ONE_CIS_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 3, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_32_2", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 1 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 80, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + }, + { + "name": "SingleDev_OneChanStereoSnk_32_1", + "subconfigurations": [ + { + "device_cnt": 1, + "ase_cnt": 2, + "direction": "SINK", + "configuration_strategy": "STEREO_TWO_CISES_PER_DEVICE", + "codec_id": { + "coding_format": 6, + "vendor_company_id": 0, + "vendor_codec_id": 0 + }, + "codec_configuration": [ + { + "name": "sampling_frequency", + "type": 1, + "compound_value": { + "value": [ + 6 + ] + } + }, + { + "name": "frame_duration", + "type": 2, + "compound_value": { + "value": [ + 0 + ] + } + }, + { + "name": "audio_channel_allocation", + "type": 3, + "compound_value": { + "value": [ + 1, + 0, + 0, + 0 + ] + } + }, + { + "name": "octets_per_codec_frame", + "type": 4, + "compound_value": { + "value": [ + 60, + 0 + ] + } + }, + { + "name": "codec_frame_blocks_per_sdu", + "type": 5, + "compound_value": { + "value": [ + 1 + ] + } + } + ] + } + ] + } + ], + "qos_configurations": [ + { + "name": "QoS_Config_16_1_1", + "retransmission_number": 2, + "max_transport_latency": 8 + }, + { + "name": "QoS_Config_16_1_2", + "retransmission_number": 13, + "max_transport_latency": 75 + }, + { + "name": "QoS_Config_16_2_1", + "retransmission_number": 2, + "max_transport_latency": 10 + }, + { + "name": "QoS_Config_16_2_2", + "retransmission_number": 13, + "max_transport_latency": 95 + }, + { + "name": "QoS_Config_24_1_1", + "retransmission_number": 2, + "max_transport_latency": 8 + }, + { + "name": "QoS_Config_24_1_2", + "retransmission_number": 13, + "max_transport_latency": 75 + }, + { + "name": "QoS_Config_24_2_1", + "retransmission_number": 2, + "max_transport_latency": 10 + }, + { + "name": "QoS_Config_24_2_2", + "retransmission_number": 13, + "max_transport_latency": 95 + }, + { + "name": "QoS_Config_32_1_1", + "retransmission_number": 2, + "max_transport_latency": 8 + }, + { + "name": "QoS_Config_32_1_2", + "retransmission_number": 13, + "max_transport_latency": 75 + }, + { + "name": "QoS_Config_32_2_1", + "retransmission_number": 2, + "max_transport_latency": 10 + }, + { + "name": "QoS_Config_32_2_2", + "retransmission_number": 13, + "max_transport_latency": 95 + }, + { + "name": "QoS_Config_48_1_2", + "retransmission_number": 13, + "max_transport_latency": 75 + }, + { + "name": "QoS_Config_48_2_2", + "retransmission_number": 13, + "max_transport_latency": 95 + }, + { + "name": "QoS_Config_48_3_2", + "retransmission_number": 13, + "max_transport_latency": 75 + }, + { + "name": "QoS_Config_48_4_1", + "retransmission_number": 5, + "max_transport_latency": 20 + }, + { + "name": "QoS_Config_48_4_2", + "retransmission_number": 13, + "max_transport_latency": 100 + }, + { + "name": "VND_QoS_Config_R3_L22", + "retransmission_number": 3, + "max_transport_latency": 22 + }, + { + "name": "VND_QoS_Config_R15_L70", + "retransmission_number": 15, + "max_transport_latency": 70 + }, + { + "name": "VND_QoS_Config_R5_L12", + "retransmission_number": 5, + "max_transport_latency": 12 + }, + { + "name": "VND_QoS_Config_R11_L40", + "retransmission_number": 11, + "max_transport_latency": 40 + }, + { + "name": "VND_QoS_Config_R3_L12", + "retransmission_number": 3, + "max_transport_latency": 12 + }, + { + "name": "QoS_Config_Low_Latency", + "target_latency": "LOW", + "retransmission_number": 0, + "max_transport_latency": 0 + }, + { + "name": "QoS_Config_Balanced_Reliability", + "target_latency": "BALANCED_RELIABILITY", + "retransmission_number": 0, + "max_transport_latency": 0 + }, + { + "name": "QoS_Config_High_Reliability", + "target_latency": "HIGH_RELIABILITY", + "retransmission_number": 0, + "max_transport_latency": 0 + } + + ] +} diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs new file mode 100644 index 0000000000..e898bdc7be --- /dev/null +++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.fbs @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +namespace aidl.android.hardware.bluetooth.audio.le_audio; +/// Scenario represents the use case such as "Media", "Conversation", etc. +/// Each scenario can list any number of codec configurations by their names in +/// the order of preference. That means if the first entry does not meet all +/// the current requirements (such as peer device capabilities etc.) next +/// configurations are being checked. +/// +/// The referenced codec configurations are defined by the +/// audio_set_configurations.fbs schema and loaded from a different source file. +/// Multiple scenarios can reference same codec configurations. +table AudioSetScenario { + _comments_: [string]; + name: string (key, required); + configurations: [string] (required); +} +table AudioSetScenarios { + _comments_: [string]; + scenarios: [AudioSetScenario] (required); +} +root_type AudioSetScenarios; diff --git a/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json new file mode 100644 index 0000000000..a28c6cd90f --- /dev/null +++ b/bluetooth/audio/utils/le_audio_configuration_set/audio_set_scenarios.json @@ -0,0 +1,304 @@ +{ + "_comments_": [ + "== Audio Set Scenarios ==", + " Each defined scenario references externally defined audio set", + " configurations, listed in the order of priority." + ], + "scenarios": [ + { + "name": "Conversational", + "configurations": [ + "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_2", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_2", + "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1", + "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1", + "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1", + "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_32_2_1", + "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_2_1", + "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "DualDev_OneChanDoubleStereoSnk_OneChanMonoSrc_16_1_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_2", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_2", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1", + "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_48_4_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_48_3_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_24_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_24_1_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability", + "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_Server_Prefered_1", + "VND_SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32khz_60oct_R3_L22_1", + "DualDev_OneChanMonoSnk_16_2_Balanced_Reliability", + "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability" + ] + }, + { + "name": "Media", + "configurations": [ + "DualDev_OneChanStereoSnk_48_4_High_Reliability", + "DualDev_OneChanStereoSnk_48_4_2", + "DualDev_OneChanStereoSnk_48_2_High_Reliability", + "DualDev_OneChanStereoSnk_48_2_2", + "DualDev_OneChanStereoSnk_48_3_High_Reliability", + "DualDev_OneChanStereoSnk_48_3_2", + "DualDev_OneChanStereoSnk_48_1_High_Reliability", + "DualDev_OneChanStereoSnk_48_1_2", + "DualDev_OneChanStereoSnk_24_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_24_2_2", + "DualDev_OneChanStereoSnk_16_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_16_2_2", + "DualDev_OneChanStereoSnk_16_1_Balanced_Reliability", + "DualDev_OneChanStereoSnk_16_1_2", + "SingleDev_OneChanStereoSnk_48_4_High_Reliability", + "SingleDev_OneChanStereoSnk_48_4_2", + "SingleDev_OneChanStereoSnk_48_2_High_Reliability", + "SingleDev_OneChanStereoSnk_48_2_2", + "SingleDev_OneChanStereoSnk_48_3_High_Reliability", + "SingleDev_OneChanStereoSnk_48_3_2", + "SingleDev_OneChanStereoSnk_48_1_High_Reliability", + "SingleDev_OneChanStereoSnk_48_1_2", + "SingleDev_OneChanStereoSnk_24_2_Balanced_Reliability", + "SingleDev_OneChanStereoSnk_24_2_2", + "SingleDev_OneChanStereoSnk_16_2_Balanced_Reliability", + "SingleDev_OneChanStereoSnk_16_2_2", + "SingleDev_OneChanStereoSnk_16_1_Balanced_Reliability", + "SingleDev_OneChanStereoSnk_16_1_2", + "SingleDev_TwoChanStereoSnk_48_4_High_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_2", + "SingleDev_TwoChanStereoSnk_48_4_High_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_2", + "SingleDev_TwoChanStereoSnk_48_2_High_Reliability", + "SingleDev_TwoChanStereoSnk_48_2_2", + "SingleDev_TwoChanStereoSnk_48_3_High_Reliability", + "SingleDev_TwoChanStereoSnk_48_3_2", + "SingleDev_TwoChanStereoSnk_48_1_High_Reliability", + "SingleDev_TwoChanStereoSnk_48_1_2", + "SingleDev_TwoChanStereoSnk_24_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_24_2_2", + "SingleDev_TwoChanStereoSnk_16_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_16_2_2", + "SingleDev_TwoChanStereoSnk_16_1_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_16_1_2", + "SingleDev_OneChanMonoSnk_48_4_High_Reliability", + "SingleDev_OneChanMonoSnk_48_4_2", + "SingleDev_OneChanMonoSnk_48_2_High_Reliability", + "SingleDev_OneChanMonoSnk_48_2_2", + "SingleDev_OneChanMonoSnk_48_3_High_Reliability", + "SingleDev_OneChanMonoSnk_48_3_2", + "SingleDev_OneChanMonoSnk_48_1_High_Reliability", + "SingleDev_OneChanMonoSnk_48_1_2", + "SingleDev_OneChanMonoSnk_32_2_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_32_2_2", + "SingleDev_OneChanMonoSnk_32_1_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_32_1_2", + "SingleDev_OneChanMonoSnk_24_2_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_24_2_2", + "SingleDev_OneChanMonoSnk_16_2_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_16_2_2", + "SingleDev_OneChanMonoSnk_16_1_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_16_1_2", + "VND_DualDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1", + "VND_DualDev_OneChanStereoSnk_48khz_100octs_R15_L70_1", + "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_High_Reliability_1", + "VND_SingleDev_TwoChanStereoSnk_48khz_100octs_R15_L70_1", + "VND_SingleDev_OneChanStereoSnk_48khz_100octs_High_Reliability_1", + "VND_SingleDev_OneChanStereoSnk_48khz_100octs_R15_L70_1", + "DualDev_OneChanMonoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanStereoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability" + ] + }, + { + "name": "Game", + "configurations": [ + "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_TwoChanStereoSrc_16khz_30octs_Balanced_Reliability_1", + "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_TwoChanStereoSrc_16khz_30octs_R3_L12_1", + "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_High_Reliability_1", + "VND_SingleDev_TwoChanStereoSnk_48khz_75octs_R5_L12_1", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency", + "DualDev_OneChanStereoSnk_48_2_Low_Latency", + "DualDev_OneChanStereoSnk_48_3_Low_Latency", + "DualDev_OneChanStereoSnk_48_1_Low_Latency", + "DualDev_OneChanStereoSnk_32_2_Low_Latency", + "DualDev_OneChanStereoSnk_32_1_Low_Latency", + "DualDev_OneChanStereoSnk_24_2_Low_Latency", + "DualDev_OneChanStereoSnk_24_1_Low_Latency", + "DualDev_OneChanStereoSnk_16_2_Low_Latency", + "DualDev_OneChanStereoSnk_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_48_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_48_3_Low_Latency", + "SingleDev_TwoChanStereoSnk_48_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_32_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_24_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_24_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_16_1_Low_Latency", + "SingleDev_OneChanStereoSnk_48_2_Low_Latency", + "SingleDev_OneChanStereoSnk_48_3_Low_Latency", + "SingleDev_OneChanStereoSnk_48_1_Low_Latency", + "SingleDev_OneChanStereoSnk_32_2_Low_Latency", + "SingleDev_OneChanStereoSnk_32_1_Low_Latency", + "SingleDev_OneChanStereoSnk_24_2_Low_Latency", + "SingleDev_OneChanStereoSnk_24_1_Low_Latency", + "SingleDev_OneChanStereoSnk_16_2_Low_Latency", + "SingleDev_OneChanStereoSnk_16_1_Low_Latency" + ] + }, + { + "name": "VoiceAssistants", + "configurations": [ + "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1", + "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_16_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_24_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_48_4_OneChanStereoSrc_32_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", + "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", + "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", + "DualDev_OneChanDoubleStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_16_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_24_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_TwoChanStereoSrc_32_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", + "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", + "SingleDev_OneChanStereoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_24_2_Balanced_Reliability", + "SingleDev_OneChanMonoSnk_48_4_OneChanMonoSrc_32_2_Balanced_Reliability" + ] + }, + { + "name": "Live", + "configurations": [ + "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_Balanced_Reliability_1", + "VND_SingleDev_TwoChanStereoSrc_48khz_100octs_R11_L40_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_32_2_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_2_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_Low_Latency", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_16_1_1", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_2_Balanced_Reliability", + "DualDev_OneChanStereoSnk_OneChanStereoSrc_48_1_Balanced_Reliability", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_32_2_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_2_1", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_TwoChanStereoSrc_16_1_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_TwoChanStereoSnk_OneChanMonoSrc_16_1_1", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_OneChanStereoSnk_OneChanMonoSrc_16_1_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_32_2_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_2_1", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_Low_Latency", + "SingleDev_OneChanMonoSnk_OneChanMonoSrc_16_1_1", + "SingleDev_OneChanMonoSrc_48_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_48_1_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_32_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_32_1_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_16_2_Balanced_Reliability", + "SingleDev_OneChanMonoSrc_16_1_Balanced_Reliability" + ] + } + ] +} From be99419521a31e64c943ac03178f22927773aaab Mon Sep 17 00:00:00 2001 From: Bao Do Date: Wed, 15 Nov 2023 03:34:00 +0000 Subject: [PATCH 06/11] Parse LE Audio Set Configuration into LeAudioAseConfiguration Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/utils Change-Id: Ia08568322e1cee1834e08172781cc77342cbd025 --- bluetooth/audio/utils/Android.bp | 10 + ...LeAudioAseConfigurationSettingProvider.cpp | 747 ++++++++++++++++++ 2 files changed, 757 insertions(+) create mode 100644 bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp index 16ee70a463..f5f8163a92 100644 --- a/bluetooth/audio/utils/Android.bp +++ b/bluetooth/audio/utils/Android.bp @@ -69,6 +69,12 @@ cc_library_shared { "le_audio_codec_capabilities", "AIDLLeAudioSetConfigSchemas_h", ], + required: [ + "aidl_audio_set_configurations_bfbs", + "aidl_audio_set_configurations_json", + "aidl_audio_set_scenarios_bfbs", + "aidl_audio_set_scenarios_json", + ], } cc_test { @@ -155,6 +161,7 @@ prebuilt_etc { src: ":AIDLLeAudioSetScenariosSchema_bfbs", filename: "aidl_audio_set_scenarios.bfbs", sub_dir: "aidl/le_audio", + vendor: true, } prebuilt_etc { @@ -162,6 +169,7 @@ prebuilt_etc { src: "le_audio_configuration_set/audio_set_scenarios.json", filename: "aidl_audio_set_scenarios.json", sub_dir: "aidl/le_audio", + vendor: true, } prebuilt_etc { @@ -169,6 +177,7 @@ prebuilt_etc { src: ":AIDLLeAudioSetConfigsSchema_bfbs", filename: "aidl_audio_set_configurations.bfbs", sub_dir: "aidl/le_audio", + vendor: true, } prebuilt_etc { @@ -176,4 +185,5 @@ prebuilt_etc { src: "le_audio_configuration_set/audio_set_configurations.json", filename: "aidl_audio_set_configurations.json", sub_dir: "aidl/le_audio", + vendor: true, } diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp new file mode 100644 index 0000000000..56a4e17811 --- /dev/null +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp @@ -0,0 +1,747 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define STREAM_TO_UINT8(u8, p) \ + { \ + (u8) = (uint8_t)(*(p)); \ + (p) += 1; \ + } +#define STREAM_TO_UINT16(u16, p) \ + { \ + (u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \ + (p) += 2; \ + } +#define STREAM_TO_UINT32(u32, p) \ + { \ + (u32) = (((uint32_t)(*(p))) + ((((uint32_t)(*((p) + 1)))) << 8) + \ + ((((uint32_t)(*((p) + 2)))) << 16) + \ + ((((uint32_t)(*((p) + 3)))) << 24)); \ + (p) += 4; \ + } + +#define LOG_TAG "BTAudioCodecsAidl" + +#include "BluetoothLeAudioAseConfigurationSettingProvider.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "flatbuffers/idl.h" +#include "flatbuffers/util.h" + +namespace aidl { +namespace android { +namespace hardware { +namespace bluetooth { +namespace audio { + +/* Internal structure definition */ +std::map>*, + std::vector>*, + ConfigurationFlags*>> + configurations_; + +std::vector ase_configuration_settings_; + +constexpr uint8_t kIsoDataPathHci = 0x00; +constexpr uint8_t kIsoDataPathPlatformDefault = 0x01; +constexpr uint8_t kIsoDataPathDisabled = 0xFF; + +constexpr uint8_t kLeAudioDirectionSink = 0x01; +constexpr uint8_t kLeAudioDirectionSource = 0x02; +constexpr uint8_t kLeAudioDirectionBoth = + kLeAudioDirectionSink | kLeAudioDirectionSource; + +/* Sampling Frequencies */ +constexpr uint8_t kLeAudioSamplingFreq8000Hz = 0x01; +constexpr uint8_t kLeAudioSamplingFreq11025Hz = 0x02; +constexpr uint8_t kLeAudioSamplingFreq16000Hz = 0x03; +constexpr uint8_t kLeAudioSamplingFreq22050Hz = 0x04; +constexpr uint8_t kLeAudioSamplingFreq24000Hz = 0x05; +constexpr uint8_t kLeAudioSamplingFreq32000Hz = 0x06; +constexpr uint8_t kLeAudioSamplingFreq44100Hz = 0x07; +constexpr uint8_t kLeAudioSamplingFreq48000Hz = 0x08; +constexpr uint8_t kLeAudioSamplingFreq88200Hz = 0x09; +constexpr uint8_t kLeAudioSamplingFreq96000Hz = 0x0A; +constexpr uint8_t kLeAudioSamplingFreq176400Hz = 0x0B; +constexpr uint8_t kLeAudioSamplingFreq192000Hz = 0x0C; +constexpr uint8_t kLeAudioSamplingFreq384000Hz = 0x0D; + +/* Frame Durations */ +constexpr uint8_t kLeAudioCodecFrameDur7500us = 0x00; +constexpr uint8_t kLeAudioCodecFrameDur10000us = 0x01; + +/* Audio Allocations */ +constexpr uint32_t kLeAudioLocationNotAllowed = 0x00000000; +constexpr uint32_t kLeAudioLocationFrontLeft = 0x00000001; +constexpr uint32_t kLeAudioLocationFrontRight = 0x00000002; +constexpr uint32_t kLeAudioLocationFrontCenter = 0x00000004; +constexpr uint32_t kLeAudioLocationLowFreqEffects1 = 0x00000008; +constexpr uint32_t kLeAudioLocationBackLeft = 0x00000010; +constexpr uint32_t kLeAudioLocationBackRight = 0x00000020; +constexpr uint32_t kLeAudioLocationFrontLeftOfCenter = 0x00000040; +constexpr uint32_t kLeAudioLocationFrontRightOfCenter = 0x00000080; +constexpr uint32_t kLeAudioLocationBackCenter = 0x00000100; +constexpr uint32_t kLeAudioLocationLowFreqEffects2 = 0x00000200; +constexpr uint32_t kLeAudioLocationSideLeft = 0x00000400; +constexpr uint32_t kLeAudioLocationSideRight = 0x00000800; +constexpr uint32_t kLeAudioLocationTopFrontLeft = 0x00001000; +constexpr uint32_t kLeAudioLocationTopFrontRight = 0x00002000; +constexpr uint32_t kLeAudioLocationTopFrontCenter = 0x00004000; +constexpr uint32_t kLeAudioLocationTopCenter = 0x00008000; +constexpr uint32_t kLeAudioLocationTopBackLeft = 0x00010000; +constexpr uint32_t kLeAudioLocationTopBackRight = 0x00020000; +constexpr uint32_t kLeAudioLocationTopSideLeft = 0x00040000; +constexpr uint32_t kLeAudioLocationTopSideRight = 0x00080000; +constexpr uint32_t kLeAudioLocationTopBackCenter = 0x00100000; +constexpr uint32_t kLeAudioLocationBottomFrontCenter = 0x00200000; +constexpr uint32_t kLeAudioLocationBottomFrontLeft = 0x00400000; +constexpr uint32_t kLeAudioLocationBottomFrontRight = 0x00800000; +constexpr uint32_t kLeAudioLocationFrontLeftWide = 0x01000000; +constexpr uint32_t kLeAudioLocationFrontRightWide = 0x02000000; +constexpr uint32_t kLeAudioLocationLeftSurround = 0x04000000; +constexpr uint32_t kLeAudioLocationRightSurround = 0x08000000; + +constexpr uint32_t kLeAudioLocationAnyLeft = + kLeAudioLocationFrontLeft | kLeAudioLocationBackLeft | + kLeAudioLocationFrontLeftOfCenter | kLeAudioLocationSideLeft | + kLeAudioLocationTopFrontLeft | kLeAudioLocationTopBackLeft | + kLeAudioLocationTopSideLeft | kLeAudioLocationBottomFrontLeft | + kLeAudioLocationFrontLeftWide | kLeAudioLocationLeftSurround; + +constexpr uint32_t kLeAudioLocationAnyRight = + kLeAudioLocationFrontRight | kLeAudioLocationBackRight | + kLeAudioLocationFrontRightOfCenter | kLeAudioLocationSideRight | + kLeAudioLocationTopFrontRight | kLeAudioLocationTopBackRight | + kLeAudioLocationTopSideRight | kLeAudioLocationBottomFrontRight | + kLeAudioLocationFrontRightWide | kLeAudioLocationRightSurround; + +constexpr uint32_t kLeAudioLocationStereo = + kLeAudioLocationFrontLeft | kLeAudioLocationFrontRight; + +/* Octets Per Frame */ +constexpr uint16_t kLeAudioCodecFrameLen30 = 30; +constexpr uint16_t kLeAudioCodecFrameLen40 = 40; +constexpr uint16_t kLeAudioCodecFrameLen60 = 60; +constexpr uint16_t kLeAudioCodecFrameLen80 = 80; +constexpr uint16_t kLeAudioCodecFrameLen100 = 100; +constexpr uint16_t kLeAudioCodecFrameLen120 = 120; + +/* Helper map for matching various sampling frequency notations */ +const std::map + sampling_freq_map = { + {kLeAudioSamplingFreq8000Hz, + CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000}, + {kLeAudioSamplingFreq16000Hz, + CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000}, + {kLeAudioSamplingFreq24000Hz, + CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000}, + {kLeAudioSamplingFreq32000Hz, + CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000}, + {kLeAudioSamplingFreq44100Hz, + CodecSpecificConfigurationLtv::SamplingFrequency::HZ44100}, + {kLeAudioSamplingFreq48000Hz, + CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000}}; + +/* Helper map for matching various frame durations notations */ +const std::map + frame_duration_map = { + {kLeAudioCodecFrameDur7500us, + CodecSpecificConfigurationLtv::FrameDuration::US7500}, + {kLeAudioCodecFrameDur10000us, + CodecSpecificConfigurationLtv::FrameDuration::US10000}}; + +/* Helper map for matching various audio channel allocation notations */ +std::map audio_channel_allocation_map = { + {kLeAudioLocationNotAllowed, + CodecSpecificConfigurationLtv::AudioChannelAllocation::NOT_ALLOWED}, + {kLeAudioLocationFrontLeft, + CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT}, + {kLeAudioLocationFrontRight, + CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT}, + {kLeAudioLocationFrontCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER}, + {kLeAudioLocationLowFreqEffects1, + CodecSpecificConfigurationLtv::AudioChannelAllocation:: + LOW_FREQUENCY_EFFECTS_1}, + {kLeAudioLocationBackLeft, + CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_LEFT}, + {kLeAudioLocationBackRight, + CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_RIGHT}, + {kLeAudioLocationFrontLeftOfCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation:: + FRONT_LEFT_OF_CENTER}, + {kLeAudioLocationFrontRightOfCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation:: + FRONT_RIGHT_OF_CENTER}, + {kLeAudioLocationBackCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation::BACK_CENTER}, + {kLeAudioLocationLowFreqEffects2, + CodecSpecificConfigurationLtv::AudioChannelAllocation:: + LOW_FREQUENCY_EFFECTS_2}, + {kLeAudioLocationSideLeft, + CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_LEFT}, + {kLeAudioLocationSideRight, + CodecSpecificConfigurationLtv::AudioChannelAllocation::SIDE_RIGHT}, + {kLeAudioLocationTopFrontLeft, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_LEFT}, + {kLeAudioLocationTopFrontRight, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_RIGHT}, + {kLeAudioLocationTopFrontCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_FRONT_CENTER}, + {kLeAudioLocationTopCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_CENTER}, + {kLeAudioLocationTopBackLeft, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_LEFT}, + {kLeAudioLocationTopBackRight, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_RIGHT}, + {kLeAudioLocationTopSideLeft, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_LEFT}, + {kLeAudioLocationTopSideRight, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_SIDE_RIGHT}, + {kLeAudioLocationTopBackCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation::TOP_BACK_CENTER}, + {kLeAudioLocationBottomFrontCenter, + CodecSpecificConfigurationLtv::AudioChannelAllocation:: + BOTTOM_FRONT_CENTER}, + {kLeAudioLocationBottomFrontLeft, + CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_LEFT}, + {kLeAudioLocationBottomFrontRight, + CodecSpecificConfigurationLtv::AudioChannelAllocation::BOTTOM_FRONT_RIGHT}, + {kLeAudioLocationFrontLeftWide, + CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_LEFT_WIDE}, + {kLeAudioLocationFrontRightWide, + CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_RIGHT_WIDE}, + {kLeAudioLocationLeftSurround, + CodecSpecificConfigurationLtv::AudioChannelAllocation::LEFT_SURROUND}, + {kLeAudioLocationRightSurround, + CodecSpecificConfigurationLtv::AudioChannelAllocation::RIGHT_SURROUND}, +}; + +static const std::vector< + std::pair> + kLeAudioSetConfigs = {{"/vendor/etc/aidl/le_audio/" + "aidl_audio_set_configurations.bfbs", + "/vendor/etc/aidl/le_audio/" + "aidl_audio_set_configurations.json"}}; +static const std::vector< + std::pair> + kLeAudioSetScenarios = {{"/vendor/etc/aidl/le_audio/" + "aidl_audio_set_scenarios.bfbs", + "/vendor/etc/aidl/le_audio/" + "aidl_audio_set_configurations.json"}}; + +/* Implementation */ + +std::vector +AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() { + AudioSetConfigurationProviderJson::LoadAudioSetConfigurationProviderJson(); + return ase_configuration_settings_; +} + +void AudioSetConfigurationProviderJson:: + LoadAudioSetConfigurationProviderJson() { + if (configurations_.empty() && ase_configuration_settings_.empty()) { + auto loaded = LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios, + CodecLocation::HOST); + if (!loaded) + LOG(ERROR) << ": Unable to load le audio set configuration files."; + } else + LOG(INFO) << ": Reusing loaded le audio set configuration"; +} + +const le_audio::CodecSpecificConfiguration* +AudioSetConfigurationProviderJson::LookupCodecSpecificParam( + const flatbuffers::Vector>* flat_codec_specific_params, + le_audio::CodecSpecificLtvGenericTypes type) { + auto it = std::find_if( + flat_codec_specific_params->cbegin(), flat_codec_specific_params->cend(), + [&type](const auto& csc) { return (csc->type() == type); }); + return (it != flat_codec_specific_params->cend()) ? *it : nullptr; +} + +void AudioSetConfigurationProviderJson::populateAudioChannelAllocation( + CodecSpecificConfigurationLtv::AudioChannelAllocation& + audio_channel_allocation, + uint32_t audio_location) { + audio_channel_allocation.bitmask = 0; + for (auto [allocation, bitmask] : audio_channel_allocation_map) { + if (audio_location & allocation) + audio_channel_allocation.bitmask |= bitmask; + } +} + +void AudioSetConfigurationProviderJson::populateConfigurationData( + LeAudioAseConfiguration& ase, + const flatbuffers::Vector< + flatbuffers::Offset>* + flat_codec_specific_params) { + uint8_t sampling_frequency = 0; + uint8_t frame_duration = 0; + uint32_t audio_channel_allocation = 0; + uint16_t octets_per_codec_frame = 0; + uint8_t codec_frames_blocks_per_sdu = 0; + + auto param = LookupCodecSpecificParam( + flat_codec_specific_params, + le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_SAMPLING_FREQUENCY); + if (param) { + auto ptr = param->compound_value()->value()->data(); + STREAM_TO_UINT8(sampling_frequency, ptr); + } + + param = LookupCodecSpecificParam( + flat_codec_specific_params, + le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_FRAME_DURATION); + if (param) { + auto ptr = param->compound_value()->value()->data(); + STREAM_TO_UINT8(frame_duration, ptr); + } + + param = LookupCodecSpecificParam( + flat_codec_specific_params, + le_audio:: + CodecSpecificLtvGenericTypes_SUPPORTED_AUDIO_CHANNEL_ALLOCATION); + if (param) { + auto ptr = param->compound_value()->value()->data(); + STREAM_TO_UINT32(audio_channel_allocation, ptr); + } + + param = LookupCodecSpecificParam( + flat_codec_specific_params, + le_audio::CodecSpecificLtvGenericTypes_SUPPORTED_OCTETS_PER_CODEC_FRAME); + if (param) { + auto ptr = param->compound_value()->value()->data(); + STREAM_TO_UINT16(octets_per_codec_frame, ptr); + } + + param = LookupCodecSpecificParam( + flat_codec_specific_params, + le_audio:: + CodecSpecificLtvGenericTypes_SUPPORTED_CODEC_FRAME_BLOCKS_PER_SDU); + if (param) { + auto ptr = param->compound_value()->value()->data(); + STREAM_TO_UINT8(codec_frames_blocks_per_sdu, ptr); + } + + // Make the correct value + ase.codecConfiguration = std::vector(); + + auto sampling_freq_it = sampling_freq_map.find(sampling_frequency); + if (sampling_freq_it != sampling_freq_map.end()) + ase.codecConfiguration.push_back(sampling_freq_it->second); + auto frame_duration_it = frame_duration_map.find(frame_duration); + if (frame_duration_it != frame_duration_map.end()) + ase.codecConfiguration.push_back(frame_duration_it->second); + + CodecSpecificConfigurationLtv::AudioChannelAllocation channel_allocation; + populateAudioChannelAllocation(channel_allocation, audio_channel_allocation); + ase.codecConfiguration.push_back(channel_allocation); + + auto octet_structure = CodecSpecificConfigurationLtv::OctetsPerCodecFrame(); + octet_structure.value = octets_per_codec_frame; + ase.codecConfiguration.push_back(octet_structure); + + auto frame_sdu_structure = + CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU(); + frame_sdu_structure.value = codec_frames_blocks_per_sdu; + ase.codecConfiguration.push_back(frame_sdu_structure); + // TODO: Channel count +} + +void AudioSetConfigurationProviderJson::populateAseConfiguration( + LeAudioAseConfiguration& ase, + const le_audio::AudioSetSubConfiguration* flat_subconfig, + const le_audio::QosConfiguration* qos_cfg) { + // Target latency + switch (qos_cfg->target_latency()) { + case le_audio::AudioSetConfigurationTargetLatency:: + AudioSetConfigurationTargetLatency_BALANCED_RELIABILITY: + ase.targetLatency = + LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY; + break; + case le_audio::AudioSetConfigurationTargetLatency:: + AudioSetConfigurationTargetLatency_HIGH_RELIABILITY: + ase.targetLatency = + LeAudioAseConfiguration::TargetLatency::HIGHER_RELIABILITY; + break; + case le_audio::AudioSetConfigurationTargetLatency:: + AudioSetConfigurationTargetLatency_LOW: + ase.targetLatency = LeAudioAseConfiguration::TargetLatency::LOWER; + break; + default: + ase.targetLatency = LeAudioAseConfiguration::TargetLatency::UNDEFINED; + break; + }; + + ase.targetPhy = Phy::TWO_M; + // Making CodecId + if (flat_subconfig->codec_id()->coding_format() == + (uint8_t)CodecId::Core::LC3) { + ase.codecId = CodecId::Core::LC3; + } else { + auto vendorC = CodecId::Vendor(); + vendorC.codecId = flat_subconfig->codec_id()->vendor_codec_id(); + vendorC.id = flat_subconfig->codec_id()->vendor_company_id(); + ase.codecId = vendorC; + } + // Codec configuration data + populateConfigurationData(ase, flat_subconfig->codec_configuration()); +} + +void AudioSetConfigurationProviderJson::populateAseQosConfiguration( + LeAudioAseQosConfiguration& qos, + const le_audio::QosConfiguration* qos_cfg) { + qos.maxTransportLatencyMs = qos_cfg->max_transport_latency(); + qos.retransmissionNum = qos_cfg->retransmission_number(); +} + +// Parse into AseDirectionConfiguration +AseDirectionConfiguration +AudioSetConfigurationProviderJson::SetConfigurationFromFlatSubconfig( + const le_audio::AudioSetSubConfiguration* flat_subconfig, + const le_audio::QosConfiguration* qos_cfg, CodecLocation location) { + AseDirectionConfiguration direction_conf; + + LeAudioAseConfiguration ase; + LeAudioAseQosConfiguration qos; + LeAudioDataPathConfiguration path; + + // Translate into LeAudioAseConfiguration + populateAseConfiguration(ase, flat_subconfig, qos_cfg); + + // Translate into LeAudioAseQosConfiguration + populateAseQosConfiguration(qos, qos_cfg); + + // Translate location to data path id + switch (location) { + case CodecLocation::ADSP: + path.isoDataPathConfiguration.isTransparent = true; + path.dataPathId = kIsoDataPathPlatformDefault; + break; + case CodecLocation::HOST: + path.isoDataPathConfiguration.isTransparent = true; + path.dataPathId = kIsoDataPathHci; + break; + case CodecLocation::CONTROLLER: + path.isoDataPathConfiguration.isTransparent = false; + path.dataPathId = kIsoDataPathPlatformDefault; + break; + } + + direction_conf.aseConfiguration = ase; + direction_conf.qosConfiguration = qos; + direction_conf.dataPathConfiguration = path; + + return direction_conf; +} + +// Parse into AseDirectionConfiguration and the ConfigurationFlags +// and put them in the given list. +void AudioSetConfigurationProviderJson::processSubconfig( + const le_audio::AudioSetSubConfiguration* subconfig, + const le_audio::QosConfiguration* qos_cfg, + std::vector>& + directionAseConfiguration, + CodecLocation location) { + directionAseConfiguration.push_back( + SetConfigurationFromFlatSubconfig(subconfig, qos_cfg, location)); +} + +void AudioSetConfigurationProviderJson::PopulateAseConfigurationFromFlat( + const le_audio::AudioSetConfiguration* flat_cfg, + std::vector* codec_cfgs, + std::vector* qos_cfgs, + CodecLocation location, + std::vector>& + sourceAseConfiguration, + std::vector>& sinkAseConfiguration, + ConfigurationFlags& /*configurationFlags*/) { + if (flat_cfg == nullptr) { + LOG(ERROR) << "flat_cfg cannot be null"; + return; + } + std::string codec_config_key = flat_cfg->codec_config_name()->str(); + auto* qos_config_key_array = flat_cfg->qos_config_name(); + + constexpr std::string_view default_qos = "QoS_Config_Balanced_Reliability"; + + std::string qos_sink_key(default_qos); + std::string qos_source_key(default_qos); + + /* We expect maximum two QoS settings. First for Sink and second for Source + */ + if (qos_config_key_array->size() > 0) { + qos_sink_key = qos_config_key_array->Get(0)->str(); + if (qos_config_key_array->size() > 1) { + qos_source_key = qos_config_key_array->Get(1)->str(); + } else { + qos_source_key = qos_sink_key; + } + } + + LOG(INFO) << "Audio set config " << flat_cfg->name()->c_str() + << ": codec config " << codec_config_key.c_str() << ", qos_sink " + << qos_sink_key.c_str() << ", qos_source " + << qos_source_key.c_str(); + + // Find the first qos config that match the name + const le_audio::QosConfiguration* qos_sink_cfg = nullptr; + for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) { + if ((*i)->name()->str() == qos_sink_key) { + qos_sink_cfg = *i; + break; + } + } + + const le_audio::QosConfiguration* qos_source_cfg = nullptr; + for (auto i = qos_cfgs->begin(); i != qos_cfgs->end(); ++i) { + if ((*i)->name()->str() == qos_source_key) { + qos_source_cfg = *i; + break; + } + } + + // First codec_cfg with the same name + const le_audio::CodecConfiguration* codec_cfg = nullptr; + for (auto i = codec_cfgs->begin(); i != codec_cfgs->end(); ++i) { + if ((*i)->name()->str() == codec_config_key) { + codec_cfg = *i; + break; + } + } + + // Process each subconfig and put it into the correct list + if (codec_cfg != nullptr && codec_cfg->subconfigurations()) { + /* Load subconfigurations */ + for (auto subconfig : *codec_cfg->subconfigurations()) { + if (subconfig->direction() == kLeAudioDirectionSink) { + processSubconfig(subconfig, qos_sink_cfg, sinkAseConfiguration, + location); + } else { + processSubconfig(subconfig, qos_source_cfg, sourceAseConfiguration, + location); + } + } + } else { + if (codec_cfg == nullptr) { + LOG(ERROR) << "No codec config matching key " << codec_config_key.c_str() + << " found"; + } else { + LOG(ERROR) << "Configuration '" << flat_cfg->name()->c_str() + << "' has no valid subconfigurations."; + } + } + + // TODO: Populate information for ConfigurationFlags +} + +bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles( + const char* schema_file, const char* content_file, CodecLocation location) { + flatbuffers::Parser configurations_parser_; + std::string configurations_schema_binary_content; + bool ok = flatbuffers::LoadFile(schema_file, true, + &configurations_schema_binary_content); + LOG(INFO) << __func__ << "Loading file " << schema_file; + if (!ok) return ok; + + /* Load the binary schema */ + ok = configurations_parser_.Deserialize( + (uint8_t*)configurations_schema_binary_content.c_str(), + configurations_schema_binary_content.length()); + if (!ok) return ok; + + /* Load the content from JSON */ + std::string configurations_json_content; + LOG(INFO) << __func__ << "Loading file " << schema_file; + ok = flatbuffers::LoadFile(content_file, false, &configurations_json_content); + if (!ok) return ok; + + /* Parse */ + LOG(INFO) << __func__ << "Parse JSON content" << schema_file; + ok = configurations_parser_.Parse(configurations_json_content.c_str()); + if (!ok) return ok; + + /* Import from flatbuffers */ + LOG(INFO) << __func__ << "Build flat buffer structure" << schema_file; + auto configurations_root = le_audio::GetAudioSetConfigurations( + configurations_parser_.builder_.GetBufferPointer()); + if (!configurations_root) return false; + + auto flat_qos_configs = configurations_root->qos_configurations(); + if ((flat_qos_configs == nullptr) || (flat_qos_configs->size() == 0)) + return false; + + LOG(DEBUG) << ": Updating " << flat_qos_configs->size() + << " qos config entries."; + std::vector qos_cfgs; + for (auto const& flat_qos_cfg : *flat_qos_configs) { + qos_cfgs.push_back(flat_qos_cfg); + } + + auto flat_codec_configs = configurations_root->codec_configurations(); + if ((flat_codec_configs == nullptr) || (flat_codec_configs->size() == 0)) + return false; + + LOG(DEBUG) << ": Updating " << flat_codec_configs->size() + << " codec config entries."; + std::vector codec_cfgs; + for (auto const& flat_codec_cfg : *flat_codec_configs) { + codec_cfgs.push_back(flat_codec_cfg); + } + + auto flat_configs = configurations_root->configurations(); + if ((flat_configs == nullptr) || (flat_configs->size() == 0)) return false; + + LOG(DEBUG) << ": Updating " << flat_configs->size() << " config entries."; + for (auto const& flat_cfg : *flat_configs) { + // Create 3 vector to use + std::vector> + sourceAseConfiguration; + std::vector> sinkAseConfiguration; + ConfigurationFlags configurationFlags; + PopulateAseConfigurationFromFlat(flat_cfg, &codec_cfgs, &qos_cfgs, location, + sourceAseConfiguration, + sinkAseConfiguration, configurationFlags); + if (sourceAseConfiguration.empty() && sinkAseConfiguration.empty()) + continue; + configurations_[flat_cfg->name()->str()] = std::make_tuple( + &sourceAseConfiguration, &sinkAseConfiguration, &configurationFlags); + } + + return true; +} + +bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles( + const char* schema_file, const char* content_file) { + flatbuffers::Parser scenarios_parser_; + std::string scenarios_schema_binary_content; + bool ok = flatbuffers::LoadFile(schema_file, true, + &scenarios_schema_binary_content); + if (!ok) return ok; + + /* Load the binary schema */ + ok = scenarios_parser_.Deserialize( + (uint8_t*)scenarios_schema_binary_content.c_str(), + scenarios_schema_binary_content.length()); + if (!ok) return ok; + + /* Load the content from JSON */ + std::string scenarios_json_content; + ok = flatbuffers::LoadFile(content_file, false, &scenarios_json_content); + if (!ok) return ok; + + /* Parse */ + ok = scenarios_parser_.Parse(scenarios_json_content.c_str()); + if (!ok) return ok; + + /* Import from flatbuffers */ + auto scenarios_root = le_audio::GetAudioSetScenarios( + scenarios_parser_.builder_.GetBufferPointer()); + if (!scenarios_root) return false; + + auto flat_scenarios = scenarios_root->scenarios(); + if ((flat_scenarios == nullptr) || (flat_scenarios->size() == 0)) + return false; + + AudioContext media_context = AudioContext(); + media_context.bitmask = + (AudioContext::ALERTS | AudioContext::INSTRUCTIONAL | + AudioContext::NOTIFICATIONS | AudioContext::EMERGENCY_ALARM | + AudioContext::UNSPECIFIED | AudioContext::MEDIA); + + AudioContext conversational_context = AudioContext(); + conversational_context.bitmask = + (AudioContext::RINGTONE_ALERTS | AudioContext::CONVERSATIONAL); + + AudioContext live_context = AudioContext(); + live_context.bitmask = AudioContext::LIVE_AUDIO; + + AudioContext game_context = AudioContext(); + game_context.bitmask = AudioContext::GAME; + + AudioContext voice_assistants_context = AudioContext(); + voice_assistants_context.bitmask = AudioContext::VOICE_ASSISTANTS; + + LOG(DEBUG) << ": Updating " << flat_scenarios->size() << " scenarios."; + for (auto const& scenario : *flat_scenarios) { + LOG(DEBUG) << "Scenario " << scenario->name()->c_str() << " configs:"; + + if (!scenario->configurations()) continue; + std::string scenario_name = scenario->name()->c_str(); + AudioContext context; + if (scenario_name == "Media") + context = AudioContext(media_context); + else if (scenario_name == "Conversational") + context = AudioContext(conversational_context); + else if (scenario_name == "Live") + context = AudioContext(live_context); + else if (scenario_name == "Game") + context = AudioContext(game_context); + else if (scenario_name == "VoiceAssistants") + context = AudioContext(voice_assistants_context); + + for (auto config_name : *scenario->configurations()) { + if (configurations_.count(config_name->str()) == 0) continue; + auto [source, sink, flags] = configurations_.at(config_name->str()); + // Each configuration will create a LeAudioAseConfigurationSetting + // with the same {context, packing} + // and different data + LeAudioAseConfigurationSetting setting; + setting.audioContext = context; + // TODO: Packing + setting.sourceAseConfiguration = *source; + setting.sinkAseConfiguration = *sink; + setting.flags = *flags; + // Add to list of setting + ase_configuration_settings_.push_back(setting); + } + } + + return true; +} + +bool AudioSetConfigurationProviderJson::LoadContent( + std::vector> + config_files, + std::vector> + scenario_files, + CodecLocation location) { + for (auto [schema, content] : config_files) { + if (!LoadConfigurationsFromFiles(schema, content, location)) return false; + } + + for (auto [schema, content] : scenario_files) { + if (!LoadScenariosFromFiles(schema, content)) return false; + } + return true; +} + +} // namespace audio +} // namespace bluetooth +} // namespace hardware +} // namespace android +} // namespace aidl From 6112bda4362d201d71359698138f9b11523670d6 Mon Sep 17 00:00:00 2001 From: Bao Do Date: Wed, 15 Nov 2023 03:57:59 +0000 Subject: [PATCH 07/11] Add template functions and implement setCodecPriority for LE Audio offloading provider Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/aidl/default Change-Id: I440a007ba3ed148834db1c3874af780b454aae39 --- .../default/LeAudioOffloadAudioProvider.cpp | 70 +++++++++++- .../default/LeAudioOffloadAudioProvider.h | 105 +++++++++++++++++- 2 files changed, 171 insertions(+), 4 deletions(-) diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp index 7f610ef3d0..91ede92667 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp @@ -70,8 +70,8 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession( return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } - return BluetoothAudioProvider::startSession( - host_if, audio_config, latency_modes, _aidl_return); + return BluetoothAudioProvider::startSession(host_if, audio_config, + latency_modes, _aidl_return); } ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady( @@ -81,6 +81,72 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSessionReady( *_aidl_return = DataMQDesc(); return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus LeAudioOffloadAudioProvider::setCodecPriority( + const CodecId& in_codecId, int32_t in_priority) { + codec_priority_map_[in_codecId] = in_priority; + return ndk::ScopedAStatus::ok(); +}; + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration( + const std::optional>>& + in_remoteSinkAudioCapabilities, + const std::optional>>& + in_remoteSourceAudioCapabilities, + const std::vector& + in_requirements, + std::vector* + _aidl_return) { + /* TODO: Implement */ + (void)in_remoteSinkAudioCapabilities; + (void)in_remoteSourceAudioCapabilities; + (void)in_requirements; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration( + const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement& + in_qosRequirement, + IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) { + /* TODO: Implement */ + (void)in_qosRequirement; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged( + IBluetoothAudioProvider::AseState in_state, + const std::optional>>& in_metadata) { + (void)in_state; + (void)in_metadata; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSourceAseMetadataChanged( + IBluetoothAudioProvider::AseState in_state, + const std::optional>>& in_metadata) { + (void)in_state; + (void)in_metadata; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; + +ndk::ScopedAStatus +LeAudioOffloadAudioProvider::getLeAudioBroadcastConfiguration( + const std::optional>>& + in_remoteSinkAudioCapabilities, + const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement& + in_requirement, + IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* + _aidl_return) { + /* TODO: Implement */ + (void)in_remoteSinkAudioCapabilities; + (void)in_requirement; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +}; } // namespace audio } // namespace bluetooth diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h index 614c794fa3..bfca061ddd 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h @@ -16,7 +16,11 @@ #pragma once +#include + #include "BluetoothAudioProvider.h" +#include "aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h" +#include "aidl/android/hardware/bluetooth/audio/MetadataLtv.h" namespace aidl { namespace android { @@ -24,6 +28,13 @@ namespace hardware { namespace bluetooth { namespace audio { +using LeAudioAseConfigurationSetting = + IBluetoothAudioProvider::LeAudioAseConfigurationSetting; +using AseDirectionRequirement = IBluetoothAudioProvider:: + LeAudioConfigurationRequirement::AseDirectionRequirement; +using AseDirectionConfiguration = IBluetoothAudioProvider:: + LeAudioAseConfigurationSetting::AseDirectionConfiguration; + class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { public: LeAudioOffloadAudioProvider(); @@ -33,11 +44,101 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { ndk::ScopedAStatus startSession( const std::shared_ptr& host_if, const AudioConfiguration& audio_config, - const std::vector& latency_modes, - DataMQDesc* _aidl_return); + const std::vector& latency_modes, DataMQDesc* _aidl_return); + ndk::ScopedAStatus setCodecPriority(const CodecId& in_codecId, + int32_t in_priority) override; + ndk::ScopedAStatus getLeAudioAseConfiguration( + const std::optional>>& + in_remoteSinkAudioCapabilities, + const std::optional>>& + in_remoteSourceAudioCapabilities, + const std::vector< + IBluetoothAudioProvider::LeAudioConfigurationRequirement>& + in_requirements, + std::vector* + _aidl_return) override; + ndk::ScopedAStatus getLeAudioAseQosConfiguration( + const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement& + in_qosRequirement, + IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) + override; + ndk::ScopedAStatus onSinkAseMetadataChanged( + IBluetoothAudioProvider::AseState in_state, + const std::optional>>& in_metadata) + override; + ndk::ScopedAStatus onSourceAseMetadataChanged( + IBluetoothAudioProvider::AseState in_state, + const std::optional>>& in_metadata) + override; + ndk::ScopedAStatus getLeAudioBroadcastConfiguration( + const std::optional>>& + in_remoteSinkAudioCapabilities, + const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement& + in_requirement, + IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* + _aidl_return) override; private: ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; + std::map codec_priority_map_; + + // Private matching function definitions + bool isMatchedValidCodec(CodecId cfg_codec, CodecId req_codec); + bool isMatchedContext( + AudioContext setting_context, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities); + bool isMatchedSamplingFreq( + CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies& + capability_freq); + bool isMatchedFrameDuration( + CodecSpecificConfigurationLtv::FrameDuration& cfg_fduration, + CodecSpecificCapabilitiesLtv::SupportedFrameDurations& + capability_fduration); + bool isMatchedAudioChannel( + CodecSpecificConfigurationLtv::AudioChannelAllocation& cfg_channel, + CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts& + capability_channel); + bool isMatchedCodecFramesPerSDU( + CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU& cfg_frame_sdu, + CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU& + capability_frame_sdu); + bool isMatchedOctetsPerCodecFrame( + CodecSpecificConfigurationLtv::OctetsPerCodecFrame& cfg_octets, + CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame& + capability_octets); + bool isCapabilitiesMatchedCodecConfiguration( + std::vector& codec_cfg, + std::vector codec_capabilities); + bool isRequirementAseConfigurationMatched( + LeAudioAseConfiguration setting_cfg, + LeAudioAseConfiguration requirement_cfg); + void filterCapabilitiesAseDirectionConfiguration( + std::vector>& + direction_configurations, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities, + std::vector>& + valid_direction_configurations); + void filterRequirementAseDirectionConfiguration( + std::vector>& + direction_configurations, + const std::optional>>& + requirements, + std::vector>& + valid_direction_configurations); + std::optional + getCapabilitiesMatchedAseConfigurationSettings( + IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities, + uint8_t direction); + std::optional + getRequirementMatchedAseConfigurationSettings( + IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, + const IBluetoothAudioProvider::LeAudioConfigurationRequirement& + requirement); }; class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { From 867af60a77f11905bad6515c414d2ffdae455f26 Mon Sep 17 00:00:00 2001 From: Bao Do Date: Wed, 15 Nov 2023 05:41:12 +0000 Subject: [PATCH 08/11] Default implementation of getLeAudioAseConfiguration for LE Audio Offload provider Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/aidl/default Change-Id: Ic09a1cbd8c85aa33375e8e1521ec03964117ac3a --- .../default/LeAudioOffloadAudioProvider.cpp | 413 +++++++++++++++++- .../default/LeAudioOffloadAudioProvider.h | 7 +- 2 files changed, 410 insertions(+), 10 deletions(-) diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp index 91ede92667..406856896c 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp @@ -28,6 +28,60 @@ namespace hardware { namespace bluetooth { namespace audio { +constexpr uint8_t kLeAudioDirectionSink = 0x01; +constexpr uint8_t kLeAudioDirectionSource = 0x02; + +const std::map + freq_to_support_bitmask_map = { + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ11025}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ16000}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ22050, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ22050}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ24000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ24000}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ32000}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ48000}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ88200, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ88200}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ96000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ96000}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ176400, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ176400}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ192000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ192000}, + {CodecSpecificConfigurationLtv::SamplingFrequency::HZ384000, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ384000}, +}; + +// Helper map from capability's tag to configuration's tag +std::map + cap_to_cfg_tag_map = { + {CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies, + CodecSpecificConfigurationLtv::Tag::samplingFrequency}, + {CodecSpecificCapabilitiesLtv::Tag::supportedMaxCodecFramesPerSDU, + CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU}, + {CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations, + CodecSpecificConfigurationLtv::Tag::frameDuration}, + {CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts, + CodecSpecificConfigurationLtv::Tag::audioChannelAllocation}, + {CodecSpecificCapabilitiesLtv::Tag::supportedOctetsPerCodecFrame, + CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame}, +}; + +const std::map + fduration_to_support_fduration_map = { + {CodecSpecificConfigurationLtv::FrameDuration::US7500, + CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500}, + {CodecSpecificConfigurationLtv::FrameDuration::US10000, + CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000}, +}; + LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider() : LeAudioOffloadAudioProvider() { session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; @@ -87,6 +141,310 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::setCodecPriority( return ndk::ScopedAStatus::ok(); }; +bool LeAudioOffloadAudioProvider::isMatchedValidCodec(CodecId cfg_codec, + CodecId req_codec) { + auto priority = codec_priority_map_.find(cfg_codec); + if (priority != codec_priority_map_.end() && priority->second == -1) + return false; + return cfg_codec == req_codec; +} + +bool LeAudioOffloadAudioProvider::isCapabilitiesMatchedContext( + AudioContext setting_context, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) { + // If has no metadata, assume match + if (!capabilities.metadata.has_value()) return true; + + for (auto metadata : capabilities.metadata.value()) { + if (!metadata.has_value()) continue; + if (metadata.value().getTag() == MetadataLtv::Tag::preferredAudioContexts) { + // Check all pref audio context to see if anything matched + auto& context = metadata.value() + .get() + .values; + if (setting_context.bitmask & context.bitmask) return true; + } + } + + return false; +} + +bool LeAudioOffloadAudioProvider::isMatchedSamplingFreq( + CodecSpecificConfigurationLtv::SamplingFrequency& cfg_freq, + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies& + capability_freq) { + for (auto [freq, bitmask] : freq_to_support_bitmask_map) + if (cfg_freq == freq) return (capability_freq.bitmask & bitmask); + return false; +} + +bool LeAudioOffloadAudioProvider::isMatchedFrameDuration( + CodecSpecificConfigurationLtv::FrameDuration& cfg_fduration, + CodecSpecificCapabilitiesLtv::SupportedFrameDurations& + capability_fduration) { + for (auto [fduration, bitmask] : fduration_to_support_fduration_map) + if (cfg_fduration == fduration) + return (capability_fduration.bitmask & bitmask); + return false; +} + +bool LeAudioOffloadAudioProvider::isMatchedAudioChannel( + CodecSpecificConfigurationLtv::AudioChannelAllocation& + /*cfg_channel*/, + CodecSpecificCapabilitiesLtv::SupportedAudioChannelCounts& + /*capability_channel*/) { + bool isMatched = true; + // TODO: how to match? + return isMatched; +} + +bool LeAudioOffloadAudioProvider::isMatchedCodecFramesPerSDU( + CodecSpecificConfigurationLtv::CodecFrameBlocksPerSDU& cfg_frame_sdu, + CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU& + capability_frame_sdu) { + return cfg_frame_sdu.value <= capability_frame_sdu.value; +} + +bool LeAudioOffloadAudioProvider::isMatchedOctetsPerCodecFrame( + CodecSpecificConfigurationLtv::OctetsPerCodecFrame& cfg_octets, + CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame& + capability_octets) { + return cfg_octets.value >= capability_octets.minimum && + cfg_octets.value <= capability_octets.maximum; +} + +bool LeAudioOffloadAudioProvider::isCapabilitiesMatchedCodecConfiguration( + std::vector& codec_cfg, + std::vector codec_capabilities) { + // Convert all codec_cfg into a map of tags -> correct data + std::map + cfg_tag_map; + for (auto codec_cfg_data : codec_cfg) + cfg_tag_map[codec_cfg_data.getTag()] = codec_cfg_data; + + for (auto& codec_capability : codec_capabilities) { + auto cfg = cfg_tag_map.find(cap_to_cfg_tag_map[codec_capability.getTag()]); + // Cannot find tag for the capability: + if (cfg == cfg_tag_map.end()) return false; + + // Matching logic for sampling frequency + if (codec_capability.getTag() == + CodecSpecificCapabilitiesLtv::Tag::supportedSamplingFrequencies) { + if (!isMatchedSamplingFreq( + cfg->second + .get(), + codec_capability.get())) + return false; + } else if (codec_capability.getTag() == + CodecSpecificCapabilitiesLtv::Tag::supportedFrameDurations) { + if (!isMatchedFrameDuration( + cfg->second + .get(), + codec_capability.get())) + return false; + } else if (codec_capability.getTag() == + CodecSpecificCapabilitiesLtv::Tag::supportedAudioChannelCounts) { + if (!isMatchedAudioChannel( + cfg->second.get< + CodecSpecificConfigurationLtv::Tag::audioChannelAllocation>(), + codec_capability.get())) + return false; + } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag:: + supportedMaxCodecFramesPerSDU) { + if (!isMatchedCodecFramesPerSDU( + cfg->second.get< + CodecSpecificConfigurationLtv::Tag::codecFrameBlocksPerSDU>(), + codec_capability.get())) + return false; + } else if (codec_capability.getTag() == CodecSpecificCapabilitiesLtv::Tag:: + supportedOctetsPerCodecFrame) { + if (!isMatchedOctetsPerCodecFrame( + cfg->second.get< + CodecSpecificConfigurationLtv::Tag::octetsPerCodecFrame>(), + codec_capability.get())) + return false; + } + } + + return true; +} + +bool LeAudioOffloadAudioProvider::isMatchedAseConfiguration( + LeAudioAseConfiguration setting_cfg, + LeAudioAseConfiguration requirement_cfg) { + // Check matching for codec configuration <=> requirement ASE codec + // Also match if no CodecId requirement + if (requirement_cfg.codecId.has_value()) { + if (!setting_cfg.codecId.has_value()) return false; + if (!isMatchedValidCodec(setting_cfg.codecId.value(), + requirement_cfg.codecId.value())) + return false; + } + + if (setting_cfg.targetLatency != requirement_cfg.targetLatency) return false; + // Ignore PHY requirement + + // Check all codec configuration + std::map + cfg_tag_map; + for (auto cfg : setting_cfg.codecConfiguration) + cfg_tag_map[cfg.getTag()] = cfg; + + for (auto requirement_cfg : requirement_cfg.codecConfiguration) { + // Directly compare CodecSpecificConfigurationLtv + auto cfg = cfg_tag_map.find(requirement_cfg.getTag()); + if (cfg == cfg_tag_map.end()) return false; + + if (cfg->second != requirement_cfg) return false; + } + // Ignore vendor configuration and metadata requirement + + return true; +} + +void LeAudioOffloadAudioProvider::filterCapabilitiesAseDirectionConfiguration( + std::vector>& + direction_configurations, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities, + std::vector>& + valid_direction_configurations) { + for (auto direction_configuration : direction_configurations) { + if (!direction_configuration.has_value()) continue; + if (!direction_configuration.value().aseConfiguration.codecId.has_value()) + continue; + if (!isMatchedValidCodec( + direction_configuration.value().aseConfiguration.codecId.value(), + capabilities.codecId)) + continue; + // Check matching for codec configuration <=> codec capabilities + if (!isCapabilitiesMatchedCodecConfiguration( + direction_configuration.value().aseConfiguration.codecConfiguration, + capabilities.codecSpecificCapabilities)) + continue; + valid_direction_configurations.push_back(direction_configuration); + } +} + +void LeAudioOffloadAudioProvider::filterRequirementAseDirectionConfiguration( + std::vector>& + direction_configurations, + const std::optional>>& + requirements, + std::vector>& + valid_direction_configurations) { + for (auto direction_configuration : direction_configurations) { + if (!requirements.has_value()) { + // If there's no requirement, all are valid + valid_direction_configurations.push_back(direction_configuration); + continue; + } + if (!direction_configuration.has_value()) continue; + + for (auto& requirement : requirements.value()) { + if (!requirement.has_value()) continue; + if (!isMatchedAseConfiguration( + direction_configuration.value().aseConfiguration, + requirement.value().aseConfiguration)) + continue; + // Valid if match any requirement. + valid_direction_configurations.push_back(direction_configuration); + break; + } + } +} + +/* Get a new LeAudioAseConfigurationSetting by matching a setting with a + * capabilities. The new setting will have a filtered list of + * AseDirectionConfiguration that matched the capabilities */ +std::optional +LeAudioOffloadAudioProvider::getCapabilitiesMatchedAseConfigurationSettings( + IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities, + uint8_t direction) { + // Try to match context in metadata. + if (!isCapabilitiesMatchedContext(setting.audioContext, capabilities)) + return std::nullopt; + + // Get a list of all matched AseDirectionConfiguration + // for the input direction + std::vector>* + direction_configuration = nullptr; + if (direction == kLeAudioDirectionSink) { + if (!setting.sinkAseConfiguration.has_value()) return std::nullopt; + direction_configuration = &setting.sinkAseConfiguration.value(); + } else { + if (!setting.sourceAseConfiguration.has_value()) return std::nullopt; + direction_configuration = &setting.sourceAseConfiguration.value(); + } + std::vector> + valid_direction_configuration; + filterCapabilitiesAseDirectionConfiguration( + *direction_configuration, capabilities, valid_direction_configuration); + if (valid_direction_configuration.empty()) return std::nullopt; + + // Create a new LeAudioAseConfigurationSetting and return + LeAudioAseConfigurationSetting filtered_setting; + filtered_setting.audioContext = setting.audioContext; + filtered_setting.packing = setting.packing; + if (direction == kLeAudioDirectionSink) { + filtered_setting.sinkAseConfiguration = valid_direction_configuration; + } else { + filtered_setting.sourceAseConfiguration = valid_direction_configuration; + } + filtered_setting.flags = setting.flags; + + return filtered_setting; +} + +/* Get a new LeAudioAseConfigurationSetting by matching a setting with a + * requirement. The new setting will have a filtered list of + * AseDirectionConfiguration that matched the requirement */ +std::optional +LeAudioOffloadAudioProvider::getRequirementMatchedAseConfigurationSettings( + IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, + const IBluetoothAudioProvider::LeAudioConfigurationRequirement& + requirement) { + // Try to match context in metadata. + if (setting.audioContext != requirement.audioContext) return std::nullopt; + + // Check requirement for the correct direction + const std::optional>>* + direction_requirement; + std::vector>* + direction_configuration; + if (setting.sinkAseConfiguration.has_value()) { + direction_configuration = &setting.sinkAseConfiguration.value(); + direction_requirement = &requirement.sinkAseRequirement; + } else { + direction_configuration = &setting.sourceAseConfiguration.value(); + direction_requirement = &requirement.sourceAseRequirement; + } + + std::vector> + valid_direction_configuration; + filterRequirementAseDirectionConfiguration(*direction_configuration, + *direction_requirement, + valid_direction_configuration); + if (valid_direction_configuration.empty()) return std::nullopt; + + // Create a new LeAudioAseConfigurationSetting and return + LeAudioAseConfigurationSetting filtered_setting; + filtered_setting.audioContext = setting.audioContext; + filtered_setting.packing = setting.packing; + if (setting.sinkAseConfiguration.has_value()) + filtered_setting.sinkAseConfiguration = valid_direction_configuration; + else + filtered_setting.sourceAseConfiguration = valid_direction_configuration; + filtered_setting.flags = setting.flags; + + return filtered_setting; +} + ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration( const std::optional>>& @@ -98,12 +456,55 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration( in_requirements, std::vector* _aidl_return) { - /* TODO: Implement */ - (void)in_remoteSinkAudioCapabilities; - (void)in_remoteSourceAudioCapabilities; - (void)in_requirements; - (void)_aidl_return; - return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + // Get all configuration settings + std::vector + ase_configuration_settings = + BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings(); + + // Currently won't handle case where both sink and source capabilities + // are passed in. Only handle one of them. + const std::optional>>* + in_remoteAudioCapabilities; + uint8_t direction = 0; + if (in_remoteSinkAudioCapabilities.has_value()) { + direction = kLeAudioDirectionSink; + in_remoteAudioCapabilities = &in_remoteSinkAudioCapabilities; + } else { + direction = kLeAudioDirectionSource; + in_remoteAudioCapabilities = &in_remoteSourceAudioCapabilities; + } + + std::vector + capability_matched_ase_configuration_settings; + // Matching with remote capabilities + for (auto& setting : ase_configuration_settings) { + for (auto& capability : in_remoteAudioCapabilities->value()) { + if (!capability.has_value()) continue; + auto filtered_ase_configuration_setting = + getCapabilitiesMatchedAseConfigurationSettings( + setting, capability.value(), direction); + if (filtered_ase_configuration_setting.has_value()) { + capability_matched_ase_configuration_settings.push_back( + filtered_ase_configuration_setting.value()); + } + } + } + + // Matching with requirements + std::vector result; + for (auto& setting : capability_matched_ase_configuration_settings) { + for (auto& requirement : in_requirements) { + auto filtered_ase_configuration_setting = + getRequirementMatchedAseConfigurationSettings(setting, requirement); + if (filtered_ase_configuration_setting.has_value()) { + result.push_back(filtered_ase_configuration_setting.value()); + } + } + } + + *_aidl_return = result; + return ndk::ScopedAStatus::ok(); }; ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration( diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h index bfca061ddd..2488f9b78b 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h @@ -87,7 +87,7 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { // Private matching function definitions bool isMatchedValidCodec(CodecId cfg_codec, CodecId req_codec); - bool isMatchedContext( + bool isCapabilitiesMatchedContext( AudioContext setting_context, const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities); bool isMatchedSamplingFreq( @@ -113,9 +113,8 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { bool isCapabilitiesMatchedCodecConfiguration( std::vector& codec_cfg, std::vector codec_capabilities); - bool isRequirementAseConfigurationMatched( - LeAudioAseConfiguration setting_cfg, - LeAudioAseConfiguration requirement_cfg); + bool isMatchedAseConfiguration(LeAudioAseConfiguration setting_cfg, + LeAudioAseConfiguration requirement_cfg); void filterCapabilitiesAseDirectionConfiguration( std::vector>& direction_configurations, From c4adf243fe6965049da7e116c09e85e1d034d285 Mon Sep 17 00:00:00 2001 From: Bao Do Date: Wed, 15 Nov 2023 08:03:20 +0000 Subject: [PATCH 09/11] Default implementation of getLeAudioAseQosConfiguration for LE Audio Offload provider Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/aidl/default Change-Id: Idffad1de0d06b4892dec1907e42ef1697fe54d60 --- .../default/LeAudioOffloadAudioProvider.cpp | 87 ++++++++++++++++++- .../default/LeAudioOffloadAudioProvider.h | 6 ++ 2 files changed, 89 insertions(+), 4 deletions(-) diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp index 406856896c..426171d321 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp @@ -507,14 +507,93 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseConfiguration( return ndk::ScopedAStatus::ok(); }; +bool LeAudioOffloadAudioProvider::isMatchedQosRequirement( + LeAudioAseQosConfiguration setting_qos, + AseQosDirectionRequirement requirement_qos) { + if (setting_qos.retransmissionNum != + requirement_qos.preferredRetransmissionNum) + return false; + if (setting_qos.maxTransportLatencyMs > requirement_qos.maxTransportLatencyMs) + return false; + // Ignore other parameters, as they are not populated in the setting_qos + return true; +} + ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration( const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement& in_qosRequirement, IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) { - /* TODO: Implement */ - (void)in_qosRequirement; - (void)_aidl_return; - return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result; + // Get all configuration settings + std::vector + ase_configuration_settings = + BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings(); + + // Direction QoS matching + // Only handle one direction input case + uint8_t direction = 0; + std::optional direction_qos_requirement = + std::nullopt; + if (in_qosRequirement.sinkAseQosRequirement.has_value()) { + direction_qos_requirement = in_qosRequirement.sinkAseQosRequirement.value(); + direction = kLeAudioDirectionSink; + } else if (in_qosRequirement.sourceAseQosRequirement.has_value()) { + direction_qos_requirement = + in_qosRequirement.sourceAseQosRequirement.value(); + direction = kLeAudioDirectionSource; + } + + for (auto& setting : ase_configuration_settings) { + // Context matching + if (setting.audioContext != in_qosRequirement.contextType) continue; + + // Match configuration flags + // Currently configuration flags are not populated, ignore. + + // Get a list of all matched AseDirectionConfiguration + // for the input direction + std::vector>* + direction_configuration = nullptr; + if (direction == kLeAudioDirectionSink) { + if (!setting.sinkAseConfiguration.has_value()) continue; + direction_configuration = &setting.sinkAseConfiguration.value(); + } else { + if (!setting.sourceAseConfiguration.has_value()) continue; + direction_configuration = &setting.sourceAseConfiguration.value(); + } + + for (auto cfg : *direction_configuration) { + if (!cfg.has_value()) continue; + // If no requirement, return the first QoS + if (!direction_qos_requirement.has_value()) { + result.sinkQosConfiguration = cfg.value().qosConfiguration; + result.sourceQosConfiguration = cfg.value().qosConfiguration; + *_aidl_return = result; + return ndk::ScopedAStatus::ok(); + } + + // If has requirement, return the first matched QoS + // Try to match the ASE configuration + // and QoS with requirement + if (!cfg.value().qosConfiguration.has_value()) continue; + if (isMatchedAseConfiguration( + cfg.value().aseConfiguration, + direction_qos_requirement.value().aseConfiguration) && + isMatchedQosRequirement(cfg.value().qosConfiguration.value(), + direction_qos_requirement.value())) { + if (direction == kLeAudioDirectionSink) + result.sinkQosConfiguration = cfg.value().qosConfiguration; + else + result.sourceQosConfiguration = cfg.value().qosConfiguration; + *_aidl_return = result; + return ndk::ScopedAStatus::ok(); + } + } + } + + // No match, return empty QoS + *_aidl_return = result; + return ndk::ScopedAStatus::ok(); }; ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged( diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h index 2488f9b78b..b6037c3c88 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h @@ -34,6 +34,10 @@ using AseDirectionRequirement = IBluetoothAudioProvider:: LeAudioConfigurationRequirement::AseDirectionRequirement; using AseDirectionConfiguration = IBluetoothAudioProvider:: LeAudioAseConfigurationSetting::AseDirectionConfiguration; +using AseQosDirectionRequirement = IBluetoothAudioProvider:: + LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement; +using LeAudioAseQosConfiguration = + IBluetoothAudioProvider::LeAudioAseQosConfiguration; class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { public: @@ -138,6 +142,8 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting, const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement); + bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos, + AseQosDirectionRequirement requirement_qos); }; class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { From c36897dbd87d76fb7bb247c83de7605333d97c96 Mon Sep 17 00:00:00 2001 From: Bao Do Date: Wed, 6 Dec 2023 01:27:54 +0000 Subject: [PATCH 10/11] Add VTS for LE multi-codec Bug: 308548462 Test: atest VtsHalBluetoothAudioTargetTest Change-Id: Ia74da644eb8e62bdf0709ba7f375a7e35ccf0936 --- .../vts/VtsHalBluetoothAudioTargetTest.cpp | 342 +++++++++++++++++- 1 file changed, 339 insertions(+), 3 deletions(-) diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp index 17be7be9d7..c18d48e943 100644 --- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp +++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp @@ -46,6 +46,7 @@ using aidl::android::hardware::bluetooth::audio::AptxCapabilities; using aidl::android::hardware::bluetooth::audio::AptxConfiguration; using aidl::android::hardware::bluetooth::audio::AudioCapabilities; using aidl::android::hardware::bluetooth::audio::AudioConfiguration; +using aidl::android::hardware::bluetooth::audio::AudioContext; using aidl::android::hardware::bluetooth::audio::BnBluetoothAudioPort; using aidl::android::hardware::bluetooth::audio::BroadcastCapability; using aidl::android::hardware::bluetooth::audio::ChannelMode; @@ -54,6 +55,8 @@ using aidl::android::hardware::bluetooth::audio::CodecConfiguration; using aidl::android::hardware::bluetooth::audio::CodecId; using aidl::android::hardware::bluetooth::audio::CodecInfo; using aidl::android::hardware::bluetooth::audio::CodecParameters; +using aidl::android::hardware::bluetooth::audio::CodecSpecificCapabilitiesLtv; +using aidl::android::hardware::bluetooth::audio::CodecSpecificConfigurationLtv; using aidl::android::hardware::bluetooth::audio::CodecType; using aidl::android::hardware::bluetooth::audio::HfpConfiguration; using aidl::android::hardware::bluetooth::audio::IBluetoothAudioPort; @@ -64,11 +67,13 @@ using aidl::android::hardware::bluetooth::audio::Lc3Capabilities; using aidl::android::hardware::bluetooth::audio::Lc3Configuration; using aidl::android::hardware::bluetooth::audio::LdacCapabilities; using aidl::android::hardware::bluetooth::audio::LdacConfiguration; +using aidl::android::hardware::bluetooth::audio::LeAudioAseConfiguration; using aidl::android::hardware::bluetooth::audio::LeAudioBroadcastConfiguration; using aidl::android::hardware::bluetooth::audio:: LeAudioCodecCapabilitiesSetting; using aidl::android::hardware::bluetooth::audio::LeAudioCodecConfiguration; using aidl::android::hardware::bluetooth::audio::LeAudioConfiguration; +using aidl::android::hardware::bluetooth::audio::MetadataLtv; using aidl::android::hardware::bluetooth::audio::OpusCapabilities; using aidl::android::hardware::bluetooth::audio::OpusConfiguration; using aidl::android::hardware::bluetooth::audio::PcmConfiguration; @@ -92,6 +97,21 @@ using MqDataMode = SynchronizedReadWrite; using DataMQ = AidlMessageQueue; using DataMQDesc = MQDescriptor; +using LeAudioAseConfigurationSetting = + IBluetoothAudioProvider::LeAudioAseConfigurationSetting; +using AseDirectionRequirement = IBluetoothAudioProvider:: + LeAudioConfigurationRequirement::AseDirectionRequirement; +using AseDirectionConfiguration = IBluetoothAudioProvider:: + LeAudioAseConfigurationSetting::AseDirectionConfiguration; +using AseQosDirectionRequirement = IBluetoothAudioProvider:: + LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement; +using LeAudioAseQosConfiguration = + IBluetoothAudioProvider::LeAudioAseQosConfiguration; +using LeAudioDeviceCapabilities = + IBluetoothAudioProvider::LeAudioDeviceCapabilities; +using LeAudioConfigurationRequirement = + IBluetoothAudioProvider::LeAudioConfigurationRequirement; + // Constants static constexpr int32_t a2dp_sample_rates[] = {0, 44100, 48000, 88200, 96000}; @@ -197,6 +217,13 @@ class BluetoothAudioProviderFactoryAidl virtual void TearDown() override { provider_factory_ = nullptr; } + void GetProviderInfoHelper(const SessionType& session_type) { + temp_provider_info_ = std::nullopt; + auto aidl_reval = + provider_factory_->getProviderInfo(session_type, &temp_provider_info_); + ASSERT_TRUE(aidl_reval.isOk()); + } + void GetProviderCapabilitiesHelper(const SessionType& session_type) { temp_provider_capabilities_.clear(); auto aidl_retval = provider_factory_->getProviderCapabilities( @@ -576,6 +603,8 @@ class BluetoothAudioProviderFactoryAidl std::shared_ptr audio_provider_; std::shared_ptr audio_port_; std::vector temp_provider_capabilities_; + std::optional + temp_provider_info_; // temp storage saves the specified codec capability by // GetOffloadCodecCapabilityHelper() @@ -2126,6 +2155,8 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl BluetoothAudioProviderFactoryAidl::SetUp(); GetProviderCapabilitiesHelper( SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH); + GetProviderInfoHelper( + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH); OpenProviderHelper( SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH); ASSERT_TRUE(temp_provider_capabilities_.empty() || @@ -2152,6 +2183,99 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl return false; } + bool IsOffloadOutputProviderInfoSupported() { + if (!temp_provider_info_.has_value()) return false; + if (temp_provider_info_.value().codecInfos.empty()) return false; + // Check if all codec info is of LeAudio type + for (auto& codec_info : temp_provider_info_.value().codecInfos) { + if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio) + return false; + } + return true; + } + + std::vector GetUnicastLc3SupportedListFromProviderInfo() { + std::vector le_audio_codec_configs; + for (auto& codec_info : temp_provider_info_.value().codecInfos) { + // Only gets LC3 codec information + if (codec_info.id != CodecId::Core::LC3) continue; + // Combine those parameters into one list of Lc3Configuration + auto& transport = + codec_info.transport.get(); + for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) { + for (int32_t frameDurationUs : transport.frameDurationUs) { + for (int32_t octetsPerFrame : transport.bitdepth) { + Lc3Configuration lc3_config = { + .samplingFrequencyHz = samplingFrequencyHz, + .frameDurationUs = frameDurationUs, + .octetsPerFrame = octetsPerFrame, + }; + le_audio_codec_configs.push_back(lc3_config); + } + } + } + } + + return le_audio_codec_configs; + } + + AudioContext GetAudioContext(int32_t bitmask) { + AudioContext media_audio_context; + media_audio_context.bitmask = bitmask; + return media_audio_context; + } + + LeAudioDeviceCapabilities GetDefaultRemoteCapability() { + // Create a capability + LeAudioDeviceCapabilities capability; + + capability.codecId = CodecId::Core::LC3; + + auto pref_context_metadata = MetadataLtv::PreferredAudioContexts(); + pref_context_metadata.values = GetAudioContext(AudioContext::MEDIA); + capability.metadata = {pref_context_metadata}; + + auto sampling_rate = + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies(); + sampling_rate.bitmask = + CodecSpecificCapabilitiesLtv::SupportedSamplingFrequencies::HZ8000; + auto frame_duration = + CodecSpecificCapabilitiesLtv::SupportedFrameDurations(); + frame_duration.bitmask = + CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US7500; + auto octets = CodecSpecificCapabilitiesLtv::SupportedOctetsPerCodecFrame(); + octets.minimum = 0; + octets.maximum = 60; + auto frames = CodecSpecificCapabilitiesLtv::SupportedMaxCodecFramesPerSDU(); + frames.value = 2; + capability.codecSpecificCapabilities = {sampling_rate, frame_duration, + octets, frames}; + return capability; + } + + LeAudioConfigurationRequirement GetDefaultRequirement( + bool is_source_requriement) { + // Create a requirements + LeAudioConfigurationRequirement requirement; + requirement.audioContext = GetAudioContext(AudioContext::MEDIA); + + auto direction_ase_requriement = AseDirectionRequirement(); + direction_ase_requriement.aseConfiguration.codecId = CodecId::Core::LC3; + direction_ase_requriement.aseConfiguration.targetLatency = + LeAudioAseConfiguration::TargetLatency::BALANCED_LATENCY_RELIABILITY; + + // Mismatch sampling frequency + direction_ase_requriement.aseConfiguration.codecConfiguration = { + CodecSpecificConfigurationLtv::SamplingFrequency::HZ11025, + CodecSpecificConfigurationLtv::FrameDuration::US7500, + }; + if (is_source_requriement) + requirement.sourceAseRequirement = {direction_ase_requriement}; + else + requirement.sinkAseRequirement = {direction_ase_requriement}; + return requirement; + } + std::vector GetUnicastLc3SupportedList(bool decoding, bool supported) { std::vector le_audio_codec_configs; @@ -2269,6 +2393,14 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl } LeAudioCodecCapabilitiesSetting temp_le_audio_capabilities_; + std::vector all_context_bitmasks = { + AudioContext::UNSPECIFIED, AudioContext::CONVERSATIONAL, + AudioContext::MEDIA, AudioContext::GAME, + AudioContext::INSTRUCTIONAL, AudioContext::VOICE_ASSISTANTS, + AudioContext::LIVE_AUDIO, AudioContext::SOUND_EFFECTS, + AudioContext::NOTIFICATIONS, AudioContext::RINGTONE_ALERTS, + AudioContext::ALERTS, AudioContext::EMERGENCY_ALARM, + }; }; /** @@ -2279,6 +2411,101 @@ class BluetoothAudioProviderLeAudioOutputHardwareAidl TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, OpenLeAudioOutputHardwareProvider) {} +/** + * Test whether each provider of type + * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and + * stopped with Unicast hardware encoding config taken from provider info + */ +TEST_P( + BluetoothAudioProviderLeAudioOutputHardwareAidl, + StartAndEndLeAudioOutputSessionWithPossibleUnicastConfigFromProviderInfo) { + if (!IsOffloadOutputProviderInfoSupported()) { + return; + } + + auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo(); + LeAudioConfiguration le_audio_config = { + .codecType = CodecType::LC3, + .peerDelayUs = 0, + }; + + for (auto& lc3_config : lc3_codec_configs) { + le_audio_config.leAudioCodecConfig + .set(lc3_config); + DataMQDesc mq_desc; + auto aidl_retval = audio_provider_->startSession( + audio_port_, AudioConfiguration(le_audio_config), latency_modes, + &mq_desc); + + ASSERT_TRUE(aidl_retval.isOk()); + EXPECT_TRUE(audio_provider_->endSession().isOk()); + } +} + +TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, + GetEmptyAseConfigurationEmptyCapability) { + std::vector> empty_capability; + std::vector empty_requirement; + std::vector configurations; + + // Check empty capability for source direction + auto aidl_retval = audio_provider_->getLeAudioAseConfiguration( + std::nullopt, empty_capability, empty_requirement, &configurations); + + ASSERT_TRUE(aidl_retval.isOk()); + ASSERT_TRUE(configurations.empty()); + + // Check empty capability for sink direction + aidl_retval = audio_provider_->getLeAudioAseConfiguration( + empty_capability, std::nullopt, empty_requirement, &configurations); + + ASSERT_TRUE(aidl_retval.isOk()); + ASSERT_TRUE(configurations.empty()); +} + +TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, + GetEmptyAseConfigurationMismatchedRequirement) { + std::vector> capabilities = { + GetDefaultRemoteCapability()}; + + // Check empty capability for source direction + std::vector configurations; + std::vector source_requirements = { + GetDefaultRequirement(true)}; + auto aidl_retval = audio_provider_->getLeAudioAseConfiguration( + std::nullopt, capabilities, source_requirements, &configurations); + + ASSERT_TRUE(aidl_retval.isOk()); + ASSERT_TRUE(configurations.empty()); + + // Check empty capability for sink direction + std::vector sink_requirements = { + GetDefaultRequirement(false)}; + aidl_retval = audio_provider_->getLeAudioAseConfiguration( + capabilities, std::nullopt, source_requirements, &configurations); + + ASSERT_TRUE(aidl_retval.isOk()); + ASSERT_TRUE(configurations.empty()); +} + +TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl, GetQoSConfiguration) { + IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement requirement; + std::vector + QoSConfigurations; + for (auto bitmask : all_context_bitmasks) { + requirement.contextType = GetAudioContext(bitmask); + IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result; + auto aidl_retval = + audio_provider_->getLeAudioAseQosConfiguration(requirement, &result); + ASSERT_TRUE(aidl_retval.isOk()); + if (result.sinkQosConfiguration.has_value()) + QoSConfigurations.push_back(result.sinkQosConfiguration.value()); + if (result.sourceQosConfiguration.has_value()) + QoSConfigurations.push_back(result.sourceQosConfiguration.value()); + } + // QoS Configurations should not be empty, as we searched for all contexts + ASSERT_FALSE(QoSConfigurations.empty()); +} /** * Test whether each provider of type * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and @@ -2435,6 +2662,8 @@ class BluetoothAudioProviderLeAudioInputHardwareAidl BluetoothAudioProviderFactoryAidl::SetUp(); GetProviderCapabilitiesHelper( SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); + GetProviderInfoHelper( + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); OpenProviderHelper( SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH); ASSERT_TRUE(temp_provider_capabilities_.empty() || @@ -2464,7 +2693,7 @@ class BluetoothAudioProviderLeAudioInputHardwareAidl /** * Test whether each provider of type - * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and + * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and * stopped */ TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, @@ -2472,7 +2701,38 @@ TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, /** * Test whether each provider of type - * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and + * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and + * stopped with Unicast hardware encoding config taken from provider info + */ +TEST_P( + BluetoothAudioProviderLeAudioInputHardwareAidl, + StartAndEndLeAudioInputSessionWithPossibleUnicastConfigFromProviderInfo) { + if (!IsOffloadOutputProviderInfoSupported()) { + return; + } + + auto lc3_codec_configs = GetUnicastLc3SupportedListFromProviderInfo(); + LeAudioConfiguration le_audio_config = { + .codecType = CodecType::LC3, + .peerDelayUs = 0, + }; + + for (auto& lc3_config : lc3_codec_configs) { + le_audio_config.leAudioCodecConfig + .set(lc3_config); + DataMQDesc mq_desc; + auto aidl_retval = audio_provider_->startSession( + audio_port_, AudioConfiguration(le_audio_config), latency_modes, + &mq_desc); + + ASSERT_TRUE(aidl_retval.isOk()); + EXPECT_TRUE(audio_provider_->endSession().isOk()); + } +} + +/** + * Test whether each provider of type + * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and * stopped with Unicast hardware encoding config */ TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, @@ -2503,7 +2763,7 @@ TEST_P(BluetoothAudioProviderLeAudioInputHardwareAidl, /** * Test whether each provider of type - * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and + * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH can be started and * stopped with Unicast hardware encoding config * * Disabled since offload codec checking is not ready @@ -2621,6 +2881,8 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl BluetoothAudioProviderFactoryAidl::SetUp(); GetProviderCapabilitiesHelper( SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH); + GetProviderInfoHelper( + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH); OpenProviderHelper( SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH); ASSERT_TRUE(temp_provider_capabilities_.empty() || @@ -2647,6 +2909,42 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl return false; } + bool IsBroadcastOffloadProviderInfoSupported() { + if (!temp_provider_info_.has_value()) return false; + if (temp_provider_info_.value().codecInfos.empty()) return false; + // Check if all codec info is of LeAudio type + for (auto& codec_info : temp_provider_info_.value().codecInfos) { + if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio) + return false; + } + return true; + } + + std::vector GetBroadcastLc3SupportedListFromProviderInfo() { + std::vector le_audio_codec_configs; + for (auto& codec_info : temp_provider_info_.value().codecInfos) { + // Only gets LC3 codec information + if (codec_info.id != CodecId::Core::LC3) continue; + // Combine those parameters into one list of Lc3Configuration + auto& transport = + codec_info.transport.get(); + for (int32_t samplingFrequencyHz : transport.samplingFrequencyHz) { + for (int32_t frameDurationUs : transport.frameDurationUs) { + for (int32_t octetsPerFrame : transport.bitdepth) { + Lc3Configuration lc3_config = { + .samplingFrequencyHz = samplingFrequencyHz, + .frameDurationUs = frameDurationUs, + .octetsPerFrame = octetsPerFrame, + }; + le_audio_codec_configs.push_back(lc3_config); + } + } + } + } + + return le_audio_codec_configs; + } + std::vector GetBroadcastLc3SupportedList(bool supported) { std::vector le_audio_codec_configs; if (!supported) { @@ -2705,6 +3003,44 @@ class BluetoothAudioProviderLeAudioBroadcastHardwareAidl TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl, OpenLeAudioOutputHardwareProvider) {} +/** + * Test whether each provider of type + * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be + * started and stopped with broadcast hardware encoding config taken from + * provider info + */ +TEST_P( + BluetoothAudioProviderLeAudioBroadcastHardwareAidl, + StartAndEndLeAudioBroadcastSessionWithPossibleUnicastConfigFromProviderInfo) { + if (!IsBroadcastOffloadProviderInfoSupported()) { + return; + } + + auto lc3_codec_configs = GetBroadcastLc3SupportedListFromProviderInfo(); + LeAudioBroadcastConfiguration le_audio_broadcast_config = { + .codecType = CodecType::LC3, + .streamMap = {}, + }; + + for (auto& lc3_config : lc3_codec_configs) { + le_audio_broadcast_config.streamMap.resize(1); + le_audio_broadcast_config.streamMap[0] + .leAudioCodecConfig.set( + lc3_config); + le_audio_broadcast_config.streamMap[0].streamHandle = 0x0; + le_audio_broadcast_config.streamMap[0].pcmStreamId = 0x0; + le_audio_broadcast_config.streamMap[0].audioChannelAllocation = 0x1 << 0; + + DataMQDesc mq_desc; + auto aidl_retval = audio_provider_->startSession( + audio_port_, AudioConfiguration(le_audio_broadcast_config), + latency_modes, &mq_desc); + + ASSERT_TRUE(aidl_retval.isOk()); + EXPECT_TRUE(audio_provider_->endSession().isOk()); + } +} + /** * Test whether each provider of type * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be From 5b2fdab61f607caf50deb113e0c8e472416d087c Mon Sep 17 00:00:00 2001 From: Bao Do Date: Mon, 20 Nov 2023 08:02:55 +0000 Subject: [PATCH 11/11] Default implementation of getLeAudioBroadcastConfiguration for LE Audio Offload provider Bug: 306225778 Test: mmm hardware/interfaces/bluetooth/audio/aidl/default Change-Id: I5bfb4a84a8222603c64ac51a28b5962825182676 --- .../default/BluetoothAudioProviderFactory.cpp | 19 +- .../default/LeAudioOffloadAudioProvider.cpp | 177 +++++++++++++++++- .../default/LeAudioOffloadAudioProvider.h | 25 ++- .../vts/VtsHalBluetoothAudioTargetTest.cpp | 36 +++- ...LeAudioAseConfigurationSettingProvider.cpp | 51 +++-- .../BluetoothLeAudioCodecsProvider.cpp | 2 +- 6 files changed, 257 insertions(+), 53 deletions(-) diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp index 275cfec35f..e55a43438c 100644 --- a/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp +++ b/bluetooth/audio/aidl/default/BluetoothAudioProviderFactory.cpp @@ -154,6 +154,8 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo( SessionType session_type, std::optional* _aidl_return) { *_aidl_return = std::nullopt; + LOG(INFO) << __func__ << " - SessionType=" << toString(session_type); + if (session_type == SessionType::A2DP_HARDWARE_OFFLOAD_ENCODING_DATAPATH || session_type == SessionType::A2DP_HARDWARE_OFFLOAD_DECODING_DATAPATH) { auto& provider_info = _aidl_return->emplace(); @@ -161,13 +163,14 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo( provider_info.name = A2dpOffloadCodecFactory::GetInstance()->name; for (auto codec : A2dpOffloadCodecFactory::GetInstance()->codecs) provider_info.codecInfos.push_back(codec->info); - } else if (session_type == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || - session_type == - SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || - session_type == - SessionType:: - LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { + } + + if (session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH || + session_type == + SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH || + session_type == + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH) { std::vector db_codec_info = BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo(session_type); if (!db_codec_info.empty()) { @@ -175,8 +178,8 @@ ndk::ScopedAStatus BluetoothAudioProviderFactory::getProviderInfo( provider_info.name = kLeAudioOffloadProviderName; provider_info.codecInfos = db_codec_info; *_aidl_return = provider_info; + return ndk::ScopedAStatus::ok(); } - return ndk::ScopedAStatus::ok(); } return ndk::ScopedAStatus::ok(); diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp index 426171d321..cff3b2582c 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp @@ -82,6 +82,19 @@ const std::map CodecSpecificCapabilitiesLtv::SupportedFrameDurations::US10000}, }; +std::map + sampling_freq_map = { + {16000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000}, + {48000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ48000}, + {96000, CodecSpecificConfigurationLtv::SamplingFrequency::HZ96000}, +}; + +std::map + frame_duration_map = { + {7500, CodecSpecificConfigurationLtv::FrameDuration::US7500}, + {10000, CodecSpecificConfigurationLtv::FrameDuration::US10000}, +}; + LeAudioOffloadOutputAudioProvider::LeAudioOffloadOutputAudioProvider() : LeAudioOffloadAudioProvider() { session_type_ = SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH; @@ -307,6 +320,16 @@ bool LeAudioOffloadAudioProvider::isMatchedAseConfiguration( return true; } +bool LeAudioOffloadAudioProvider::isMatchedBISConfiguration( + LeAudioBisConfiguration bis_cfg, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities) { + if (!isMatchedValidCodec(bis_cfg.codecId, capabilities.codecId)) return false; + if (!isCapabilitiesMatchedCodecConfiguration( + bis_cfg.codecConfiguration, capabilities.codecSpecificCapabilities)) + return false; + return true; +} + void LeAudioOffloadAudioProvider::filterCapabilitiesAseDirectionConfiguration( std::vector>& direction_configurations, @@ -597,7 +620,8 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioAseQosConfiguration( }; ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged( - IBluetoothAudioProvider::AseState in_state, + IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/, + int32_t /*in_cisId*/, const std::optional>>& in_metadata) { (void)in_state; (void)in_metadata; @@ -605,13 +629,95 @@ ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSinkAseMetadataChanged( }; ndk::ScopedAStatus LeAudioOffloadAudioProvider::onSourceAseMetadataChanged( - IBluetoothAudioProvider::AseState in_state, + IBluetoothAudioProvider::AseState in_state, int32_t /*in_cigId*/, + int32_t /*in_cisId*/, const std::optional>>& in_metadata) { (void)in_state; (void)in_metadata; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); }; +void LeAudioOffloadAudioProvider::getBroadcastSettings() { + if (!broadcast_settings.empty()) return; + + LOG(INFO) << __func__ << ": Loading broadcast settings from provider info"; + + std::vector db_codec_info = + BluetoothAudioCodecs::GetLeAudioOffloadCodecInfo( + SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH); + broadcast_settings.clear(); + CodecSpecificConfigurationLtv::AudioChannelAllocation default_allocation; + default_allocation.bitmask = + CodecSpecificConfigurationLtv::AudioChannelAllocation::FRONT_CENTER; + + for (auto& codec_info : db_codec_info) { + if (codec_info.transport.getTag() != CodecInfo::Transport::leAudio) + continue; + auto& transport = codec_info.transport.get(); + LeAudioBroadcastConfigurationSetting setting; + // Default setting + setting.numBis = 1; + setting.phy = {Phy::TWO_M}; + // Populate BIS configuration info using codec_info + LeAudioBisConfiguration bis_cfg; + bis_cfg.codecId = codec_info.id; + + CodecSpecificConfigurationLtv::OctetsPerCodecFrame octets; + octets.value = transport.bitdepth[0]; + + bis_cfg.codecConfiguration = { + sampling_freq_map[transport.samplingFrequencyHz[0]], octets, + frame_duration_map[transport.frameDurationUs[0]], default_allocation}; + + // Add information to structure + IBluetoothAudioProvider::LeAudioSubgroupBisConfiguration sub_bis_cfg; + sub_bis_cfg.numBis = 1; + sub_bis_cfg.bisConfiguration = bis_cfg; + IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration sub_cfg; + sub_cfg.bisConfigurations = {sub_bis_cfg}; + setting.subgroupsConfigurations = {sub_cfg}; + + broadcast_settings.push_back(setting); + } + + LOG(INFO) << __func__ + << ": Done loading broadcast settings from provider info"; +} + +/* Get a new LeAudioAseConfigurationSetting by matching a setting with a + * capabilities. The new setting will have a filtered list of + * AseDirectionConfiguration that matched the capabilities */ +std::optional +LeAudioOffloadAudioProvider:: + getCapabilitiesMatchedBroadcastConfigurationSettings( + LeAudioBroadcastConfigurationSetting& setting, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& + capabilities) { + std::vector + filter_subgroup; + for (auto& sub_cfg : setting.subgroupsConfigurations) { + std::vector + filtered_bis_cfg; + for (auto& bis_cfg : sub_cfg.bisConfigurations) + if (isMatchedBISConfiguration(bis_cfg.bisConfiguration, capabilities)) { + filtered_bis_cfg.push_back(bis_cfg); + } + if (!filtered_bis_cfg.empty()) { + IBluetoothAudioProvider::LeAudioBroadcastSubgroupConfiguration + subgroup_cfg; + subgroup_cfg.bisConfigurations = filtered_bis_cfg; + filter_subgroup.push_back(subgroup_cfg); + } + } + if (filter_subgroup.empty()) return std::nullopt; + + // Create a new LeAudioAseConfigurationSetting and return + LeAudioBroadcastConfigurationSetting filtered_setting(setting); + filtered_setting.subgroupsConfigurations = filter_subgroup; + + return filtered_setting; +} + ndk::ScopedAStatus LeAudioOffloadAudioProvider::getLeAudioBroadcastConfiguration( const std::optional filtered_settings; + if (!in_remoteSinkAudioCapabilities.has_value()) { + LOG(WARNING) << __func__ << ": Empty capability"; + return ndk::ScopedAStatus::ok(); + } + for (auto& setting : broadcast_settings) { + for (auto& capability : in_remoteSinkAudioCapabilities.value()) { + if (!capability.has_value()) continue; + auto filtered_setting = + getCapabilitiesMatchedBroadcastConfigurationSettings( + setting, capability.value()); + if (filtered_setting.has_value()) + filtered_settings.push_back(filtered_setting.value()); + } + } + + if (filtered_settings.empty()) { + LOG(WARNING) << __func__ << ": Cannot match any remote capability"; + return ndk::ScopedAStatus::ok(); + } + + // Match and return the first matched requirement + if (in_requirement.subgroupConfigurationRequirements.empty()) { + LOG(INFO) << __func__ << ": Empty requirement"; + *_aidl_return = filtered_settings[0]; + return ndk::ScopedAStatus::ok(); + } + + for (auto& setting : filtered_settings) { + // Further filter out bis configuration + LeAudioBroadcastConfigurationSetting filtered_setting(setting); + filtered_setting.subgroupsConfigurations.clear(); + for (auto& sub_cfg : setting.subgroupsConfigurations) { + bool isMatched = false; + for (auto& sub_req : in_requirement.subgroupConfigurationRequirements) { + // Matching number of BIS + if (sub_req.bisNumPerSubgroup != sub_cfg.bisConfigurations.size()) + continue; + // Currently will ignore quality and context hint. + isMatched = true; + break; + } + if (isMatched) + filtered_setting.subgroupsConfigurations.push_back(sub_cfg); + } + // Return the first match + if (!filtered_setting.subgroupsConfigurations.empty()) { + LOG(INFO) << __func__ << ": Matched requirement"; + *_aidl_return = filtered_setting; + return ndk::ScopedAStatus::ok(); + } + } + + LOG(WARNING) << __func__ << ": Cannot match any requirement"; + return ndk::ScopedAStatus::ok(); }; } // namespace audio diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h index b6037c3c88..2785e7fe1d 100644 --- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h +++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h @@ -21,6 +21,7 @@ #include "BluetoothAudioProvider.h" #include "aidl/android/hardware/bluetooth/audio/LeAudioAseConfiguration.h" #include "aidl/android/hardware/bluetooth/audio/MetadataLtv.h" +#include "aidl/android/hardware/bluetooth/audio/SessionType.h" namespace aidl { namespace android { @@ -38,6 +39,8 @@ using AseQosDirectionRequirement = IBluetoothAudioProvider:: LeAudioAseQosConfigurationRequirement::AseQosDirectionRequirement; using LeAudioAseQosConfiguration = IBluetoothAudioProvider::LeAudioAseQosConfiguration; +using LeAudioBroadcastConfigurationSetting = + IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting; class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { public: @@ -68,12 +71,14 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { in_qosRequirement, IBluetoothAudioProvider::LeAudioAseQosConfigurationPair* _aidl_return) override; - ndk::ScopedAStatus onSinkAseMetadataChanged( - IBluetoothAudioProvider::AseState in_state, + ndk::ScopedAStatus onSourceAseMetadataChanged( + IBluetoothAudioProvider::AseState in_state, int32_t in_cigId, + int32_t in_cisId, const std::optional>>& in_metadata) override; - ndk::ScopedAStatus onSourceAseMetadataChanged( - IBluetoothAudioProvider::AseState in_state, + ndk::ScopedAStatus onSinkAseMetadataChanged( + IBluetoothAudioProvider::AseState in_state, int32_t in_cigId, + int32_t in_cisId, const std::optional>>& in_metadata) override; ndk::ScopedAStatus getLeAudioBroadcastConfiguration( @@ -82,12 +87,12 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { in_remoteSinkAudioCapabilities, const IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement& in_requirement, - IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* - _aidl_return) override; + LeAudioBroadcastConfigurationSetting* _aidl_return) override; private: ndk::ScopedAStatus onSessionReady(DataMQDesc* _aidl_return) override; std::map codec_priority_map_; + std::vector broadcast_settings; // Private matching function definitions bool isMatchedValidCodec(CodecId cfg_codec, CodecId req_codec); @@ -119,6 +124,9 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { std::vector codec_capabilities); bool isMatchedAseConfiguration(LeAudioAseConfiguration setting_cfg, LeAudioAseConfiguration requirement_cfg); + bool isMatchedBISConfiguration( + LeAudioBisConfiguration bis_cfg, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities); void filterCapabilitiesAseDirectionConfiguration( std::vector>& direction_configurations, @@ -144,6 +152,11 @@ class LeAudioOffloadAudioProvider : public BluetoothAudioProvider { requirement); bool isMatchedQosRequirement(LeAudioAseQosConfiguration setting_qos, AseQosDirectionRequirement requirement_qos); + std::optional + getCapabilitiesMatchedBroadcastConfigurationSettings( + LeAudioBroadcastConfigurationSetting& setting, + const IBluetoothAudioProvider::LeAudioDeviceCapabilities& capabilities); + void getBroadcastSettings(); }; class LeAudioOffloadOutputAudioProvider : public LeAudioOffloadAudioProvider { diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp index c18d48e943..88f2f97e28 100644 --- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp +++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp @@ -1515,7 +1515,7 @@ class BluetoothAudioProviderHfpSoftwareEncodingAidl } bool OpenSession(int32_t sample_rate, int8_t bits_per_sample, - ChannelMode channel_mode, int32_t data_interval_us) { + ChannelMode channel_mode, int32_t data_interval_us) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, .channelMode = channel_mode, @@ -1552,9 +1552,9 @@ TEST_P(BluetoothAudioProviderHfpSoftwareEncodingAidl, for (auto sample_rate : hfp_sample_rates_) { for (auto bits_per_sample : hfp_bits_per_samples_) { for (auto channel_mode : hfp_channel_modes_) { - for (auto data_interval_us: hfp_data_interval_us_) { - EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, - channel_mode, data_interval_us)); + for (auto data_interval_us : hfp_data_interval_us_) { + EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode, + data_interval_us)); EXPECT_TRUE(audio_provider_->endSession().isOk()); } } @@ -1582,7 +1582,7 @@ class BluetoothAudioProviderHfpSoftwareDecodingAidl } bool OpenSession(int32_t sample_rate, int8_t bits_per_sample, - ChannelMode channel_mode, int32_t data_interval_us) { + ChannelMode channel_mode, int32_t data_interval_us) { PcmConfiguration pcm_config{ .sampleRateHz = sample_rate, .channelMode = channel_mode, @@ -1616,10 +1616,10 @@ TEST_P(BluetoothAudioProviderHfpSoftwareDecodingAidl, for (auto sample_rate : hfp_sample_rates_) { for (auto bits_per_sample : hfp_bits_per_samples_) { for (auto channel_mode : hfp_channel_modes_) { - for (auto data_interval_us: hfp_data_interval_us_) { - EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, - channel_mode, data_interval_us)); - EXPECT_TRUE(audio_provider_->endSession().isOk()); + for (auto data_interval_us : hfp_data_interval_us_) { + EXPECT_TRUE(OpenSession(sample_rate, bits_per_sample, channel_mode, + data_interval_us)); + EXPECT_TRUE(audio_provider_->endSession().isOk()); } } } @@ -1899,7 +1899,7 @@ class BluetoothAudioProviderHfpHardwareAidl } bool OpenSession(CodecId codec_id, int connection_handle, bool nrec, - bool controller_codec) { + bool controller_codec) { // Check if can open session with a Hfp configuration HfpConfiguration hfp_configuration{ .codecId = codec_id, @@ -3041,6 +3041,22 @@ TEST_P( } } +TEST_P(BluetoothAudioProviderLeAudioBroadcastHardwareAidl, + GetEmptyBroadcastConfigurationEmptyCapability) { + std::vector> empty_capability; + IBluetoothAudioProvider::LeAudioBroadcastConfigurationRequirement + empty_requirement; + + IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting* configuration = + new IBluetoothAudioProvider::LeAudioBroadcastConfigurationSetting(); + + // Check empty capability for source direction + auto aidl_retval = audio_provider_->getLeAudioBroadcastConfiguration( + empty_capability, empty_requirement, configuration); + + ASSERT_TRUE(aidl_retval.isOk()); +} + /** * Test whether each provider of type * SessionType::LE_AUDIO_BROADCAST_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp index 56a4e17811..5429a8fca7 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp @@ -32,7 +32,7 @@ (p) += 4; \ } -#define LOG_TAG "BTAudioCodecsAidl" +#define LOG_TAG "BTAudioAseConfigAidl" #include "BluetoothLeAudioAseConfigurationSettingProvider.h" @@ -58,9 +58,9 @@ namespace audio { /* Internal structure definition */ std::map>*, - std::vector>*, - ConfigurationFlags*>> + std::tuple>, + std::vector>, + ConfigurationFlags>> configurations_; std::vector ase_configuration_settings_; @@ -251,7 +251,7 @@ static const std::vector< kLeAudioSetScenarios = {{"/vendor/etc/aidl/le_audio/" "aidl_audio_set_scenarios.bfbs", "/vendor/etc/aidl/le_audio/" - "aidl_audio_set_configurations.json"}}; + "aidl_audio_set_scenarios.json"}}; /* Implementation */ @@ -263,7 +263,9 @@ AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() { void AudioSetConfigurationProviderJson:: LoadAudioSetConfigurationProviderJson() { - if (configurations_.empty() && ase_configuration_settings_.empty()) { + if (configurations_.empty() || ase_configuration_settings_.empty()) { + ase_configuration_settings_.clear(); + configurations_.clear(); auto loaded = LoadContent(kLeAudioSetConfigs, kLeAudioSetScenarios, CodecLocation::HOST); if (!loaded) @@ -565,7 +567,7 @@ bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles( std::string configurations_schema_binary_content; bool ok = flatbuffers::LoadFile(schema_file, true, &configurations_schema_binary_content); - LOG(INFO) << __func__ << "Loading file " << schema_file; + LOG(INFO) << __func__ << ": Loading file " << schema_file; if (!ok) return ok; /* Load the binary schema */ @@ -576,17 +578,17 @@ bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles( /* Load the content from JSON */ std::string configurations_json_content; - LOG(INFO) << __func__ << "Loading file " << schema_file; + LOG(INFO) << __func__ << ": Loading file " << content_file; ok = flatbuffers::LoadFile(content_file, false, &configurations_json_content); if (!ok) return ok; /* Parse */ - LOG(INFO) << __func__ << "Parse JSON content" << schema_file; + LOG(INFO) << __func__ << ": Parse JSON content"; ok = configurations_parser_.Parse(configurations_json_content.c_str()); if (!ok) return ok; /* Import from flatbuffers */ - LOG(INFO) << __func__ << "Build flat buffer structure" << schema_file; + LOG(INFO) << __func__ << ": Build flat buffer structure"; auto configurations_root = le_audio::GetAudioSetConfigurations( configurations_parser_.builder_.GetBufferPointer()); if (!configurations_root) return false; @@ -629,7 +631,7 @@ bool AudioSetConfigurationProviderJson::LoadConfigurationsFromFiles( if (sourceAseConfiguration.empty() && sinkAseConfiguration.empty()) continue; configurations_[flat_cfg->name()->str()] = std::make_tuple( - &sourceAseConfiguration, &sinkAseConfiguration, &configurationFlags); + sourceAseConfiguration, sinkAseConfiguration, configurationFlags); } return true; @@ -641,6 +643,7 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles( std::string scenarios_schema_binary_content; bool ok = flatbuffers::LoadFile(schema_file, true, &scenarios_schema_binary_content); + LOG(INFO) << __func__ << ": Loading file " << schema_file; if (!ok) return ok; /* Load the binary schema */ @@ -650,15 +653,18 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles( if (!ok) return ok; /* Load the content from JSON */ + LOG(INFO) << __func__ << ": Loading file " << content_file; std::string scenarios_json_content; ok = flatbuffers::LoadFile(content_file, false, &scenarios_json_content); if (!ok) return ok; /* Parse */ + LOG(INFO) << __func__ << ": Parse json content"; ok = scenarios_parser_.Parse(scenarios_json_content.c_str()); if (!ok) return ok; /* Import from flatbuffers */ + LOG(INFO) << __func__ << ": Build flat buffer structure"; auto scenarios_root = le_audio::GetAudioSetScenarios( scenarios_parser_.builder_.GetBufferPointer()); if (!scenarios_root) return false; @@ -667,6 +673,7 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles( if ((flat_scenarios == nullptr) || (flat_scenarios->size() == 0)) return false; + LOG(INFO) << __func__ << ": Turn flat buffer into structure"; AudioContext media_context = AudioContext(); media_context.bitmask = (AudioContext::ALERTS | AudioContext::INSTRUCTIONAL | @@ -686,9 +693,10 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles( AudioContext voice_assistants_context = AudioContext(); voice_assistants_context.bitmask = AudioContext::VOICE_ASSISTANTS; - LOG(DEBUG) << ": Updating " << flat_scenarios->size() << " scenarios."; + LOG(DEBUG) << "Updating " << flat_scenarios->size() << " scenarios."; for (auto const& scenario : *flat_scenarios) { - LOG(DEBUG) << "Scenario " << scenario->name()->c_str() << " configs:"; + LOG(DEBUG) << "Scenario " << scenario->name()->c_str() + << " configs: " << scenario->configurations()->size(); if (!scenario->configurations()) continue; std::string scenario_name = scenario->name()->c_str(); @@ -704,19 +712,24 @@ bool AudioSetConfigurationProviderJson::LoadScenariosFromFiles( else if (scenario_name == "VoiceAssistants") context = AudioContext(voice_assistants_context); - for (auto config_name : *scenario->configurations()) { - if (configurations_.count(config_name->str()) == 0) continue; - auto [source, sink, flags] = configurations_.at(config_name->str()); + for (auto it = scenario->configurations()->begin(); + it != scenario->configurations()->end(); ++it) { + auto config_name = it->str(); + auto configuration = configurations_.find(config_name); + if (configuration == configurations_.end()) continue; + LOG(DEBUG) << "Getting configuration with name: " << config_name; + auto [source, sink, flags] = configuration->second; // Each configuration will create a LeAudioAseConfigurationSetting // with the same {context, packing} // and different data LeAudioAseConfigurationSetting setting; setting.audioContext = context; // TODO: Packing - setting.sourceAseConfiguration = *source; - setting.sinkAseConfiguration = *sink; - setting.flags = *flags; + setting.sourceAseConfiguration = source; + setting.sinkAseConfiguration = sink; + setting.flags = flags; // Add to list of setting + LOG(DEBUG) << "Pushing configuration to list: " << config_name; ase_configuration_settings_.push_back(setting); } } diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp index 8c7a740cc2..b6df67e133 100644 --- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp +++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp @@ -107,7 +107,7 @@ BluetoothLeAudioCodecsProvider::GetLeAudioCodecInfo( break; default: codec_info.name = "UNDEFINE"; - codec_info.id = CodecId::make(); + codec_info.id = CodecId::Vendor(); break; } codec_info.transport =