Audio Development Guide_Rev1.1

中文

1 Revision History

Version

Date

Author

Reviewer

Revision Content

Rev1.0

2026-01-29

sxx

zlc

Document created

2 Introduction

This document describes the LTE-EC71X Audio interface APIs, which are declared in the liot_audio2.h file.

The Audio interface is a wrapper for Codec device audio interfaces that integrate I2S data transmission. Currently adapted hardware drivers include ES8311, TM8211, ES8374, and ES8375.

2.1 Audio Control Logic

Upon receiving audio initialization, the system first matches the Codec type and performs Codec hardware initialization. For example, ES8311 first configures related registers via I2C, then initializes the I2S bus, and creates an audio playback queue. Audio playback is asynchronous — after calling Liot_AudioPlay(), a backup is created in the audio playback queue for playback. Theoretically, the queue length has no upper limit and is determined by the system’s memory allocation limit.

MP3 and PCM playback first decodes the data source and then places it into the audio playback queue.

2.2 I2S Playback Principle

I2S (Inter-IC Sound) is a serial digital communication bus dedicated to audio, specifically designed for transmitting digital audio data between chips.

  • MCLK: Master clock (system audio clock, commonly 256x sample rate)

  • BCLK (SCK): Bit clock, transfers 1 bit per transition

  • LRCK (WS): Channel clock. Low level = left channel; High level = right channel

  • SDIN/SDOUT: Audio data serial line

Working logic:

  1. Based on the sample rate (e.g., 44.1K, 48KHz), WS switches channels the corresponding number of times per second;

  2. Within each WS cycle, BCLK shifts out 16/24/32-bit audio sample data bit by bit;

  3. The transmitter sends data serially according to the clock, the receiver samples and parses synchronously, separates left and right channels, and restores digital audio;

  4. Only pure audio data streams are transmitted; commands and configuration use separate I2C/SPI control.

3 API Function Overview

Function

Description

Liot_AudioInit

Audio initialization interface

Liot_AudioDeInit

Audio deinitialization interface

Liot_AudioSetVolume

Set software volume

Liot_AudioGetVolume

Get software volume

Liot_AudioSetCodecVolume

Set Codec hardware volume

Liot_AudioGetCodecVolume

Get Codec hardware volume

Liot_AudioSetMicVolume

Set microphone volume

Liot_AudioSetVolMode

Set volume step mode

Liot_AudioPlay

Play PCM audio data

Liot_AudioRecord

Record audio

Liot_AudioPlayPause

Pause playback

Liot_AudioPlayResume

Resume playback

Liot_AudioPlayFile

Play audio file (PCM)

Liot_AudioWaitPlayFinish

Wait for playback to finish

Liot_AudioStop

Stop playback

Liot_AudioPlayMp3File

Play MP3 file

Liot_AudioPlayMp3

Play MP3 data from memory

Liot_AudioPlayWavFile

Play WAV file

Liot_AudioPlayWav

Play WAV data from memory

Liot_AudioMp3StreamStart

Start MP3 streaming playback session

Liot_AudioMp3StreamPlay

Feed MP3 data to the streaming decoder

Liot_AudioMp3StreamStop

Stop MP3 streaming playback

Liot_AudioSetAns

Set 3A ANS parameters

Liot_AudioSetAgc

Set 3A AGC parameters

Liot_AudioSetAec

Set 3A AEC parameters

Liot_AudioRecordStream

Start PCM streaming recording

Liot_AudioRecordStreamStop

Stop PCM streaming recording

Liot_AudioPlayStream

Write PCM streaming playback data

Liot_AudioPlayStreamStop

Stop PCM streaming playback

Note: The seven interfaces listed above, from Liot_AudioSetAns through Liot_AudioPlayStreamStop, are supported only by the F6D_D and F9D_D base packages. Other base packages do not support them.

4 Type Descriptions

4.1 Liot_AudErr_e

  1. Enum definition:

typedef enum {
    L_AUD_ERR_SUCCESS  = 0,
    L_AUD_ERR_EXECUTE,
    L_AUD_ERR_INVALID_PARAM,
    L_AUD_ERR_OPEN,
    L_AUD_ERR_CONFIG,
    L_AUD_ERR_PULL_SET,
    L_AUD_ERR_CALLBACK,
    L_AUD_ERR_LEVEL_TRIGGER,
    L_AUD_ERR_NOMEM,
    L_AUD_ERR_FILE,
    L_AUD_ERR_TIMEOUT,
    L_AUD_ERR_NO_SUPPORT,
} Liot_AudErr_e;
  1. Enum description

