switch to 16-bit dumps & add a script for dumping cleaned waveforms
I can see very clear signal when I: - tape only the contacts of the sensor to the table, and - bend the free end into the air, and release (it snaps down)
This commit is contained in:
70
scripts/itm-to-pcm.py
Executable file
70
scripts/itm-to-pcm.py
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
'''
|
||||
Convert itm.txt dumps to pcm (wave) files
|
||||
|
||||
usage: itmdump -f /tmp/itm.txt > dump.txt
|
||||
itm-to-pcm.py dump.txt dump.wav
|
||||
'''
|
||||
|
||||
import wave
|
||||
import sys
|
||||
|
||||
def read_itm(file_in):
|
||||
f = open(file_in, 'rb')
|
||||
while True:
|
||||
samples = f.read(2)
|
||||
if not samples: break
|
||||
#if len(set(samples)) != 1: continue # corrupted
|
||||
#yield samples[0]
|
||||
yield samples[0] + 0x100*samples[1]
|
||||
#for line in f:
|
||||
# try:
|
||||
# if line.startswith(b'ADC:'):
|
||||
# sample = int(line[len('ADC: '):].strip(), 16)
|
||||
# if sample < 0x1000: yield sample
|
||||
# except:
|
||||
# pass
|
||||
|
||||
def frames_from_samples(itm):
|
||||
b = bytearray()
|
||||
for sample in itm:
|
||||
sample = (sample + 0x10000) % 0x10000 # counteract Python's signed mod badness
|
||||
lsb0 = sample % 0x100
|
||||
lsb1 = (sample // 0x100) % 0x100
|
||||
b.append(lsb0)
|
||||
b.append(lsb1)
|
||||
|
||||
return b
|
||||
|
||||
def clean_frames(frames):
|
||||
# Run a median filter over the frames to clean outliers:
|
||||
post_med = [0]*len(frames)
|
||||
for i, _ in enumerate(frames):
|
||||
left = max(0, i-2)
|
||||
right = min(len(frames), i+3)
|
||||
post_med[i] = median(frames[left:right])
|
||||
# Remove DC component
|
||||
dc = sum(post_med) / len(post_med)
|
||||
post_dc = [f - dc for f in post_med]
|
||||
# Amplify to [-0x7fff, 0x7fff]
|
||||
prev_max = max(abs(f) for f in post_dc)
|
||||
amp_factor = 0x7fff / prev_max
|
||||
post_amp = [f*amp_factor for f in post_dc]
|
||||
# Round to int
|
||||
return [int(round(f)) for f in post_amp]
|
||||
|
||||
def median(samples):
|
||||
x = list(sorted(samples))
|
||||
return x[len(x) // 2]
|
||||
|
||||
def main():
|
||||
_self, file_in, file_out = sys.argv
|
||||
itm = clean_frames(list(read_itm(file_in)))
|
||||
wave_out = wave.open(file_out, 'wb')
|
||||
wave_out.setnchannels(1)
|
||||
wave_out.setsampwidth(2)
|
||||
wave_out.setframerate(1000)
|
||||
wave_out.writeframes(frames_from_samples(itm))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user