1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.bluetooth;
18 
19 import static android.bluetooth.BluetoothLeAudioCodecConfig.FRAME_DURATION_10000;
20 import static android.bluetooth.BluetoothLeAudioCodecConfig.FRAME_DURATION_7500;
21 import static android.bluetooth.BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE;
22 import static android.bluetooth.BluetoothLeAudioCodecConfig.FrameDuration;
23 import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_16000;
24 import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_24000;
25 import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_32000;
26 import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_44100;
27 import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000;
28 import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_8000;
29 import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE;
30 import static android.bluetooth.BluetoothLeAudioCodecConfig.SampleRate;
31 
32 import android.annotation.NonNull;
33 import android.annotation.Nullable;
34 import android.annotation.SystemApi;
35 import android.bluetooth.BluetoothLeAudioCodecConfig.FrameDuration;
36 import android.bluetooth.BluetoothLeAudioCodecConfig.SampleRate;
37 import android.bluetooth.BluetoothUtils.TypeValueEntry;
38 import android.os.Parcel;
39 import android.os.Parcelable;
40 
41 import com.android.bluetooth.flags.Flags;
42 
43 import java.nio.ByteBuffer;
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.List;
47 import java.util.Objects;
48 
49 /**
50  * A class representing the codec specific config metadata information defined in the Basic Audio
51  * Profile.
52  *
53  * @hide
54  */
55 @SystemApi
56 public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
57     private static final int SAMPLING_FREQUENCY_TYPE = 0x01;
58     private static final int FRAME_DURATION_TYPE = 0x02;
59     private static final int AUDIO_CHANNEL_LOCATION_TYPE = 0x03;
60     private static final int OCTETS_PER_FRAME_TYPE = 0x04;
61 
62     private final long mAudioLocation;
63     private final @SampleRate int mSampleRate;
64     private final @FrameDuration int mFrameDuration;
65     private final int mOctetsPerFrame;
66     private final byte[] mRawMetadata;
67 
68     /** Audio codec sampling frequency from metadata. */
69     private static final int CONFIG_SAMPLING_FREQUENCY_UNKNOWN = 0;
70 
71     private static final int CONFIG_SAMPLING_FREQUENCY_8000 = 0x01;
72     private static final int CONFIG_SAMPLING_FREQUENCY_16000 = 0x03;
73     private static final int CONFIG_SAMPLING_FREQUENCY_24000 = 0x05;
74     private static final int CONFIG_SAMPLING_FREQUENCY_32000 = 0x06;
75     private static final int CONFIG_SAMPLING_FREQUENCY_44100 = 0x07;
76     private static final int CONFIG_SAMPLING_FREQUENCY_48000 = 0x08;
77     private static final int CONFIG_SAMPLING_FREQUENCY_11025 = 0x09;
78     private static final int CONFIG_SAMPLING_FREQUENCY_22050 = 0x0a;
79     private static final int CONFIG_SAMPLING_FREQUENCY_88200 = 0x0b;
80     private static final int CONFIG_SAMPLING_FREQUENCY_96000 = 0x0c;
81     private static final int CONFIG_SAMPLING_FREQUENCY_176400 = 0x0d;
82     private static final int CONFIG_SAMPLING_FREQUENCY_192000 = 0x0e;
83     private static final int CONFIG_SAMPLING_FREQUENCY_384000 = 0x0f;
84 
85     /** Audio codec config frame duration from metadata. */
86     private static final int CONFIG_FRAME_DURATION_UNKNOWN = -1;
87 
88     private static final int CONFIG_FRAME_DURATION_7500 = 0x00;
89     private static final int CONFIG_FRAME_DURATION_10000 = 0x01;
90 
BluetoothLeAudioCodecConfigMetadata( long audioLocation, @SampleRate int sampleRate, @FrameDuration int frameDuration, int octetsPerFrame, byte[] rawMetadata)91     private BluetoothLeAudioCodecConfigMetadata(
92             long audioLocation,
93             @SampleRate int sampleRate,
94             @FrameDuration int frameDuration,
95             int octetsPerFrame,
96             byte[] rawMetadata) {
97         mAudioLocation = audioLocation;
98         mSampleRate = sampleRate;
99         mFrameDuration = frameDuration;
100         mOctetsPerFrame = octetsPerFrame;
101         mRawMetadata = rawMetadata;
102     }
103 
104     @Override
equals(@ullable Object o)105     public boolean equals(@Nullable Object o) {
106         if (o != null && o instanceof BluetoothLeAudioCodecConfigMetadata) {
107             final BluetoothLeAudioCodecConfigMetadata oth = (BluetoothLeAudioCodecConfigMetadata) o;
108             return mAudioLocation == oth.getAudioLocation()
109                     && mSampleRate == oth.getSampleRate()
110                     && mFrameDuration == oth.getFrameDuration()
111                     && mOctetsPerFrame == oth.getOctetsPerFrame()
112                     && Arrays.equals(mRawMetadata, oth.getRawMetadata());
113         }
114         return false;
115     }
116 
117     @Override
hashCode()118     public int hashCode() {
119         return Objects.hash(
120                 mAudioLocation,
121                 mSampleRate,
122                 mFrameDuration,
123                 mOctetsPerFrame,
124                 Arrays.hashCode(mRawMetadata));
125     }
126 
127     @Override
toString()128     public String toString() {
129         return "BluetoothLeAudioCodecConfigMetadata{"
130                 + ("audioLocation=" + mAudioLocation)
131                 + (", sampleRate=" + mSampleRate)
132                 + (", frameDuration=" + mFrameDuration)
133                 + (", octetsPerFrame=" + mOctetsPerFrame)
134                 + (", rawMetadata=" + Arrays.toString(mRawMetadata))
135                 + '}';
136     }
137 
138     /**
139      * Get the audio location information as defined in the Generic Audio section of Bluetooth
140      * Assigned numbers.
141      *
142      * @return configured audio location, -1 if this metadata does not exist
143      * @hide
144      */
145     @SystemApi
getAudioLocation()146     public long getAudioLocation() {
147         return mAudioLocation;
148     }
149 
150     /**
151      * Get the audio sample rate information as defined in the Generic Audio section of Bluetooth
152      * Assigned numbers 6.12.4.1 Supported_Sampling_Frequencies.
153      *
154      * <p>Internally this is converted from Sampling_Frequency values as defined in 6.12.5.1
155      *
156      * @return configured sample rate from meta data, {@link
157      *     BluetoothLeAudioCodecConfig#SAMPLE_RATE_NONE} if this metadata does not exist
158      * @hide
159      */
160     @SystemApi
getSampleRate()161     public @SampleRate int getSampleRate() {
162         return mSampleRate;
163     }
164 
165     /**
166      * Get the audio frame duration information as defined in the Generic Audio section of Bluetooth
167      * Assigned numbers 6.12.5.2 Frame_Duration.
168      *
169      * <p>Internally this is converted from Frame_Durations values as defined in 6.12.4.2
170      *
171      * @return configured frame duration from meta data, {@link
172      *     BluetoothLeAudioCodecConfig#FRAME_DURATION_NONE} if this metadata does not exist
173      * @hide
174      */
175     @SystemApi
getFrameDuration()176     public @FrameDuration int getFrameDuration() {
177         return mFrameDuration;
178     }
179 
180     /**
181      * Get the audio octets per frame information as defined in the Generic Audio section of
182      * Bluetooth Assigned numbers.
183      *
184      * @return configured octets per frame from meta data 0 if this metadata does not exist
185      * @hide
186      */
187     @SystemApi
getOctetsPerFrame()188     public int getOctetsPerFrame() {
189         return mOctetsPerFrame;
190     }
191 
192     /**
193      * Get the raw bytes of stream metadata in Bluetooth LTV format.
194      *
195      * <p>Bluetooth LTV format for stream metadata is defined in the Generic Audio section of <a
196      * href="https://www.bluetooth.com/specifications/assigned-numbers/">Bluetooth Assigned
197      * Numbers</a>, including metadata that was not covered by the getter methods in this class.
198      *
199      * @return raw bytes of stream metadata in Bluetooth LTV format
200      * @hide
201      */
202     @SystemApi
getRawMetadata()203     public @NonNull byte[] getRawMetadata() {
204         return mRawMetadata;
205     }
206 
207     /**
208      * {@inheritDoc}
209      *
210      * @hide
211      */
212     @Override
describeContents()213     public int describeContents() {
214         return 0;
215     }
216 
217     /**
218      * {@inheritDoc}
219      *
220      * @hide
221      */
222     @Override
writeToParcel(Parcel out, int flags)223     public void writeToParcel(Parcel out, int flags) {
224         out.writeLong(mAudioLocation);
225         if (mRawMetadata != null) {
226             out.writeInt(mRawMetadata.length);
227             out.writeByteArray(mRawMetadata);
228         } else {
229             out.writeInt(-1);
230         }
231         out.writeInt(mSampleRate);
232         out.writeInt(mFrameDuration);
233         out.writeInt(mOctetsPerFrame);
234     }
235 
236     /**
237      * A {@link Parcelable.Creator} to create {@link BluetoothLeAudioCodecConfigMetadata} from
238      * parcel.
239      *
240      * @hide
241      */
242     @SystemApi @NonNull
243     public static final Creator<BluetoothLeAudioCodecConfigMetadata> CREATOR =
244             new Creator<>() {
245                 public @NonNull BluetoothLeAudioCodecConfigMetadata createFromParcel(
246                         @NonNull Parcel in) {
247                     long audioLocation = in.readLong();
248                     int rawMetadataLen = in.readInt();
249                     byte[] rawMetadata;
250                     if (rawMetadataLen != -1) {
251                         rawMetadata = new byte[rawMetadataLen];
252                         in.readByteArray(rawMetadata);
253                     } else {
254                         rawMetadata = new byte[0];
255                     }
256                     int sampleRate = in.readInt();
257                     int frameDuration = in.readInt();
258                     int octetsPerFrame = in.readInt();
259                     return new BluetoothLeAudioCodecConfigMetadata(
260                             audioLocation, sampleRate, frameDuration, octetsPerFrame, rawMetadata);
261                 }
262 
263                 public @NonNull BluetoothLeAudioCodecConfigMetadata[] newArray(int size) {
264                     return new BluetoothLeAudioCodecConfigMetadata[size];
265                 }
266             };
267 
268     /**
269      * Construct a {@link BluetoothLeAudioCodecConfigMetadata} from raw bytes.
270      *
271      * <p>The byte array will be parsed and values for each getter will be populated
272      *
273      * <p>Raw metadata cannot be set using builder in order to maintain raw bytes and getter value
274      * consistency
275      *
276      * @param rawBytes raw bytes of stream metadata in Bluetooth LTV format
277      * @return parsed {@link BluetoothLeAudioCodecConfigMetadata} object
278      * @throws IllegalArgumentException if <var>rawBytes</var> is null or when the raw bytes cannot
279      *     be parsed to build the object
280      * @hide
281      */
282     @SystemApi
283     @NonNull
fromRawBytes(@onNull byte[] rawBytes)284     public static BluetoothLeAudioCodecConfigMetadata fromRawBytes(@NonNull byte[] rawBytes) {
285         if (rawBytes == null) {
286             throw new IllegalArgumentException("Raw bytes cannot be null");
287         }
288         List<TypeValueEntry> entries = BluetoothUtils.parseLengthTypeValueBytes(rawBytes);
289         if (rawBytes.length > 0 && rawBytes[0] > 0 && entries.isEmpty()) {
290             throw new IllegalArgumentException(
291                     "No LTV entries are found from rawBytes of size " + rawBytes.length);
292         }
293         long audioLocation = 0;
294         int samplingFrequency = CONFIG_SAMPLING_FREQUENCY_UNKNOWN;
295         int frameDuration = CONFIG_FRAME_DURATION_UNKNOWN;
296         int octetsPerFrame = 0;
297         for (TypeValueEntry entry : entries) {
298             if (entry.getType() == AUDIO_CHANNEL_LOCATION_TYPE) {
299                 byte[] bytes = entry.getValue();
300                 // Get unsigned uint32_t to long
301                 audioLocation =
302                         ((bytes[0] & 0xFF) << 0)
303                                 | ((bytes[1] & 0xFF) << 8)
304                                 | ((bytes[2] & 0xFF) << 16)
305                                 | ((long) (bytes[3] & 0xFF) << 24);
306             } else if (entry.getType() == SAMPLING_FREQUENCY_TYPE) {
307                 byte[] bytes = entry.getValue();
308                 // Get one byte for sampling frequency in value
309                 samplingFrequency = (int) (bytes[0] & 0xFF);
310             } else if (entry.getType() == FRAME_DURATION_TYPE) {
311                 byte[] bytes = entry.getValue();
312                 // Get one byte for frame duration in value
313                 frameDuration = (int) (bytes[0] & 0xFF);
314             } else if (entry.getType() == OCTETS_PER_FRAME_TYPE) {
315                 byte[] bytes = entry.getValue();
316                 // Get two bytes for octets per frame to int
317                 octetsPerFrame = ((bytes[0] & 0xFF) << 0) | ((int) (bytes[1] & 0xFF) << 8);
318             }
319         }
320         return new BluetoothLeAudioCodecConfigMetadata(
321                 audioLocation,
322                 convertToSampleRateBitset(samplingFrequency),
323                 convertToFrameDurationBitset(frameDuration),
324                 octetsPerFrame,
325                 rawBytes);
326     }
327 
328     /**
329      * Builder for {@link BluetoothLeAudioCodecConfigMetadata}.
330      *
331      * @hide
332      */
333     @SystemApi
334     public static final class Builder {
335         private long mAudioLocation = 0;
336         private int mSampleRate = SAMPLE_RATE_NONE;
337         private int mFrameDuration = FRAME_DURATION_NONE;
338         private int mOctetsPerFrame = 0;
339         private byte[] mRawMetadata = null;
340 
341         /**
342          * Create an empty builder.
343          *
344          * @hide
345          */
346         @SystemApi
Builder()347         public Builder() {}
348 
349         /**
350          * Create a builder with copies of information from original object.
351          *
352          * @param original original object
353          * @hide
354          */
355         @SystemApi
Builder(@onNull BluetoothLeAudioCodecConfigMetadata original)356         public Builder(@NonNull BluetoothLeAudioCodecConfigMetadata original) {
357             mAudioLocation = original.getAudioLocation();
358             mSampleRate = original.getSampleRate();
359             mFrameDuration = original.getFrameDuration();
360             mOctetsPerFrame = original.getOctetsPerFrame();
361             mRawMetadata = original.getRawMetadata();
362         }
363 
364         /**
365          * Set the audio location information as defined in the Generic Audio section of Bluetooth
366          * Assigned numbers.
367          *
368          * @param audioLocation configured audio location, -1 if does not exist
369          * @return this builder
370          * @hide
371          */
372         @SystemApi
373         @NonNull
setAudioLocation(long audioLocation)374         public Builder setAudioLocation(long audioLocation) {
375             mAudioLocation = audioLocation;
376             return this;
377         }
378 
379         /**
380          * Set the audio sample rate information as defined in the Generic Audio section of
381          * Bluetooth Assigned 6.12.4.1 Supported_Sampling_Frequencies.
382          *
383          * <p>Internally this will be converted to Sampling_Frequency values as defined in 6.12.5.1
384          *
385          * @param sampleRate configured sample rate in meta data
386          * @return this builder
387          * @throws IllegalArgumentException if sample rate is invalid value
388          * @hide
389          */
390         @SystemApi
391         @NonNull
setSampleRate(@ampleRate int sampleRate)392         public Builder setSampleRate(@SampleRate int sampleRate) {
393             if (sampleRate != SAMPLE_RATE_NONE
394                     && sampleRate != SAMPLE_RATE_8000
395                     && sampleRate != SAMPLE_RATE_16000
396                     && sampleRate != SAMPLE_RATE_24000
397                     && sampleRate != SAMPLE_RATE_32000
398                     && sampleRate != SAMPLE_RATE_44100
399                     && sampleRate != SAMPLE_RATE_48000) {
400 
401                 if (Flags.leaudioAddSamplingFrequencies()) {
402                     if (sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_11025
403                             && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_22050
404                             && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_88200
405                             && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_96000
406                             && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_176400
407                             && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_192000
408                             && sampleRate != BluetoothLeAudioCodecConfig.SAMPLE_RATE_384000) {
409                         throw new IllegalArgumentException("Invalid sample rate " + sampleRate);
410                     }
411                 } else {
412                     throw new IllegalArgumentException("Invalid sample rate " + sampleRate);
413                 }
414             }
415             mSampleRate = sampleRate;
416             return this;
417         }
418 
419         /**
420          * Set the audio frame duration information as defined in the Generic Audio section of
421          * Bluetooth Assigned numbers 6.12.5.2 Frame_Duration.
422          *
423          * <p>Internally this will be converted to Frame_Durations values as defined in 6.12.4.2
424          *
425          * @param frameDuration configured frame duration in meta data
426          * @return this builder
427          * @throws IllegalArgumentException if frameDuration is invalid value
428          * @hide
429          */
430         @SystemApi
431         @NonNull
setFrameDuration(@rameDuration int frameDuration)432         public Builder setFrameDuration(@FrameDuration int frameDuration) {
433             if (frameDuration != FRAME_DURATION_NONE
434                     && frameDuration != FRAME_DURATION_7500
435                     && frameDuration != FRAME_DURATION_10000) {
436                 throw new IllegalArgumentException("Invalid frame duration " + frameDuration);
437             }
438             mFrameDuration = frameDuration;
439             return this;
440         }
441 
442         /**
443          * Set the audio octets per frame information as defined in the Generic Audio section of
444          * Bluetooth Assigned numbers.
445          *
446          * @param octetsPerFrame configured octets per frame in meta data
447          * @return this builder
448          * @throws IllegalArgumentException if octetsPerFrame is invalid value
449          * @hide
450          */
451         @SystemApi
452         @NonNull
setOctetsPerFrame(int octetsPerFrame)453         public Builder setOctetsPerFrame(int octetsPerFrame) {
454             if (octetsPerFrame < 0) {
455                 throw new IllegalArgumentException("Invalid octetsPerFrame " + octetsPerFrame);
456             }
457             mOctetsPerFrame = octetsPerFrame;
458             return this;
459         }
460 
461         /**
462          * Build {@link BluetoothLeAudioCodecConfigMetadata}.
463          *
464          * @return constructed {@link BluetoothLeAudioCodecConfigMetadata}
465          * @throws IllegalArgumentException if the object cannot be built
466          * @hide
467          */
468         @SystemApi
build()469         public @NonNull BluetoothLeAudioCodecConfigMetadata build() {
470             List<TypeValueEntry> entries = new ArrayList<>();
471             if (mRawMetadata != null) {
472                 entries = BluetoothUtils.parseLengthTypeValueBytes(mRawMetadata);
473                 if (mRawMetadata.length > 0 && mRawMetadata[0] > 0 && entries.isEmpty()) {
474                     throw new IllegalArgumentException(
475                             "No LTV entries are found from rawBytes of"
476                                     + " size "
477                                     + mRawMetadata.length
478                                     + " please check the original object"
479                                     + " passed to Builder's copy constructor");
480                 }
481             }
482             if (mSampleRate != SAMPLE_RATE_NONE) {
483                 int samplingFrequency = convertToSamplingFrequencyValue(mSampleRate);
484                 entries.removeIf(entry -> entry.getType() == SAMPLING_FREQUENCY_TYPE);
485                 entries.add(
486                         new TypeValueEntry(
487                                 SAMPLING_FREQUENCY_TYPE,
488                                 ByteBuffer.allocate(1)
489                                         .put((byte) (samplingFrequency & 0xFF))
490                                         .array()));
491             }
492             if (mFrameDuration != FRAME_DURATION_NONE) {
493                 int frameDuration = convertToFrameDurationValue(mFrameDuration);
494                 entries.removeIf(entry -> entry.getType() == FRAME_DURATION_TYPE);
495                 entries.add(
496                         new TypeValueEntry(
497                                 FRAME_DURATION_TYPE,
498                                 ByteBuffer.allocate(1).put((byte) (frameDuration & 0xFF)).array()));
499             }
500             if (mAudioLocation != -1) {
501                 entries.removeIf(entry -> entry.getType() == AUDIO_CHANNEL_LOCATION_TYPE);
502                 entries.add(
503                         new TypeValueEntry(
504                                 AUDIO_CHANNEL_LOCATION_TYPE,
505                                 ByteBuffer.allocate(4)
506                                         .putInt((int) (mAudioLocation & 0xFFFFFFFF))
507                                         .array()));
508             }
509             if (mOctetsPerFrame != 0) {
510                 entries.removeIf(entry -> entry.getType() == OCTETS_PER_FRAME_TYPE);
511                 entries.add(
512                         new TypeValueEntry(
513                                 OCTETS_PER_FRAME_TYPE,
514                                 ByteBuffer.allocate(2)
515                                         .putShort((short) (mOctetsPerFrame & 0xFFFF))
516                                         .array()));
517             }
518             byte[] rawBytes = BluetoothUtils.serializeTypeValue(entries);
519             if (rawBytes == null) {
520                 throw new IllegalArgumentException("Failed to serialize entries to bytes");
521             }
522             return new BluetoothLeAudioCodecConfigMetadata(
523                     mAudioLocation, mSampleRate, mFrameDuration, mOctetsPerFrame, rawBytes);
524         }
525     }
526 
convertToSampleRateBitset(int samplingFrequencyValue)527     private static int convertToSampleRateBitset(int samplingFrequencyValue) {
528         switch (samplingFrequencyValue) {
529             case CONFIG_SAMPLING_FREQUENCY_8000:
530                 return SAMPLE_RATE_8000;
531             case CONFIG_SAMPLING_FREQUENCY_16000:
532                 return SAMPLE_RATE_16000;
533             case CONFIG_SAMPLING_FREQUENCY_24000:
534                 return SAMPLE_RATE_24000;
535             case CONFIG_SAMPLING_FREQUENCY_32000:
536                 return SAMPLE_RATE_32000;
537             case CONFIG_SAMPLING_FREQUENCY_44100:
538                 return SAMPLE_RATE_44100;
539             case CONFIG_SAMPLING_FREQUENCY_48000:
540                 return SAMPLE_RATE_48000;
541             default:
542                 if (Flags.leaudioAddSamplingFrequencies()) {
543                     switch (samplingFrequencyValue) {
544                         case CONFIG_SAMPLING_FREQUENCY_11025:
545                             return BluetoothLeAudioCodecConfig.SAMPLE_RATE_11025;
546                         case CONFIG_SAMPLING_FREQUENCY_22050:
547                             return BluetoothLeAudioCodecConfig.SAMPLE_RATE_22050;
548                         case CONFIG_SAMPLING_FREQUENCY_88200:
549                             return BluetoothLeAudioCodecConfig.SAMPLE_RATE_88200;
550                         case CONFIG_SAMPLING_FREQUENCY_96000:
551                             return BluetoothLeAudioCodecConfig.SAMPLE_RATE_96000;
552                         case CONFIG_SAMPLING_FREQUENCY_176400:
553                             return BluetoothLeAudioCodecConfig.SAMPLE_RATE_176400;
554                         case CONFIG_SAMPLING_FREQUENCY_192000:
555                             return BluetoothLeAudioCodecConfig.SAMPLE_RATE_192000;
556                         case CONFIG_SAMPLING_FREQUENCY_384000:
557                             return BluetoothLeAudioCodecConfig.SAMPLE_RATE_384000;
558                     }
559                 }
560                 return SAMPLE_RATE_NONE;
561         }
562     }
563 
convertToSamplingFrequencyValue(int sampleRateBitSet)564     private static int convertToSamplingFrequencyValue(int sampleRateBitSet) {
565         switch (sampleRateBitSet) {
566             case SAMPLE_RATE_8000:
567                 return CONFIG_SAMPLING_FREQUENCY_8000;
568             case SAMPLE_RATE_16000:
569                 return CONFIG_SAMPLING_FREQUENCY_16000;
570             case SAMPLE_RATE_24000:
571                 return CONFIG_SAMPLING_FREQUENCY_24000;
572             case SAMPLE_RATE_32000:
573                 return CONFIG_SAMPLING_FREQUENCY_32000;
574             case SAMPLE_RATE_44100:
575                 return CONFIG_SAMPLING_FREQUENCY_44100;
576             case SAMPLE_RATE_48000:
577                 return CONFIG_SAMPLING_FREQUENCY_48000;
578             default:
579                 if (Flags.leaudioAddSamplingFrequencies()) {
580                     switch (sampleRateBitSet) {
581                         case BluetoothLeAudioCodecConfig.SAMPLE_RATE_11025:
582                             return CONFIG_SAMPLING_FREQUENCY_11025;
583                         case BluetoothLeAudioCodecConfig.SAMPLE_RATE_22050:
584                             return CONFIG_SAMPLING_FREQUENCY_22050;
585                         case BluetoothLeAudioCodecConfig.SAMPLE_RATE_88200:
586                             return CONFIG_SAMPLING_FREQUENCY_88200;
587                         case BluetoothLeAudioCodecConfig.SAMPLE_RATE_96000:
588                             return CONFIG_SAMPLING_FREQUENCY_96000;
589                         case BluetoothLeAudioCodecConfig.SAMPLE_RATE_176400:
590                             return CONFIG_SAMPLING_FREQUENCY_176400;
591                         case BluetoothLeAudioCodecConfig.SAMPLE_RATE_192000:
592                             return CONFIG_SAMPLING_FREQUENCY_192000;
593                         case BluetoothLeAudioCodecConfig.SAMPLE_RATE_384000:
594                             return CONFIG_SAMPLING_FREQUENCY_384000;
595                     }
596                 }
597                 return CONFIG_SAMPLING_FREQUENCY_UNKNOWN;
598         }
599     }
600 
convertToFrameDurationBitset(int frameDurationValue)601     private static int convertToFrameDurationBitset(int frameDurationValue) {
602         switch (frameDurationValue) {
603             case CONFIG_FRAME_DURATION_7500:
604                 return FRAME_DURATION_7500;
605             case CONFIG_FRAME_DURATION_10000:
606                 return FRAME_DURATION_10000;
607             default:
608                 return FRAME_DURATION_NONE;
609         }
610     }
611 
convertToFrameDurationValue(int frameDurationBitset)612     private static int convertToFrameDurationValue(int frameDurationBitset) {
613         switch (frameDurationBitset) {
614             case FRAME_DURATION_7500:
615                 return CONFIG_FRAME_DURATION_7500;
616             case FRAME_DURATION_10000:
617                 return CONFIG_FRAME_DURATION_10000;
618             default:
619                 return CONFIG_FRAME_DURATION_UNKNOWN;
620         }
621     }
622 }
623