本文是本系列文章的第一篇,后续计划会根据UAC+PDM音频播放实践案例,分享一系列文章。
PDM 即Pulse Density Modulation脉冲密度调试, 我们简单的可以理解其为不同于PWM的用占空比等效不同幅度,而是时间上划分为更小的1(高电平)和0(低电平)的单位,用1和0的密度来等效幅度。所以其实反过来说,本质上PDM也还是和PWM一样还是占空比不同对应幅度不同,因为1的密度大了自然而然就是相当于占空比大了。可以理解为PDM是在PWM的基础上的细分,即划分为更小的时间颗粒度来处理,每个时间颗粒度要么是1要么是0,这里的1和0即对应这个颗粒度。
划分为这个时间颗粒度之后,对这些颗粒度的1和0,进行编码,编码后的数据从宏观上看就是1的密度变化的bit流,1的密度即可反应对应的幅度,所以宏观上就可以用PDM直接驱动模拟喇叭(过滤掉高频分量),和之前我们分享的PWM播放音频一样,本质上没有区别。当然这个编码算法就是核心了。本文不讲PDM的原理,后面有时间再单独出一些列文章,所以这里的说法可能都不是很准确的说法,但是力求好理解。
比如如下是对于一个正弦波,PDM输出的一个简单的分析。1的密度大的地方正的幅度越大,0的个数密度大的地方负的幅度越小,1和0交替出现即均匀的地方对应幅度为0,以下对应的示意图:
一般通过输出正的最大值,负的最大值,0,以及正弦波,可以大致肉眼分辨出输出是否正确。进一步的精确的分析,需要专门的工具,比如支持PDM接口的音频分析AP工具。当然在没有专门音频分析工具时,我们也可以借助逻辑分析仪进行分析,有些高端逻辑分析仪是支持PDM的。我们这里就介绍基于TL4234B这个逻辑分析仪和上位机工具Acute TravelLogic Analyzer 进行PDM的分析。实在没有对应的逻辑分析仪,普通逻辑分析仪抓取信号,自己通过matlab等现成的音频处理工具也是可以进行分析的。
使用两个人通道抓取CLK和DATA数据,添加协议解析PDM
配置PDM解析参数
指定CLK和DATA对应的通道
如果要用PDM直接驱动模拟喇叭,必须要两个通道发送完全一样的数据,即上升沿和下降沿发送完全一样的数据,否则两个通道的数据不一样会干扰,宏观上将不再是1的密度对应占空比,对应幅度了,因为两个通道的数据交错了。
所以这里为单通道Mono模式,设置Audio Frequence为音频的采样率,PDM Sample Rade为PDM信号的频率,可以设置为自动检测。
然后下面可以选中储存声音波形,画出声音波形,都选Original数据,FullScle可以进行自动缩放。声音重放选择All,点击确定。
会显示波形和生成wav文件PDM_20240325_180500_477.WAV,直接播放即可。
我们可以使用python的wav库进行wav分析和处理。但是本逻辑分析仪生成的wav 带扩展格式块,wav库可能不能处理,我们手动修改下,使用二进制编辑工具010editor,进行如下修改。
(1)总长减小16
(2)块长减小16
(3)类型FEFF改为0100
(4)删除16字节的扩展格式块
此时可以使用以下脚本wavplot.py显示波形
python3 wavplot.py PDM_20240325_180500_477_copy.WAV
# -*- coding: utf-8 -*-
import wave
import pylab as pl
import numpy as np
import sys
# 打开WAV文档
f = wave.open(sys.argv[1], "rb")
# 读取格式信息
# (nchannels, sampwidth, framerate, nframes, comptype, compname)
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
print(params)
# 读取波形数据
str_data = f.readframes(nframes)
f.close()
#将波形数据转换为数组
wave_data = np.frombuffer(str_data, dtype=np.short)
wave_data.shape = -1, nchannels
wave_data = wave_data.T
time = np.arange(0, nframes) * (1.0 / framerate)
# 绘制波形
pl.subplot(211)
pl.plot(time, wave_data[0])
if nchannels==2:
pl.subplot(212)
pl.plot(time, wave_data[1], c="g")
pl.xlabel("time (seconds)")
pl.show()
还可以使用scipy的signal进行滤波等处理。
我这里分享一个项目中逻辑分析仪采集的PDM数据,以及导出的WAV音频。
PDM的波形肉眼只能大致进行判断是否正确,要精确的分析,可以借助逻辑分析仪进行分析。这样可以在没有专门的音频分析工具时也能方便的进行分析。