1 /*
2 * Copyright 2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <zephyr/bluetooth/sbc.h>
9
10 #if defined(CONFIG_LIBSBC)
11
sbc_setup_encoder(struct sbc_encoder * encoder,struct sbc_encoder_init_param * param)12 int sbc_setup_encoder(struct sbc_encoder *encoder, struct sbc_encoder_init_param *param)
13 {
14 SBC_ENC_PARAMS *encoder_params;
15
16 if (encoder == NULL) {
17 return -EINVAL;
18 }
19
20 memset(encoder, 0, sizeof(struct sbc_encoder));
21
22 encoder_params = &encoder->sbc_encoder_params;
23
24 encoder_params->s16ChannelMode = (int16_t)param->ch_mode;
25 encoder_params->s16NumOfSubBands = (int16_t)param->subband;
26 if (!encoder_params->s16NumOfSubBands) {
27 return -EINVAL;
28 }
29 encoder_params->s16NumOfBlocks = (int16_t)param->blk_len;
30 if (!encoder_params->s16NumOfBlocks) {
31 return -EINVAL;
32 }
33 encoder_params->s16AllocationMethod = (int16_t)param->alloc_mthd;
34 encoder_params->s16NumOfChannels = param->ch_num;
35 if (!encoder_params->s16NumOfChannels) {
36 return -EINVAL;
37 }
38
39 switch (param->samp_freq) {
40 case 16000u:
41 encoder_params->s16SamplingFreq = 0;
42 break;
43 case 32000u:
44 encoder_params->s16SamplingFreq = 1;
45 break;
46 case 44100u:
47 encoder_params->s16SamplingFreq = 2;
48 break;
49 case 48000u:
50 encoder_params->s16SamplingFreq = 3;
51 break;
52 default:
53 return -EINVAL;
54 }
55
56 encoder_params->u16BitRate = param->bit_rate;
57
58 SBC_Encoder_Init(encoder_params);
59
60 if (encoder_params->s16BitPool < param->min_bitpool) {
61 /* need to increase the `param->bit_rate` */
62 return -EINVAL;
63 } else if (encoder_params->s16BitPool > param->max_bitpool) {
64 /* need to decrease the `param->bit_rate` */
65 return -EOVERFLOW;
66 }
67
68 return 0;
69 }
70
71 /**
72 * Encode a SBC frame
73 */
sbc_encode(struct sbc_encoder * encoder,const void * in_data,void * out_data)74 uint32_t sbc_encode(struct sbc_encoder *encoder, const void *in_data, void *out_data)
75 {
76 uint32_t ret;
77
78 if ((encoder == NULL) || (in_data == NULL) || (out_data == NULL)) {
79 return 0;
80 }
81
82 ret = SBC_Encode(&encoder->sbc_encoder_params, (int16_t *)in_data, out_data);
83
84 return ret;
85 }
86
sbc_frame_samples(struct sbc_encoder * encoder)87 int sbc_frame_samples(struct sbc_encoder *encoder)
88 {
89 if (encoder == NULL) {
90 return -EINVAL;
91 }
92
93 return encoder->sbc_encoder_params.s16NumOfSubBands *
94 encoder->sbc_encoder_params.s16NumOfBlocks;
95 }
96
sbc_frame_bytes(struct sbc_encoder * encoder)97 int sbc_frame_bytes(struct sbc_encoder *encoder)
98 {
99 if (encoder == NULL) {
100 return -EINVAL;
101 }
102
103 return sbc_frame_samples(encoder) * 2 *
104 (encoder->sbc_encoder_params.s16ChannelMode == SBC_CH_MODE_MONO ? 1 : 2);
105 }
106
sbc_frame_encoded_bytes(struct sbc_encoder * encoder)107 int sbc_frame_encoded_bytes(struct sbc_encoder *encoder)
108 {
109 int size = 4;
110 int channel_num = 2;
111 SBC_ENC_PARAMS *encoder_params;
112
113 if (encoder == NULL) {
114 return -EINVAL;
115 }
116
117 encoder_params = &encoder->sbc_encoder_params;
118
119 if (encoder_params->s16ChannelMode == SBC_CH_MODE_MONO) {
120 channel_num = 1;
121 }
122
123 size += (4 * encoder_params->s16NumOfSubBands * channel_num) / 8;
124 if ((encoder_params->s16ChannelMode == SBC_CH_MODE_MONO) ||
125 (encoder_params->s16ChannelMode == SBC_CH_MODE_DUAL_CHANNEL)) {
126 size += ((encoder_params->s16NumOfBlocks * channel_num *
127 encoder_params->s16BitPool + 7) / 8);
128 } else if (encoder_params->s16ChannelMode == SBC_CH_MODE_STEREO) {
129 size += ((encoder_params->s16NumOfBlocks *
130 encoder_params->s16BitPool + 7) / 8);
131 } else {
132 size += ((encoder_params->s16NumOfSubBands +
133 encoder_params->s16NumOfBlocks *
134 encoder_params->s16BitPool + 7) / 8);
135 }
136
137 return size;
138 }
139
140 /**
141 * Setup decoder
142 */
sbc_setup_decoder(struct sbc_decoder * decoder)143 int sbc_setup_decoder(struct sbc_decoder *decoder)
144 {
145 OI_STATUS status;
146
147 if (decoder == NULL) {
148 return -EINVAL;
149 }
150
151 memset(decoder, 0, sizeof(struct sbc_decoder));
152
153 status = OI_CODEC_SBC_DecoderReset(
154 &decoder->context,
155 &decoder->context_data[0],
156 sizeof(decoder->context_data),
157 2, 2, FALSE);
158 if (!OI_SUCCESS(status)) {
159 return -EIO;
160 }
161
162 return 0;
163 }
164
165 /**
166 * Decode a frame
167 */
sbc_decode(struct sbc_decoder * decoder,const void ** in_data,uint32_t * in_size,void * out_data,uint32_t * out_size)168 int sbc_decode(struct sbc_decoder *decoder, const void **in_data, uint32_t *in_size,
169 void *out_data, uint32_t *out_size)
170 {
171 OI_STATUS status;
172
173 if (decoder == NULL || in_data == NULL || in_size == NULL ||
174 out_data == NULL || out_size == NULL) {
175 return -EINVAL;
176 }
177
178 status = OI_CODEC_SBC_DecodeFrame(&decoder->context,
179 (const OI_BYTE**)in_data,
180 in_size,
181 out_data,
182 out_size);
183 if (!OI_SUCCESS(status)) {
184 return -EIO;
185 } else {
186 return 0;
187 }
188 }
189 #endif
190