Skip to content

CODEC MANAGER


1. Features

  • The chip has its own CODEC;
  • ALC processing logic specially designed for internal CODEC;
  • IIS dedicated IISDMA;
  • The driver is easy to use and flexible to use.

As an intelligent voice chip, CI130X’s voice channels (CODEC, IIS, IISDMA) occupy a very important part. The CI130X also has on chip CODEC (single channel ADC and single channel DAC). The CI130X can be used for recording and playback without external CODEC chips, which greatly increases the stability of the system and reduces the cost. The dedicated IISDMA makes it more flexible and convenient to configure IIS to receive or send data, without considering the impact of other peripherals using DMA. In addition, CI130X has designed separate IIS for ADC and DAC of the on-chip CODEC. They work independently, do not affect each other, and are flexible in use. In addition, CI130X also has one channel of IIS reserved for external CODEC to ensure that users can still select other CODEC chips according to their own needs to collect multi-channel voice, which has met more complex algorithm requirements. The recording and playback components connect CODEC, IIS and IISDMA together to form the voice channel of CI130X.


2. Overview

放音设备驱动API

Figure 1-1 Audio playback device driver API

录音设备驱动API

Figure 1-1 Recording Device Driver API

The CI130X SDK provides a set of drivers for recording devices and playback devices. By calling the API provided by this set of drivers, users can complete the recording and playback operations of the general configuration, without considering the tedious configuration of IIS, IISDMA, and CODEC. This driver is based on FreeRTOS, so it can only run on the basis of FreeRTOS.


3. Recording and playback equipment API

Function name Description
cm_ reg_ Codec Register codec
cm_ config_ pcm_ Buffer Configure the recording/playback PCM buffer
cm_ config_ Codec Configure recording/playback audio format
cm_ start_ Codec Start recording/playing
cm_ stop_ Codec Stop recording/playing
cm_ read_ Codec Get the recording data
cm_ write_ Codec Write playback data
cm_ get_ pcm_ buffer Get playback PCM buffer
cm_ release_ pcm_ Buffer Release the playback PCM buffer
cm_ set_ codec_ dac_ Gain Set playback volume
cm_ set_ codec_ Alc Set codec alc
cm_ set_ codec_ dac_ Enable Set the codec dac enable
cm_ set_ codec_ Mute Mute the recording device

4. Recording example

Driver file address: “SDK components codec_manager codec_manager. c”

Examples of initialization code and data acquisition:

#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 =
{
.sapmple_ 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)
{
//Recording
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 address: “SDK components codec_manager codec_manager. c”

Example of playing initialization code and writing data:

#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 perframe*/

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 =
{
.sapmple_ 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 playing
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);
}
}
}