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