def decode(input_filename): """Given a filename, read the WAVE file and use Fourier analysis to extract and decode the chords from the WAVE file. This decoding method will read a full message from a chord containing the START note to chord containing an END note, anywhere it appears in the WAVE file. It will read only the first full message in the file. """ data, params = wavetools.read_wav(input_filename) data_bytes = [] sequence_started = False last_csn = 0 for w in range(0, len(data), fourier.WINDOW_SIZE): start = w end = w + fourier.WINDOW_SIZE (cnote, raw_data) = decode_chord(data[start:end]) (csn, cnibble) = chords.ctrl_to_tuple(cnote) # If we have found the first readable chord, start # recording data bytes. if not sequence_started and cnibble == chords.CTRL_NIB_START: sequence_started = True data_bytes += raw_data last_csn = csn continue # If we are recording a sequence and the CSN of this chord # is incorrect, or the control nibble is malformed, skip to the next # possible window. if sequence_started and ((last_csn + 1) % 2**4) != csn or \ cnibble == None: continue # If we encountered a chord with an END note, record the last # chord of data and stop. if sequence_started and cnibble == chords.CTRL_NIB_END: data_bytes += raw_data break if sequence_started: data_bytes += raw_data last_csn = csn return data_bytes
def listen(): """Open the computer microphone and listen for incoming signals. When a complete message is heard, print the bytes to the standard out. """ p = pyaudio.PyAudio() stream = p.open(format = wavetools.SAMPLE_WIDTH, channels = wavetools.NUM_CHANNELS, rate = wavetools.SAMPLE_RATE, input = True, frames_per_buffer = fourier.WINDOW_SIZE) data_bytes = [] last_csn = 0 sequence_started = False t = 0 while True and t < 100: print(sys.argv[0] + ': [' + str(t) + ']: listening') data = stream.read(fourier.WINDOW_SIZE) (cnote, raw_data) = codec.decode_chord(data) print(str(raw_data)) (csn, cnibble) = chords.ctrl_to_tuple(cnote) # If we have found the first readable chord, start # recording data bytes. if not sequence_started and cnibble == chords.CTRL_NIB_START: print(sys.argv[0] + ': [' + str(t) + ']: found START') sequence_started = True data_bytes += raw_data last_csn = csn t = 0 continue # If we are recording a sequence and the CSN of this chord # is incorrect, or the control nibble is malformed, skip to the next # possible window. if sequence_started and ((last_csn + 1) % 2**4) != csn or \ cnibble == None: print(sys.argv[0] + ': [' + str(t) + ']: skipped bad chord') t += 1 continue # If we encountered a chord with an END note, record the last # chord of data and stop. if sequence_started and cnibble == chords.CTRL_NIB_END: print(sys.argv[0] + ': [' + str(t) + ']: found END') data_bytes += raw_data break if sequence_started: data_bytes += raw_data last_csn = csn t += 1 stream.stop_stream() stream.close() p.terminate() print(str(all_chords))