Variable

Description

L_AUD_ERR_SUCCESS

Operation successful

L_AUD_ERR_EXECUTE

General execution error

L_AUD_ERR_INVALID_PARAM

Invalid input parameter

L_AUD_ERR_OPEN

Failed to open

L_AUD_ERR_CONFIG

Configuration interface failed

L_AUD_ERR_PULL_SET

Pull-up setting failed

L_AUD_ERR_NOMEM

Out of memory

L_AUD_ERR_FILE

File operation failed

L_AUD_ERR_TIMEOUT

Operation timed out

L_AUD_ERR_NO_SUPPORT

Operation not supported

4.2 Liot_AudDevice_e

  1. Enum definition:

typedef enum {
    L_AUD_DEV_NONE,
    L_AUD_TM8211,
    L_AUD_ES8311,
    L_AUD_ES8374,
    L_AUD_ES8375,
    L_AUD_DEV_MAX,
} Liot_AudDevice_e;
  1. Enum description

Variable

Description

L_AUD_DEV_NONE

No audio device

L_AUD_TM8211

TM8211

L_AUD_ES8311

ES8311

L_AUD_ES8374

ES8374

L_AUD_ES8375

ES8375

L_AUD_DEV_MAX

Maximum audio device enum value

4.3 Liot_AudSample_e

Sample rate.

  1. Enum definition:

typedef enum
{
    L_AUD_08K_SAMPLES,
    L_AUD_16K_SAMPLES,
    L_AUD_22K_SAMPLES,
    L_AUD_24K_SAMPLES,
    L_AUD_32K_SAMPLES,
    L_AUD_44K_SAMPLES,
    L_AUD_48K_SAMPLES,
    L_AUD_96K_SAMPLES,
} Liot_AudSample_e;
  1. Enum description

Variable

Description

L_AUD_08K_SAMPLES

8KHz sample rate

L_AUD_16K_SAMPLES

16KHz sample rate

L_AUD_22K_SAMPLES

22.05KHz sample rate

L_AUD_24K_SAMPLES

24KHz sample rate

L_AUD_32K_SAMPLES

32KHz sample rate

L_AUD_44K_SAMPLES

44.1KHz sample rate

L_AUD_48K_SAMPLES

48KHz sample rate

L_AUD_96K_SAMPLES

96KHz sample rate

4.4 Liot_AudFrameSize_e

Data frame format.

  1. Enum definition:

typedef enum
{
    L_AUD_FRAMESIZE_16_16 = 0,
    L_AUD_FRAMESIZE_16_32 = 1,
    L_AUD_FRAMESIZE_24_32 = 2,
    L_AUD_FRAMESIZE_32_32 = 3,
} Liot_AudFrameSize_e;
  1. Enum description

Variable

Description

L_AUD_FRAMESIZE_16_16

16_16 frame format, word size 16, 16bit per frame

L_AUD_FRAMESIZE_16_32

16_32 frame format, slot size 32, 16bit per frame

L_AUD_FRAMESIZE_24_32

24_32 frame format, slot size 32, 24bit per frame

L_AUD_FRAMESIZE_32_32

32_32 frame format, slot size 32, 32bit per frame

4.5 Liot_AudMode_e

Audio data format.

  1. Enum definition:

typedef enum
{
    L_AUD_MODE_MSB,
    L_AUD_MODE_LSB,
    L_AUD_MODE_I2S,
    L_AUD_MODE_PCM,
} Liot_AudMode_e;
  1. Enum description

Variable

Description

L_AUD_MODE_MSB

Audio data left-aligned

L_AUD_MODE_LSB

Audio data right-aligned

L_AUD_MODE_I2S

I2S data stream format

L_AUD_MODE_PCM

PCM data stream format

4.6 Liot_AudRole_e

Codec master/slave mode.

  1. Enum definition:

typedef enum
{
    L_AUD_ROLE_MASTER,
    L_AUD_ROLE_SLAVE,
} Liot_AudRole_e;
  1. Enum description

Variable

Description

L_AUD_ROLE_MASTER

Codec operates as master

L_AUD_ROLE_SLAVE

Codec operates as slave

4.7 Liot_AudChannel_e

Audio channel.

  1. Enum definition:

