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