blob: 3f591553f62b31332bf747a60bed8a953dc82734 [file] [log] [blame]
Patty5c05c2f2021-11-04 21:03:32 +08001/*
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
17package android.bluetooth;
18
Sagar Vermacda6dbf2024-01-19 11:32:47 +053019import android.annotation.FlaggedApi;
Patty5c05c2f2021-11-04 21:03:32 +080020import android.annotation.IntDef;
21import android.annotation.NonNull;
Anton Hanssonfa927a52023-11-09 09:08:19 +000022import android.annotation.Nullable;
Pattyd8c49272022-01-19 16:26:00 +080023import android.os.Parcel;
24import android.os.Parcelable;
Patty5c05c2f2021-11-04 21:03:32 +080025
Sagar Vermacda6dbf2024-01-19 11:32:47 +053026import com.android.bluetooth.flags.Flags;
27
Patty5c05c2f2021-11-04 21:03:32 +080028import java.lang.annotation.Retention;
29import java.lang.annotation.RetentionPolicy;
Patty5aa4bd22022-01-25 19:58:37 +080030import java.util.Objects;
Patty5c05c2f2021-11-04 21:03:32 +080031
32/**
33 * Represents the codec configuration for a Bluetooth LE Audio source device.
Patty5c05c2f2021-11-04 21:03:32 +080034 *
David Duarteee52b7e2023-12-02 01:32:11 +000035 * <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 *
David Duarte5a02bb42023-12-04 23:07:42 +000039 * @see BluetoothLeAudioCodecConfig
Patty5c05c2f2021-11-04 21:03:32 +080040 */
Pattyd8c49272022-01-19 16:26:00 +080041public final class BluetoothLeAudioCodecConfig implements Parcelable {
Patty5c05c2f2021-11-04 21:03:32 +080042 // Add an entry for each source codec here.
43
44 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000045 @IntDef(
46 prefix = "SOURCE_CODEC_TYPE_",
Jakub Tyszkowski676bd922025-04-10 11:02:14 +000047 value = {
48 SOURCE_CODEC_TYPE_LC3,
49 SOURCE_CODEC_TYPE_OPUS,
50 SOURCE_CODEC_TYPE_OPUS_HI_RES,
51 SOURCE_CODEC_TYPE_INVALID
52 })
Patty5c05c2f2021-11-04 21:03:32 +080053 @Retention(RetentionPolicy.SOURCE)
54 public @interface SourceCodecType {};
55
56 public static final int SOURCE_CODEC_TYPE_LC3 = 0;
Łukasz Rymanowski61e11882024-11-20 14:13:27 +000057
58 @FlaggedApi(Flags.FLAG_LEAUDIO_ADD_OPUS_CODEC_TYPE)
59 public static final int SOURCE_CODEC_TYPE_OPUS = 1;
60
Jakub Tyszkowski676bd922025-04-10 11:02:14 +000061 /** @hide */
62 public static final int SOURCE_CODEC_TYPE_OPUS_HI_RES = 2;
63
Patty5c05c2f2021-11-04 21:03:32 +080064 public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
65
Pattyd8c49272022-01-19 16:26:00 +080066 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000067 @IntDef(
68 prefix = "CODEC_PRIORITY_",
Pattyd8c49272022-01-19 16:26:00 +080069 value = {CODEC_PRIORITY_DISABLED, CODEC_PRIORITY_DEFAULT, CODEC_PRIORITY_HIGHEST})
70 @Retention(RetentionPolicy.SOURCE)
71 public @interface CodecPriority {}
72
73 /**
David Duarteee52b7e2023-12-02 01:32:11 +000074 * Codec priority disabled. Used to indicate that this codec is disabled and should not be used.
Pattyd8c49272022-01-19 16:26:00 +080075 */
76 public static final int CODEC_PRIORITY_DISABLED = -1;
77
David Duarteee52b7e2023-12-02 01:32:11 +000078 /** Codec priority default. Default value used for codec priority. */
Pattyd8c49272022-01-19 16:26:00 +080079 public static final int CODEC_PRIORITY_DEFAULT = 0;
80
David Duarteee52b7e2023-12-02 01:32:11 +000081 /** Codec priority highest. Used to indicate the highest priority a codec can have. */
Pattyd8c49272022-01-19 16:26:00 +080082 public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
83
84 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +000085 @IntDef(
86 flag = true,
87 prefix = "SAMPLE_RATE_",
88 value = {
89 SAMPLE_RATE_NONE,
90 SAMPLE_RATE_8000,
Sagar Vermacda6dbf2024-01-19 11:32:47 +053091 SAMPLE_RATE_11025,
David Duarteee52b7e2023-12-02 01:32:11 +000092 SAMPLE_RATE_16000,
Sagar Vermacda6dbf2024-01-19 11:32:47 +053093 SAMPLE_RATE_22050,
David Duarteee52b7e2023-12-02 01:32:11 +000094 SAMPLE_RATE_24000,
95 SAMPLE_RATE_32000,
96 SAMPLE_RATE_44100,
Sagar Vermacda6dbf2024-01-19 11:32:47 +053097 SAMPLE_RATE_48000,
98 SAMPLE_RATE_88200,
99 SAMPLE_RATE_96000,
100 SAMPLE_RATE_176400,
101 SAMPLE_RATE_192000,
102 SAMPLE_RATE_384000
David Duarteee52b7e2023-12-02 01:32:11 +0000103 })
Pattyd8c49272022-01-19 16:26:00 +0800104 @Retention(RetentionPolicy.SOURCE)
105 public @interface SampleRate {}
106
107 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000108 * Codec sample rate 0 Hz. Default value used for codec sample rate. Values are the bit mask as
109 * defined in the Bluetooth Assigned Numbers, Generic Audio, Supported_Sampling_Frequencies
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530110 * table.
Pattyd8c49272022-01-19 16:26:00 +0800111 */
112 public static final int SAMPLE_RATE_NONE = 0;
113
David Duarteee52b7e2023-12-02 01:32:11 +0000114 /** Codec sample rate 8000 Hz. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000115 public static final int SAMPLE_RATE_8000 = 0x01 << 0;
Pattyd8c49272022-01-19 16:26:00 +0800116
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530117 /** Codec sample rate 11025 Hz. */
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530118 public static final int SAMPLE_RATE_11025 = 0x01 << 1;
119
David Duarteee52b7e2023-12-02 01:32:11 +0000120 /** Codec sample rate 16000 Hz. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000121 public static final int SAMPLE_RATE_16000 = 0x01 << 2;
Pattyd8c49272022-01-19 16:26:00 +0800122
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530123 /** Codec sample rate 22050 Hz. */
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530124 public static final int SAMPLE_RATE_22050 = 0x01 << 3;
125
David Duarteee52b7e2023-12-02 01:32:11 +0000126 /** Codec sample rate 24000 Hz. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000127 public static final int SAMPLE_RATE_24000 = 0x01 << 4;
Pattyd8c49272022-01-19 16:26:00 +0800128
David Duarteee52b7e2023-12-02 01:32:11 +0000129 /** Codec sample rate 32000 Hz. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000130 public static final int SAMPLE_RATE_32000 = 0x01 << 5;
Pattyd8c49272022-01-19 16:26:00 +0800131
David Duarteee52b7e2023-12-02 01:32:11 +0000132 /** Codec sample rate 44100 Hz. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000133 public static final int SAMPLE_RATE_44100 = 0x01 << 6;
Pattyd8c49272022-01-19 16:26:00 +0800134
David Duarteee52b7e2023-12-02 01:32:11 +0000135 /** Codec sample rate 48000 Hz. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000136 public static final int SAMPLE_RATE_48000 = 0x01 << 7;
Pattyd8c49272022-01-19 16:26:00 +0800137
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530138 /** Codec sample rate 88200 Hz. */
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530139 public static final int SAMPLE_RATE_88200 = 0x01 << 8;
140
141 /** Codec sample rate 96000 Hz. */
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530142 public static final int SAMPLE_RATE_96000 = 0x01 << 9;
143
144 /** Codec sample rate 176400 Hz. */
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530145 public static final int SAMPLE_RATE_176400 = 0x01 << 10;
146
147 /** Codec sample rate 192000 Hz. */
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530148 public static final int SAMPLE_RATE_192000 = 0x01 << 11;
149
150 /** Codec sample rate 384000 Hz. */
Sagar Vermacda6dbf2024-01-19 11:32:47 +0530151 public static final int SAMPLE_RATE_384000 = 0x01 << 12;
152
Pattyd8c49272022-01-19 16:26:00 +0800153 /** @hide */
David Duarteee52b7e2023-12-02 01:32:11 +0000154 @IntDef(
155 flag = true,
156 prefix = "BITS_PER_SAMPLE_",
157 value = {
158 BITS_PER_SAMPLE_NONE,
159 BITS_PER_SAMPLE_16,
160 BITS_PER_SAMPLE_24,
161 BITS_PER_SAMPLE_32
162 })
Pattyd8c49272022-01-19 16:26:00 +0800163 @Retention(RetentionPolicy.SOURCE)
164 public @interface BitsPerSample {}
165
David Duarteee52b7e2023-12-02 01:32:11 +0000166 /** Codec bits per sample 0. Default value of the codec bits per sample. */
Pattyd8c49272022-01-19 16:26:00 +0800167 public static final int BITS_PER_SAMPLE_NONE = 0;
168
David Duarteee52b7e2023-12-02 01:32:11 +0000169 /** Codec bits per sample 16. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000170 public static final int BITS_PER_SAMPLE_16 = 0x01 << 0;
Pattyd8c49272022-01-19 16:26:00 +0800171
David Duarteee52b7e2023-12-02 01:32:11 +0000172 /** Codec bits per sample 24. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000173 public static final int BITS_PER_SAMPLE_24 = 0x01 << 1;
Pattyd8c49272022-01-19 16:26:00 +0800174
David Duarteee52b7e2023-12-02 01:32:11 +0000175 /** Codec bits per sample 32. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000176 public static final int BITS_PER_SAMPLE_32 = 0x01 << 3;
Pattyd8c49272022-01-19 16:26:00 +0800177
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000178 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000179 * Values are the bit mask as defined in the Bluetooth Assigned Numbers, Generic Audio,
180 * Supported_Audio_Channel_Counts table Note: We use only part of it.
181 *
182 * @hide
183 */
184 @IntDef(
185 flag = true,
186 prefix = "CHANNEL_COUNT_",
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000187 value = {CHANNEL_COUNT_NONE, CHANNEL_COUNT_1, CHANNEL_COUNT_2})
Pattyd8c49272022-01-19 16:26:00 +0800188 @Retention(RetentionPolicy.SOURCE)
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000189 public @interface ChannelCount {}
Pattyd8c49272022-01-19 16:26:00 +0800190
David Duarteee52b7e2023-12-02 01:32:11 +0000191 /** Codec channel mode NONE. Default value of the codec channel mode. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000192 public static final int CHANNEL_COUNT_NONE = 0;
Pattyd8c49272022-01-19 16:26:00 +0800193
David Duarteee52b7e2023-12-02 01:32:11 +0000194 /** Codec channel mode MONO. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000195 public static final int CHANNEL_COUNT_1 = 0x01 << 0;
Pattyd8c49272022-01-19 16:26:00 +0800196
David Duarteee52b7e2023-12-02 01:32:11 +0000197 /** Codec channel mode STEREO. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000198 public static final int CHANNEL_COUNT_2 = 0x01 << 1;
Pattyd8c49272022-01-19 16:26:00 +0800199
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000200 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000201 * Values are the bit mask as defined in the Bluetooth Assigned Numbers, Generic Audio,
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000202 * Supported_Frame_Durations table
203 *
David Duarteee52b7e2023-12-02 01:32:11 +0000204 * @hide
205 */
206 @IntDef(
207 flag = true,
208 prefix = "FRAME_DURATION_",
Pattyd8c49272022-01-19 16:26:00 +0800209 value = {FRAME_DURATION_NONE, FRAME_DURATION_7500, FRAME_DURATION_10000})
210 @Retention(RetentionPolicy.SOURCE)
211 public @interface FrameDuration {}
212
David Duarteee52b7e2023-12-02 01:32:11 +0000213 /** Frame duration 0. Default value of the frame duration. */
Pattyd8c49272022-01-19 16:26:00 +0800214 public static final int FRAME_DURATION_NONE = 0;
215
David Duarteee52b7e2023-12-02 01:32:11 +0000216 /** Frame duration 7500 us. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000217 public static final int FRAME_DURATION_7500 = 0x01 << 0;
Pattyd8c49272022-01-19 16:26:00 +0800218
David Duarteee52b7e2023-12-02 01:32:11 +0000219 /** Frame duration 10000 us. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000220 public static final int FRAME_DURATION_10000 = 0x01 << 1;
Pattyd8c49272022-01-19 16:26:00 +0800221
Patty5c05c2f2021-11-04 21:03:32 +0800222 private final @SourceCodecType int mCodecType;
Pattyd8c49272022-01-19 16:26:00 +0800223 private final @CodecPriority int mCodecPriority;
224 private final @SampleRate int mSampleRate;
225 private final @BitsPerSample int mBitsPerSample;
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000226 private final @ChannelCount int mChannelCount;
Pattyd8c49272022-01-19 16:26:00 +0800227 private final @FrameDuration int mFrameDuration;
228 private final int mOctetsPerFrame;
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000229 private final int mMinOctetsPerFrame;
230 private final int mMaxOctetsPerFrame;
231
Patty5c05c2f2021-11-04 21:03:32 +0800232 /**
233 * Creates a new BluetoothLeAudioCodecConfig.
234 *
235 * @param codecType the source codec type
Pattyd8c49272022-01-19 16:26:00 +0800236 * @param codecPriority the priority of this codec
237 * @param sampleRate the codec sample rate
238 * @param bitsPerSample the bits per sample of this codec
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000239 * @param channelCount the channel count of this codec
Pattyd8c49272022-01-19 16:26:00 +0800240 * @param frameDuration the frame duration of this codec
241 * @param octetsPerFrame the octets per frame of this codec
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000242 * @param minOctetsPerFrame the minimum octets per frame of this codec
243 * @param maxOctetsPerFrame the maximum octets per frame of this codec
Patty5c05c2f2021-11-04 21:03:32 +0800244 */
David Duarteee52b7e2023-12-02 01:32:11 +0000245 private BluetoothLeAudioCodecConfig(
246 @SourceCodecType int codecType,
247 @CodecPriority int codecPriority,
248 @SampleRate int sampleRate,
249 @BitsPerSample int bitsPerSample,
250 @ChannelCount int channelCount,
251 @FrameDuration int frameDuration,
252 int octetsPerFrame,
253 int minOctetsPerFrame,
254 int maxOctetsPerFrame) {
Patty5c05c2f2021-11-04 21:03:32 +0800255 mCodecType = codecType;
Pattyd8c49272022-01-19 16:26:00 +0800256 mCodecPriority = codecPriority;
257 mSampleRate = sampleRate;
258 mBitsPerSample = bitsPerSample;
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000259 mChannelCount = channelCount;
Pattyd8c49272022-01-19 16:26:00 +0800260 mFrameDuration = frameDuration;
261 mOctetsPerFrame = octetsPerFrame;
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000262 mMinOctetsPerFrame = minOctetsPerFrame;
263 mMaxOctetsPerFrame = maxOctetsPerFrame;
Pattyd8c49272022-01-19 16:26:00 +0800264 }
265
266 @Override
267 public int describeContents() {
268 return 0;
269 }
270
David Duarteee52b7e2023-12-02 01:32:11 +0000271 /** {@link Parcelable.Creator} interface implementation. */
Ömer Faruk Yılmaz9d13b8f2025-04-10 05:01:39 +0000272 public static final @NonNull Parcelable.Creator<BluetoothLeAudioCodecConfig> CREATOR =
273 new Parcelable.Creator<BluetoothLeAudioCodecConfig>() {
274 public BluetoothLeAudioCodecConfig createFromParcel(Parcel in) {
275 int codecType = in.readInt();
276 int codecPriority = in.readInt();
277 int sampleRate = in.readInt();
278 int bitsPerSample = in.readInt();
279 int channelCount = in.readInt();
280 int frameDuration = in.readInt();
281 int octetsPerFrame = in.readInt();
282 int minOctetsPerFrame = in.readInt();
283 int maxOctetsPerFrame = in.readInt();
284 return new BluetoothLeAudioCodecConfig(
285 codecType,
286 codecPriority,
287 sampleRate,
288 bitsPerSample,
289 channelCount,
290 frameDuration,
291 octetsPerFrame,
292 minOctetsPerFrame,
293 maxOctetsPerFrame);
294 }
Pattyd8c49272022-01-19 16:26:00 +0800295
Ömer Faruk Yılmaz9d13b8f2025-04-10 05:01:39 +0000296 public BluetoothLeAudioCodecConfig[] newArray(int size) {
297 return new BluetoothLeAudioCodecConfig[size];
298 }
299 };
Pattyd8c49272022-01-19 16:26:00 +0800300
301 @Override
302 public void writeToParcel(@NonNull Parcel out, int flags) {
303 out.writeInt(mCodecType);
304 out.writeInt(mCodecPriority);
305 out.writeInt(mSampleRate);
306 out.writeInt(mBitsPerSample);
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000307 out.writeInt(mChannelCount);
Pattyd8c49272022-01-19 16:26:00 +0800308 out.writeInt(mFrameDuration);
309 out.writeInt(mOctetsPerFrame);
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000310 out.writeInt(mMinOctetsPerFrame);
311 out.writeInt(mMaxOctetsPerFrame);
Patty5c05c2f2021-11-04 21:03:32 +0800312 }
313
William Escande0f45ca02025-02-20 18:21:32 -0800314 private static String sampleRateToString(@SampleRate int sampleRateBit) {
William Escanded3098922025-05-02 10:22:00 -0700315 return switch (sampleRateBit) {
316 case SAMPLE_RATE_NONE -> "None";
317 case SAMPLE_RATE_8000 -> "8 kHz";
318 case SAMPLE_RATE_11025 -> "11.025 kHz";
319 case SAMPLE_RATE_16000 -> "16 kHz";
320 case SAMPLE_RATE_22050 -> "22.05 kHz";
321 case SAMPLE_RATE_24000 -> "24 kHz";
322 case SAMPLE_RATE_32000 -> "32 kHz";
323 case SAMPLE_RATE_44100 -> "44.1 kHz";
324 case SAMPLE_RATE_48000 -> "48 kHz";
325 case SAMPLE_RATE_88200 -> "88.2 kHz";
326 case SAMPLE_RATE_96000 -> "96 kHz";
327 case SAMPLE_RATE_176400 -> "176.4 kHz";
328 case SAMPLE_RATE_192000 -> "192 kHz";
329 case SAMPLE_RATE_384000 -> "384 kHz";
330 default -> "Unknown bit " + sampleRateBit;
331 };
Łukasz Rymanowski4b6c0d02024-04-22 15:02:02 +0000332 }
333
William Escande0f45ca02025-02-20 18:21:32 -0800334 private static String frameDurationToString(@FrameDuration int frameDurationBit) {
William Escanded3098922025-05-02 10:22:00 -0700335 return switch (frameDurationBit) {
336 case FRAME_DURATION_NONE -> "None";
337 case FRAME_DURATION_7500 -> "7.5 ms";
338 case FRAME_DURATION_10000 -> "10 ms";
339 default -> "Unknown bit " + frameDurationBit;
340 };
Łukasz Rymanowski4b6c0d02024-04-22 15:02:02 +0000341 }
342
Patty5c05c2f2021-11-04 21:03:32 +0800343 @Override
344 public String toString() {
David Duarteee52b7e2023-12-02 01:32:11 +0000345 return "{codecName:"
346 + getCodecName()
347 + ",mCodecType:"
348 + mCodecType
349 + ",mCodecPriority:"
350 + mCodecPriority
351 + ",mSampleRate:"
Łukasz Rymanowski4b6c0d02024-04-22 15:02:02 +0000352 + sampleRateToString(mSampleRate)
David Duarteee52b7e2023-12-02 01:32:11 +0000353 + ",mBitsPerSample:"
354 + mBitsPerSample
Łukasz Rymanowski4b6c0d02024-04-22 15:02:02 +0000355 + ",mChannelCountBitMask:"
David Duarteee52b7e2023-12-02 01:32:11 +0000356 + mChannelCount
357 + ",mFrameDuration:"
Łukasz Rymanowski4b6c0d02024-04-22 15:02:02 +0000358 + frameDurationToString(mFrameDuration)
David Duarteee52b7e2023-12-02 01:32:11 +0000359 + ",mOctetsPerFrame:"
360 + mOctetsPerFrame
361 + ",mMinOctetsPerFrame:"
362 + mMinOctetsPerFrame
363 + ",mMaxOctetsPerFrame:"
364 + mMaxOctetsPerFrame
365 + "}";
Patty5c05c2f2021-11-04 21:03:32 +0800366 }
367
368 /**
369 * Gets the codec type.
370 *
371 * @return the codec type
372 */
373 public @SourceCodecType int getCodecType() {
374 return mCodecType;
375 }
376
377 /**
Patty5c05c2f2021-11-04 21:03:32 +0800378 * Gets the codec name.
379 *
380 * @return the codec name
381 */
382 public @NonNull String getCodecName() {
383 switch (mCodecType) {
384 case SOURCE_CODEC_TYPE_LC3:
385 return "LC3";
386 case SOURCE_CODEC_TYPE_INVALID:
387 return "INVALID CODEC";
Jakub Tyszkowski676bd922025-04-10 11:02:14 +0000388 case SOURCE_CODEC_TYPE_OPUS_HI_RES:
389 if (Flags.leaudioAddOpusHiResCodecType()) {
390 return "Opus Hi-Res";
391 }
392 // Fall-through intended
Patty5c05c2f2021-11-04 21:03:32 +0800393 default:
Łukasz Rymanowski61e11882024-11-20 14:13:27 +0000394 if (Flags.leaudioAddOpusCodecType()) {
395 if (mCodecType == SOURCE_CODEC_TYPE_OPUS) {
396 return "Opus";
397 }
398 }
Patty5c05c2f2021-11-04 21:03:32 +0800399 break;
400 }
401 return "UNKNOWN CODEC(" + mCodecType + ")";
402 }
403
404 /**
Pattyd8c49272022-01-19 16:26:00 +0800405 * Returns the codec selection priority.
David Duarteee52b7e2023-12-02 01:32:11 +0000406 *
407 * <p>The codec selection priority is relative to other codecs: larger value means higher
408 * priority.
Pattyd8c49272022-01-19 16:26:00 +0800409 */
410 public @CodecPriority int getCodecPriority() {
411 return mCodecPriority;
412 }
413
David Duarteee52b7e2023-12-02 01:32:11 +0000414 /** Returns the codec sample rate. */
Pattyd8c49272022-01-19 16:26:00 +0800415 public @SampleRate int getSampleRate() {
416 return mSampleRate;
417 }
418
David Duarteee52b7e2023-12-02 01:32:11 +0000419 /** Returns the codec bits per sample. */
Pattyd8c49272022-01-19 16:26:00 +0800420 public @BitsPerSample int getBitsPerSample() {
421 return mBitsPerSample;
422 }
423
David Duarteee52b7e2023-12-02 01:32:11 +0000424 /** Returns the codec channel mode. */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000425 public @ChannelCount int getChannelCount() {
426 return mChannelCount;
Pattyd8c49272022-01-19 16:26:00 +0800427 }
428
David Duarteee52b7e2023-12-02 01:32:11 +0000429 /** Returns the frame duration. */
Patty3a61c472022-02-08 12:16:46 +0800430 public @FrameDuration int getFrameDuration() {
Pattyd8c49272022-01-19 16:26:00 +0800431 return mFrameDuration;
432 }
433
David Duarteee52b7e2023-12-02 01:32:11 +0000434 /** Returns the octets per frame */
Patty3a61c472022-02-08 12:16:46 +0800435 public int getOctetsPerFrame() {
Pattyd8c49272022-01-19 16:26:00 +0800436 return mOctetsPerFrame;
437 }
438
David Duarteee52b7e2023-12-02 01:32:11 +0000439 /** Returns the minimum octets per frame */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000440 public int getMinOctetsPerFrame() {
441 return mMinOctetsPerFrame;
442 }
443
David Duarteee52b7e2023-12-02 01:32:11 +0000444 /** Returns the maximum octets per frame */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000445 public int getMaxOctetsPerFrame() {
446 return mMaxOctetsPerFrame;
447 }
448
Patty5aa4bd22022-01-25 19:58:37 +0800449 @Override
Anton Hanssonfa927a52023-11-09 09:08:19 +0000450 public boolean equals(@Nullable Object o) {
Patty5aa4bd22022-01-25 19:58:37 +0800451 if (o instanceof BluetoothLeAudioCodecConfig) {
452 BluetoothLeAudioCodecConfig other = (BluetoothLeAudioCodecConfig) o;
453 return (other.getCodecType() == mCodecType
454 && other.getCodecPriority() == mCodecPriority
455 && other.getSampleRate() == mSampleRate
456 && other.getBitsPerSample() == mBitsPerSample
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000457 && other.getChannelCount() == mChannelCount
Patty5aa4bd22022-01-25 19:58:37 +0800458 && other.getFrameDuration() == mFrameDuration
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000459 && other.getOctetsPerFrame() == mOctetsPerFrame
460 && other.getMinOctetsPerFrame() == mMinOctetsPerFrame
461 && other.getMaxOctetsPerFrame() == mMaxOctetsPerFrame);
Patty5aa4bd22022-01-25 19:58:37 +0800462 }
463 return false;
464 }
465
466 /**
David Duarteee52b7e2023-12-02 01:32:11 +0000467 * Returns a hash representation of this BluetoothLeAudioCodecConfig based on all the config
468 * values.
Patty5aa4bd22022-01-25 19:58:37 +0800469 */
470 @Override
471 public int hashCode() {
David Duarteee52b7e2023-12-02 01:32:11 +0000472 return Objects.hash(
473 mCodecType,
474 mCodecPriority,
475 mSampleRate,
476 mBitsPerSample,
477 mChannelCount,
478 mFrameDuration,
479 mOctetsPerFrame,
480 mMinOctetsPerFrame,
481 mMaxOctetsPerFrame);
Patty5aa4bd22022-01-25 19:58:37 +0800482 }
483
Pattyd8c49272022-01-19 16:26:00 +0800484 /**
Patty5c05c2f2021-11-04 21:03:32 +0800485 * Builder for {@link BluetoothLeAudioCodecConfig}.
David Duarteee52b7e2023-12-02 01:32:11 +0000486 *
487 * <p>By default, the codec type will be set to {@link
488 * BluetoothLeAudioCodecConfig#SOURCE_CODEC_TYPE_INVALID}
Patty5c05c2f2021-11-04 21:03:32 +0800489 */
490 public static final class Builder {
491 private int mCodecType = BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_INVALID;
Pattyd8c49272022-01-19 16:26:00 +0800492 private int mCodecPriority = BluetoothLeAudioCodecConfig.CODEC_PRIORITY_DEFAULT;
493 private int mSampleRate = BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE;
494 private int mBitsPerSample = BluetoothLeAudioCodecConfig.BITS_PER_SAMPLE_NONE;
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000495 private int mChannelCount = BluetoothLeAudioCodecConfig.CHANNEL_COUNT_NONE;
Pattyd8c49272022-01-19 16:26:00 +0800496 private int mFrameDuration = BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE;
497 private int mOctetsPerFrame = 0;
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000498 private int mMinOctetsPerFrame = 0;
499 private int mMaxOctetsPerFrame = 0;
Pattyd8c49272022-01-19 16:26:00 +0800500
501 public Builder() {}
502
503 public Builder(@NonNull BluetoothLeAudioCodecConfig config) {
504 mCodecType = config.getCodecType();
505 mCodecPriority = config.getCodecPriority();
506 mSampleRate = config.getSampleRate();
507 mBitsPerSample = config.getBitsPerSample();
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000508 mChannelCount = config.getChannelCount();
Pattyd8c49272022-01-19 16:26:00 +0800509 mFrameDuration = config.getFrameDuration();
510 mOctetsPerFrame = config.getOctetsPerFrame();
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000511 mMinOctetsPerFrame = config.getMinOctetsPerFrame();
512 mMaxOctetsPerFrame = config.getMaxOctetsPerFrame();
Pattyd8c49272022-01-19 16:26:00 +0800513 }
Patty5c05c2f2021-11-04 21:03:32 +0800514
515 /**
Pattyd8c49272022-01-19 16:26:00 +0800516 * Set codec type for Bluetooth LE audio codec config.
Patty5c05c2f2021-11-04 21:03:32 +0800517 *
518 * @param codecType of this codec
519 * @return the same Builder instance
520 */
521 public @NonNull Builder setCodecType(@SourceCodecType int codecType) {
522 mCodecType = codecType;
523 return this;
524 }
525
526 /**
Pattyd8c49272022-01-19 16:26:00 +0800527 * Set codec priority for Bluetooth LE audio codec config.
528 *
529 * @param codecPriority of this codec
530 * @return the same Builder instance
531 */
532 public @NonNull Builder setCodecPriority(@CodecPriority int codecPriority) {
533 mCodecPriority = codecPriority;
534 return this;
535 }
536
537 /**
538 * Set sample rate for Bluetooth LE audio codec config.
539 *
540 * @param sampleRate of this codec
541 * @return the same Builder instance
542 */
543 public @NonNull Builder setSampleRate(@SampleRate int sampleRate) {
544 mSampleRate = sampleRate;
545 return this;
546 }
547
548 /**
549 * Set the bits per sample for LE audio codec config.
550 *
551 * @param bitsPerSample of this codec
552 * @return the same Builder instance
553 */
554 public @NonNull Builder setBitsPerSample(@BitsPerSample int bitsPerSample) {
555 mBitsPerSample = bitsPerSample;
556 return this;
557 }
558
559 /**
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000560 * Set the channel count for Bluetooth LE audio codec config.
Pattyd8c49272022-01-19 16:26:00 +0800561 *
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000562 * @param channelCount of this codec
Pattyd8c49272022-01-19 16:26:00 +0800563 * @return the same Builder instance
564 */
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000565 public @NonNull Builder setChannelCount(@ChannelCount int channelCount) {
566 mChannelCount = channelCount;
Pattyd8c49272022-01-19 16:26:00 +0800567 return this;
568 }
569
570 /**
571 * Set the frame duration for Bluetooth LE audio codec config.
572 *
573 * @param frameDuration of this codec
574 * @return the same Builder instance
575 */
576 public @NonNull Builder setFrameDuration(@FrameDuration int frameDuration) {
577 mFrameDuration = frameDuration;
578 return this;
579 }
580
581 /**
582 * Set the octets per frame for Bluetooth LE audio codec config.
583 *
584 * @param octetsPerFrame of this codec
585 * @return the same Builder instance
586 */
587 public @NonNull Builder setOctetsPerFrame(int octetsPerFrame) {
588 mOctetsPerFrame = octetsPerFrame;
589 return this;
590 }
591
592 /**
Łukasz Rymanowski3c979452022-03-10 10:28:12 +0000593 * Set the minimum octets per frame for Bluetooth LE audio codec config.
594 *
595 * @param minOctetsPerFrame of this codec
596 * @return the same Builder instance
597 */
598 public @NonNull Builder setMinOctetsPerFrame(int minOctetsPerFrame) {
599 mMinOctetsPerFrame = minOctetsPerFrame;
600 return this;
601 }
602
603 /**
604 * Set the maximum octets per frame for Bluetooth LE audio codec config.
605 *
606 * @param maxOctetsPerFrame of this codec
607 * @return the same Builder instance
608 */
609 public @NonNull Builder setMaxOctetsPerFrame(int maxOctetsPerFrame) {
610 mMaxOctetsPerFrame = maxOctetsPerFrame;
611 return this;
612 }
613
614 /**
Patty5c05c2f2021-11-04 21:03:32 +0800615 * Build {@link BluetoothLeAudioCodecConfig}.
David Duarteee52b7e2023-12-02 01:32:11 +0000616 *
Patty5c05c2f2021-11-04 21:03:32 +0800617 * @return new BluetoothLeAudioCodecConfig built
618 */
619 public @NonNull BluetoothLeAudioCodecConfig build() {
David Duarteee52b7e2023-12-02 01:32:11 +0000620 return new BluetoothLeAudioCodecConfig(
621 mCodecType,
622 mCodecPriority,
623 mSampleRate,
624 mBitsPerSample,
625 mChannelCount,
626 mFrameDuration,
627 mOctetsPerFrame,
628 mMinOctetsPerFrame,
629 mMaxOctetsPerFrame);
Patty5c05c2f2021-11-04 21:03:32 +0800630 }
631 }
632}