/* * Copyright 2024 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include #include #if defined(CONFIG_LIBSBC_ENCODER) int sbc_setup_encoder(struct sbc_encoder *encoder, struct sbc_encoder_init_param *param) { SBC_ENC_PARAMS *encoder_params; if (encoder == NULL) { return -EINVAL; } memset(encoder, 0, sizeof(struct sbc_encoder)); encoder_params = &encoder->sbc_encoder_params; encoder_params->s16ChannelMode = (int16_t)param->ch_mode; encoder_params->s16NumOfSubBands = (int16_t)param->subband; if (!encoder_params->s16NumOfSubBands) { return -EINVAL; } encoder_params->s16NumOfBlocks = (int16_t)param->blk_len; if (!encoder_params->s16NumOfBlocks) { return -EINVAL; } encoder_params->s16AllocationMethod = (int16_t)param->alloc_mthd; encoder_params->s16NumOfChannels = param->ch_num; if (!encoder_params->s16NumOfChannels) { return -EINVAL; } switch (param->samp_freq) { case 16000u: encoder_params->s16SamplingFreq = 0; break; case 32000u: encoder_params->s16SamplingFreq = 1; break; case 44100u: encoder_params->s16SamplingFreq = 2; break; case 48000u: encoder_params->s16SamplingFreq = 3; break; default: return -EINVAL; } encoder_params->u16BitRate = param->bit_rate; SBC_Encoder_Init(encoder_params); if (encoder_params->s16BitPool < param->min_bitpool) { /* need to increase the `param->bit_rate` */ return -EINVAL; } else if (encoder_params->s16BitPool > param->max_bitpool) { /* need to decrease the `param->bit_rate` */ return -EOVERFLOW; } return 0; } /** * Encode a SBC frame */ uint32_t sbc_encode(struct sbc_encoder *encoder, const void *in_data, void *out_data) { uint32_t ret; if ((encoder == NULL) || (in_data == NULL) || (out_data == NULL)) { return 0; } ret = SBC_Encode(&encoder->sbc_encoder_params, (int16_t *)in_data, out_data); return ret; } int sbc_frame_samples(struct sbc_encoder *encoder) { if (encoder == NULL) { return -EINVAL; } return encoder->sbc_encoder_params.s16NumOfSubBands * encoder->sbc_encoder_params.s16NumOfBlocks; } int sbc_frame_bytes(struct sbc_encoder *encoder) { if (encoder == NULL) { return -EINVAL; } return sbc_frame_samples(encoder) * 2 * (encoder->sbc_encoder_params.s16ChannelMode == SBC_CH_MODE_MONO ? 1 : 2); } int sbc_frame_encoded_bytes(struct sbc_encoder *encoder) { int size = 4; int channel_num = 2; SBC_ENC_PARAMS *encoder_params; if (encoder == NULL) { return -EINVAL; } encoder_params = &encoder->sbc_encoder_params; if (encoder_params->s16ChannelMode == SBC_CH_MODE_MONO) { channel_num = 1; } size += (4 * encoder_params->s16NumOfSubBands * channel_num) / 8; if ((encoder_params->s16ChannelMode == SBC_CH_MODE_MONO) || (encoder_params->s16ChannelMode == SBC_CH_MODE_DUAL_CHANNEL)) { size += ((encoder_params->s16NumOfBlocks * channel_num * encoder_params->s16BitPool + 7) / 8); } else if (encoder_params->s16ChannelMode == SBC_CH_MODE_STEREO) { size += ((encoder_params->s16NumOfBlocks * encoder_params->s16BitPool + 7) / 8); } else { size += ((encoder_params->s16NumOfSubBands + encoder_params->s16NumOfBlocks * encoder_params->s16BitPool + 7) / 8); } return size; } #endif #if defined(CONFIG_LIBSBC_DECODER) /** * Setup decoder */ int sbc_setup_decoder(struct sbc_decoder *decoder) { OI_STATUS status; if (decoder == NULL) { return -EINVAL; } memset(decoder, 0, sizeof(struct sbc_decoder)); status = OI_CODEC_SBC_DecoderReset( &decoder->context, &decoder->context_data[0], sizeof(decoder->context_data), 2, 2, FALSE); if (!OI_SUCCESS(status)) { return -EIO; } return 0; } /** * Decode a frame */ int sbc_decode(struct sbc_decoder *decoder, const void **in_data, uint32_t *in_size, void *out_data, uint32_t *out_size) { OI_STATUS status; if (decoder == NULL || in_data == NULL || in_size == NULL || out_data == NULL || out_size == NULL) { return -EINVAL; } status = OI_CODEC_SBC_DecodeFrame(&decoder->context, (const OI_BYTE**)in_data, in_size, out_data, out_size); if (!OI_SUCCESS(status)) { return -EIO; } else { return 0; } } #endif