Practical Audio Playback with UAC and PDM

This article is the first in a series, with plans to share a series of articles based on the UAC+PDM audio playback practical cases.

PDM stands for Pulse Density Modulation, which can be simply understood as a method that differs from PWM in that it uses the density of 1s and 0s to represent amplitude rather than duty cycle. The time is divided into smaller units of 1 (high level) and 0 (low level), where the density of 1s and 0s reflects the amplitude. Thus, essentially, PDM is still similar to PWM in that different duty cycles correspond to different amplitudes, as a higher density of 1s naturally corresponds to a larger duty cycle. PDM can be understood as a refinement of PWM, dividing it into smaller time granularity for processing, where each time granularity is either 1 or 0, corresponding to this granularity.

After dividing into this time granularity, the 1s and 0s are encoded, and the encoded data macroscopically appears as a bitstream of varying density of 1s. The density of 1s can reflect the corresponding amplitude, allowing PDM to drive an analog speaker directly (filtering out high-frequency components). Essentially, this is no different from the PWM audio playback we previously shared. Of course, the encoding algorithm is the core aspect. This article will not discuss the principles of PDM, as we plan to release a series of articles on that later, so the explanations here may not be entirely accurate but aim to be easy to understand.

For example, the following is a simple analysis of a sine wave output in PDM. Where the density of 1s is high, the positive amplitude is larger, while where the density of 0s is high, the negative amplitude is smaller. The alternating appearance of 1s and 0s in uniform areas corresponds to an amplitude of 0. Below is a schematic diagram:

Practical Audio Playback with UAC and PDM

Generally, by outputting the positive maximum value, negative maximum value, 0, and the sine wave, one can roughly discern whether the output is correct. For further precise analysis, specialized tools are needed, such as audio analysis tools that support PDM interfaces. However, in the absence of specialized audio analysis tools, we can also use a logic analyzer for analysis. Some high-end logic analyzers support PDM. Here we will introduce the analysis of PDM based on the TL4234B logic analyzer and the upper computer tool Acute TravelLogic Analyzer. If there is no corresponding logic analyzer, a regular logic analyzer can capture the signal, and one can analyze it using existing audio processing tools like matlab.

2. Capturing PDM Signals

Use two channels to capture CLK and DATA data, and add protocol parsing for PDM

Practical Audio Playback with UAC and PDM

Configure PDM parsing parameters

Practical Audio Playback with UAC and PDM

Specify the corresponding channels for CLK and DATA

If you want to use PDM to directly drive an analog speaker, both channels must send exactly the same data, meaning the rising and falling edges must send identical data. Otherwise, if the data of the two channels is different, it will interfere, and macroscopically it will no longer correspond to the density of 1 to duty cycle and amplitude, as the data of the two channels will be interleaved.

Thus, this is set for single-channel Mono mode, setting Audio Frequency to the audio sampling rate, and PDM Sample Rate to the frequency of the PDM signal, which can be set for automatic detection.

Then, select to store the sound waveform and plot the sound waveform, selecting all Original data, and FullScale can be used for automatic scaling. Choose to replay sound as All and click OK.

Practical Audio Playback with UAC and PDM

Practical Audio Playback with UAC and PDM

This will display the waveform and generate a wav file named PDM_20240325_180500_477.WAV, which can be played directly.

3. .WAV Processing

We can use the python wav library for wav analysis and processing. However, the wav generated by this logic analyzer contains extended format chunks that the wav library may not handle. We need to manually modify it using a binary editing tool, such as 010editor, to make the following changes.

(1)Reduce total length by 16

(2)Reduce chunk length by 16

(3)Change type from FEFF to 0100

(4)Delete the 16-byte extended format chunk

Practical Audio Playback with UAC and PDM

At this point, you can use the following script wavplot.py to display the waveform

python3 wavplot.py PDM_20240325_180500_477_copy.WAV

# -*- coding: utf-8 -*-import waveimport pylab as plimport numpy as npimport sys# Open WAV documentf = wave.open(sys.argv[1], "rb")# Read format information# (nchannels, sampwidth, framerate, nframes, comptype, compname)params = f.getparams()nchannels, sampwidth, framerate, nframes = params[:4]print(params)# Read waveform datastr_data = f.readframes(nframes)f.close()# Convert waveform data to arraywave_data = np.frombuffer(str_data, dtype=np.short)wave_data.shape = -1, nchannelswave_data = wave_data.Ttime = np.arange(0, nframes) * (1.0 / framerate)# Plot waveformpl.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()

Practical Audio Playback with UAC and PDM

We can also use scipy’s signal for filtering and other processing.

4. Attachments

I am sharing PDM data collected from the logic analyzer in a project, as well as the exported WAV audio.

Practical Audio Playback with UAC and PDM

5. Conclusion

The waveform of PDM can only be roughly judged visually for correctness. For precise analysis, one can use a logic analyzer. This makes it convenient to perform analysis even without specialized audio analysis tools.

Leave a Comment