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