from scipy.io import wavfile from pydub import AudioSegment from collections import OrderedDict DEBUG = False def get_direction(prev, next_): if prev > next_: direction = 'down' elif prev < next_: direction = 'up' else: direction = 'continue' return direction def quantize(samples, samplerate, thresholds): buf = [] prev = 0 prev_direction = '' continue_count = 0 for sample in samples: if prev_direction != '': direction = get_direction(prev, sample) else: prev_direction = 'continue' direction = 'continue' if direction == 'continue': continue_count += 1 else: continue_count = 0 if (continue_count == (samplerate / 10) - 1): buf += [thresholds[str(int(sample))]] continue_count = 0 prev = sample prev_direction = direction return buf def group_by_octal(data): tmp = '' j = 0 buf = OrderedDict() for i in range(len(data)): if len(buf) <= j: buf[j] = '' tmp += data[i] current = '{}{}'.format(buf[j], tmp) shift = int(current) > 199 if (len(tmp) - 1) % 3 == 2 or shift: if shift: buf[j+1] = current[-1] tmp = current[:-1] buf[j] = tmp tmp = '' j += 1 i += 1 return buf # Read WAV file audio_file = 'audible.wav' samplerate, samples = wavfile.read(audio_file) # Signal quantization (3-bit) thresholds = OrderedDict([ ('-32000', '0'), ('-24000', '1'), ('-16200', '2'), ('-8100', '3'), ('8100', '4'), ('16200', '5'), ('24000', '6'), ('32000', '7') ]) buf = quantize(samples, samplerate, thresholds) if DEBUG: print(buf) # Get octal values from quantized data buf = group_by_octal(buf) if DEBUG: print(buf) # Convert octal values to chars flag = '' for i in range(len(buf)): flag += chr(int(buf[i], 8)) # Print flag print(flag)