#!/usr/bin/env python3 import wave import seaborn as sns import pandas as pd from matplotlib import pyplot as plt from sys import argv CAPTURE_FILE = argv[1] def read_wav(wav_file): wav = wave.open(wav_file) timestamps = [] values = [] # as floats uwu num_frames = wav.getnframes() samp_rate = wav.getframerate() samp_width = wav.getsampwidth() for i in range(0, num_frames): timestamp_seconds = i / samp_rate timestamp_microseconds = 1000 * 1000 * timestamp_seconds timestamps.append(timestamp_microseconds) value = wav.readframes(1) value_int = int.from_bytes(value, byteorder="little", signed=True) value_float = value_int / 2 ** (8 * samp_width) values.append(value_float) return pd.DataFrame( { "timestamp": timestamps, "value": values, } ) def main(): df = read_wav(CAPTURE_FILE) # eeever so slightly clean up high-frequent-ish noise mean = df.rolling(window=5).mean() df["value"] = mean["value"] # convert to binary signal df["high"] = df["value"] > 0 # create a list of durations of high pulses prev_state = False t_last_change = 0 t_last_high = 0 high_durations = [] for _, row in df.iterrows(): state = bool(row["high"]) if state != prev_state: if state: # rising edge t_last_change = row["timestamp"] else: # falling edge duration = row["timestamp"] - t_last_change high_durations.append(duration) if state: t_last_high = row["timestamp"] elif (row["timestamp"] - t_last_high) > 1200: if len(high_durations) > 0 and high_durations[-1] > 0: high_durations.append(-1) # long silence prev_state = state # sns.histplot([d for d in high_durations if d > 50 and d < 1200], bins=100) # plt.show() short = 200 # us long = 800 # us epsilon = 50 # us # print decoded packets to stdout: # short high pulse -> `1` # long high pulse -> `0` # silence in between -> `\n` i = 0 for duration in high_durations: if duration < 0: print() if abs(duration - short) < epsilon: print("1", end="") if abs(duration - long) < epsilon: print("0", end="") i += 1 if __name__ == "__main__": main()