Bluetooth: Stream: Add functions to parse codec parameters

This is the opesite of the macros to build codec configurations.
As some information was not up-to-date with the adopted
specification this change also includes alignment of the assigned
numbers in the Generic Audio section.
The codec config macros currently in lc3.h have moved from LC3
codec config parameters in the older specification to generic
codec configuration parameters in the adbpted specification.
This is why these additions have been made in the audio.h API
file rather in lc3.h. It is the expectation that lc3.h will be
merged into audio .h at some point.

Signed-off-by: Casper Bonde <casper_bonde@bose.com>
This commit is contained in:
Casper Bonde 2022-03-29 13:58:50 +02:00 committed by Carles Cufí
commit 4d6b0ee47d
5 changed files with 432 additions and 62 deletions

View file

@ -8,3 +8,7 @@ API Reference
************* *************
.. doxygengroup:: bt_audio .. doxygengroup:: bt_audio
.. doxygengroup:: bt_audio_client
.. doxygengroup:: bt_audio_server
.. doxygengroup:: bt_audio_broadcast
.. doxygengroup:: bt_audio_codec_cfg

View file

@ -119,7 +119,7 @@ extern "C" {
* Emergency alerts as, for example, with fire alarms or other urgent alerts. * Emergency alerts as, for example, with fire alarms or other urgent alerts.
*/ */
#define BT_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM BIT(11) #define BT_AUDIO_CONTEXT_TYPE_EMERGENCY_ALARM BIT(11)
/* @def BT_AUDIO_CONTEXT_TYPE_ANY /** @def BT_AUDIO_CONTEXT_TYPE_ANY
* *
* Any known context. * Any known context.
*/ */
@ -200,15 +200,26 @@ struct bt_codec_data {
.meta = _meta, \ .meta = _meta, \
} }
/* TODO: Remove base once LTV types are defined, are these specific to LC3? */
#define BT_CODEC_META_BASE 0x01
#define BT_CODEC_META_PREFER_CONTEXT (BT_CODEC_META_BASE) /** @brief Meta data type ids used for LTV encoded metadata.
#define BT_CODEC_META_CONTEXT (BT_CODEC_META_BASE + 1)
/** Location values for BT Audio.
* *
* These values are defined by the Generic Audio Assigned Numbers * These values are defined by the Generic Audio Assigned Numbers, bluetooth.com
*/
enum bt_audio_meta_type {
BT_CODEC_META_PREFER_CONTEXT = 0x01,
BT_CODEC_META_CONTEXT = 0x02,
BT_CODEC_META_PROGRAM_INFO = 0x03,
BT_CODEC_META_LANGUAGE = 0x04,
BT_CODEC_META_CCID_LIST = 0x05,
BT_CODEC_META_PARENTAL_RATING = 0x06,
BT_CODEC_META_PROGRAM_INFO_URI = 0x07,
BT_CODEC_META_EXTENDED_METADATA = 0xFE,
BT_CODEC_META_VENDOR_SPECIFIC = 0xFF,
};
/** @brief Location values for BT Audio.
*
* These values are defined by the Generic Audio Assigned Numbers, bluetooth.com
*/ */
enum bt_audio_location { enum bt_audio_location {
BT_AUDIO_LOCATION_FRONT_LEFT = BIT(0), BT_AUDIO_LOCATION_FRONT_LEFT = BIT(0),
@ -1293,6 +1304,11 @@ struct bt_audio_stream_ops {
*/ */
void bt_audio_stream_cb_register(struct bt_audio_stream *stream, void bt_audio_stream_cb_register(struct bt_audio_stream *stream,
struct bt_audio_stream_ops *ops); struct bt_audio_stream_ops *ops);
/**
* @defgroup bt_audio_server Audio Server APIs
* @ingroup bt_audio
* @{
*/
/** @brief Register unicast server callbacks. /** @brief Register unicast server callbacks.
* *
@ -1324,6 +1340,8 @@ int bt_audio_unicast_server_unregister_cb(const struct bt_audio_unicast_server_c
*/ */
int bt_audio_unicast_server_location_changed(enum bt_audio_pac_type type); int bt_audio_unicast_server_location_changed(enum bt_audio_pac_type type);
/** @} */ /* End of group bt_audio_server */
/** /**
* @defgroup bt_audio_client Audio Client APIs * @defgroup bt_audio_client Audio Client APIs
* @ingroup bt_audio * @ingroup bt_audio
@ -1590,6 +1608,15 @@ int bt_audio_unicast_group_remove_streams(struct bt_audio_unicast_group *unicast
*/ */
int bt_audio_unicast_group_delete(struct bt_audio_unicast_group *unicast_group); int bt_audio_unicast_group_delete(struct bt_audio_unicast_group *unicast_group);
/** @} */ /* End of group bt_audio_client */
/**
* @brief Audio Broadcast APIs
* @defgroup bt_audio_broadcast Audio Broadcast APIs
* @{
*/
/** @brief Create audio broadcast source. /** @brief Create audio broadcast source.
* *
* Create a new audio broadcast source with one or more audio streams. * Create a new audio broadcast source with one or more audio streams.
@ -1745,14 +1772,134 @@ int bt_audio_broadcast_sink_stop(struct bt_audio_broadcast_sink *sink);
*/ */
int bt_audio_broadcast_sink_delete(struct bt_audio_broadcast_sink *sink); int bt_audio_broadcast_sink_delete(struct bt_audio_broadcast_sink *sink);
/** @} */ /** @} */ /* End of bt_audio_broadcast */
/**
* @brief Audio codec Config APIs
* @defgroup bt_audio_codec_cfg Codec config parsing APIs
*
* Functions to parse codec config data when formatted as LTV wrapped into @ref bt_codec.
*
* @{
*/
/**
* @brief Codec parser error codes for @ref bt_audio_codec_cfg.
*/
enum bt_audio_codec_parse_err {
/** @brief The requested type is not present in the data set. */
BT_AUDIO_CODEC_PARSE_ERR_SUCCESS = 0,
/** @brief The requested type is not present in the data set. */
BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND = -1,
/** @brief The value found is invalid. */
BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND = -2,
/** @brief The parameters specified to the function call are not valid. */
BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM = -3,
};
/**@brief Extract the frequency from a codec configuration.
*
* @param codec The codec configuration to extract data from.
*
* @return The frequency in Hz if found else a negative value of type
* @ref bt_audio_codec_parse_err.
*/
int bt_codec_cfg_get_freq(const struct bt_codec *codec);
/** @brief Extract frame duration from BT codec config
*
* @param codec The codec configuration to extract data from.
*
* @return Frame duration in microseconds if value is found else a negative value
* of type @ref bt_audio_codec_parse_err.
*/
int bt_codec_cfg_get_frame_duration_us(const struct bt_codec *codec);
/** @brief Extract channel allocation from BT codec config
*
* The value returned is a bit field representing one or more audio locations as
* specified by @ref bt_audio_location
* Shall match one or more of the bits set in BT_PAC_SNK_LOC/BT_PAC_SRC_LOC.
*
* Up to the configured @ref BT_CODEC_LC3_CHAN_COUNT number of channels can be present.
*
* @param codec The codec configuration to extract data from.
* @param chan_allocation Pointer to the variable to store the extracted value in.
*
* @return BT_AUDIO_CODEC_PARSE_SUCCESS if value is found and stored in the pointer provided
* else a negative value of type @ref bt_audio_codec_parse_err.
*/
int bt_codec_cfg_get_chan_allocation_val(const struct bt_codec *codec, uint32_t *chan_allocation);
/** @brief Extract frame size in octets from BT codec config
*
* The overall SDU size will be octets_per_frame * blocks_per_sdu.
*
* The Bluetooth specificationa are not clear about this value - it does not state that
* the codec shall use this SDU size only. A codec like LC3 supports variable bit-rate
* (per SDU) hence it might be allowed for an encoder to reduce the frame size below this
* value.
* Hence it is recommended to use the received SDU size and divide by
* blocks_per_sdu rather than relying on this octets_per_sdu value to be fixed.
*
* @param codec The codec configuration to extract data from.
*
* @return Frame length in octets if value is found else a negative value
* of type @ref bt_audio_codec_parse_err.
*/
int bt_codec_cfg_get_octets_per_frame(const struct bt_codec *codec);
/** @brief Extract number of audio frame blockss in each SDU from BT codec config
*
* The overall SDU size will be octets_per_frame * frame_blocks_per_sdu * number-of-channels.
*
* If this value is not present a default value of 1 shall be used.
*
* A frame block is one or more frames that represents data for the same period of time but
* for different channels. If the stream have two audio channels and this value is two
* there will be four frames in the SDU.
*
* @param codec The codec configuration to extract data from.
* @param fallback_to_default If true this function will return the default value of 1
* if the type is not found. In this case the function will only fail if a NULL
* pointer is provided.
*
* @return The count of codec frames in each SDU if value is found else a negative value
* of type @ref bt_audio_codec_parse_err - unless when \p fallback_to_default is true
* then the value 1 is returned if frames per sdu is not found.
*/
int bt_codec_cfg_get_frame_blocks_per_sdu(const struct bt_codec *codec, bool fallback_to_default);
/** @brief Lookup a specific value based on type
*
* Depending on context bt_codec will be either codec capabilities, codec configuration or
* meta data.
*
* Typically types used are:
* @ref bt_codec_capability_type
* @ref bt_codec_config_type
* @ref bt_audio_meta_type
*
* @param codec The codec data to search in.
* @param type The type id to look for
* @param data Pointer to the data-pointer to update when item is found
* @return True if the type is found, false otherwise.
*/
bool bt_codec_get_val(const struct bt_codec *codec,
uint8_t type,
const struct bt_codec_data **data);
/** @} */ /* End of bt_audio_codec_cfg */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/** /** @} */ /* end of bt_audio */
* @}
*/
#endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_H_ */ #endif /* ZEPHYR_INCLUDE_BLUETOOTH_AUDIO_H_ */

View file

@ -27,13 +27,42 @@ extern "C" {
*/ */
#define BT_CODEC_LC3_ID 0x06 #define BT_CODEC_LC3_ID 0x06
/* TODO: Remove base once LTV types are defined */ /**
#define BT_CODEC_LC3_CAP_BASE 0x01 * @brief Codec capability type id's
*
/** @def BT_CODEC_LC3_FREQ * Used to build and parse codec capabilities as specified in the PAC specification.
* @brief LC3 sample frequency capability type * Source is assigned numbers for Generic Audio, bluetooth.com.
*
* Even though they are in-fixed with LC3 they can be used for other codec types as well.
*/ */
#define BT_CODEC_LC3_FREQ (BT_CODEC_LC3_CAP_BASE) enum bt_codec_capability_type {
/** @def BT_CODEC_LC3_FREQ
* @brief LC3 sample frequency capability type
*/
BT_CODEC_LC3_FREQ = 0x01,
/** @def BT_CODEC_LC3_DURATION
* @brief LC3 frame duration capability type
*/
BT_CODEC_LC3_DURATION = 0x02,
/** @def BT_CODEC_LC3_CHAN_COUNT
* @brief LC3 channel count capability type
*/
BT_CODEC_LC3_CHAN_COUNT = 0x03,
/** @def BT_CODEC_LC3_FRAME_LEN
* @brief LC3 frame length capability type
*/
BT_CODEC_LC3_FRAME_LEN = 0x04,
/** @def BT_CODEC_LC3_FRAME_COUNT
* @brief Max codec frame count per SDU capability type
*/
BT_CODEC_LC3_FRAME_COUNT = 0x05,
};
/** @def BT_CODEC_LC3_FREQ_8KHZ /** @def BT_CODEC_LC3_FREQ_8KHZ
* @brief LC3 8 Khz frequency capability * @brief LC3 8 Khz frequency capability
*/ */
@ -76,10 +105,6 @@ extern "C" {
BT_CODEC_LC3_FREQ_44KHZ | \ BT_CODEC_LC3_FREQ_44KHZ | \
BT_CODEC_LC3_FREQ_48KHZ) BT_CODEC_LC3_FREQ_48KHZ)
/** @def BT_CODEC_LC3_DURATION
* @brief LC3 frame duration capability type
*/
#define BT_CODEC_LC3_DURATION (BT_CODEC_LC3_CAP_BASE + 1)
/** @def BT_CODEC_LC3_DURATION_7_5 /** @def BT_CODEC_LC3_DURATION_7_5
* @brief LC3 7.5 msec frame duration capability * @brief LC3 7.5 msec frame duration capability
*/ */
@ -103,74 +128,101 @@ extern "C" {
#define BT_CODEC_LC3_DURATION_PREFER_10 BIT(5) #define BT_CODEC_LC3_DURATION_PREFER_10 BIT(5)
/** @def BT_CODEC_LC3_CHAN_COUNT
* @brief LC3 channel count capability type
*/
#define BT_CODEC_LC3_CHAN_COUNT (BT_CODEC_LC3_CAP_BASE + 2)
/** @def BT_CODEC_LC3_CHAN_COUNT_SUPPORT /** @def BT_CODEC_LC3_CHAN_COUNT_SUPPORT
* @brief LC3 channel count support capability * @brief LC3 channel count support capability
* OR multiple supported counts together from 1 to 8
* Example to support 1 and 3 channels:
* BT_CODEC_LC3_CHAN_COUNT_SUPPORT(1) | BT_CODEC_LC3_CHAN_COUNT_SUPPORT(3)
*/ */
#define BT_CODEC_LC3_CHAN_COUNT_SUPPORT BIT(0) #define BT_CODEC_LC3_CHAN_COUNT_SUPPORT(_count) ((uint8_t)BIT((_count) - 1))
/** @def BT_CODEC_LC3_FRAME_LEN
* @brief LC3 frame length capability type
*/
#define BT_CODEC_LC3_FRAME_LEN (BT_CODEC_LC3_CAP_BASE + 3)
/** @def BT_CODEC_LC3_FRAME_COUNT
* @brief LC3 frame count capability type
*/
#define BT_CODEC_LC3_FRAME_COUNT (BT_CODEC_LC3_CAP_BASE + 4)
/* TODO: Remove base once LTV types are defined */
#define BT_CODEC_LC3_CONFIG_BASE 0x01
struct bt_codec_lc3_frame_len { struct bt_codec_lc3_frame_len {
uint16_t min; uint16_t min;
uint16_t max; uint16_t max;
}; };
/** @def BT_CODEC_CONFIG_LC3_FREQ
* @brief LC3 Sample Frequency configuration type /**
* @brief Codec configuration type IDs
*
* Used to build and parse codec configurations as specified in the ASCS and BAP specifications.
* Source is assigned numbers for Generic Audio, bluetooth.com.
*
* Even though they are in-fixed with LC3 they can be used for other codec types as well.
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ (BT_CODEC_LC3_CONFIG_BASE) enum bt_codec_config_type {
/** @brief LC3 Sample Frequency configuration type. */
BT_CODEC_CONFIG_LC3_FREQ = 0x01,
/** @brief LC3 Frame Duration configuration type. */
BT_CODEC_CONFIG_LC3_DURATION = 0x02,
/** @brief LC3 channel Allocation configuration type. */
BT_CODEC_CONFIG_LC3_CHAN_ALLOC = 0x03,
/** @brief LC3 Frame Length configuration type. */
BT_CODEC_CONFIG_LC3_FRAME_LEN = 0x04,
/** @brief Codec frames = blocks, per SDU configuration type. */
BT_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU = 0x05,
};
/** @def BT_CODEC_CONFIG_LC3_FREQ_8KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_8KHZ
* @brief LC3 8 Khz Sample Frequency configuration * @brief 8 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_8KHZ 0x01 #define BT_CODEC_CONFIG_LC3_FREQ_8KHZ 0x01
/** @def BT_CODEC_CONFIG_LC3_FREQ_11KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_11KHZ
* @brief LC3 11.025 Khz Sample Frequency configuration * @brief 11.025 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_11KHZ 0x02 #define BT_CODEC_CONFIG_LC3_FREQ_11KHZ 0x02
/** @def BT_CODEC_CONFIG_LC3_FREQ_16KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_16KHZ
* @brief LC3 16 Khz Sample Frequency configuration * @brief 16 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_16KHZ 0x03 #define BT_CODEC_CONFIG_LC3_FREQ_16KHZ 0x03
/** @def BT_CODEC_CONFIG_LC3_FREQ_22KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_22KHZ
* @brief LC3 22.05 Khz Sample Frequency configuration * @brief 22.05 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_22KHZ 0x04 #define BT_CODEC_CONFIG_LC3_FREQ_22KHZ 0x04
/** @def BT_CODEC_CONFIG_LC3_FREQ_24KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_24KHZ
* @brief LC3 24 Khz Sample Frequency configuration * @brief 24 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_24KHZ 0x05 #define BT_CODEC_CONFIG_LC3_FREQ_24KHZ 0x05
/** @def BT_CODEC_CONFIG_LC3_FREQ_32KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_32KHZ
* @brief LC3 32 Khz Sample Frequency configuration * @brief 32 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_32KHZ 0x06 #define BT_CODEC_CONFIG_LC3_FREQ_32KHZ 0x06
/** @def BT_CODEC_CONFIG_LC3_FREQ_44KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_44KHZ
* @brief LC3 44.1 Khz Sample Frequency configuration * @brief 44.1 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_44KHZ 0x07 #define BT_CODEC_CONFIG_LC3_FREQ_44KHZ 0x07
/** @def BT_CODEC_CONFIG_LC3_FREQ_48KHZ /** @def BT_CODEC_CONFIG_LC3_FREQ_48KHZ
* @brief LC3 48 Khz Sample Frequency configuration * @brief 48 Khz codec Sample Frequency configuration
*/ */
#define BT_CODEC_CONFIG_LC3_FREQ_48KHZ 0x08 #define BT_CODEC_CONFIG_LC3_FREQ_48KHZ 0x08
/** @def BT_CODEC_CONFIG_LC3_FREQ_88KHZ
/** @def BT_CODEC_CONFIG_LC3_DURATION * @brief 88.2 Khz codec Sample Frequency configuration
* @brief LC3 Frame Duration configuration type
*/ */
#define BT_CODEC_CONFIG_LC3_DURATION (BT_CODEC_LC3_CONFIG_BASE + 1) #define BT_CODEC_CONFIG_LC3_FREQ_88KHZ 0x09
/** @def BT_CODEC_CONFIG_LC3_FREQ_96KHZ
* @brief 96 Khz codec Sample Frequency configuration
*/
#define BT_CODEC_CONFIG_LC3_FREQ_96KHZ 0x0a
/** @def BT_CODEC_CONFIG_LC3_FREQ_176KHZ
* @brief 176.4 Khz codec Sample Frequency configuration
*/
#define BT_CODEC_CONFIG_LC3_FREQ_176KHZ 0x0b
/** @def BT_CODEC_CONFIG_LC3_FREQ_192KHZ
* @brief 192 Khz codec Sample Frequency configuration
*/
#define BT_CODEC_CONFIG_LC3_FREQ_192KHZ 0x0c
/** @def BT_CODEC_CONFIG_LC3_FREQ_384KHZ
* @brief 384 Khz codec Sample Frequency configuration
*/
#define BT_CODEC_CONFIG_LC3_FREQ_384KHZ 0x0d
/** @def BT_CODEC_CONFIG_LC3_DURATION_7_5 /** @def BT_CODEC_CONFIG_LC3_DURATION_7_5
* @brief LC3 7.5 msec Frame Duration configuration * @brief LC3 7.5 msec Frame Duration configuration
*/ */
@ -180,15 +232,7 @@ struct bt_codec_lc3_frame_len {
*/ */
#define BT_CODEC_CONFIG_LC3_DURATION_10 0x01 #define BT_CODEC_CONFIG_LC3_DURATION_10 0x01
/** @def BT_CODEC_CONFIG_LC3_CHAN_ALLOC
* @brief LC3 channel Allocation configuration type
*/
#define BT_CODEC_CONFIG_LC3_CHAN_ALLOC (BT_CODEC_LC3_CONFIG_BASE + 2)
/** @def BT_CODEC_CONFIG_LC3_FRAME_LEN
* @brief LC3 Frame Length configuration type
*/
#define BT_CODEC_CONFIG_LC3_FRAME_LEN (BT_CODEC_LC3_CONFIG_BASE + 3)
/** @def BT_CODEC_LC3_DATA /** @def BT_CODEC_LC3_DATA
* @brief Helper to declare LC3 codec capability * @brief Helper to declare LC3 codec capability
@ -392,6 +436,9 @@ struct bt_codec_lc3_frame_len {
#define BT_CODEC_LC3_QOS_10_UNFRAMED(_sdu, _rtn, _latency, _pd) \ #define BT_CODEC_LC3_QOS_10_UNFRAMED(_sdu, _rtn, _latency, _pd) \
BT_CODEC_QOS_UNFRAMED(10000u, _sdu, _rtn, _latency, _pd) BT_CODEC_QOS_UNFRAMED(10000u, _sdu, _rtn, _latency, _pd)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -46,7 +46,7 @@ zephyr_library_sources_ifdef(CONFIG_MCTL media_proxy.c)
zephyr_library_sources_ifdef(CONFIG_BT_ASCS ascs.c) zephyr_library_sources_ifdef(CONFIG_BT_ASCS ascs.c)
zephyr_library_sources_ifdef(CONFIG_BT_PACS pacs.c) zephyr_library_sources_ifdef(CONFIG_BT_PACS pacs.c)
zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_STREAM stream.c) zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_STREAM stream.c codec.c)
zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_UNICAST_SERVER unicast_server.c) zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_UNICAST_SERVER unicast_server.c)
zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_CAPABILITY capabilities.c) zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_CAPABILITY capabilities.c)
zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_UNICAST_CLIENT unicast_client.c) zephyr_library_sources_ifdef(CONFIG_BT_AUDIO_UNICAST_CLIENT unicast_client.c)

View file

@ -0,0 +1,172 @@
/*
* Copyright (c) 2022 Bose Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Bluetooth LE-Audio codec LTV parsing
*
* Helper functions to parse codec config data as specified in the Bluetooth assigned numbers for
* Generic Audio.
*/
#include <bluetooth/audio/audio.h>
#include <sys/byteorder.h>
#include <sys/check.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_AUDIO)
#define LOG_MODULE_NAME bt_audio
#include "common/log.h"
bool bt_codec_get_val(const struct bt_codec *codec,
uint8_t type,
const struct bt_codec_data **data)
{
CHECKIF(codec == NULL) {
BT_DBG("codec is NULL");
return false;
}
for (size_t i = 0; i < codec->data_count; i++) {
if (codec->data[i].data.type == type) {
*data = &codec->data[i];
return true;
}
}
return false;
}
int bt_codec_cfg_get_freq(const struct bt_codec *codec)
{
const struct bt_codec_data *element;
CHECKIF(codec == NULL) {
BT_DBG("codec is NULL");
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM;
}
if (bt_codec_get_val(codec, BT_CODEC_CONFIG_LC3_FREQ, &element)) {
switch (element->data.data[0]) {
case BT_CODEC_CONFIG_LC3_FREQ_8KHZ:
return 8000;
case BT_CODEC_CONFIG_LC3_FREQ_11KHZ:
return 11025;
case BT_CODEC_CONFIG_LC3_FREQ_16KHZ:
return 16000;
case BT_CODEC_CONFIG_LC3_FREQ_22KHZ:
return 22050;
case BT_CODEC_CONFIG_LC3_FREQ_24KHZ:
return 24000;
case BT_CODEC_CONFIG_LC3_FREQ_32KHZ:
return 32000;
case BT_CODEC_CONFIG_LC3_FREQ_44KHZ:
return 44100;
case BT_CODEC_CONFIG_LC3_FREQ_48KHZ:
return 48000;
case BT_CODEC_CONFIG_LC3_FREQ_88KHZ:
return 88200;
case BT_CODEC_CONFIG_LC3_FREQ_96KHZ:
return 96000;
case BT_CODEC_CONFIG_LC3_FREQ_176KHZ:
return 176400;
case BT_CODEC_CONFIG_LC3_FREQ_192KHZ:
return 192000;
case BT_CODEC_CONFIG_LC3_FREQ_384KHZ:
return 384000;
default:
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND;
}
}
return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND;
}
int bt_codec_cfg_get_frame_duration_us(const struct bt_codec *codec)
{
const struct bt_codec_data *element;
CHECKIF(codec == NULL) {
BT_DBG("codec is NULL");
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM;
}
if (bt_codec_get_val(codec, BT_CODEC_CONFIG_LC3_DURATION, &element)) {
switch (element->data.data[0]) {
case BT_CODEC_CONFIG_LC3_DURATION_7_5:
return 7500;
case BT_CODEC_CONFIG_LC3_DURATION_10:
return 10000;
default:
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND;
}
}
return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND;
}
int bt_codec_cfg_get_chan_allocation_val(const struct bt_codec *codec,
enum bt_audio_location *chan_allocation)
{
const struct bt_codec_data *element;
CHECKIF(codec == NULL) {
BT_DBG("codec is NULL");
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM;
}
CHECKIF(chan_allocation == NULL) {
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM;
}
*chan_allocation = 0;
if (bt_codec_get_val(codec, BT_CODEC_CONFIG_LC3_CHAN_ALLOC, &element)) {
*chan_allocation = sys_le32_to_cpu(*((uint32_t *)&element->data.data[0]));
return BT_AUDIO_CODEC_PARSE_ERR_SUCCESS;
}
return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND;
}
int bt_codec_cfg_get_octets_per_frame(const struct bt_codec *codec)
{
const struct bt_codec_data *element;
CHECKIF(codec == NULL) {
BT_DBG("codec is NULL");
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM;
}
if (bt_codec_get_val(codec, BT_CODEC_CONFIG_LC3_FRAME_LEN, &element)) {
return sys_le16_to_cpu(*((uint16_t *)&element->data.data[0]));
}
return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND;
}
int bt_codec_cfg_get_frame_blocks_per_sdu(const struct bt_codec *codec, bool fallback_to_default)
{
const struct bt_codec_data *element;
CHECKIF(codec == NULL) {
BT_DBG("codec is NULL");
return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM;
}
if (bt_codec_get_val(codec, BT_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU, &element)) {
return element->data.data[0];
}
if (fallback_to_default) {
return 1;
}
return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND;
}