Skip to content

Audio System Management (CODEC MANAGER)


1. Audio System Overview

  • As an intelligent voice SoC, CI13XX dedicates key resources to the audio path (CODEC, I2S, IISDMA). CI13XX integrates an on-chip CODEC (single-channel ADC and single-channel DAC). Using CI13XX for capture and playback removes the need for an external CODEC, improving system stability and reducing cost. The dedicated IISDMA makes configuring I2S reception or transmission more flexible and convenient, without interference from other peripherals using DMA. CI13XX also provides independent I2S interfaces for the on-chip CODEC’s ADC and DAC, enabling independent operation and flexible usage. In addition, CI13XX reserves one I2S interface for an external CODEC so users can still choose other CODEC chips to capture multiple channels of audio and meet more complex algorithm requirements. The capture and playback components chain CODEC, I2S, and IISDMA together to form the CI13XX audio path.

2. Audio System Manager Overview

Audio System Management Playback API

Figure 1-1 Audio System Management Playback API

Audio System Management Recording API

Figure 1-2 Audio System Management Recording API
  • The CI13XX SDK provides a management module for capture and playback devices. By invoking the APIs of this driver, you can complete typical capture and playback operations without handling tedious configurations of I2S, IISDMA, and the CODEC. This driver is implemented on FreeRTOS and therefore requires a FreeRTOS environment.

3. API List

Function Name Description
cm_reg_codec Register codec
cm_config_pcm_buffer Configure PCM buffer for recording/playback
cm_config_codec Configure audio format for recording/playback
cm_start_codec Start recording/playback
cm_stop_codec Stop recording/playback
cm_read_codec Retrieve recorded data
cm_write_codec Write playback data
cm_get_pcm_buffer Get playback PCM buffer
cm_release_pcm_buffer Release playback PCM buffer
cm_set_codec_dac_gain Set playback volume
cm_set_codec_alc Configure codec ALC
cm_set_codec_dac_enable Enable codec DAC
cm_set_codec_mute Mute recording device

4. Recording Example

Driver file path: “SDK\components\codec_manager\codec_manager.c”

Initialization and data acquisition example:

#include "audio_in_manage_inner.h"
#include "codec_manager.h"
#include "audio_play_api.h"
#include "audio_play_decoder.h"

#define RECORD_CODEC_INDEX 0

const cm_codec_hw_info_t inner_codec_info = 
{
    .IICx = IIC_NULL,
    .input_iis.IISx = IIS1,
    .input_iis.iis_mode_sel = IIS_MASTER,
    .input_iis.oversample = IIS_MCLK_FS_256,
    .input_iis.clk_source = AUDIO_PLAY_CLK_SOURCE_IPCORE,
    .input_iis.mclk_out_en = IIS_MCLK_OUT,
    .input_iis.iis_data_format = IIS_DF_IIS,
    .input_iis.sck_lrck_radio = IIS_SCK_LRCK_64,
    .input_iis.rx_cha = IIS_RX_CHANNAL_RX0,
    .input_iis.scklrck_out_en = IIS_SCKLRCK_OUT,
    codec_if = 
    {
        .codec_init = icodec_init,
        .codec_config = icodec_config,
        .codec_start = icodec_stop,
        .codec_ioctl = icodec_ioctl,
    }
}

const cm_sound_info_t record_sound_info = 
{
    .sample_rate = 16000,
    .channel_flag = 3,
    .sample_depth = IIS_DW_16BIT,
}

