跳转至

音频系统管理(CODEC MANAGER)


1、音频系统简介

  • 芯片内部自带 MIC ADC(MADC)和内部 CODEC(DCODEC);
  • 支持模拟 MIC、数字 MIC(PDM)、内部 DAC 播放、外挂 IIS CODEC 多种录音/放音通路;
  • 采音与放音经 IIS 专用 IISDMA 搬运,互不占用通用 DMA;
  • 驱动程序简单易用,基于 FreeRTOS 编写,只能在 FreeRTOS 的基础上运行。

CI14LP 系列芯片作为一款低功耗智能语音芯片,其语音通路(MADC、DCODEC、IIS、IISDMA)占有非常重要的部分。片内 MADC 支持单通道模拟 MIC 输入和双通道数字 MIC 输入;片内 DCODEC 提供单通道 ADC 与双声道 DAC 输出(支持差分/单端、模拟/数字功放对接)。使用 CI14LP 芯片进行录音和放音,无需外接 CODEC 芯片,大大增加系统稳定性并降低成本。录音和放音组件(codec_manager)将 MADC、DCODEC、IIS 和 IISDMA 串联起来,形成 CI14LP 芯片的语音通路。


2、音频系统管理程序简介

CI14LP SDK 提供了一套录音设备和放音设备的驱动程序(codec_manager)。通过调用这套驱动程序提供的 API,用户就可以完成常规配置的录音和放音操作,而不需要考虑繁琐的 IIS、IISDMA、MADC/DCODEC 的配置。

组件源码位于 components\codec_manager\(codec_manager.c / codec_manager.h),同时提供无锁环形队列(ringbuf.c / ringbuf.h)用于双核间音频数据传输。


3、API列表

函数名 描述
cm_init 初始化音频 CODEC 管理模块
cm_reg_codec 注册一个音频 CODEC
cm_register_codec_callback 注册 CODEC 事件回调函数
cm_config_pcm_buffer 配置录音/放音 PCM buffer
cm_config_codec 配置录音/放音音频格式
cm_start_codec 启动录音或放音
cm_stop_codec 停止录音或放音
cm_read_codec 同步读取录制的 PCM 数据
cm_write_codec 写入放音数据
cm_get_pcm_buffer 获取空闲 PCM buffer
cm_release_pcm_buffer 释放读到的录音 buffer
cm_set_codec_dac_gain 设置 DAC(播放)增益
cm_set_codec_adc_gain 设置 ADC(录音)增益
cm_set_codec_adc_digital_gain 设置 ADC 数字增益
cm_set_codec_alc 录音 ALC 使能控制
cm_set_codec_dac_enable DAC 功能使能控制
cm_set_codec_mute 设置静音模式
cm_config_iis_probe_en 配置 IIS 探针模式
cm_get_codec_empty_buffer_number 查询空闲 buffer 数量
cm_get_codec_busy_buffer_number 查询忙 buffer 数量

4、录音示例

驱动文件地址:SDK\components\codec_manager\codec_manager.c

初始化代码、获取数据的示例(参考 driver\boards\board.c 中 audio_in_codec_registe() 与示例工程用法):

#include "codec_manager.h"

#define HOST_MIC_RECORD_CODEC_ID  1   // 主MIC录音codec id(sdk_default_config.h定义)

//录音codec硬件信息(板级注册,静态配置)
static const cm_codec_hw_info_t madc_hw_info =
{
    .IICx = IIC_NULL,                          //片内CODEC无需IIC
    .input_iis.iisnum = IISNum1_MADC_RX,       //录音使用与MADC关联的IIS1 RX
    .input_iis.iis_mode_sel = IIS_SLAVE,
    .input_iis.codec_device = CM_MADC_ANALOG_MIC_RECORD,  //模拟MIC录音
    .input_iis.over_sample = IIS_MCLK_FS_256,
    .input_iis.iis_data_format = IIS_DF_IIS,
    .input_iis.sck_lrck_ratio = IIS_SCK_LRCK_64,
    .codec_if =
    {
        .codec_init = madc_codec_init,         //MADC驱动实现
        .codec_config = madc_codec_config,
        .codec_start = madc_codec_start,
        .codec_stop = madc_codec_stop,
        .codec_ioctl = madc_codec_ioctl,
    },
};

//音频格式
static const cm_sound_info_t host_mic_sound_info =
{
    .sample_rate = 16000,        //采样率16K
    .sample_depth = IIS_DW_16BIT,//采样深度16bit
    .channel_flag = CM_CHA_LEFT, //左声道
};

