PDM to PCM for the Nano 33 BLE Sense, fast BLE and TensorFlow Lite micro_speech

I am attempting to capture raw audio from the Nano 33 BLE Sense, so I can use it to train TensorFlow models. Currently I'm transferring raw PDM audio from the device back to the desktop, which I have achieved via Serial.print via an accumulated buffer of multiple PDM buffers. (Flipping between recording and transmitting, as they don't appear to be possible at the same time over Serial). Now I'm trying to decode the PDM data, into PCM.

The Arduino example project 'micro_speech' for the TensorFlow lite library, contains internal classes for both the Arduino Nano 33 BLE Sense and the Sparkfun Edge. However the Sparkfun edge data is PCM, whereas the Nano 33 BLE Sense is a PDM microphone. I can't see any circuitry in the Nano 33 BLE Sense which converts the PDM data, or operations which treat the raw audio data. The tensorflow micro_frontend doesn't convert the data as far as I can tell.

Furthermore there is, as many have commented on, a significant lack of documentation around the PDM library, example code which produces PCM audio, or any accompanying third party libraries which can be utilised to further process this data. I have found the mbed DSP library which supports getting a scalar unsigned RMS value for a PDM buffer, but not a signed PCM waveform.

  1. Is anyone able to explain the processes used in the treatment of PDM audio data on the Nano 33 BLE Sense, to create PCM audio? Can anyone provide worked examples of how this should be achieved?

  2. Can anyone advise what desktop libraries are helping them transfer data fast over BLE, using large byte arrays of data from a BLE characteristic? I believe it would make an excellent worked example for the broader community of the power of the Nano 33 BLE Sense.

So, reading the Nordic Semiconductor forum and documentation, it seems the PDM module, built into the chip does the conversion.


I’m now trying to reconcile what I’m seeing in the raw data, as it isn’t what I would consider clean audio.

Using Arduino PDM Serial Plotter example, and a nearby iPhone to generate a 600Hz tone, I was able to produce a sinusoidal waveform having an approximate DC offset of 0.0.

Clearly there are artefacts which result from the PDM to PCM conversion, as the sinusoid contains breaks, where the buffers start and end.

However, when I view speech audio waveforms the DC offset drifts all over the place, and the audio playback is horrible.

I’ll post some code here shortly to demonstrate.

Were you able to get this working? I was able to get the PCM audio onto my laptop from the Nano Sense. The trick was doing a Serial.write() instead of a print.

The audio seems to be very clipped though, with it getting distorted from just talking. I have left the gain at the default values.

Has anyone recorded and played it back?