1 /*
2 * Copyright 2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <errno.h>
8 #include <zephyr/libsbc/sbc.h>
9
10 #if defined(CONFIG_LIBSBC_ENCODER)
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 #endif
140
141 #if defined(CONFIG_LIBSBC_DECODER)
142 /**
143 * Setup decoder
144 */
sbc_setup_decoder(struct sbc_decoder * decoder)145 int sbc_setup_decoder(struct sbc_decoder *decoder)
146 {
147 OI_STATUS status;
148
149 if (decoder == NULL) {
150 return -EINVAL;
151 }
152
153 memset(decoder, 0, sizeof(struct sbc_decoder));
154
155 status = OI_CODEC_SBC_DecoderReset(
156 &decoder->context,
157 &decoder->context_data[0],
158 sizeof(decoder->context_data),
159 2, 2, FALSE);
160 if (!OI_SUCCESS(status)) {
161 return -EIO;
162 }
163
164 return 0;
165 }
166
167 /**
168 * Decode a frame
169 */
sbc_decode(struct sbc_decoder * decoder,const void ** in_data,uint32_t * in_size,void * out_data,uint32_t * out_size)170 int sbc_decode(struct sbc_decoder *decoder, const void **in_data, uint32_t *in_size,
171 void *out_data, uint32_t *out_size)
172 {
173 OI_STATUS status;
174
175 if (decoder == NULL || in_data == NULL || in_size == NULL ||
176 out_data == NULL || out_size == NULL) {
177 return -EINVAL;
178 }
179
180 status = OI_CODEC_SBC_DecodeFrame(&decoder->context,
181 (const OI_BYTE**)in_data,
182 in_size,
183 out_data,
184 out_size);
185 if (!OI_SUCCESS(status)) {
186 return -EIO;
187 } else {
188 return 0;
189 }
190 }
191 #endif
192