【Audio】I2S传输PCM音频数据分析总结(二)

相关文章

1.《【Audio】I2S传输PCM音频数据分析总结(一)》
2.《【Audio】I2S传输PCM音频数据分析总结(二)》
3.《【Audio】基于STM32 I2S移植WM8978 Audio Codec驱动》

1. 前言

I2S传输PCM音频数据分析总结》主要是介绍PCM音频数据是如何通过I2S进行传输的,主要是分成2个部分:

  • PCM音频数据介绍
  • I2S协议介绍

上一篇文章已经有介绍PCM音频数据,本篇文章主要是以I2S协议来介绍。

2. I2S 简介

Inter-IC Sount Bus(I2S)是飞利浦半导体公司(现为恩智浦半导体公司)针对数字音频设备之间的音频数据传输而制定的一种总线标准。在飞利浦公司的 I2S 标准中,既规定了硬件接口规范,也规定了数字音频数据的格式。

3. I2S 特点

I2S总线只处理音频数据,而其它控制信号,是分开传输的。在比较常用的CODEC音频芯片基本都是I2SI2C搭配,I2S传输音频数据I2C传输命令控制。主要特点如下:

  1. 支持全双工/半双工:全双工是需要2个Data线,半双工是1个Data线。
  2. 支持主/从模式:主模式需要提供I2S通信的SCKWS信号。
  3. I2S支持多声道数据传输:通过WS信号控制声道的选择。

下面是《I2S bus specification》协议文档里面的截图,它是典型I2S信号时序图,产生SCKWS的信号端就是主设备,用MASTER表示,具体如下:
在这里插入图片描述
根据上图我们可以知道I2S总线一个是三条数据信号线

  1. BCLK:串行时钟,也叫位时钟,对应数字音频的每一位数据。对应数字音频的每一位数据,SCK都有1个脉冲。SCK的频率=2×采样频率×采样位数
  2. WS:字段(声道)选择,帧时钟LRCK(左右时钟),用于选择左右声道。为“0”表示正在传输的是左声道的数据, 为“1”表示正在传输的是右声道的数据。用于切换左右声道的数据。WS的频率=采样频率
  3. SD:串行数据,用二进制补码来表示音频数据(数据传输从高位到低位)。

I2S总线半双工是3条数据线,但是全双工是4条数据线。下面的截图是WM8978 CODEC音频编解码器芯片,它采用全双工4条数据线I2S接口,并且通过I2C接口进行控制。(备注:后面还会有一篇专门介绍WM8978的驱动移植)
在这里插入图片描述

4. I2S总线时序图

音频协议目前主要有4种标准,总体遵循I2S总线协议,但是细节有一些差异:

  • I2S Philips 标准
  • MSB 对齐标准
  • LSB 对齐标准
  • PCM 标准

4.1 I2S Philips 标准

使用 WS 信号来指示当前正在发送的数据所属的通道。该信号从当前通道数据的第一个位(MSB) 之前的一个时钟开始有效。
在这里插入图片描述
发送方在时钟信号 (CK) 的下降沿改变数据,接收方在上升沿读取数据。WS 信号也在 CK 的下降沿变化。

举例:下面是在播放采样率44.1KHz 16bit双声道正弦波1KHz的PCM音频数据时,用逻辑分析仪抓取的I2S数据,具体如下:
在这里插入图片描述
下面时序图显示了如何发送一个24bit的音频数据,24bit高位先发送,剩余8bit强制清零。因为一般CPU是字(32Bit)对齐方式,所以这里设计时将剩余的8bit用0来填充:
在这里插入图片描述

4.2 MSB 对齐标准

MSB标准同时生成 WS 信号第一个数据位(即 MSBit)。这里和 I2S Philips 标准存在的差异,如图所示:
在这里插入图片描述
发送方在时钟信号的下降沿改变数据;接收方在上升沿读取数据