typedef enum
{
    L_AUD_DUAL = 1,
    L_AUD_MONO_LEFT,
    L_AUD_MONO_RIGHT,
} Liot_AudChannel_e;
  1. Enum description

Variable

Description

L_AUD_DUAL

Dual channel (stereo) audio

L_AUD_MONO_LEFT

Mono left channel

L_AUD_MONO_RIGHT

Mono right channel

4.8 Liot_AudState_e

Audio state.

  1. Enum definition:

typedef enum
{
    L_AUD_STA_DEINIT,
    L_AUD_STA_IDLE,
    L_AUD_STA_PLAYING,
    L_AUD_STA_PAUSE,
    L_AUD_STA_RESUME,
    L_AUD_STA_STOP,
} Liot_AudState_e;
  1. Enum description

Variable

Description

L_AUD_STA_DEINIT

Audio uninitialized state

L_AUD_STA_IDLE

Audio idle state

L_AUD_STA_PLAYING

Audio playing state

L_AUD_STA_PAUSE

Audio paused state

L_AUD_STA_RESUME

Audio resumed state

L_AUD_STA_STOP

Audio stopped state

4.9 Liot_AudEvent_e

Audio playback event (used in callbacks).

  1. Enum definition:

typedef enum {
    L_AUD_EVT_ERROR   = -1,
    L_AUD_EVT_START   = 0,
    L_AUD_EVT_PAUSE   = 1,
    L_AUD_EVT_FINISH  = 2,
    L_AUD_EVT_CLOSE   = 3,
    L_AUD_EVT_RESUME  = 4,
} Liot_AudEvent_e;
  1. Enum description

Variable

Description

L_AUD_EVT_ERROR

Playback error

L_AUD_EVT_START

Playback started

L_AUD_EVT_PAUSE

Playback paused

L_AUD_EVT_FINISH

Playback finished

L_AUD_EVT_CLOSE

Playback channel closed

L_AUD_EVT_RESUME

Playback resumed

4.10 Liot_AudVolStep_e

Volume step mode.

  1. Enum definition:

typedef enum {
    L_AUD_VOL_STEP_0_1 = 0,
    L_AUD_VOL_STEP_0_01,
} Liot_AudVolStep_e;
  1. Enum description

Variable

Description

L_AUD_VOL_STEP_0_1

Volume step 0.1

L_AUD_VOL_STEP_0_01

Volume step 0.01

4.11 Liot_AudHwConfig_t

Hardware configuration structure.

  1. Structure definition:

typedef struct
{
    int8_t i2cNum;
    int8_t i2sNum;
    int8_t paGpioNum;
    Liot_AudDevice_e codecType;
    Liot_AudChannel_e channel;
    Liot_AudRole_e role;
    Liot_AudMode_e mode;
    Liot_AudFrameSize_e frameSize;
    Liot_AudSample_e samples;
    Liot_AudCb_t callback;
    void *cbContext;
    uint8_t use3A;
} Liot_AudHwConfig_t;
  1. Structure member description

Variable

Description

i2cNum

I2C bus number used for audio communication

i2sNum

I2S bus number used for audio communication

paGpioNum

GPIO number of the PA control pin

codecType

Audio Codec type

channel

Audio channel

role

Codec role

mode

Data stream format

frameSize

Data frame format

samples

Sample rate

callback

Audio event callback (may be NULL)

cbContext

Callback user context

use3A

3A audio processing switch: 1 enables the VEM 3A path, 0 uses the raw DMA path (default)

4.12 Liot_AudAnsConfig_t

3A ANS (Ambient Noise Suppression) configuration structure. The eqBand array length is L_AUD_ANS_EQ_BAND_MAX (32).

typedef struct {
    int8_t    bypass;
    int8_t    mode;
    int16_t   eqBypass;
    uint16_t  eqBand[L_AUD_ANS_EQ_BAND_MAX];
} Liot_AudAnsConfig_t;

Variable

Description

bypass

ANS main switch, whether to bypass ANS

mode

ANS operating mode

eqBypass

EQ bypass switch

eqBand

32 EQ band parameters

4.13 Liot_AudAgcConfig_t

3A AGC (Automatic Gain Control) configuration structure.

typedef struct {
    int8_t     bypass;
    int8_t     targetLevel;
    int8_t     compressionGain;
    int8_t     limiterEnable;
} Liot_AudAgcConfig_t;

Variable

Description

bypass

AGC bypass switch

targetLevel

Target level

compressionGain

Compression gain