cm_pcm_buffer_info_t record_buffer_info;

void audio_in_codec_registe(void)
{
    //注册录音codec
    cm_reg_codec(HOST_MIC_RECORD_CODEC_ID, (cm_codec_hw_info_t*)&madc_hw_info);

    //配置录音PCM buffer
    record_buffer_info.record_buffer_info.block_num = AUDIO_IN_BUFFER_NUM;
    record_buffer_info.record_buffer_info.block_size = 160*2;   //每帧160点16bit
    record_buffer_info.record_buffer_info.buffer_size =
        record_buffer_info.record_buffer_info.block_size *
        record_buffer_info.record_buffer_info.block_num;
    record_buffer_info.record_buffer_info.pcm_buffer = record_pcm_buffer;
    cm_config_pcm_buffer(HOST_MIC_RECORD_CODEC_ID, CODEC_INPUT, &record_buffer_info);

    //配置录音音频格式
    cm_config_codec(HOST_MIC_RECORD_CODEC_ID, CODEC_INPUT, (cm_sound_info_t*)&host_mic_sound_info);
}

读取录音数据:

uint32_t data_addr, data_size;
cm_read_codec(HOST_MIC_RECORD_CODEC_ID, &data_addr, &data_size, wait_tick);

if(data_addr)
{
    //处理data_addr指向的data_size字节PCM数据
    //处理完成后释放buffer,继续循环录音
    cm_release_pcm_buffer(HOST_MIC_RECORD_CODEC_ID, CODEC_INPUT, (void*)data_addr);
}

5、放音示例

初始化代码、写入数据播放示例(参考 driver\boards\board.c 中 audio_play_out_codec_registe()):

#include "codec_manager.h"

#define PLAY_CODEC_ID  2   //播音codec id(sdk_default_config.h定义)

//放音codec硬件信息(板级注册,静态配置)
static const cm_codec_hw_info_t dcodec_hw_info =
{
    .IICx = IIC_NULL,
    .output_iis.iisnum = IISNum1_DCODEC_TX,     //放音使用与DCODEC关联的IIS1 TX
    .output_iis.iis_mode_sel = IIS_SLAVE,
    .output_iis.codec_device = CM_DCODEC_DAC_PLAY,        //内部DAC放音
    .output_iis.iis_data_format = IIS_DF_IIS,
    .codec_if =
    {
        .codec_init = dcodec_codec_init,        //DCODEC驱动实现
        .codec_config = dcodec_codec_config,
        .codec_start = dcodec_codec_start,
        .codec_stop = dcodec_codec_stop,
        .codec_ioctl = dcodec_codec_ioctl,
    },
};

void audio_play_out_codec_registe(void)
{
    //注册放音codec
    cm_reg_codec(PLAY_CODEC_ID, (cm_codec_hw_info_t*)&dcodec_hw_info);

    //放音引脚、功放使能配置
    pad_config_for_power_amplifier();
}

获取 buffer 并写入数据播放:

uint32_t ret_p = 0;
//获取空闲PCM buffer
cm_get_pcm_buffer(PLAY_CODEC_ID, &ret_p, portMAX_DELAY);
int16_t *out_p = (int16_t *)ret_p;

if(out_p)
{
    memcpy(out_p, pcm_src, 320*2);     //填入待播放数据
    cm_write_codec(PLAY_CODEC_ID, out_p, portMAX_DELAY);  //写入播放
}

6、codec 设备类型

cm_codec_device_t 指定 codec_manager 管理的设备通路:

枚举值 说明
CM_MADC_ANALOG_MIC_RECORD (0x11) MADC 模拟 MIC 录音
CM_MADC_DIGITAL_MIC_RECORD (0x22) MADC 数字 MIC(PDM)录音
CM_DCODEC_DIGITAL_MIC_RECORD (0x33) DCODEC 数字 MIC(PDM)录音
CM_DCODEC_DAC_PLAY (0x44) DCODEC DAC 播放

7、API 参考

本模块接口声明于 components\codec_manager\codec_manager.h,无锁环形队列接口声明于 components\codec_manager\ringbuf.h。

底层驱动接入接口:

  • MADC:driver\ci14lp_chip_driver\inc\ci14lp_madc.h(madc_codec_init/start/config/stop/ioctl)
  • DCODEC:driver\ci14lp_chip_driver\inc\ci14lp_dcodec.h(dcodec_codec_init/start/config/stop/ioctl)