summaryrefslogtreecommitdiff
path: root/tools/pdm2pcm.py
diff options
context:
space:
mode:
authorJon Nordby <jononor@gmail.com>2025-04-18 00:04:20 +0200
committerMartin StensgÄrd <mastensg@mastensg.net>2025-04-18 16:12:03 +0200
commitd26152cb2fdaf1381dc43eb69a3f299911b68d50 (patch)
tree53e739df86ffb3e48c7c719842784da6e95654c7 /tools/pdm2pcm.py
parent793057e0021154278a77d0decd00e543b2c66a23 (diff)
tools: WIP on PDM<->PCM conversion in Python
First test signal does not seem correct...
Diffstat (limited to 'tools/pdm2pcm.py')
-rw-r--r--tools/pdm2pcm.py50
1 files changed, 50 insertions, 0 deletions
diff --git a/tools/pdm2pcm.py b/tools/pdm2pcm.py
new file mode 100644
index 0000000..6d2c284
--- /dev/null
+++ b/tools/pdm2pcm.py
@@ -0,0 +1,50 @@
+
+import numpy
+import numpy as np
+from scipy.signal import firwin, lfilter, decimate
+import soundfile
+
+def load_pdm_file(filename):
+ with open(filename, 'rb') as f:
+ byte_data = np.frombuffer(f.read(), dtype=np.uint8)
+ bit_data = np.unpackbits(byte_data)
+ # Convert to +1 (for 1s) and -1 (for 0s)
+ pdm_signal = 2 * bit_data - 1
+ return pdm_signal
+
+def pdm_to_pcm(pdm_signal, decimation_factor=64):
+ # Design a low-pass filter
+ fir_filter = firwin(numtaps=101, cutoff=0.5/decimation_factor)
+ # Filter the PDM signal
+ filtered = lfilter(fir_filter, [1.0], pdm_signal)
+ # Decimate (downsample)
+ pcm_signal = filtered[::decimation_factor]
+ return pcm_signal
+
+def main():
+
+ pdm_path = 'test_tone.pdm'
+ out_path = 'output.wav'
+ pdm_data = load_pdm_file(pdm_path)
+
+ # Convert to PCM
+ oversample = 64
+ samplerate = 16000
+ pcm_data = pdm_to_pcm(pdm_data, decimation_factor=oversample)
+
+ # Normalize and save to WAV
+ pcm_data = np.expand_dims(pcm_data, axis=1)
+ #print(pcm_data.shape)
+
+ print(numpy.min(pcm_data), numpy.max(pcm_data), numpy.mean(pcm_data))
+
+ # Normalize
+ pcm_data -= 128.0
+ pcm_data = 2**15 * (pcm_data / np.max(np.abs(pcm_data)))
+
+ print(numpy.min(pcm_data), numpy.max(pcm_data), numpy.mean(pcm_data))
+
+ soundfile.write(out_path, pcm_data, samplerate)
+
+if __name__ == '__main__':
+ main()