1 /*
2  * Copyright 2024 NXP
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <zephyr/sys/atomic.h>
11 #include <zephyr/sys/byteorder.h>
12 #include <zephyr/sys/util.h>
13 #include <zephyr/sys/printk.h>
14 
15 #include <zephyr/bluetooth/classic/a2dp_codec_sbc.h>
16 #include <zephyr/bluetooth/classic/a2dp.h>
17 #include <zephyr/bluetooth/sbc.h>
18 
bt_a2dp_sbc_get_channel_num(struct bt_a2dp_codec_sbc_params * sbc_codec)19 uint8_t bt_a2dp_sbc_get_channel_num(struct bt_a2dp_codec_sbc_params *sbc_codec)
20 {
21 	__ASSERT_NO_MSG(sbc_codec != NULL);
22 
23 	if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_MONO) {
24 		return 1U;
25 	} else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_DUAL) {
26 		return 2U;
27 	} else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_STEREO) {
28 		return 2U;
29 	} else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_JOINT) {
30 		return 2U;
31 	} else {
32 		return 0U;
33 	}
34 }
35 
bt_a2dp_sbc_get_channel_mode(struct bt_a2dp_codec_sbc_params * sbc_codec)36 enum sbc_ch_mode bt_a2dp_sbc_get_channel_mode(struct bt_a2dp_codec_sbc_params *sbc_codec)
37 {
38 	__ASSERT_NO_MSG(sbc_codec != NULL);
39 
40 	if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_MONO) {
41 		return SBC_CH_MODE_MONO;
42 	} else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_DUAL) {
43 		return SBC_CH_MODE_DUAL_CHANNEL;
44 	} else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_STEREO) {
45 		return SBC_CH_MODE_STEREO;
46 	} else if (sbc_codec->config[0] & A2DP_SBC_CH_MODE_JOINT) {
47 		return SBC_CH_MODE_JOINT_STEREO;
48 	} else {
49 		return SBC_CH_MODE_MONO;
50 	}
51 }
52 
bt_a2dp_sbc_get_sampling_frequency(struct bt_a2dp_codec_sbc_params * sbc_codec)53 uint32_t bt_a2dp_sbc_get_sampling_frequency(struct bt_a2dp_codec_sbc_params *sbc_codec)
54 {
55 	__ASSERT_NO_MSG(sbc_codec != NULL);
56 
57 	if (sbc_codec->config[0] & A2DP_SBC_SAMP_FREQ_16000) {
58 		return 16000U;
59 	} else if (sbc_codec->config[0] & A2DP_SBC_SAMP_FREQ_32000) {
60 		return 32000U;
61 	} else if (sbc_codec->config[0] & A2DP_SBC_SAMP_FREQ_44100) {
62 		return 44100U;
63 	} else if (sbc_codec->config[0] & A2DP_SBC_SAMP_FREQ_48000) {
64 		return 48000U;
65 	} else {
66 		return 0U;
67 	}
68 }
69 
bt_a2dp_sbc_get_subband_num(struct bt_a2dp_codec_sbc_params * sbc_codec)70 uint8_t bt_a2dp_sbc_get_subband_num(struct bt_a2dp_codec_sbc_params *sbc_codec)
71 {
72 	__ASSERT_NO_MSG(sbc_codec != NULL);
73 
74 	if (sbc_codec->config[1] & A2DP_SBC_SUBBAND_4) {
75 		return 4U;
76 	} else if (sbc_codec->config[1] & A2DP_SBC_SUBBAND_8) {
77 		return 8U;
78 	} else {
79 		return 0U;
80 	}
81 }
82 
bt_a2dp_sbc_get_block_length(struct bt_a2dp_codec_sbc_params * sbc_codec)83 uint8_t bt_a2dp_sbc_get_block_length(struct bt_a2dp_codec_sbc_params *sbc_codec)
84 {
85 	__ASSERT_NO_MSG(sbc_codec != NULL);
86 
87 	if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_4) {
88 		return 4U;
89 	} else if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_8) {
90 		return 8U;
91 	} else if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_12) {
92 		return 12U;
93 	} else if (sbc_codec->config[1] & A2DP_SBC_BLK_LEN_16) {
94 		return 16U;
95 	} else {
96 		return 0U;
97 	}
98 }
99 
bt_a2dp_sbc_get_allocation_method(struct bt_a2dp_codec_sbc_params * sbc_codec)100 enum sbc_alloc_mthd bt_a2dp_sbc_get_allocation_method(struct bt_a2dp_codec_sbc_params *sbc_codec)
101 {
102 	__ASSERT_NO_MSG(sbc_codec != NULL);
103 
104 	if (sbc_codec->config[1] & A2DP_SBC_ALLOC_MTHD_SNR) {
105 		return SBC_ALLOC_MTHD_SNR;
106 	} else {
107 		return SBC_ALLOC_MTHD_LOUDNESS;
108 	}
109 }
110