limiterEnable

Limiter enable

4.14 Liot_AudAecConfig_t

3A AEC (Acoustic Echo Cancellation) configuration structure.

typedef struct {
    int8_t      bypass;
    int16_t     delay;
    int8_t      cngMode;
    int8_t      echoMode;
    int8_t      nlpFlag;
} Liot_AudAecConfig_t;

Variable

Description

bypass

AEC bypass switch

delay

Echo path delay parameter

cngMode

Comfort Noise Generation (CNG) mode

echoMode

Echo processing mode

nlpFlag

Nonlinear Processing (NLP) switch

4.15 Liot_AudRecordCb_t

PCM streaming recording callback function type. The pcmData in the callback points to the current data segment; for asynchronous use, copy the data promptly inside the callback.

typedef void (*Liot_AudRecordCb_t)(uint8_t* pcmData, uint16_t len);

Parameter

Description

pcmData

PCM data processed by the VEM 3A pipeline

len

PCM data length (bytes)

5 API Function Details

5.1 Liot_AudioInit

Audio initialization.

  1. Declaration

Liot_AudErr_e Liot_AudioInit(Liot_AudHwConfig_t *config);
  1. Parameters

  • config: [In] Audio format configuration.

  1. Return value

Error code, see Liot_AudErr_e.

5.2 Liot_AudioDeInit

Audio deinitialization.

  1. Declaration

