zsy-s 发表于 2024-12-4 11:30

【Follow me第二季第4期】任务2:PDM麦克风的学习

本帖最后由 zsy-s 于 2024-12-4 17:23 编辑

# 硬件
麦克风使用的型号:MP34DT06JTR
手册

lr引脚的定义

# 知识点学习
高保真音频:44khz
数字音频信号PDM代表脉冲密度调制(Pulse Density Modulation)。以非常高的频率采集音频信号,也被称为:Oversampled 1-bit Audio。PDM是一种调制形式,用于表示数字域中的模拟信号。
采样时许:
sck是采样频率,在每个上升沿或者下降沿采集一位音频数据。
对于右声道来说,上升沿启动右声道数据,最多tren时间后,右声道数据有效,下降沿后延迟trdis时间后,数据可以变化,这样保证了下降沿采集音频数据时,数据能保证有效。

## 数据的使用
PDM信号无法直接驱动DA进行声音播放,PDM信号要变为声音信号还需要进行下采样,经过一次低通滤波和抽样,然后成为PCM信号。
pdm是快速对音频进行调制的一种协议,通过密度来表示音频的模拟信号的幅度。密集的1标志正幅度,密集的0标识负幅度,平均交替的01标识 0幅度。如下如所示。

# 代码
包含官方的pdm头文件。
#include <PDM.h>
配置pdm 并启动pdm数据采集。
```c
static const int frequency = 16000;
static const char channels = 1;

PDM.onReceive(onPDMdata);
if (!PDM.begin(channels, frequency)) {
    Serial.println("Failed to start PDM!");
    while (1);
}
```

回调读取数据并设置可读数据长度。
```c
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = PDM.available();

// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);

// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
```
打印采集到pdm数据
```c
if (samplesRead) {
    for (int i = 0; i < samplesRead; i++) {
      if(channels == 2) {
      Serial.print("L:");
      Serial.print(sampleBuffer);
      Serial.print(" R:");
      i++;
      }
      Serial.println(sampleBuffer);
    }
    samplesRead = 0;
}
```

# 效果

# 结论
pdm转换声音的逻辑,不太熟悉,学习到了,在更新一下

串口工具

lijinlei 发表于 2024-12-4 12:32

<p>大佬,你的串口数据是用什么工具采集的啊?</p>

zsy-s 发表于 2024-12-4 17:22

lijinlei 发表于 2024-12-4 12:32
大佬,你的串口数据是用什么工具采集的啊?

<p>我是菜鸟,我看论坛的各位都是大佬,我一会传上去</p>

yilonglucky 发表于 2024-12-4 18:21

<p>请教下最后一个波形图是怎么打印的?</p>

<div style="position: fixed; opacity: 1; height: 300px; width: 100%; font-size: 25px; text-align: center; bottom: 200px; left: 0px; display: none; flex-direction: column; justify-content: center; z-index: 1661789940; top: calc(50% + 0px);">&nbsp;</div>
页: [1]
查看完整版本: 【Follow me第二季第4期】任务2:PDM麦克风的学习