1 /* 2 * Copyright (C) 2021 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 android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import com.android.bluetooth.flags.Flags; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.Objects; 31 32 /** 33 * Represents the codec configuration for a Bluetooth LE Audio source device. 34 * 35 * <p>Contains the source codec type. 36 * 37 * <p>The source codec type values are the same as those supported by the device hardware. 38 * 39 * @see BluetoothLeAudioCodecConfig 40 */ 41 public final class BluetoothLeAudioCodecConfig implements Parcelable { 42 // Add an entry for each source codec here. 43 44 /** @hide */ 45 @IntDef( 46 prefix = "SOURCE_CODEC_TYPE_", 47 value = {SOURCE_CODEC_TYPE_LC3, SOURCE_CODEC_TYPE_OPUS, SOURCE_CODEC_TYPE_INVALID}) 48 @Retention(RetentionPolicy.SOURCE) 49 public @interface SourceCodecType {}; 50 51 public static final int SOURCE_CODEC_TYPE_LC3 = 0; 52 53 @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_OPUS_CODEC_TYPE) 54 public static final int SOURCE_CODEC_TYPE_OPUS = 1; 55 56 public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000; 57 58 /** @hide */ 59 @IntDef( 60 prefix = "CODEC_PRIORITY_", 61 value = {CODEC_PRIORITY_DISABLED, CODEC_PRIORITY_DEFAULT, CODEC_PRIORITY_HIGHEST}) 62 @Retention(RetentionPolicy.SOURCE) 63 public @interface CodecPriority {} 64 65 /** 66 * Codec priority disabled. Used to indicate that this codec is disabled and should not be used. 67 */ 68 public static final int CODEC_PRIORITY_DISABLED = -1; 69 70 /** Codec priority default. Default value used for codec priority. */ 71 public static final int CODEC_PRIORITY_DEFAULT = 0; 72 73 /** Codec priority highest. Used to indicate the highest priority a codec can have. */ 74 public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000; 75 76 /** @hide */ 77 @IntDef( 78 flag = true, 79 prefix = "SAMPLE_RATE_", 80 value = { 81 SAMPLE_RATE_NONE, 82 SAMPLE_RATE_8000, 83 SAMPLE_RATE_11025, 84 SAMPLE_RATE_16000, 85 SAMPLE_RATE_22050, 86 SAMPLE_RATE_24000, 87 SAMPLE_RATE_32000, 88 SAMPLE_RATE_44100, 89 SAMPLE_RATE_48000, 90 SAMPLE_RATE_88200, 91 SAMPLE_RATE_96000, 92 SAMPLE_RATE_176400, 93 SAMPLE_RATE_192000, 94 SAMPLE_RATE_384000 95 }) 96 @Retention(RetentionPolicy.SOURCE) 97 public @interface SampleRate {} 98 99 /** 100 * Codec sample rate 0 Hz. Default value used for codec sample rate. Values are the bit mask as 101 * defined in the Bluetooth Assigned Numbers, Generic Audio, Supported_Sampling_Frequencies 102 * table. 103 */ 104 public static final int SAMPLE_RATE_NONE = 0; 105 106 /** Codec sample rate 8000 Hz. */ 107 public static final int SAMPLE_RATE_8000 = 0x01 << 0; 108 109 /** Codec sample rate 11025 Hz. */ 110 public static final int SAMPLE_RATE_11025 = 0x01 << 1; 111 112 /** Codec sample rate 16000 Hz. */ 113 public static final int SAMPLE_RATE_16000 = 0x01 << 2; 114 115 /** Codec sample rate 22050 Hz. */ 116 public static final int SAMPLE_RATE_22050 = 0x01 << 3; 117 118 /** Codec sample rate 24000 Hz. */ 119 public static final int SAMPLE_RATE_24000 = 0x01 << 4; 120 121 /** Codec sample rate 32000 Hz. */ 122 public static final int SAMPLE_RATE_32000 = 0x01 << 5; 123 124 /** Codec sample rate 44100 Hz. */ 125 public static final int SAMPLE_RATE_44100 = 0x01 << 6; 126 127 /** Codec sample rate 48000 Hz. */ 128 public static final int SAMPLE_RATE_48000 = 0x01 << 7; 129 130 /** Codec sample rate 88200 Hz. */ 131 public static final int SAMPLE_RATE_88200 = 0x01 << 8; 132 133 /** Codec sample rate 96000 Hz. */ 134 public static final int SAMPLE_RATE_96000 = 0x01 << 9; 135 136 /** Codec sample rate 176400 Hz. */ 137 public static final int SAMPLE_RATE_176400 = 0x01 << 10; 138 139 /** Codec sample rate 192000 Hz. */ 140 public static final int SAMPLE_RATE_192000 = 0x01 << 11; 141 142 /** Codec sample rate 384000 Hz. */ 143 public static final int SAMPLE_RATE_384000 = 0x01 << 12; 144 145 /** @hide */ 146 @IntDef( 147 flag = true, 148 prefix = "BITS_PER_SAMPLE_", 149 value = { 150 BITS_PER_SAMPLE_NONE, 151 BITS_PER_SAMPLE_16, 152 BITS_PER_SAMPLE_24, 153 BITS_PER_SAMPLE_32 154 }) 155 @Retention(RetentionPolicy.SOURCE) 156 public @interface BitsPerSample {} 157 158 /** Codec bits per sample 0. Default value of the codec bits per sample. */ 159 public static final int BITS_PER_SAMPLE_NONE = 0; 160 161 /** Codec bits per sample 16. */ 162 public static final int BITS_PER_SAMPLE_16 = 0x01 << 0; 163 164 /** Codec bits per sample 24. */ 165 public static final int BITS_PER_SAMPLE_24 = 0x01 << 1; 166 167 /** Codec bits per sample 32. */ 168 public static final int BITS_PER_SAMPLE_32 = 0x01 << 3; 169 170 /** 171 * Values are the bit mask as defined in the Bluetooth Assigned Numbers, Generic Audio, 172 * Supported_Audio_Channel_Counts table Note: We use only part of it. 173 * 174 * @hide 175 */ 176 @IntDef( 177 flag = true, 178 prefix = "CHANNEL_COUNT_", 179 value = {CHANNEL_COUNT_NONE, CHANNEL_COUNT_1, CHANNEL_COUNT_2}) 180 @Retention(RetentionPolicy.SOURCE) 181 public @interface ChannelCount {} 182 183 /** Codec channel mode NONE. Default value of the codec channel mode. */ 184 public static final int CHANNEL_COUNT_NONE = 0; 185 186 /** Codec channel mode MONO. */ 187 public static final int CHANNEL_COUNT_1 = 0x01 << 0; 188 189 /** Codec channel mode STEREO. */ 190 public static final int CHANNEL_COUNT_2 = 0x01 << 1; 191 192 /** 193 * Values are the bit mask as defined in the Bluetooth Assigned Numbers, Generic Audio, 194 * Supported_Frame_Durations table 195 * 196 * @hide 197 */ 198 @IntDef( 199 flag = true, 200 prefix = "FRAME_DURATION_", 201 value = {FRAME_DURATION_NONE, FRAME_DURATION_7500, FRAME_DURATION_10000}) 202 @Retention(RetentionPolicy.SOURCE) 203 public @interface FrameDuration {} 204 205 /** Frame duration 0. Default value of the frame duration. */ 206 public static final int FRAME_DURATION_NONE = 0; 207 208 /** Frame duration 7500 us. */ 209 public static final int FRAME_DURATION_7500 = 0x01 << 0; 210 211 /** Frame duration 10000 us. */ 212 public static final int FRAME_DURATION_10000 = 0x01 << 1; 213 214 private final @SourceCodecType int mCodecType; 215 private final @CodecPriority int mCodecPriority; 216 private final @SampleRate int mSampleRate; 217 private final @BitsPerSample int mBitsPerSample; 218 private final @ChannelCount int mChannelCount; 219 private final @FrameDuration int mFrameDuration; 220 private final int mOctetsPerFrame; 221 private final int mMinOctetsPerFrame; 222 private final int mMaxOctetsPerFrame; 223 224 /** 225 * Creates a new BluetoothLeAudioCodecConfig. 226 * 227 * @param codecType the source codec type 228 * @param codecPriority the priority of this codec 229 * @param sampleRate the codec sample rate 230 * @param bitsPerSample the bits per sample of this codec 231 * @param channelCount the channel count of this codec 232 * @param frameDuration the frame duration of this codec 233 * @param octetsPerFrame the octets per frame of this codec 234 * @param minOctetsPerFrame the minimum octets per frame of this codec 235 * @param maxOctetsPerFrame the maximum octets per frame of this codec 236 */ BluetoothLeAudioCodecConfig( @ourceCodecType int codecType, @CodecPriority int codecPriority, @SampleRate int sampleRate, @BitsPerSample int bitsPerSample, @ChannelCount int channelCount, @FrameDuration int frameDuration, int octetsPerFrame, int minOctetsPerFrame, int maxOctetsPerFrame)237 private BluetoothLeAudioCodecConfig( 238 @SourceCodecType int codecType, 239 @CodecPriority int codecPriority, 240 @SampleRate int sampleRate, 241 @BitsPerSample int bitsPerSample, 242 @ChannelCount int channelCount, 243 @FrameDuration int frameDuration, 244 int octetsPerFrame, 245 int minOctetsPerFrame, 246 int maxOctetsPerFrame) { 247 mCodecType = codecType; 248 mCodecPriority = codecPriority; 249 mSampleRate = sampleRate; 250 mBitsPerSample = bitsPerSample; 251 mChannelCount = channelCount; 252 mFrameDuration = frameDuration; 253 mOctetsPerFrame = octetsPerFrame; 254 mMinOctetsPerFrame = minOctetsPerFrame; 255 mMaxOctetsPerFrame = maxOctetsPerFrame; 256 } 257 258 @Override describeContents()259 public int describeContents() { 260 return 0; 261 } 262 263 /** {@link Parcelable.Creator} interface implementation. */ 264 public static final @android.annotation.NonNull Parcelable.Creator<BluetoothLeAudioCodecConfig> 265 CREATOR = 266 new Parcelable.Creator<BluetoothLeAudioCodecConfig>() { 267 public BluetoothLeAudioCodecConfig createFromParcel(Parcel in) { 268 int codecType = in.readInt(); 269 int codecPriority = in.readInt(); 270 int sampleRate = in.readInt(); 271 int bitsPerSample = in.readInt(); 272 int channelCount = in.readInt(); 273 int frameDuration = in.readInt(); 274 int octetsPerFrame = in.readInt(); 275 int minOctetsPerFrame = in.readInt(); 276 int maxOctetsPerFrame = in.readInt(); 277 return new BluetoothLeAudioCodecConfig( 278 codecType, 279 codecPriority, 280 sampleRate, 281 bitsPerSample, 282 channelCount, 283 frameDuration, 284 octetsPerFrame, 285 minOctetsPerFrame, 286 maxOctetsPerFrame); 287 } 288 289 public BluetoothLeAudioCodecConfig[] newArray(int size) { 290 return new BluetoothLeAudioCodecConfig[size]; 291 } 292 }; 293 294 @Override writeToParcel(@onNull Parcel out, int flags)295 public void writeToParcel(@NonNull Parcel out, int flags) { 296 out.writeInt(mCodecType); 297 out.writeInt(mCodecPriority); 298 out.writeInt(mSampleRate); 299 out.writeInt(mBitsPerSample); 300 out.writeInt(mChannelCount); 301 out.writeInt(mFrameDuration); 302 out.writeInt(mOctetsPerFrame); 303 out.writeInt(mMinOctetsPerFrame); 304 out.writeInt(mMaxOctetsPerFrame); 305 } 306 sampleRateToString(@ampleRate int sampleRateBit)307 private static String sampleRateToString(@SampleRate int sampleRateBit) { 308 switch (sampleRateBit) { 309 case SAMPLE_RATE_NONE: 310 return "None"; 311 case SAMPLE_RATE_8000: 312 return "8 kHz"; 313 case SAMPLE_RATE_11025: 314 return "11.025 kHz"; 315 case SAMPLE_RATE_16000: 316 return "16 kHz"; 317 case SAMPLE_RATE_22050: 318 return "22.05 kHz"; 319 case SAMPLE_RATE_24000: 320 return "24 kHz"; 321 case SAMPLE_RATE_32000: 322 return "32 kHz"; 323 case SAMPLE_RATE_44100: 324 return "44.1 kHz"; 325 case SAMPLE_RATE_48000: 326 return "48 kHz"; 327 case SAMPLE_RATE_88200: 328 return "88.2 kHz"; 329 case SAMPLE_RATE_96000: 330 return "96 kHz"; 331 case SAMPLE_RATE_176400: 332 return "176.4 kHz"; 333 case SAMPLE_RATE_192000: 334 return "192 kHz"; 335 case SAMPLE_RATE_384000: 336 return "384 kHz"; 337 default: 338 return "Unknown bit " + sampleRateBit; 339 } 340 } 341 frameDurationToString(@rameDuration int frameDurationBit)342 private static String frameDurationToString(@FrameDuration int frameDurationBit) { 343 switch (frameDurationBit) { 344 case FRAME_DURATION_NONE: 345 return "None"; 346 case FRAME_DURATION_7500: 347 return "7.5 ms"; 348 case FRAME_DURATION_10000: 349 return "10 ms"; 350 default: 351 return "Unknown bit " + frameDurationBit; 352 } 353 } 354 355 @Override toString()356 public String toString() { 357 return "{codecName:" 358 + getCodecName() 359 + ",mCodecType:" 360 + mCodecType 361 + ",mCodecPriority:" 362 + mCodecPriority 363 + ",mSampleRate:" 364 + sampleRateToString(mSampleRate) 365 + ",mBitsPerSample:" 366 + mBitsPerSample 367 + ",mChannelCountBitMask:" 368 + mChannelCount 369 + ",mFrameDuration:" 370 + frameDurationToString(mFrameDuration) 371 + ",mOctetsPerFrame:" 372 + mOctetsPerFrame 373 + ",mMinOctetsPerFrame:" 374 + mMinOctetsPerFrame 375 + ",mMaxOctetsPerFrame:" 376 + mMaxOctetsPerFrame 377 + "}"; 378 } 379 380 /** 381 * Gets the codec type. 382 * 383 * @return the codec type 384 */ getCodecType()385 public @SourceCodecType int getCodecType() { 386 return mCodecType; 387 } 388 389 /** 390 * Gets the codec name. 391 * 392 * @return the codec name 393 */ getCodecName()394 public @NonNull String getCodecName() { 395 switch (mCodecType) { 396 case SOURCE_CODEC_TYPE_LC3: 397 return "LC3"; 398 case SOURCE_CODEC_TYPE_INVALID: 399 return "INVALID CODEC"; 400 default: 401 if (Flags.leaudioAddOpusCodecType()) { 402 if (mCodecType == SOURCE_CODEC_TYPE_OPUS) { 403 return "Opus"; 404 } 405 } 406 break; 407 } 408 return "UNKNOWN CODEC(" + mCodecType + ")"; 409 } 410 411 /** 412 * Returns the codec selection priority. 413 * 414 * <p>The codec selection priority is relative to other codecs: larger value means higher 415 * priority. 416 */ getCodecPriority()417 public @CodecPriority int getCodecPriority() { 418 return mCodecPriority; 419 } 420 421 /** Returns the codec sample rate. */ getSampleRate()422 public @SampleRate int getSampleRate() { 423 return mSampleRate; 424 } 425 426 /** Returns the codec bits per sample. */ getBitsPerSample()427 public @BitsPerSample int getBitsPerSample() { 428 return mBitsPerSample; 429 } 430 431 /** Returns the codec channel mode. */ getChannelCount()432 public @ChannelCount int getChannelCount() { 433 return mChannelCount; 434 } 435 436 /** Returns the frame duration. */ getFrameDuration()437 public @FrameDuration int getFrameDuration() { 438 return mFrameDuration; 439 } 440 441 /** Returns the octets per frame */ getOctetsPerFrame()442 public int getOctetsPerFrame() { 443 return mOctetsPerFrame; 444 } 445 446 /** Returns the minimum octets per frame */ getMinOctetsPerFrame()447 public int getMinOctetsPerFrame() { 448 return mMinOctetsPerFrame; 449 } 450 451 /** Returns the maximum octets per frame */ getMaxOctetsPerFrame()452 public int getMaxOctetsPerFrame() { 453 return mMaxOctetsPerFrame; 454 } 455 456 @Override equals(@ullable Object o)457 public boolean equals(@Nullable Object o) { 458 if (o instanceof BluetoothLeAudioCodecConfig) { 459 BluetoothLeAudioCodecConfig other = (BluetoothLeAudioCodecConfig) o; 460 return (other.getCodecType() == mCodecType 461 && other.getCodecPriority() == mCodecPriority 462 && other.getSampleRate() == mSampleRate 463 && other.getBitsPerSample() == mBitsPerSample 464 && other.getChannelCount() == mChannelCount 465 && other.getFrameDuration() == mFrameDuration 466 && other.getOctetsPerFrame() == mOctetsPerFrame 467 && other.getMinOctetsPerFrame() == mMinOctetsPerFrame 468 && other.getMaxOctetsPerFrame() == mMaxOctetsPerFrame); 469 } 470 return false; 471 } 472 473 /** 474 * Returns a hash representation of this BluetoothLeAudioCodecConfig based on all the config 475 * values. 476 */ 477 @Override hashCode()478 public int hashCode() { 479 return Objects.hash( 480 mCodecType, 481 mCodecPriority, 482 mSampleRate, 483 mBitsPerSample, 484 mChannelCount, 485 mFrameDuration, 486 mOctetsPerFrame, 487 mMinOctetsPerFrame, 488 mMaxOctetsPerFrame); 489 } 490 491 /** 492 * Builder for {@link BluetoothLeAudioCodecConfig}. 493 * 494 * <p>By default, the codec type will be set to {@link 495 * BluetoothLeAudioCodecConfig#SOURCE_CODEC_TYPE_INVALID} 496 */ 497 public static final class Builder { 498 private int mCodecType = BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID; 499 private int mCodecPriority = BluetoothLeAudioCodecConfig.CODEC_PRIORITY_DEFAULT; 500 private int mSampleRate = BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE; 501 private int mBitsPerSample = BluetoothLeAudioCodecConfig.BITS_PER_SAMPLE_NONE; 502 private int mChannelCount = BluetoothLeAudioCodecConfig.CHANNEL_COUNT_NONE; 503 private int mFrameDuration = BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE; 504 private int mOctetsPerFrame = 0; 505 private int mMinOctetsPerFrame = 0; 506 private int mMaxOctetsPerFrame = 0; 507 Builder()508 public Builder() {} 509 Builder(@onNull BluetoothLeAudioCodecConfig config)510 public Builder(@NonNull BluetoothLeAudioCodecConfig config) { 511 mCodecType = config.getCodecType(); 512 mCodecPriority = config.getCodecPriority(); 513 mSampleRate = config.getSampleRate(); 514 mBitsPerSample = config.getBitsPerSample(); 515 mChannelCount = config.getChannelCount(); 516 mFrameDuration = config.getFrameDuration(); 517 mOctetsPerFrame = config.getOctetsPerFrame(); 518 mMinOctetsPerFrame = config.getMinOctetsPerFrame(); 519 mMaxOctetsPerFrame = config.getMaxOctetsPerFrame(); 520 } 521 522 /** 523 * Set codec type for Bluetooth LE audio codec config. 524 * 525 * @param codecType of this codec 526 * @return the same Builder instance 527 */ setCodecType(@ourceCodecType int codecType)528 public @NonNull Builder setCodecType(@SourceCodecType int codecType) { 529 mCodecType = codecType; 530 return this; 531 } 532 533 /** 534 * Set codec priority for Bluetooth LE audio codec config. 535 * 536 * @param codecPriority of this codec 537 * @return the same Builder instance 538 */ setCodecPriority(@odecPriority int codecPriority)539 public @NonNull Builder setCodecPriority(@CodecPriority int codecPriority) { 540 mCodecPriority = codecPriority; 541 return this; 542 } 543 544 /** 545 * Set sample rate for Bluetooth LE audio codec config. 546 * 547 * @param sampleRate of this codec 548 * @return the same Builder instance 549 */ setSampleRate(@ampleRate int sampleRate)550 public @NonNull Builder setSampleRate(@SampleRate int sampleRate) { 551 mSampleRate = sampleRate; 552 return this; 553 } 554 555 /** 556 * Set the bits per sample for LE audio codec config. 557 * 558 * @param bitsPerSample of this codec 559 * @return the same Builder instance 560 */ setBitsPerSample(@itsPerSample int bitsPerSample)561 public @NonNull Builder setBitsPerSample(@BitsPerSample int bitsPerSample) { 562 mBitsPerSample = bitsPerSample; 563 return this; 564 } 565 566 /** 567 * Set the channel count for Bluetooth LE audio codec config. 568 * 569 * @param channelCount of this codec 570 * @return the same Builder instance 571 */ setChannelCount(@hannelCount int channelCount)572 public @NonNull Builder setChannelCount(@ChannelCount int channelCount) { 573 mChannelCount = channelCount; 574 return this; 575 } 576 577 /** 578 * Set the frame duration for Bluetooth LE audio codec config. 579 * 580 * @param frameDuration of this codec 581 * @return the same Builder instance 582 */ setFrameDuration(@rameDuration int frameDuration)583 public @NonNull Builder setFrameDuration(@FrameDuration int frameDuration) { 584 mFrameDuration = frameDuration; 585 return this; 586 } 587 588 /** 589 * Set the octets per frame for Bluetooth LE audio codec config. 590 * 591 * @param octetsPerFrame of this codec 592 * @return the same Builder instance 593 */ setOctetsPerFrame(int octetsPerFrame)594 public @NonNull Builder setOctetsPerFrame(int octetsPerFrame) { 595 mOctetsPerFrame = octetsPerFrame; 596 return this; 597 } 598 599 /** 600 * Set the minimum octets per frame for Bluetooth LE audio codec config. 601 * 602 * @param minOctetsPerFrame of this codec 603 * @return the same Builder instance 604 */ setMinOctetsPerFrame(int minOctetsPerFrame)605 public @NonNull Builder setMinOctetsPerFrame(int minOctetsPerFrame) { 606 mMinOctetsPerFrame = minOctetsPerFrame; 607 return this; 608 } 609 610 /** 611 * Set the maximum octets per frame for Bluetooth LE audio codec config. 612 * 613 * @param maxOctetsPerFrame of this codec 614 * @return the same Builder instance 615 */ setMaxOctetsPerFrame(int maxOctetsPerFrame)616 public @NonNull Builder setMaxOctetsPerFrame(int maxOctetsPerFrame) { 617 mMaxOctetsPerFrame = maxOctetsPerFrame; 618 return this; 619 } 620 621 /** 622 * Build {@link BluetoothLeAudioCodecConfig}. 623 * 624 * @return new BluetoothLeAudioCodecConfig built 625 */ build()626 public @NonNull BluetoothLeAudioCodecConfig build() { 627 return new BluetoothLeAudioCodecConfig( 628 mCodecType, 629 mCodecPriority, 630 mSampleRate, 631 mBitsPerSample, 632 mChannelCount, 633 mFrameDuration, 634 mOctetsPerFrame, 635 mMinOctetsPerFrame, 636 mMaxOctetsPerFrame); 637 } 638 } 639 } 640