Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03e9ca4c authored by Rongxuan Liu's avatar Rongxuan Liu
Browse files

[le audio] Reuse existing constants for broadcast metadata codec config

Tag: #feature
Bug: 264692800
Test: atest BluetoothInstrumentationTests
Change-Id: Iaa6c44aba6db657b4bca484f00f930b4e051c542
parent 0b878bf9
Loading
Loading
Loading
Loading
+2 −12
Original line number Diff line number Diff line
@@ -459,17 +459,7 @@ package android.bluetooth {
    method public int getFrameDuration();
    method public int getOctetsPerFrame();
    method @NonNull public byte[] getRawMetadata();
    method public int getSamplingFrequency();
    field public static final int CONFIG_FRAME_DURATION_10000 = 1; // 0x1
    field public static final int CONFIG_FRAME_DURATION_7500 = 0; // 0x0
    field public static final int CONFIG_FRAME_DURATION_UNKNOWN = -1; // 0xffffffff
    field public static final int CONFIG_SAMPLING_FREQUENCY_16000 = 3; // 0x3
    field public static final int CONFIG_SAMPLING_FREQUENCY_24000 = 5; // 0x5
    field public static final int CONFIG_SAMPLING_FREQUENCY_32000 = 6; // 0x6
    field public static final int CONFIG_SAMPLING_FREQUENCY_44100 = 7; // 0x7
    field public static final int CONFIG_SAMPLING_FREQUENCY_48000 = 8; // 0x8
    field public static final int CONFIG_SAMPLING_FREQUENCY_8000 = 1; // 0x1
    field public static final int CONFIG_SAMPLING_FREQUENCY_UNKNOWN = 0; // 0x0
    method public int getSampleRate();
    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothLeAudioCodecConfigMetadata> CREATOR;
  }

