[MCU] RVB2601评估板试用4: 麦克风录音测试

我爱下载   2021-8-11 13:31 楼主

麦克风录音测试

1、概述

    RVB2601采用ES7210进行麦克风的数字化采样。本次测试,学习使用I2S接口从ES7210中进行一定时间的麦克风音频数据采集和暂存。

2、驱动描述

2.1 硬件接口原理

131252i1a682a1kp1h88bb.jpg

CH2601采用I2C接口完成ES7210的配置,采用I2S接口读取ES7210的转换数据,其接口如图所示。

序号

ES7210

GPIO

1

I2C SCL

PA8(I2C0_SCL

2

I2C SDA

PA9I2C0_SDA

3

ADC MCLK

PA10I2S0_MCLK

4

ADC BCLK

I2S4_SCLK

5

ADC LRLK

I2S4_LSCLK

6

ADC DAT1

I2S4_DATA

7

ADC DAT2

I2S5_DATA

2.2 软件驱动设计 CODEC

CODEC在这里指的是同时具有D/A(数字讯号转换成模拟讯号)和A/D(模拟讯号转换成数字讯号)转换功能的编解码器,播放音乐的时候用到的是D/A转换功能。在录音的时候用到的是A/D转换功能。

在接口中,D/A指的是输出通道,A/D指的是输入通道。我们这里主要使用AD的输入通道

本次使用CODECCSI接口如下所示:

 

函数

说明

csi_codec_init

CODEC设备初始化

csi_codec_uninit

CODEC设备去初始化

csi_codec_input_open

CODEC输入通道打开

csi_codec_input_config

CODEC输入通道配置

csi_codec_input_analog_gain

CODEC输入通道设置模拟增益

csi_codec_input_start

CODEC接收输入音频流

csi_codec_input_stop

CODEC结束接收输入音频流

csi_codec_input_read_async

CODEC输入通道异步模式读取数据

csi_codec_input_read

CODEC输入通道同步模式读取数据

csi_codec_input_attach_callback

CODEC输入通道注册回调函数

csi_codec_input_detach_callback

CODEC输入通道注销回调函数

csi_codec_input_close

CODEC输入通道关闭

csi_codec_input_link_dma

CODEC输入通道配置DMA


CODEC设备初始化CODEC用于输入接口详细说明

  • CODEC设备初始化

    csi_error_t csi_codec_init(csi_codec_t *codec, uint32_t idx)

    功能描述:

            通过设备ID初始化对应的CODEC实例。

    参数:     codec: 设备句柄(需要用户申请句柄空间)。

        idx: 设备ID。

    返回值:

            CSI_OK: 初始化成功。

            CSI_ERROR: 初始化失败。

    csi_codec_t

成员

类型

说明

dev

csi_dev_t

csi设备统一句柄

output_chs

csi_codec_output_t

输出通道句柄

input_chs

csi_codec_input_t

输入通道句柄

*priv

void

设备私有变量

    ringbuffer_t

成员

类型

描述

buffer

uint8_t *

环形缓冲区地址

size

uint32_t

环形缓冲区大小

write

uint32_t

环形缓冲区当前写指针位置

read

uint32_t

环形缓冲区当前读指针位置

data_len

uint32_t

环形缓冲区当前可读数据长度

    csi_codec_output_t

成员

类型

描述

codec

csi_codec_t *

CODEC设备句柄

ch_idx

uint32_t

当前通道的序号

callback

void (callback)(csi_codec_output_t output, csi_codec_event_t event, void *arg)

当前通道的回调

arg

void *

当前通道的用户参数

ring_buf

ringbuffer_t *

当前通道的缓冲器句柄

period

uint32_t

设置完成多少数据发送上报周期

sound_channel_num

uint32_t

声道数

state

csi_state_t

当前通道的状态

dma

csi_dma_ch_t *

当前通道的DMA句柄

next

struct csi_codec_output *

下一个输出通道的地址指针

priv

void *

设备私有变量

    csi_codec_input_t

成员

类型

描述

codec

csi_codec_t *

CODEC设备句柄

ch_idx

uint32_t

当前通道的序号

callback

void (callback)(csi_codec_input_t input, csi_codec_event_t event, void *arg)

当前通道的回调

arg

void *

当前通道的用户参数

ring_buf

ringbuffer_t *

当前通道的缓冲器句柄

period

uint32_t

设置完成多少数据接收上报周期

sound_channel_num

uint32_t

声道数

state

csi_state_t

当前通道的状态

dma

csi_dma_ch_t *

当前通道的DMA句柄

next

struct csi_codec_input *

下一个输入通道的地址指针

priv

void *

设备私有变量

 

  • CODEC设备去初始化

    void csi_codec_uninit(csi_codec_t *codec)

        功能描述:

            codec实例反初始化。该接口会清理并释放相关的软硬件资源。

        参数:

        codec: 实例句柄。

        返回值:

            无。

  • CODEC输入通道打开

    csi_error_t csi_codec_input_open(csi_codec_t *codec, csi_codec_input_t *ch, uint32_t ch_idx)

        功能描述:

            将输入通道的ch句柄注册到codec句柄中。初始化输入通道有关的硬件资源。

        参数:

        codec: codec实例句柄。

        ch: 输入通道的实例句柄。

        ch_idx:通道的ID。

        返回值:

                错误码csi_error_t。

 

  • CODEC输入通道配置

    csi_error_t csi_codec_input_config(csi_codec_input_t *ch, csi_codec_input_config_t *config)

        功能描述:

            根据传入的配置配置输入通道。配置输入通道采样宽度、采样比率、设置缓冲区地址、设置输入通道的输出模式(差分输入还是单端输入)。

        参数

        ch:通道实例句柄。

        config:配置参数。

        返回值:

                    错误码csi_error_t。

  • CODEC输入通道注册回调函数

    csi_error_t csi_codec_input_attach_callback(csi_codec_input_t *ch, void *callback, void *arg)

        功能描述:

                设置输入通道回调函数。

        参数:

            csi_codec_input_t:输入通道实例句柄。

            callback:codec:输入通道的事件回调函数(一般在上下文执行)。

            arg:回调函数参数(可选,由用户定义)。

        返回值:

                            错误码csi_error_t。

    callback

        void (*callback)(csi_codec_input_t *input, csi_codec_event_t event, void *arg)

            其中 input为输入通道句柄,event 为传给回调函数的事件类型,arg 为用户自定义的回调函数对应的参数。

 

    codec 回调事件枚举类型csi_codec_event_t定义如下:

类型

说明

CODEC_EVENT_PERIOD_READ_COMPLETE

接收period完成

CODEC_EVENT_PERIOD_WRITE_COMPLETE

发送period完成

CODEC_EVENT_WRITE_BUFFER_EMPTY

发送缓冲区已经空

CODEC_EVENT_READ_BUFFER_FULL

接收缓冲区已经满

CODEC_EVENT_TRANSFER_ERROR

传输错误

  • CODEC输入通道注销回调函数

    void csi_codec_input_detach_callback(csi_codec_input_t *ch)

        功能描述:

                注销CODEC 输入通道的回调函数。

        参数:

        ch:通道实例句柄。

        返回值:

                无。

  • CODEC输入通道关闭

    void csi_codec_input_close(csi_codec_input_t *ch)

        功能描述:

            关闭输入通道。调用该接口会马上停止接收数据。

        参数:

        ch:通道实例句柄。

  • CODEC输入通道配置DMA

    csi_error_t csi_codec_input_link_dma(csi_codec_input_t *ch, csi_dma_ch_t *dma)

        功能描述:

            输入通道连接DMA。

        参数:

        ch:输入通道的实例句柄。

        dma:dma实例句柄。

        返回:

                错误码csi_error_t。

 

  • CODEC接收输入音频流

    csi_error_t csi_codec_input_start(csi_codec_input_t *ch)

        功能描述:

                输入通道开始数据流。

        参数:

        ch:输入通道的实例句柄。

        返回值:

                错误码csi_error_t。

  • CODEC结束接收输入音频流

    csi_error_t csi_codec_input_stop(csi_codec_input_t *ch)

        功能描述:

                输入通道结束数据流。

        参数:

        ch:输入通道的实例句柄。

        返回值:

                错误码csi_error_t。

 

  • CODEC输入通道设置模拟增益

    csi_error_t csi_codec_input_analog_gain(csi_codec_input_t *ch, uint32_t val)

        功能描述:

            设置输入通道模拟增益。

        参数:

        ch:输入通道的实例句柄。

        val: 增益的DB值。

        返回值:

        错误码csi_error_t。

3、测试程序

    本测试程序通过RVB2601建立一个通过I2S接口读取ES7210录音测试程序,数据录取结束后将数据打印到串口终端

3.1 初始化

初始化代码参考wiki上的基本配置信息完成。

csi_codec_input_config_t input_config;
/* init函数的idx参数,请根据soc的实际情况进行选择 */
ret = csi_codec_init(&codec, 0);;
if (ret != CSI_OK) {
return -1;
}

/* input ch config */
csi_codec_input_attach_callback(&codec_input_ch, codec_input_event_cb_fun, NULL);

codec_input_ch.period = INPUT_BUF_SIZE/2;
codec_input_ch.ring_buf = &input_ring_buffer;
csi_codec_input_open(&codec, &codec_input_ch, 0);

input_config.bit_width = 16;
input_config.sample_rate = 8000;
input_config.buffer = input_buf;
input_config.buffer_size = INPUT_BUF_SIZE;
input_config.period = INPUT_BUF_SIZE/2;
input_config.mode = CODEC_INPUT_DIFFERENCE;
csi_codec_input_config(&codec_input_ch,&input_config);

csi_codec_input_link_dma(&codec_input_ch,&dma_ch_input_handle);

csi_codec_input_start(&codec_input_ch);

3.2 事件处理

static void codec_input_event_cb_fun(csi_codec_input_t *i2s, csi_codec_event_t event, void *arg)
{
    if (event == CODEC_EVENT_PERIOD_READ_COMPLETE) {
        cb_input_transfer_flag = 1;
    }
}

 

3.3 数据的显示

int i;
uint16_t *p = (uint16_t *)(repeater_data_addr + 24*1024);
for(i=0;i<48*512;i++)
{
	if(i%16 == 0)
		printf("\n");
	printf("%04x ",p);
}

3.4 通过console调用

static void mic_handler(char *wbuf, int wbuf_len, int argc, char **argv)
{
    csi_error_t ret;
    csi_codec_input_config_t input_config;
    ret = csi_codec_init(&codec, 0);

    if (ret != CSI_OK) {
        printf("csi_codec_init error\n");
        return ;
    }

    codec_input_ch.ring_buf = &input_ring_buffer;
    csi_codec_input_open(&codec, &codec_input_ch, 0);
    
	/* input ch config */
    csi_codec_input_attach_callback(&codec_input_ch, codec_input_event_cb_fun, NULL);
    input_config.bit_width = 16;
    input_config.sample_rate = 8000;
    input_config.buffer = input_buf;
    input_config.buffer_size = INPUT_BUF_SIZE;
    input_config.period = 1024;
    input_config.mode = CODEC_INPUT_DIFFERENCE;
    csi_codec_input_config(&codec_input_ch, &input_config);
    csi_codec_input_analog_gain(&codec_input_ch, 0xbf);
    csi_codec_input_link_dma(&codec_input_ch, &dma_ch_input_handle);

    printf("start recorder\n");
    csi_codec_input_start(&codec_input_ch);

  while (new_data_flag < 48) {
            if (cb_input_transfer_flag) {
                csi_codec_input_read_async(&codec_input_ch, repeater_data_addr + (new_data_flag * 1024), 1024);
                cb_input_transfer_flag = 0U;
                new_data_flag ++;
         }
     }
aos_msleep(100);
	printf("record sound data: \n");
	int i;
	uint16_t *p = (uint16_t *)(repeater_data_addr + 24*1024);
	for(i=0;i<512;i++)
	{
		if(i%16 == 0)
			printf("\n");
		printf("%04x ",p);
		
	}

    printf("stop reorder\n");
    csi_codec_input_stop(&codec_input_ch);
    csi_codec_input_link_dma(&codec_input_ch, NULL);
    csi_codec_input_detach_callback(&codec_input_ch);
    csi_codec_uninit(&codec);
    return;
}
int cli_reg_cmd_ft(void)
{
static const struct cli_command mic_cmd_info = {
        "mic",
        "mic",
        mic_handler,
    };

    aos_cli_register_command(&mic_cmd_info);
    return 0;
}

 

4、实测效果演示:

4.1 录取数据开始

131252ymm3l6mtwrut7nu7.png

 

4.2 展示数据结束:

131252dsnd0ruz0gh0845g.png

4.3 波形数据展示

131252gbtdxddiiy7mz5v5.png

本帖最后由 我爱下载 于 2021-8-11 13:41 编辑

回复评论 (3)

赞一个

加油!在电子行业默默贡献自己的力量!:)
点赞  2021-8-11 18:08

听着效果怎么样

点赞  2021-8-11 19:13

有没有相关的资料能不能共享一下,什么格式的都行

点赞  2021-8-14 23:48
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复