void record_task(void* p)
{
    // Register internal codec
    cm_reg_codec(RECORD_CODEC_INDEX, (cm_codec_hw_info_t*)&inner_codec_info);

    // Configure recording PCM buffer
    cm_record_buffer_info_t record_buffer_info;
    record_buffer_info.block_num = 2;
    record_buffer_info.block_size = 320*4; //576;
    record_buffer_info.buffer_size = record_buffer_info.block_size * record_buffer_info.block_num;
    record_buffer_info.pcm_buffer = pvPortMalloc(record_buffer_info.buffer_size);
    cm_config_pcm_buffer(RECORD_CODEC_INDEX, CODEC_INPUT, &record_buffer_info);

    // Configure recording audio format
    cm_config_codec(RECORD_CODEC_INDEX, CODEC_INPUT, &record_sound_info);

    // Start recording
    cm_start_codec(RECORD_CODEC_INDEX, CODEC_INPUT);

    while(1)
    {
        // Record
        uint32_t data_addr, data_size;
        cm_read_codec(RECORD_CODEC_INDEX, &data_addr, &data_size);

        if(data_addr)
        {

        }
        else
        {
            //mprintf("iisdma int too slow\n");
            continue;
        }
    }
}

5. Playback Example

Driver file path: “SDK\components\codec_manager\codec_manager.c”

Initialization and playback (write data) example:

#include "audio_in_manage_inner.h"
#include "codec_manager.h"
#include "audio_play_api.h"
#include "audio_play_decoder.h"

#define PLAYER_CODEC_INDEX 0
#define ALG_FRAME_SIZE (320) /*16ms per frame*/

uint16_t send_buf_addr[2048] = {0};

const cm_codec_hw_info_t inner_codec_info = 
{
    .IICx = IIC_NULL,
    .output_iis.IISx = IIS1,
    .output_iis.iis_mode_sel = IIS_MASTER,
    .output_iis.oversample = IIS_MCLK_FS_256,
    .output_iis.clk_source = AUDIO_PLAY_CLK_SOURCE_INTER_RC,
    .output_iis.mclk_out_en = IIS_MCLK_MODENULL,
    .output_iis.iis_data_format = IIS_DF_IIS,
    .output_iis.sck_lrck_radio = IIS_TX_CHANNAL_TX0,
    .output_iis.sck_lrck_radio = IIS_SCK_LRCK_64,
    .output_iis.scklrck_out_en = IIS_SCKLRCK_MODENULL,
    codec_if = 
    {
        .codec_init = icodec_init,
        .codec_config = icodec_config,
        .codec_start = icodec_stop,
        .codec_stop = icodec_stop,
        .codec_ioctl = icodec_ioctl,
    }
}

const cm_sound_info_t play_sound_info = 
{
    .sample_rate = 16000,
    .channel_flag = 3,
    .sample_depth = IIS_DW_16BIT,
}

void play_task(void* p)
{
    // Register internal codec
    cm_reg_codec(PLAYER_CODEC_INDEX, (cm_codec_hw_info_t*)&inner_codec_info);

    // Configure playback PCM buffer
    cm_play_buffer_info_t play_buffer_info;
    play_buffer_info.block_num = 2;
    play_buffer_info.buffer_num = 4;
    play_buffer_info.block_size = 320*4;
    play_buffer_info.buffer_size = play_buffer_info.block_size * play_buffer_info.block_num;
    play_buffer_info.pcm_buffer = pvPortMalloc(play_buffer_info.buffer_size*play_buffer_info.buffer_num);
    cm_config_pcm_buffer(PLAYER_CODEC_INDEX, CODEC_OUTPUT, &play_buffer_info);

    // Configure playback audio format
    cm_config_codec(PLAYER_CODEC_INDEX, CODEC_OUTPUT, &play_sound_info);

    // Start playback
    cm_start_codec(PLAYER_CODEC_INDEX, CODEC_OUTPUT);

    while(1)
    {
        // Playback
        uint32_t ret_p = 0;
        cm_get_pcm_buffer(PLAYER_CODEC_INDEX,&ret_p,portMAX_DELAY);    //TODO HSL
        volatile int16_t * out_p = (void*)ret_p;

        if(out_p)
        {
            memcpy(out_p, send_buf_addr, ALG_FRAME_SIZE*2*2);    // Playback data comes from send_buf_addr
            cm_write_codec(PLAYER_CODEC_INDEX, out_p,portMAX_DELAY);
        }
    }
}

6. API Reference