@@ -480,7 +470,7 @@ package android.bluetooth {
    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfigMetadata.Builder setAudioLocation(long);
    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfigMetadata.Builder setFrameDuration(int);
    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfigMetadata.Builder setOctetsPerFrame(int);
    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfigMetadata.Builder setSamplingFrequency(int);
    method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfigMetadata.Builder setSampleRate(int);
  }

  public final class BluetoothLeAudioContentMetadata implements android.os.Parcelable {
+155 −163
Original line number Diff line number Diff line
@@ -16,7 +16,19 @@

package android.bluetooth;

import android.annotation.IntDef;
import static android.bluetooth.BluetoothLeAudioCodecConfig.FRAME_DURATION_10000;
import static android.bluetooth.BluetoothLeAudioCodecConfig.FRAME_DURATION_7500;
import static android.bluetooth.BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE;
import static android.bluetooth.BluetoothLeAudioCodecConfig.FrameDuration;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_16000;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_24000;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_32000;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_44100;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_48000;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_8000;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE;
import static android.bluetooth.BluetoothLeAudioCodecConfig.SampleRate;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -24,8 +36,6 @@ import android.bluetooth.BluetoothUtils.TypeValueEntry;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -46,125 +56,34 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
    private static final int OCTETS_PER_FRAME_TYPE = 0x04;

    private final long mAudioLocation;
    private final @ConfigSamplingFrequency int mSamplingFrequency;
    private final @ConfigFrameDuration int mFrameDuration;
    private final @SampleRate int mSampleRate;
    private final @FrameDuration int mFrameDuration;
    private final int mOctetsPerFrame;
    private final byte[] mRawMetadata;

    /**
     * Audio codec sampling frequency.
     * Defined in the Bluetooth Assigned Numbers, Generic Audio,
     * Sampling_Frequencies table
     * Note: For broadcast, only part of it is being used.
     *
     * @hide
     */
    @IntDef(prefix = "CONFIG_SAMPLING_FREQUENCY_",
            value = {CONFIG_SAMPLING_FREQUENCY_UNKNOWN, CONFIG_SAMPLING_FREQUENCY_8000,
                    CONFIG_SAMPLING_FREQUENCY_16000, CONFIG_SAMPLING_FREQUENCY_24000,
                    CONFIG_SAMPLING_FREQUENCY_32000, CONFIG_SAMPLING_FREQUENCY_44100,
                    CONFIG_SAMPLING_FREQUENCY_48000})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ConfigSamplingFrequency {}

    /**
     * Codec sampling frequency 0 Hz. Default value used for codec sampling frequency.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_SAMPLING_FREQUENCY_UNKNOWN = 0;

    /**
     * Codec Config sampling frequency 8000 Hz.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_SAMPLING_FREQUENCY_8000 = 0x01;

    /**
     * Codec Config sampling frequency 16000 Hz.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_SAMPLING_FREQUENCY_16000 = 0x03;

    /**
     * Codec Config sampling frequency 24000 Hz.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_SAMPLING_FREQUENCY_24000 = 0x05;

    /**
     * Codec Config sampling frequency 32000 Hz.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_SAMPLING_FREQUENCY_32000 = 0x06;

    /**
     * Codec Config sampling frequency 44100 Hz.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_SAMPLING_FREQUENCY_44100 = 0x07;

    /**
     * Codec Config sampling frequency 48000 Hz.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_SAMPLING_FREQUENCY_48000 = 0x08;

    /**
     * Audio codec config frame duration.
     * Defined in the Bluetooth Assigned Numbers, Generic Audio,
     * Frame_Durations table
     *
     * @hide
     */
    @IntDef(prefix = "CONFIG_FRAME_DURATION_",
            value = {CONFIG_FRAME_DURATION_UNKNOWN,
                    CONFIG_FRAME_DURATION_7500, CONFIG_FRAME_DURATION_10000})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ConfigFrameDuration {}

    /**
     * Codec Config frame duration invalid default value.
     *
     * @hide
     */
    @SystemApi
    public static final int CONFIG_FRAME_DURATION_UNKNOWN = -1;

    /**
     * Codec Config frame duration 7500 us.
     *
     * @hide
     * Audio codec sampling frequency from metadata.
     */
    @SystemApi
    public static final int CONFIG_FRAME_DURATION_7500 = 0x00;
    private static final int CONFIG_SAMPLING_FREQUENCY_UNKNOWN = 0;
    private static final int CONFIG_SAMPLING_FREQUENCY_8000 = 0x01;
    private static final int CONFIG_SAMPLING_FREQUENCY_16000 = 0x03;
    private static final int CONFIG_SAMPLING_FREQUENCY_24000 = 0x05;
    private static final int CONFIG_SAMPLING_FREQUENCY_32000 = 0x06;
    private static final int CONFIG_SAMPLING_FREQUENCY_44100 = 0x07;
    private static final int CONFIG_SAMPLING_FREQUENCY_48000 = 0x08;

    /**
     * Codec Config frame duration 10000 us.
     *
     * @hide
     * Audio codec config frame duration from metadata.
     */
    @SystemApi
    public static final int CONFIG_FRAME_DURATION_10000 = 0x01;
    private static final int CONFIG_FRAME_DURATION_UNKNOWN = -1;
    private static final int CONFIG_FRAME_DURATION_7500 = 0x00;
    private static final int CONFIG_FRAME_DURATION_10000 = 0x01;

    private BluetoothLeAudioCodecConfigMetadata(long audioLocation,
            @ConfigSamplingFrequency int samplingFrequency, @ConfigFrameDuration int frameDuration,
            @SampleRate int sampleRate, @FrameDuration int frameDuration,
            int octetsPerFrame, byte[] rawMetadata) {
        mAudioLocation = audioLocation;
        mSamplingFrequency = samplingFrequency;
        mSampleRate = sampleRate;
        mFrameDuration = frameDuration;
        mOctetsPerFrame = octetsPerFrame;
        mRawMetadata = rawMetadata;
@@ -175,7 +94,7 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
        if (o != null && o instanceof BluetoothLeAudioCodecConfigMetadata) {
            final BluetoothLeAudioCodecConfigMetadata oth = (BluetoothLeAudioCodecConfigMetadata) o;
            return mAudioLocation == oth.getAudioLocation()
                    && mSamplingFrequency == oth.getSamplingFrequency()
                    && mSampleRate == oth.getSampleRate()
                    && mFrameDuration == oth.getFrameDuration()
                    && mOctetsPerFrame == oth.getOctetsPerFrame()
                    && Arrays.equals(mRawMetadata, oth.getRawMetadata());
@@ -185,7 +104,7 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {

    @Override
    public int hashCode() {
        return Objects.hash(mAudioLocation, mSamplingFrequency, mFrameDuration,
        return Objects.hash(mAudioLocation, mSampleRate, mFrameDuration,
                mOctetsPerFrame, Arrays.hashCode(mRawMetadata));
    }

@@ -202,30 +121,36 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
    }

    /**
     * Get the audio sampling frequency information as defined in the Generic Audio section of
     * Bluetooth Assigned numbers.
     * Get the audio sample rate information as defined in the Generic Audio section of
     * Bluetooth Assigned numbers 6.12.4.1 Supported_Sampling_Frequencies.
     *
     * Internally this is converted from Sampling_Frequency values as defined in
     * 6.12.5.1
     *
     * @return configured sampling frequency from meta data,
     * {@link BluetoothLeAudioCodecConfigMetadata#CONFIG_SAMPLING_FREQUENCY_UNKNOWN}
     * @return configured sample rate from meta data,
     * {@link BluetoothLeAudioCodecConfig#SAMPLE_RATE_NONE}
     * if this metadata does not exist
     * @hide
     */
    @SystemApi
    public @ConfigSamplingFrequency int getSamplingFrequency() {
        return mSamplingFrequency;
    public @SampleRate int getSampleRate() {
        return mSampleRate;
    }

    /**
     * Get the audio frame duration information as defined in the Generic Audio section of
     * Bluetooth Assigned numbers.
     * Bluetooth Assigned numbers 6.12.5.2 Frame_Duration.
     *
     * Internally this is converted from Frame_Durations values as defined in
     * 6.12.4.2
     *
     * @return configured frame duration from meta data,
     * {@link BluetoothLeAudioCodecConfigMetadata#CONFIG_FRAME_DURATION_UNKNOWN}
     * {@link BluetoothLeAudioCodecConfig#FRAME_DURATION_NONE}
     * if this metadata does not exist
     * @hide
     */
    @SystemApi
    public @ConfigFrameDuration int getFrameDuration() {
    public @FrameDuration int getFrameDuration() {
        return mFrameDuration;
    }

@@ -279,7 +204,7 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
        } else {
            out.writeInt(-1);
        }
        out.writeInt(mSamplingFrequency);
        out.writeInt(mSampleRate);
        out.writeInt(mFrameDuration);
        out.writeInt(mOctetsPerFrame);
    }
@@ -302,10 +227,10 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
            } else {
                rawMetadata = new byte[0];
            }
            int samplingFrequency = in.readInt();
            int sampleRate = in.readInt();
            int frameDuration = in.readInt();
            int octetsPerFrame = in.readInt();
            return new BluetoothLeAudioCodecConfigMetadata(audioLocation, samplingFrequency,
            return new BluetoothLeAudioCodecConfigMetadata(audioLocation, sampleRate,
                    frameDuration, octetsPerFrame, rawMetadata);
        }

@@ -340,10 +265,8 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
                    + rawBytes.length);
        }
        long audioLocation = 0;
        int samplingFrequency =
                BluetoothLeAudioCodecConfigMetadata.CONFIG_SAMPLING_FREQUENCY_UNKNOWN;
        int frameDuration =
                BluetoothLeAudioCodecConfigMetadata.CONFIG_FRAME_DURATION_UNKNOWN;
        int samplingFrequency = CONFIG_SAMPLING_FREQUENCY_UNKNOWN;
        int frameDuration = CONFIG_FRAME_DURATION_UNKNOWN;
        int octetsPerFrame = 0;
        for (TypeValueEntry entry : entries) {
            if (entry.getType() == AUDIO_CHANNEL_LOCATION_TYPE) {
@@ -353,11 +276,11 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
                        | ((bytes[2] & 0xFF) << 16) | ((long) (bytes[3] & 0xFF) << 24);
            } else if (entry.getType() == SAMPLING_FREQUENCY_TYPE) {
                byte[] bytes = entry.getValue();
                // Get one byte for sampling frequency
                // Get one byte for sampling frequency in value
                samplingFrequency = (int) (bytes[0] & 0xFF);
            } else if (entry.getType() == FRAME_DURATION_TYPE) {
                byte[] bytes = entry.getValue();
                // Get one byte for frame duration
                // Get one byte for frame duration in value
                frameDuration = (int) (bytes[0] & 0xFF);
            } else if (entry.getType() == OCTETS_PER_FRAME_TYPE) {
                byte[] bytes = entry.getValue();
@@ -365,8 +288,10 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
                octetsPerFrame = ((bytes[0] & 0xFF) <<  0) | ((int) (bytes[1] & 0xFF) <<  8);
            }
        }
        return new BluetoothLeAudioCodecConfigMetadata(audioLocation, samplingFrequency,
                frameDuration, octetsPerFrame, rawBytes);
        return new BluetoothLeAudioCodecConfigMetadata(audioLocation,
                convertToSampleRateBitset(samplingFrequency),
                convertToFrameDurationBitset(frameDuration),
                octetsPerFrame, rawBytes);
    }

    /**
@@ -376,10 +301,8 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
    @SystemApi
    public static final class Builder {
        private long mAudioLocation = 0;
        private int mSamplingFrequency =
                BluetoothLeAudioCodecConfigMetadata.CONFIG_SAMPLING_FREQUENCY_UNKNOWN;
        private int mFrameDuration =
                BluetoothLeAudioCodecConfigMetadata.CONFIG_FRAME_DURATION_UNKNOWN;
        private int mSampleRate = SAMPLE_RATE_NONE;
        private int mFrameDuration = FRAME_DURATION_NONE;
        private int mOctetsPerFrame = 0;
        private byte[] mRawMetadata = null;

@@ -399,7 +322,7 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
        @SystemApi
        public Builder(@NonNull BluetoothLeAudioCodecConfigMetadata original) {
            mAudioLocation = original.getAudioLocation();
            mSamplingFrequency = original.getSamplingFrequency();
            mSampleRate = original.getSampleRate();
            mFrameDuration = original.getFrameDuration();
            mOctetsPerFrame = original.getOctetsPerFrame();
            mRawMetadata = original.getRawMetadata();
@@ -421,34 +344,40 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
        }

        /**
         * Set the audio sampling frequency information as defined in the Generic Audio section of
         * Bluetooth Assigned numbers.
         * Set the audio sample rate information as defined in the Generic Audio section of
         * Bluetooth Assigned 6.12.4.1 Supported_Sampling_Frequencies.
         *
         * @param samplingFrequency configured sampling frequency in meta data
         * Internally this will be converted to Sampling_Frequency values as defined in
         * 6.12.5.1
         *
         * @param sampleRate configured sample rate in meta data
         * @return this builder
         * @throws IllegalArgumentException if sampling frequency is invalid value
         * @throws IllegalArgumentException if sample rate is invalid value
         * @hide
         */
        @SystemApi
        @NonNull
        public Builder setSamplingFrequency(@ConfigSamplingFrequency int samplingFrequency) {
            if (samplingFrequency != CONFIG_SAMPLING_FREQUENCY_UNKNOWN
                    && samplingFrequency != CONFIG_SAMPLING_FREQUENCY_8000
                    && samplingFrequency != CONFIG_SAMPLING_FREQUENCY_16000
                    && samplingFrequency != CONFIG_SAMPLING_FREQUENCY_24000
                    && samplingFrequency != CONFIG_SAMPLING_FREQUENCY_32000
                    && samplingFrequency != CONFIG_SAMPLING_FREQUENCY_44100
                    && samplingFrequency != CONFIG_SAMPLING_FREQUENCY_48000) {
                throw new IllegalArgumentException("Invalid samplingFrequency "
                        + samplingFrequency);
            }
            mSamplingFrequency = samplingFrequency;
        public Builder setSampleRate(@SampleRate int sampleRate) {
            if (sampleRate != SAMPLE_RATE_NONE
                    && sampleRate != SAMPLE_RATE_8000
                    && sampleRate != SAMPLE_RATE_16000
                    && sampleRate != SAMPLE_RATE_24000
                    && sampleRate != SAMPLE_RATE_32000
                    && sampleRate != SAMPLE_RATE_44100
                    && sampleRate != SAMPLE_RATE_48000) {
                throw new IllegalArgumentException("Invalid sample rate "
                        + sampleRate);
            }
            mSampleRate = sampleRate;
            return this;
        }

        /**
         * Set the audio frame duration information as defined in the Generic Audio section of
         * Bluetooth Assigned numbers.
         * Bluetooth Assigned numbers 6.12.5.2 Frame_Duration.
         *
         * Internally this will be converted to Frame_Durations values as defined in
         * 6.12.4.2
         *
         * @param frameDuration configured frame duration in meta data
         * @return this builder
@@ -457,11 +386,12 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
         */
        @SystemApi
        @NonNull
        public Builder setFrameDuration(@ConfigFrameDuration int frameDuration) {
            if (frameDuration != CONFIG_FRAME_DURATION_UNKNOWN
                    && frameDuration != CONFIG_FRAME_DURATION_7500
                    && frameDuration != CONFIG_FRAME_DURATION_10000) {
                throw new IllegalArgumentException("Invalid frameDuration " + frameDuration);
        public Builder setFrameDuration(@FrameDuration
                int frameDuration) {
            if (frameDuration != FRAME_DURATION_NONE
                    && frameDuration != FRAME_DURATION_7500
                    && frameDuration != FRAME_DURATION_10000) {
                throw new IllegalArgumentException("Invalid frame duration " + frameDuration);
            }
            mFrameDuration = frameDuration;
            return this;
@@ -504,17 +434,19 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
                            + " passed to Builder's copy constructor");
                }
            }
            if (mSamplingFrequency != CONFIG_SAMPLING_FREQUENCY_UNKNOWN) {
            if (mSampleRate != SAMPLE_RATE_NONE) {
                int samplingFrequency = convertToSamplingFrequencyValue(mSampleRate);
                entries.removeIf(entry -> entry.getType() == SAMPLING_FREQUENCY_TYPE);
                entries.add(new TypeValueEntry(SAMPLING_FREQUENCY_TYPE,
                        ByteBuffer.allocate(1)
                        .put((byte) (mSamplingFrequency & 0xFF)).array()));
                        .put((byte) (samplingFrequency & 0xFF)).array()));
            }
            if (mFrameDuration != CONFIG_FRAME_DURATION_UNKNOWN) {
            if (mFrameDuration != FRAME_DURATION_NONE) {
                int frameDuration = convertToFrameDurationValue(mFrameDuration);
                entries.removeIf(entry -> entry.getType() == FRAME_DURATION_TYPE);
                entries.add(new TypeValueEntry(FRAME_DURATION_TYPE,
                        ByteBuffer.allocate(1)
                        .put((byte) (mFrameDuration & 0xFF)).array()));
                        .put((byte) (frameDuration & 0xFF)).array()));
            }
            if (mAudioLocation != -1) {
                entries.removeIf(entry -> entry.getType() == AUDIO_CHANNEL_LOCATION_TYPE);
@@ -532,8 +464,68 @@ public final class BluetoothLeAudioCodecConfigMetadata implements Parcelable {
            if (rawBytes == null) {
                throw new IllegalArgumentException("Failed to serialize entries to bytes");
            }
            return new BluetoothLeAudioCodecConfigMetadata(mAudioLocation, mSamplingFrequency,
            return new BluetoothLeAudioCodecConfigMetadata(mAudioLocation, mSampleRate,
                    mFrameDuration, mOctetsPerFrame, rawBytes);
        }
    }

    private static int convertToSampleRateBitset(int samplingFrequencyValue) {
        switch (samplingFrequencyValue) {
            case CONFIG_SAMPLING_FREQUENCY_8000:
                return SAMPLE_RATE_8000;
            case CONFIG_SAMPLING_FREQUENCY_16000:
                return SAMPLE_RATE_16000;
            case CONFIG_SAMPLING_FREQUENCY_24000:
                return SAMPLE_RATE_24000;
            case CONFIG_SAMPLING_FREQUENCY_32000:
                return SAMPLE_RATE_32000;
            case CONFIG_SAMPLING_FREQUENCY_44100:
                return SAMPLE_RATE_44100;
            case CONFIG_SAMPLING_FREQUENCY_48000:
                return SAMPLE_RATE_48000;
            default:
                return SAMPLE_RATE_NONE;
        }
    }

    private static int convertToSamplingFrequencyValue(int sampleRateBitSet) {
        switch (sampleRateBitSet) {
            case SAMPLE_RATE_8000:
                return CONFIG_SAMPLING_FREQUENCY_8000;
            case SAMPLE_RATE_16000:
                return CONFIG_SAMPLING_FREQUENCY_16000;
            case SAMPLE_RATE_24000:
                return CONFIG_SAMPLING_FREQUENCY_24000;
            case SAMPLE_RATE_32000:
                return CONFIG_SAMPLING_FREQUENCY_32000;
            case SAMPLE_RATE_44100:
                return CONFIG_SAMPLING_FREQUENCY_44100;
            case SAMPLE_RATE_48000:
                return CONFIG_SAMPLING_FREQUENCY_48000;
            default:
                return CONFIG_SAMPLING_FREQUENCY_UNKNOWN;
        }
    }

    private static int convertToFrameDurationBitset(int frameDurationValue) {
        switch (frameDurationValue) {
            case CONFIG_FRAME_DURATION_7500:
                return FRAME_DURATION_7500;
            case CONFIG_FRAME_DURATION_10000:
                return FRAME_DURATION_10000;
            default:
                return FRAME_DURATION_NONE;
        }
    }

    private static int convertToFrameDurationValue(int frameDurationBitset) {
        switch (frameDurationBitset) {
            case FRAME_DURATION_7500:
                return CONFIG_FRAME_DURATION_7500;
            case FRAME_DURATION_10000:
                return CONFIG_FRAME_DURATION_10000;
            default:
                return CONFIG_FRAME_DURATION_UNKNOWN;
        }
    }
}