请问一个音频 I2S 通讯中 DMA bufsize 最大为4092的相关问题。
Posted: Sat Jun 15, 2024 11:29 am
您好:
我正在使用 esp-idf-v5.2,为 esp32-s3 编译,开发板为ESP32-S3_DevKitM-1。
我在外部连接了pcm1808 芯片作为从机为S3传输音频帧。
我已经了解的如下:尽管pcm1808 发送的数据宽度为 I2S_DATA_BIT_WIDTH_24BIT (24位3字节),但实际ESP I2S DMA buffer仍然是按照每个数据4字节的宽度用i2s_dma_calloc申请到内存,我的应用中只需要I2S接收单声道音频,所以只需要一个左声道,由于 DMA bufsize 最大为4092,是否也就是限制了我的通道配置中dma_frame_num最大只能1023,也就是每帧最大1023个样本?
1023 *声道数*4字节位宽 = 4092
但事实上我需要在随后的音频帧处理中用到 ESP dsp库的FFT函数处理,FFT处理的样本数为2的n次方,1024个样本数是我需要的,512个显然对于我的应用不够。在这种情况下我是否无法从I2S DMA buffer得到1024个样本数据呢?如果是真的这样的话我也许只能再补0凑足1024个样本数再进行FFT计算。
我的I2S 初始化代码如下:
得到的调试信息包含:
D (34676) i2s_common: rx channel is registered on I2S0 successfully
W (34676) i2s_common: dma frame num is out of dma buffer size, limited to 10
D (34676) i2s_common: DMA malloc info: dma_desc_num = 2, dma_desc_buf_size = data_bit_width = 4092
D (34696) i2s_std: Clock division info: [sclk] 160000000 Hz [mdiv] 13 [mclk]] 1536000 Hz
D (34706) i2s_common: MCLK is pinned to GPIO42 on I2S0
D (34706) i2s_std: The rx channel on I2S0 has been initialized to STD mode successfully
D (34716) i2s_common: i2s rx channel enabled
我的另一个问题是:
以上初始化代码在编译中出现了警告:
In function 'i2s_example_init_std_duplex':
warning: initialized field overwritten [-Woverride-init]
70 | .slot_cfg.slot_mode = I2S_SLOT_MODE_MONO,
| ^~~~~~~~~~~~~~~~~~
note: (near initialization for 'std_cfg.slot_cfg.slot_mode')
warning: initialized field overwritten [-Woverride-init]
71 | .slot_cfg.slot_mask = I2S_STD_SLOT_LEFT,
| ^~~~~~~~~~~~~~~~~
note: (near initialization for 'std_cfg.slot_cfg.slot_mask')
warning: initialized field overwritten [-Woverride-init]
73 | .slot_cfg.bit_shift = true,
| ^~~~
note: (near initialization for 'std_cfg.slot_cfg.bit_shift')
warning: initialized field overwritten [-Woverride-init]
74 | .slot_cfg.left_align = false,
请问这是我代码中两个配置函数使用的顺序问题吗?
如果您能提供帮助非常感谢!
我正在使用 esp-idf-v5.2,为 esp32-s3 编译,开发板为ESP32-S3_DevKitM-1。
我在外部连接了pcm1808 芯片作为从机为S3传输音频帧。
我已经了解的如下:尽管pcm1808 发送的数据宽度为 I2S_DATA_BIT_WIDTH_24BIT (24位3字节),但实际ESP I2S DMA buffer仍然是按照每个数据4字节的宽度用i2s_dma_calloc申请到内存,我的应用中只需要I2S接收单声道音频,所以只需要一个左声道,由于 DMA bufsize 最大为4092,是否也就是限制了我的通道配置中dma_frame_num最大只能1023,也就是每帧最大1023个样本?
1023 *声道数*4字节位宽 = 4092
但事实上我需要在随后的音频帧处理中用到 ESP dsp库的FFT函数处理,FFT处理的样本数为2的n次方,1024个样本数是我需要的,512个显然对于我的应用不够。在这种情况下我是否无法从I2S DMA buffer得到1024个样本数据呢?如果是真的这样的话我也许只能再补0凑足1024个样本数再进行FFT计算。
我的I2S 初始化代码如下:
Code: Select all
// 新建I2S通道配置、新建I2S通道,新建I2S std配置、初始换通道的std模式
static void i2s_example_init_std_duplex(void)
{
// i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_SLAVE);
i2s_chan_config_t chan_cfg = {
.id = I2S_NUM_AUTO,
.role = I2S_ROLE_MASTER,
.dma_desc_num = 2,
.dma_frame_num = 1024,
.auto_clear = false,
.intr_priority = 0,
};
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_chan));
i2s_std_config_t std_cfg = {
// .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(PCM1808_SAMPLE_RATE),
.clk_cfg.sample_rate_hz = PCM1808_SAMPLE_RATE,
.clk_cfg.clk_src = I2S_CLK_SRC_DEFAULT, // I2S_CLK_SRC_EXTERNAL,
.clk_cfg.mclk_multiple = I2S_MULTIPLE,
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_24BIT, I2S_SLOT_MODE_STEREO),
.slot_cfg.slot_mode = I2S_SLOT_MODE_MONO,
.slot_cfg.slot_mask = I2S_STD_SLOT_LEFT,
.slot_cfg.bit_shift = true,
.slot_cfg.left_align = false,
.gpio_cfg = {
.mclk = I2S_STD_MCLK_EXTERNAL_IO1, // some codecs may require mclk signal, this example doesn't need it
.bclk = I2S_BCLK_IO1,
.ws = I2S_STD_WS_IO1,
.dout = I2S_STD_DOUT_IO1,
.din = I2S_STD_DIN_IO1, // In duplex mode, bind output and input to a same gpio can loopback internally
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
};
ESP_ERROR_CHECK(i2s_channel_init_std_mode(rx_chan, &std_cfg));
}
D (34676) i2s_common: rx channel is registered on I2S0 successfully
W (34676) i2s_common: dma frame num is out of dma buffer size, limited to 10
D (34676) i2s_common: DMA malloc info: dma_desc_num = 2, dma_desc_buf_size = data_bit_width = 4092
D (34696) i2s_std: Clock division info: [sclk] 160000000 Hz [mdiv] 13 [mclk]] 1536000 Hz
D (34706) i2s_common: MCLK is pinned to GPIO42 on I2S0
D (34706) i2s_std: The rx channel on I2S0 has been initialized to STD mode successfully
D (34716) i2s_common: i2s rx channel enabled
我的另一个问题是:
以上初始化代码在编译中出现了警告:
In function 'i2s_example_init_std_duplex':
warning: initialized field overwritten [-Woverride-init]
70 | .slot_cfg.slot_mode = I2S_SLOT_MODE_MONO,
| ^~~~~~~~~~~~~~~~~~
note: (near initialization for 'std_cfg.slot_cfg.slot_mode')
warning: initialized field overwritten [-Woverride-init]
71 | .slot_cfg.slot_mask = I2S_STD_SLOT_LEFT,
| ^~~~~~~~~~~~~~~~~
note: (near initialization for 'std_cfg.slot_cfg.slot_mask')
warning: initialized field overwritten [-Woverride-init]
73 | .slot_cfg.bit_shift = true,
| ^~~~
note: (near initialization for 'std_cfg.slot_cfg.bit_shift')
warning: initialized field overwritten [-Woverride-init]
74 | .slot_cfg.left_align = false,
请问这是我代码中两个配置函数使用的顺序问题吗?
如果您能提供帮助非常感谢!