下面MSB标准时序图显示了如何发送一个24bit的音频数据,和前面一样,24bit高位先发送,剩余8bit强制清零。在这里插入图片描述

4.3 LSB 对齐标准

该标准与 MSB 对齐标准类似(对于 16 位和 32 位全精度帧格式,没有任何不同)
在这里插入图片描述
下面是LSB标准时序图显示了如何发送一个24bit的音频数据,因为是LSB左对齐,所以高8bit强制清零先发送,然后24bit有效数据从高位再发送。
在这里插入图片描述

4.4 PCM 标准

对于 PCM 标准,无需使用通道信息。有两种 PCM 模式:短帧长帧
在这里插入图片描述
对于长帧同步,在主模式下会将 WS 信号持续 13 个周期。
对于短帧同步,WS 同步信号的持续时间仅为一个周期。
在这里插入图片描述

  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的音频PCM数据相似度分析的C语言源码示例: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #define SAMPLE_RATE 44100 // 采样率 #define NUM_SAMPLES 44100 // 采样数 #define WINDOW_SIZE 512 // 窗口大小 #define HOP_SIZE 256 // 跳跃大小 typedef struct { float* data; int size; } AudioBuffer; float calculate_rms(AudioBuffer* buffer) { float sum = 0.0f; for (int i = 0; i < buffer->size; i++) { sum += buffer->data[i] * buffer->data[i]; } return sqrtf(sum / buffer->size); } float calculate_similarity(AudioBuffer* buffer1, AudioBuffer* buffer2) { int num_windows = (NUM_SAMPLES - WINDOW_SIZE) / HOP_SIZE + 1; float* window1 = (float*)malloc(sizeof(float) * WINDOW_SIZE); float* window2 = (float*)malloc(sizeof(float) * WINDOW_SIZE); float* buffer1_rms = (float*)malloc(sizeof(float) * num_windows); float* buffer2_rms = (float*)malloc(sizeof(float) * num_windows); for (int i = 0; i < num_windows; i++) { // 提取窗口 for (int j = 0; j < WINDOW_SIZE; j++) { window1[j] = buffer1->data[i * HOP_SIZE + j]; window2[j] = buffer2->data[i * HOP_SIZE + j]; } // 计算两个窗口的RMS buffer1_rms[i] = calculate_rms(&(AudioBuffer){ window1, WINDOW_SIZE }); buffer2_rms[i] = calculate_rms(&(AudioBuffer){ window2, WINDOW_SIZE }); } // 计算相似度 float sum = 0.0f; for (int i = 0; i < num_windows; i++) { sum += buffer1_rms[i] * buffer2_rms[i]; } float similarity = sum / num_windows; free(window1); free(window2); free(buffer1_rms); free(buffer2_rms); return similarity; } int main() { AudioBuffer buffer1 = { .data = (float*)malloc(sizeof(float) * NUM_SAMPLES), .size = NUM_SAMPLES }; AudioBuffer buffer2 = { .data = (float*)malloc(sizeof(float) * NUM_SAMPLES), .size = NUM_SAMPLES }; // 填充音频数据 for (int i = 0; i < NUM_SAMPLES; i++) { buffer1.data[i] = sinf(2.0f * M_PI * 440.0f * i / SAMPLE_RATE); buffer2.data[i] = sinf(2.0f * M_PI * 440.0f * i / SAMPLE_RATE + M_PI / 2.0f); } float similarity = calculate_similarity(&buffer1, &buffer2); printf("Similarity: %f\n", similarity); free(buffer1.data); free(buffer2.data); return 0; } ``` 该示例代码使用RMS(均方根)和窗口技术来计算两个音频PCM数据的相似度。通过将音频数据分成多个窗口,然后计算每个窗口的RMS,最后计算RMS的平均值来计算相似度。这种方法可以减少时间域中的干扰,并更好地捕获频域中的相似度。该示例仅用于演示目的,实际应用中可能需要更复杂的算法来获得更准确的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值