Liot_AudErr_e Liot_AudioDeInit(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e.

5.3 Liot_AudioSetVolume

Set software volume (0-100).

  1. Declaration

Liot_AudErr_e Liot_AudioSetVolume(int Volume);
  1. Parameters

  • Volume: [In] Volume value (0-100).

  1. Return value

Error code, see Liot_AudErr_e.

5.4 Liot_AudioGetVolume

Get current software volume.

  1. Declaration

Liot_AudErr_e Liot_AudioGetVolume(int *Volume);
  1. Parameters

  • Volume: [Out] Volume value.

  1. Return value

Error code, see Liot_AudErr_e.

5.5 Liot_AudioSetCodecVolume

Set Codec hardware volume register.

  1. Declaration

Liot_AudErr_e Liot_AudioSetCodecVolume(int Volume);
  1. Parameters

  • Volume: [In] Volume value (range depends on Codec).

  1. Return value

Error code, see Liot_AudErr_e.

5.6 Liot_AudioGetCodecVolume

Get Codec hardware volume register value.

  1. Declaration

Liot_AudErr_e Liot_AudioGetCodecVolume(int *Volume);
  1. Parameters

  • Volume: [Out] Volume value.

  1. Return value

Error code, see Liot_AudErr_e.

5.7 Liot_AudioSetMicVolume

Set microphone volume.

  1. Declaration

Liot_AudErr_e Liot_AudioSetMicVolume(uint8_t micGain, int micVolume);
  1. Parameters

  • micGain: [In] Microphone gain.

  • micVolume: [In] Microphone volume value.

  1. Return value

Error code, see Liot_AudErr_e.

5.8 Liot_AudioSetVolMode

Set volume step mode.

  1. Declaration

Liot_AudErr_e Liot_AudioSetVolMode(Liot_AudVolStep_e mode);
  1. Parameters

  • mode: [In] Step mode, see Liot_AudVolStep_e.

  1. Return value

Error code, see Liot_AudErr_e.

5.9 Liot_AudioPlay

Play PCM audio data (asynchronous).

  1. Declaration

Liot_AudErr_e Liot_AudioPlay(uint8_t* data, int datalen);
  1. Parameters

  • data: [In] Audio data to play.

  • datalen: [In] Data length (bytes).

  1. Return value

Error code, see Liot_AudErr_e.

5.10 Liot_AudioRecord

Record audio (blocking, until datalen bytes are recorded).

  1. Declaration

Liot_AudErr_e Liot_AudioRecord(uint8_t* data, int datalen);
  1. Parameters

  • data: [Out] Recording buffer.

  • datalen: [In] Buffer length (bytes).

  1. Return value

Error code, see Liot_AudErr_e.

5.11 Liot_AudioPlayPause

Pause playback.

  1. Declaration

Liot_AudErr_e Liot_AudioPlayPause(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e.

5.12 Liot_AudioPlayResume

Resume playback.

  1. Declaration

Liot_AudErr_e Liot_AudioPlayResume(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e.

5.13 Liot_AudioPlayFile

Play audio file (raw PCM stream).

  1. Declaration

Liot_AudErr_e Liot_AudioPlayFile(char* fileName);
  1. Parameters

  • fileName: [In] File path.

  1. Return value

Error code, see Liot_AudErr_e.

5.14 Liot_AudioWaitPlayFinish

Wait for all audio in the current queue to finish playing.

  1. Declaration

Liot_AudErr_e Liot_AudioWaitPlayFinish(int timeout);
  1. Parameters

  • timeout: [In] Timeout in seconds, or LIOT_WAIT_FOREVER.

  1. Return value

Error code, see Liot_AudErr_e.

5.15 Liot_AudioStop

Immediately stop playback and clear the queue.

  1. Declaration

Liot_AudErr_e Liot_AudioStop(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e.

5.16 Liot_AudioPlayMp3File

Play MP3 file.

  1. Declaration

Liot_AudErr_e Liot_AudioPlayMp3File(char* fileName);
  1. Parameters

  • fileName: [In] File path.

  1. Return value

Error code, see Liot_AudErr_e.

5.17 Liot_AudioPlayMp3

Play MP3 data from memory.

  1. Declaration

Liot_AudErr_e Liot_AudioPlayMp3(uint8_t* data, int datalen);
  1. Parameters

  • data: [In] MP3 data buffer.

  • datalen: [In] Data length (bytes).

  1. Return value

Error code, see Liot_AudErr_e.

5.18 Liot_AudioPlayWavFile

Play WAV file.

  1. Declaration

Liot_AudErr_e Liot_AudioPlayWavFile(char* fileName);
  1. Parameters

  • fileName: [In] File path.

  1. Return value

Error code, see Liot_AudErr_e.

5.19 Liot_AudioPlayWav

Play WAV data from memory (including WAV header).

  1. Declaration

Liot_AudErr_e Liot_AudioPlayWav(uint8_t* data, int datalen);
  1. Parameters

  • data: [In] WAV data buffer (including 44-byte header).

  • datalen: [In] Total data length (bytes).

  1. Return value

Error code, see Liot_AudErr_e.

5.20 Liot_AudioMp3StreamStart

Start an MP3 streaming playback session, initializing the decoder only once.

  1. Declaration

Liot_AudErr_e Liot_AudioMp3StreamStart(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e.

5.21 Liot_AudioMp3StreamPlay

Feed a chunk of MP3 data to the streaming decoder for decoding and playback.

  1. Declaration

Liot_AudErr_e Liot_AudioMp3StreamPlay(uint8_t* data, int datalen);
  1. Parameters

  • data: [In] MP3 data chunk.

  • datalen: [In] Data length (bytes).

  1. Return value

Error code, see Liot_AudErr_e.

5.22 Liot_AudioMp3StreamStop

Stop MP3 streaming playback and release decoder resources.

  1. Declaration

Liot_AudErr_e Liot_AudioMp3StreamStop(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e.

5.23 Liot_AudioSetAns

Set 3A ANS parameters. Liot_AudHwConfig_t.use3A must be set to 1 during audio initialization to enable the 3A processing pipeline.

  1. Declaration

Liot_AudErr_e Liot_AudioSetAns(Liot_AudAnsConfig_t *cfg);
  1. Parameters

  • cfg: [In] ANS configuration, see Liot_AudAnsConfig_t. Returns L_AUD_ERR_INVALID_PARAM if NULL.

  1. Return value

Error code, see Liot_AudErr_e. Returns L_AUD_ERR_NO_SUPPORT if the 3A feature is not enabled.

5.24 Liot_AudioSetAgc

Set 3A AGC parameters.

  1. Declaration

Liot_AudErr_e Liot_AudioSetAgc(Liot_AudAgcConfig_t *cfg);
  1. Parameters

  • cfg: [In] AGC configuration, see Liot_AudAgcConfig_t. Returns L_AUD_ERR_INVALID_PARAM if NULL.

  1. Return value

Error code, see Liot_AudErr_e. Returns L_AUD_ERR_NO_SUPPORT if the 3A feature is not enabled.

5.25 Liot_AudioSetAec

Set 3A AEC parameters.

  1. Declaration

Liot_AudErr_e Liot_AudioSetAec(Liot_AudAecConfig_t *cfg);
  1. Parameters

  • cfg: [In] AEC configuration, see Liot_AudAecConfig_t. Returns L_AUD_ERR_INVALID_PARAM if NULL.

  1. Return value

Error code, see Liot_AudErr_e. Returns L_AUD_ERR_NO_SUPPORT if the 3A feature is not enabled.

5.26 Liot_AudioRecordStream

Start PCM streaming recording. Once started, audio data is continuously delivered via the callback; only available when use3A = 1.

  1. Declaration

Liot_AudErr_e Liot_AudioRecordStream(Liot_AudRecordCb_t callback);
  1. Parameters

  • callback: [In] PCM data callback, see Liot_AudRecordCb_t. Cannot be NULL.

  1. Return value

Error code, see Liot_AudErr_e. Returns L_AUD_ERR_EXECUTE if the 3A path is not enabled; returns L_AUD_ERR_NO_SUPPORT if the corresponding feature is not compiled in.

5.27 Liot_AudioRecordStreamStop

Stop PCM streaming recording.

  1. Declaration

Liot_AudErr_e Liot_AudioRecordStreamStop(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e. The stop interface typically returns L_AUD_ERR_SUCCESS; returns L_AUD_ERR_NO_SUPPORT if the corresponding feature is not compiled in.

5.28 Liot_AudioPlayStream

Write a segment of PCM data to the 3A PCM streaming playback channel. Returns after the data is written to the internal buffer; only available when use3A = 1.

  1. Declaration

Liot_AudErr_e Liot_AudioPlayStream(uint8_t* data, uint16_t len);
  1. Parameters

  • data: [In] PCM data buffer.

  • len: [In] PCM data length (bytes).

  1. Return value

Error code, see Liot_AudErr_e. Returns L_AUD_ERR_EXECUTE if the 3A path is not enabled; returns L_AUD_ERR_NO_SUPPORT if the corresponding feature is not compiled in.

5.29 Liot_AudioPlayStreamStop

Stop 3A PCM streaming playback and wait for the written data to finish playing.

  1. Declaration

Liot_AudErr_e Liot_AudioPlayStreamStop(void);
  1. Parameters

None.

  1. Return value

Error code, see Liot_AudErr_e. Returns L_AUD_ERR_NO_SUPPORT if the corresponding feature is not compiled in.

6 Code Example

Refer to the example code in LSDK\examples\demo\src\demo_audio.c.

#include "liot_type.h"
#include "liot_audio.h"
#include "liot_log.h"
#include "liot_os.h"
#include "liot_gpio2.h"

#define TEST_PLAY
//#define TEST_RECORD

#ifdef TEST_PLAY
__attribute__((aligned(16))) uint8_t audio16k_16[] = {
    //audio source data
}
#endif

#ifdef TEST_RECORD
#define TEST_CACHE_LEN (1280)
__attribute__((aligned(16))) uint8_t audioRecord[TEST_CACHE_LEN] = {0};
#endif

void liot_audio_demo_thread(void *argv)
{
    liot_rtos_task_sleep_ms(2000);

    Liot_AonPowerCtl(TRUE);
    Liot_SetVoltage(L_DOMAIN_ALL, L_VOLT_3_30V);

    Liot_AudHwConfig_t cfg = {
        .i2cNum    = 1,
        .i2sNum    = 0,
        .paGpioNum = 0,
        .codecType = L_AUD_ES8311,
        .channel   = L_AUD_MONO_RIGHT,
        .role      = L_AUD_ROLE_SLAVE,
        .mode      = L_AUD_MODE_I2S,
        .frameSize = L_AUD_FRAMESIZE_16_16,
        .samples   = L_AUD_16K_SAMPLES,
    };

    liot_trace("Liot_AudioInit");
    Liot_AudioInit(&cfg);

    liot_trace("Liot_AudioSetVolume");
    Liot_AudioSetVolume(50);
    Liot_AudioSetMicVolume(8, 200);

    while(1)
    {
        #ifdef TEST_PLAY
        liot_trace("Liot_AudioPlay ...");
        Liot_AudioPlay(audio16k_16, sizeof(audio16k_16));
        liot_rtos_task_sleep_ms(5000);
        #endif

        #ifdef TEST_RECORD
        liot_trace("Liot_AudioRecord ...");
        Liot_AudioRecord(audioRecord, TEST_CACHE_LEN);
        Liot_AudioPlay(audioRecord, TEST_CACHE_LEN);
        liot_rtos_task_sleep_ms(1);
        #endif
    }
    Liot_AudioDeInit();
    liot_rtos_task_delete(0);
}