demo工程暂存 优化菜单界面UI和功能
This commit is contained in:
319
MCU/components/modules/audio/codec/codec.c
Normal file
319
MCU/components/modules/audio/codec/codec.c
Normal file
@ -0,0 +1,319 @@
|
||||
/*
|
||||
* codec.c
|
||||
*
|
||||
* Created on: 2018-3-28
|
||||
* Author: Administrator
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "codec.h"
|
||||
#include "audio_rpmsg.h"
|
||||
#include "dsp.h"
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_decoder_init
|
||||
*
|
||||
* @brief reqeust to init a decoder instance.
|
||||
*
|
||||
* @param decoder_type: decoder type, @ref codec_decoder_type.
|
||||
* @param param: decoder parameters.
|
||||
*
|
||||
* @return decoder instance, the value should be NULL when initialization is failed.
|
||||
*/
|
||||
struct codec_decoder_handle *codec_decoder_init(uint8_t decoder_type, void *param)
|
||||
{
|
||||
struct rpmsg_sync_msg_decoder_init_t *sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
|
||||
sync_msg = pvPortMalloc(sizeof(struct rpmsg_sync_msg_decoder_init_t));
|
||||
if (sync_msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sync_msg->decoder_type = decoder_type;
|
||||
sync_msg->param = param;
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_DEC_INIT, sync_msg, (uint32_t *)&result);
|
||||
|
||||
vPortFree(sync_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_decoder_destroy
|
||||
*
|
||||
* @brief remove a created decoder instance.
|
||||
*
|
||||
* @param handle: decoder instance
|
||||
*/
|
||||
void codec_decoder_destroy(struct codec_decoder_handle *handle)
|
||||
{
|
||||
struct rpmsg_sync_msg_decoder_destroy_t sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
|
||||
if (handle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sync_msg.handle = handle;
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_DEC_DESTROY, (void *)&sync_msg, (uint32_t *)&result);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_decoder_decode
|
||||
*
|
||||
* @brief reqeust to execute decode.
|
||||
*
|
||||
* @param handle: decoder instance
|
||||
* @param in_buf: buffer used to store raw data, caller should take care that this
|
||||
* buffer should be accessable for dsp.
|
||||
* @param in_length: the length of raw data, this value will be updated to length of
|
||||
* dealed data after decode operation is executed.
|
||||
* @param out_buf: used to store the buffer address of decoded data. Decoder will allocate
|
||||
* out buffer for internal used to store decoded data. If *out_buf is NULL,
|
||||
* decoder will update *out_buf to internal used out buffer address. If *out_buf
|
||||
* is not NULL, the decoded data will be copied into *out_buf.
|
||||
* @param out_length: the length of decoded data.
|
||||
*
|
||||
* @return execute result.
|
||||
*/
|
||||
int codec_decoder_decode(struct codec_decoder_handle *handle,
|
||||
const uint8_t *in_buf,
|
||||
uint32_t *in_length,
|
||||
uint8_t **out_buf,
|
||||
uint32_t *out_length)
|
||||
{
|
||||
struct rpmsg_sync_msg_decoder_exec_t *sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
bool trans_addr = false;
|
||||
|
||||
sync_msg = pvPortMalloc(sizeof(struct rpmsg_sync_msg_decoder_exec_t));
|
||||
if (sync_msg == NULL) {
|
||||
return CODEC_ERROR_INSUFFICIENT_RESOURCE;
|
||||
}
|
||||
|
||||
if (((uint32_t)in_buf >= DSP_DRAM_MCU_BASE_ADDR) && ((uint32_t)in_buf < (DSP_DRAM_MCU_BASE_ADDR+DSP_DRAM_SIZE))) {
|
||||
in_buf = (const void *)MCU_SRAM_2_DSP_DRAM(in_buf);
|
||||
}
|
||||
|
||||
sync_msg->handle = handle;
|
||||
sync_msg->in_buffer = in_buf;
|
||||
sync_msg->in_length = in_length;
|
||||
sync_msg->out_buffer = out_buf;
|
||||
sync_msg->out_length = out_length;
|
||||
|
||||
if (*out_buf == NULL) {
|
||||
trans_addr = true;
|
||||
}
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_DEC_EXEC, sync_msg, (uint32_t *)&result);
|
||||
|
||||
if (trans_addr) {
|
||||
if ((uint32_t)*out_buf >= DSP_DRAM_BASE_ADDR) {
|
||||
*out_buf = (void *)DSP_DRAM_2_MCU_SRAM(*out_buf);
|
||||
}
|
||||
}
|
||||
|
||||
vPortFree(sync_msg);
|
||||
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_decoder_plc
|
||||
*
|
||||
* @brief reqeust to execute packet loss compensation.
|
||||
*
|
||||
* @param handle: decoder instance
|
||||
* @param out_buf: used to store the buffer address of decoded data. Decoder will allocate
|
||||
* out buffer for internal used to store decoded data. If *out_buf is NULL,
|
||||
* decoder will update *out_buf to internal used out buffer address. If *out_buf
|
||||
* is not NULL, the decoded data will be copied into *out_buf.
|
||||
* @param out_length: the length of decoded data.
|
||||
*
|
||||
* @return execute result.
|
||||
*/
|
||||
int codec_decoder_plc(struct codec_decoder_handle *handle,
|
||||
uint8_t **out_buf,
|
||||
uint32_t *out_length)
|
||||
{
|
||||
struct rpmsg_sync_msg_decoder_plc_t *sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
bool trans_addr = false;
|
||||
|
||||
sync_msg = pvPortMalloc(sizeof(struct rpmsg_sync_msg_decoder_exec_t));
|
||||
if (sync_msg == NULL) {
|
||||
return CODEC_ERROR_INSUFFICIENT_RESOURCE;
|
||||
}
|
||||
sync_msg->handle = handle;
|
||||
sync_msg->out_buffer = out_buf;
|
||||
sync_msg->out_length = out_length;
|
||||
|
||||
if (*out_buf == NULL) {
|
||||
trans_addr = true;
|
||||
}
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_DEC_PLC, sync_msg, (uint32_t *)&result);
|
||||
|
||||
if (trans_addr) {
|
||||
if ((uint32_t)*out_buf >= DSP_DRAM_BASE_ADDR) {
|
||||
*out_buf = (void *)DSP_DRAM_2_MCU_SRAM(*out_buf);
|
||||
}
|
||||
}
|
||||
|
||||
vPortFree(sync_msg);
|
||||
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_decoder_get_param
|
||||
*
|
||||
* @brief get information of latest decoded frame.
|
||||
*
|
||||
* @param handle: decoder instance
|
||||
* @param sample_rate: sample rate.
|
||||
* @param channels: channel number.
|
||||
*
|
||||
* @return 0: get success, 1: get failed.
|
||||
*/
|
||||
int codec_decoder_get_param(struct codec_decoder_handle *handle, uint32_t *sample_rate, uint8_t *channels)
|
||||
{
|
||||
struct rpmsg_sync_msg_decoder_get_param_t *sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
|
||||
sync_msg = pvPortMalloc(sizeof(struct rpmsg_sync_msg_decoder_get_param_t));
|
||||
if (sync_msg == NULL) {
|
||||
return CODEC_ERROR_INSUFFICIENT_RESOURCE;
|
||||
}
|
||||
sync_msg->handle = handle;
|
||||
sync_msg->sample_rate = sample_rate;
|
||||
sync_msg->channels = channels;
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_DEC_GET_PARAM, sync_msg, (uint32_t *)&result);
|
||||
|
||||
vPortFree(sync_msg);
|
||||
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_encoder_init
|
||||
*
|
||||
* @brief reqeust to init a encoder instance.
|
||||
*
|
||||
* @param encoder_type: encoder type, @ref codec_encoder_type.
|
||||
* @param param: encoder parameters.
|
||||
*
|
||||
* @return encoder instance, the value should be NULL when initialization is failed.
|
||||
*/
|
||||
struct codec_encoder_handle *codec_encoder_init(uint8_t encoder_type, void *param)
|
||||
{
|
||||
struct rpmsg_sync_msg_encoder_init_t *sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
|
||||
sync_msg = pvPortMalloc(sizeof(struct rpmsg_sync_msg_encoder_init_t));
|
||||
if (sync_msg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sync_msg->encoder_type = encoder_type;
|
||||
sync_msg->param = param;
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_ENC_INIT, sync_msg, (uint32_t *)&result);
|
||||
|
||||
vPortFree(sync_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_encoder_destroy
|
||||
*
|
||||
* @brief remove a created encoder instance.
|
||||
*
|
||||
* @param handle: encoder instance
|
||||
*/
|
||||
void codec_encoder_destroy(struct codec_encoder_handle *handle)
|
||||
{
|
||||
struct rpmsg_sync_msg_encoder_destroy_t sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
|
||||
if (handle == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sync_msg.handle = handle;
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_ENC_DESTROY, (void *)&sync_msg, (uint32_t *)&result);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* @fn codec_encoder_encode
|
||||
*
|
||||
* @brief reqeust to execute encode.
|
||||
*
|
||||
* @param handle: encoder instance
|
||||
* @param in_buf: buffer used to store PCM data, caller should take care that this
|
||||
* buffer should be accessable for dsp.
|
||||
* @param in_length: the length of PCM data, this value will be updated to length of
|
||||
* dealed data after encode operation is executed.
|
||||
* @param out_buf: used to store the buffer address of encoded data. Encoder will allocate
|
||||
* out buffer for internal used to store decoded data. If *out_buf is NULL,
|
||||
* decoder will update *out_buf to internal used out buffer address. If *out_buf
|
||||
* is not NULL, the decoded data will be copied into *out_buf.
|
||||
* @param out_length: the length of encoded data.
|
||||
*
|
||||
* @return execute result.
|
||||
*/
|
||||
int codec_encoder_encode(struct codec_encoder_handle *handle,
|
||||
const uint8_t *in_buf,
|
||||
uint32_t *in_length,
|
||||
uint8_t **out_buf,
|
||||
uint32_t *out_length)
|
||||
{
|
||||
struct rpmsg_sync_msg_encoder_exec_t *sync_msg;
|
||||
void *result;
|
||||
uint32_t ret;
|
||||
bool trans_addr = false;
|
||||
|
||||
sync_msg = pvPortMalloc(sizeof(struct rpmsg_sync_msg_encoder_exec_t));
|
||||
if (sync_msg == NULL) {
|
||||
return CODEC_ERROR_INSUFFICIENT_RESOURCE;
|
||||
}
|
||||
|
||||
if (((uint32_t)in_buf >= DSP_DRAM_MCU_BASE_ADDR) && ((uint32_t)in_buf < (DSP_DRAM_MCU_BASE_ADDR+DSP_DRAM_SIZE))) {
|
||||
in_buf = (void *)MCU_SRAM_2_DSP_DRAM(in_buf);
|
||||
}
|
||||
|
||||
sync_msg->handle = handle;
|
||||
sync_msg->in_buffer = in_buf;
|
||||
sync_msg->in_length = in_length;
|
||||
sync_msg->out_buffer = out_buf;
|
||||
sync_msg->out_length = out_length;
|
||||
|
||||
if (*out_buf == NULL) {
|
||||
trans_addr = true;
|
||||
}
|
||||
|
||||
ret = rpmsg_sync_invoke(rpmsg_get_remote_instance(), RPMSG_SYNC_FUNC_ENC_EXEC, sync_msg, (uint32_t *)&result);
|
||||
|
||||
if (trans_addr) {
|
||||
if ((uint32_t)*out_buf >= DSP_DRAM_BASE_ADDR) {
|
||||
*out_buf = (void *)DSP_DRAM_2_MCU_SRAM(*out_buf);
|
||||
}
|
||||
}
|
||||
|
||||
vPortFree(sync_msg);
|
||||
|
||||
return (int)result;
|
||||
}
|
||||
|
204
MCU/components/modules/audio/codec/codec.h
Normal file
204
MCU/components/modules/audio/codec/codec.h
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* codec.h
|
||||
*
|
||||
* Created on: 2018-3-28
|
||||
* Author: Administrator
|
||||
*/
|
||||
|
||||
#ifndef _CODEC_H
|
||||
#define _CODEC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "FreeRTOS.h" // for malloc
|
||||
|
||||
#define codec_alloc pvPortMalloc
|
||||
#define codec_free vPortFree
|
||||
|
||||
enum codec_error {
|
||||
CODEC_ERROR_NO_ERROR,
|
||||
CODEC_ERROR_FAILED,
|
||||
CODEC_ERROR_INVALID_HANDLE,
|
||||
CODEC_ERROR_UNACCEPTABLE_PARAM,
|
||||
CODEC_ERROR_INSUFFICIENT_RESOURCE,
|
||||
CODEC_ERROR_NONE_FATAL,
|
||||
CODEC_ERROR_FATAL,
|
||||
CODEC_ERROR_NEED_MORE_DATA,
|
||||
};
|
||||
|
||||
enum codec_decoder_type {
|
||||
CODEC_DECODER_TYPE_MP3,
|
||||
CODEC_DECODER_TYPE_CVSD,
|
||||
CODEC_DECODER_TYPE_LC3,
|
||||
CODEC_DECODER_TYPE_MSBC,
|
||||
CODEC_DECODER_TYPE_SBC,
|
||||
CODEC_DECODER_TYPE_OGGOPUS,
|
||||
CODEC_DECODER_TYPE_AAC,
|
||||
CODEC_DECODER_TYPE_PCM,
|
||||
};
|
||||
|
||||
enum codec_encoder_type {
|
||||
CODEC_ENCODER_TYPE_CVSD,
|
||||
CODEC_ENCODER_TYPE_LC3,
|
||||
CODEC_ENCODER_TYPE_MSBC,
|
||||
CODEC_ENCODER_TYPE_SBC,
|
||||
CODEC_ENCODER_TYPE_OPUS,
|
||||
CODEC_ENCODER_TYPE_AAC,
|
||||
};
|
||||
|
||||
struct sbc_encoder_param {
|
||||
uint32_t i_samp_freq;
|
||||
uint32_t i_num_chan;
|
||||
uint32_t i_subbands;
|
||||
uint32_t i_blocks;
|
||||
uint32_t i_bitpool;
|
||||
};
|
||||
|
||||
struct aac_encoder_param {
|
||||
uint32_t i_samp_freq;
|
||||
uint32_t i_num_chan;
|
||||
uint32_t i_pcm_wdsz;
|
||||
};
|
||||
|
||||
struct sbc_orign_encoder_param{
|
||||
int subbands;
|
||||
int bitpool;
|
||||
int joint;
|
||||
int dualchannel;
|
||||
int snr;
|
||||
int blocks;
|
||||
bool msbc;
|
||||
uint32_t input_size;
|
||||
|
||||
uint32_t channels;
|
||||
uint32_t sample_rate; /* sample rate */
|
||||
// uint8_t sbc_mode;
|
||||
};
|
||||
|
||||
struct msbc_encoder_param {
|
||||
uint32_t i_bitrate;
|
||||
uint32_t i_samp_freq;
|
||||
};
|
||||
|
||||
struct lc3_encoder_param{
|
||||
int dt_us;
|
||||
int sr_hz;
|
||||
int sr_pcm_hz;
|
||||
int pcm_format;
|
||||
};
|
||||
|
||||
struct lc3_hifi3z_encoder_param{
|
||||
int dt_ms;
|
||||
int sr_hz;
|
||||
int bit_rate;
|
||||
int bips_in;
|
||||
int ch;
|
||||
};
|
||||
|
||||
struct lc3_hifi3z_decoder_param{
|
||||
int bips_out;
|
||||
uint32_t sample_rate;
|
||||
int16_t nchannels;
|
||||
int bitrate;
|
||||
float frame_ms;
|
||||
uint32_t signal_len;
|
||||
int epmode;
|
||||
int hrmode;
|
||||
uint16_t frame_size;
|
||||
};
|
||||
|
||||
struct cvsd_encoder_param{
|
||||
int ch;
|
||||
double step_decay; //I2 decay
|
||||
double accum_decay; //I1 decay
|
||||
};
|
||||
|
||||
struct cvsd_decoder_param{
|
||||
int ch;
|
||||
|
||||
double step_decay; //I2 decay
|
||||
double accum_decay; //I1 decay
|
||||
};
|
||||
|
||||
struct lc3_decoder_param{
|
||||
int dt_us;
|
||||
int sr_hz;
|
||||
int sr_pcm_hz;
|
||||
int pcm_format;
|
||||
};
|
||||
|
||||
struct opus_decoder_param{
|
||||
int sample_rate;
|
||||
int nb_coupled;
|
||||
int channel_mapping;
|
||||
uint8_t channels;
|
||||
uint8_t frames_per_pack;
|
||||
int gain;
|
||||
};
|
||||
|
||||
struct opus_encoder_param{
|
||||
int application;
|
||||
int sampleRate;
|
||||
int numChannels;
|
||||
int bitRate;
|
||||
float frame_size_ms;
|
||||
};
|
||||
|
||||
struct aac_decoder_param{
|
||||
int PcmWidth;
|
||||
};
|
||||
|
||||
struct pcm_decoder_param {
|
||||
uint32_t sample_rate;
|
||||
uint16_t frame_size;
|
||||
uint8_t channels;
|
||||
};
|
||||
|
||||
struct codec_decoder_api {
|
||||
void *(*init)(void *param);
|
||||
void (*destroy)(void *handle);
|
||||
int (*decode)(void *handle, const uint8_t *data, uint32_t *length, uint8_t **out_buf, uint32_t *out_length);
|
||||
int (*plc)(void *handle, uint8_t **out_buf, uint32_t *out_length);
|
||||
int (*get_param)(void *handle, uint32_t *sample_rate, uint8_t *channels);
|
||||
};
|
||||
|
||||
struct codec_decoder_handle {
|
||||
struct codec_decoder_api *api;
|
||||
void *decoder_env;
|
||||
};
|
||||
|
||||
struct codec_encoder_api {
|
||||
void *(*init)(void *param);
|
||||
void (*destroy)(void *handle);
|
||||
int (*encode)(void *handle, const uint8_t *data, uint32_t *length, uint8_t **out_buf, uint32_t *out_length);
|
||||
};
|
||||
|
||||
struct codec_encoder_handle {
|
||||
struct codec_encoder_api *api;
|
||||
void *encoder_env;
|
||||
};
|
||||
|
||||
struct codec_decoder_handle *codec_decoder_init(uint8_t decoder_type, void *param);
|
||||
void codec_decoder_destroy(struct codec_decoder_handle *handle);
|
||||
int codec_decoder_decode(struct codec_decoder_handle *handle,
|
||||
const uint8_t *in_buf,
|
||||
uint32_t *in_length,
|
||||
uint8_t **out_buf,
|
||||
uint32_t *out_length);
|
||||
int codec_decoder_plc(struct codec_decoder_handle *handle,
|
||||
uint8_t **out_buf,
|
||||
uint32_t *out_length);
|
||||
int codec_decoder_get_param(struct codec_decoder_handle *handle, uint32_t *sample_rate, uint8_t *channels);
|
||||
|
||||
struct codec_encoder_handle *codec_encoder_init(uint8_t encoder_type, void *param);
|
||||
void codec_encoder_destroy(struct codec_encoder_handle *handle);
|
||||
int codec_encoder_encode(struct codec_encoder_handle *handle,
|
||||
const uint8_t *in_buf,
|
||||
uint32_t *in_length,
|
||||
uint8_t **out_buf,
|
||||
uint32_t *out_length);
|
||||
int codec_encoder_plc(struct codec_encoder_handle *handle,
|
||||
uint8_t **out_buf,
|
||||
uint32_t *out_length);
|
||||
#endif /* _CODEC_H */
|
Reference in New Issue
Block a user