diff options
author | David Doan <daviddoan@Davids-MacBook-Pro-193.local> | 2023-12-15 03:12:09 -0500 |
---|---|---|
committer | David Doan <daviddoan@Davids-MacBook-Pro-193.local> | 2023-12-15 03:12:09 -0500 |
commit | 5c191f4ac00c28b5fa9e971bda68ead235a8fcc0 (patch) | |
tree | 22f48dbc0f2d72dde54c7fb9e6373d15641df973 | |
parent | db626076acc73fbcd499b3235bf4503c22b47e2b (diff) |
code cleanup
-rw-r--r-- | Recv.py | 26 | ||||
-rw-r--r-- | Sender.py | 155 | ||||
-rw-r--r-- | __pycache__/utils.cpython-38.pyc | bin | 2403 -> 2605 bytes | |||
-rw-r--r-- | utils.py | 19 |
4 files changed, 34 insertions, 166 deletions
@@ -1,29 +1,26 @@ import struct - -import numpy as np import pyaudio -import threading - -import utils from utils import * - +# Receiver Class: Used to continuos listen for sound waves in the corresponding frequency range +# and decode the data being sent class Recv: def __init__(self, start_freq=19000): + # initialize frequency related variables with default values self.start_freq = start_freq self.freq_range = 500 self.sampling_rate = 44100 self.p = pyaudio.PyAudio() self.bytes_per_transmit = 1 - - # TODO: use stream to send back the data + # initialize stream variables self.CHUNK = 2048 * 2 self.FORMAT = pyaudio.paInt32 self.CHANNELS = 1 self.RATE = 44100 self.pause = False - # stream object + + # initialize stream object self.p = pyaudio.PyAudio() self.stream = self.p.open( format=self.FORMAT, @@ -34,14 +31,13 @@ class Recv: frames_per_buffer=self.CHUNK, ) + # reads and unpacks the incoming audio stream def read_audio_stream(self): data = self.stream.read(self.CHUNK) data_int = struct.unpack(str(self.CHUNK) + 'i', data) return data_int - def print_data(self, data): - print(data) - + # checks if the byte is safe to add to the data structure def safe_check_byte(self, bytes_seen): safe_byte = [] @@ -62,6 +58,8 @@ class Recv: return safe_byte + # listens for incoming data + # uses two extra bits to handle data transmission protocol def listen(self): prev_is_data_flag = '0' prev_is_new_byte_flag = '0' @@ -99,7 +97,7 @@ class Recv: # FIXME: what to do with buffer? # for now print buffer as string - buffer_as_string = ''.join([utils.receive_string(byte) for byte in recv_buffer]) + buffer_as_string = ''.join([receive_string(byte) for byte in recv_buffer]) print("data received: ", buffer_as_string) # clear data structure & buffer @@ -127,8 +125,6 @@ class Recv: continue - - def main(): recv = Recv() recv.listen() @@ -3,142 +3,16 @@ import pyaudio import threading from utils import * -""" -Play a single frequency. - -:param freq: Frequency in Hz. -:param amplitude: Amplitude of the frequency (0.0 to 1.0). -:param duration: Duration of the sound in seconds. -:param samplingRate: Sampling rate in Hz. -""" - - -def play_frequency(freq, amplitude, duration=1.0, samplingRate=44100, p=None): - # Generate sample for the given frequency as a float32 array - samples = (amplitude * np.sin(2 * np.pi * np.arange(samplingRate * duration) * freq / samplingRate)).astype( - np.float32).tobytes() - - # Open stream - stream = p.open(format=pyaudio.paFloat32, - channels=1, - rate=samplingRate, - output=True) - - stream.write(samples) - - # Stop and close the stream - stream.stop_stream() - stream.close() - - # p.terminate() - - -""" -Use threads to play multiple frequencies simultaneously. - -:param freq_map: A dictionary with frequency (Hz) as keys and amplitude (0.0 to 1.0) as values. -:param duration: Duration of the sound in seconds. -:param samplingRate: Sampling rate in Hz. -""" - - -def play_frequencies_separately(freq_map, duration=1.0, samplingRate=44100): - p = pyaudio.PyAudio() - - threads = [] - for freq, amplitude in freq_map.items(): - thread = threading.Thread(target=play_frequency, args=(freq, amplitude, duration, samplingRate, p)) - threads.append(thread) - thread.start() - - # Wait for all threads to complete - for thread in threads: - thread.join() - - p.terminate() - - -# hello in binary -# data = "01101000 01100101 01101100 01101100 01101111" - -# convert string to binary representation -""" -:param data: A string of characters. -:return: A list of binary strings. -""" - - -def string_to_binary(data): - data_list = [] - for char in data: - binary_representation = format(ord(char), 'b').zfill(8) - data_list.append(binary_representation) - return data_list - - -# transmit string -""" -:param data: A string of characters. -""" - - -def transmit_string(data): - data_list = string_to_binary(data) - - for i in range(len(data_list)): - freq_map = {} - start_freq = 18000 - for j in range(len(data_list[i])): - if data_list[i][j] == "0": - freq_map[start_freq + j * 250] = 0.0 - - if data_list[i][j] == "1": - freq_map[start_freq + j * 250] = 1.0 - - # print(freq_map) - play_frequencies_separately(freq_map, duration=1000) - - -""" -:param data: A list of peak frequencies. -return: A string of characters. -""" - - -def receive_string(data, start_freq=18000, freq_step=250): - binary = ['0'] * 8 - - for item in data: - freqPosition = (item - start_freq) // freq_step - if 0 <= freqPosition < 8: binary[freqPosition] = '1' - - binary_string = ''.join(binary) - try: - return chr(int(binary_string, 2)) - except ValueError: - return "Error: Invalid binary data" - - -# Example usage -# data for the letter h -# # 01101000 -# data = [18250, 18500, 19000] -# decoded_string = receive_string(data) -# print(decoded_string) - - -# transmit_string("h") - - -class LinkLayer: +class Sender: def __init__(self, start_freq=19000): + # initialize frequency related variables with default values self.start_freq = start_freq self.freq_range = 500 self.sampling_rate = 44100 - self.p = pyaudio.PyAudio() - self.isReceiving = False - self.isEstablished = False self.bytes_per_transmit = 1 + + # initialize stream variables + self.p = pyaudio.PyAudio() self.stream = self.p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True) def transmit_string(self, data): @@ -147,22 +21,19 @@ class LinkLayer: def send_data(self): while True: - if not self.isReceiving: - user_input = input("Enter data to send: ") - if user_input == "exit" or user_input == "q": - self.stream.stop_stream() - self.stream.close() - break - self.transmit_string(user_input) - else: - print("Currently receiving data, please wait...") + user_input = input("Enter data to send: ") + if user_input == "exit" or user_input == "q": + self.stream.stop_stream() + self.stream.close() + break + self.transmit_string(user_input) def main(): - link_layer = LinkLayer() + sender = Sender() # Create a thread for sending data - send_thread = threading.Thread(target=link_layer.send_data) + send_thread = threading.Thread(target=sender.send_data) # Start the threads send_thread.start() diff --git a/__pycache__/utils.cpython-38.pyc b/__pycache__/utils.cpython-38.pyc Binary files differindex 690b063..8685b58 100644 --- a/__pycache__/utils.cpython-38.pyc +++ b/__pycache__/utils.cpython-38.pyc @@ -1,18 +1,13 @@ -# given the cmdline arg, turns the byte sequencies into a list of frequencies, and vice versa -# 1875 1924 +24, -25, range/2, 1, flipping new info 2 sending or not import numpy as np -import pyaudio -import threading from scipy.fftpack import fft - +# converts frequencies to bits def wave_to_bits(wave, starting_freq, freq_range, bytes_per_transmit, chunk=4096, rate=44100): spectrum = fft(wave) spectrum = np.abs(spectrum) spectrum = spectrum / (np.linalg.norm(spectrum) + 1e-16) - # FIXME: update to self values, given if ur a sender or receiver starting_freq = starting_freq end_freq = starting_freq + freq_range freq_to_index_ratio = (chunk - 1) / rate @@ -65,7 +60,7 @@ def play_data(data, start_freq, freq_step, bytes_per_transmit, stream): send_duration = .35 - flip_flag = 0 # TODO: make this global between plays + flip_flag = 0 for byte in data: byte = byte + str(flip_flag) + '1' samples = None @@ -84,8 +79,14 @@ def play_data(data, start_freq, freq_step, bytes_per_transmit, stream): def receive_string(binary): binary_string = ''.join(binary) try: - # print(chr(int(binary_string, 2))) return chr(int(binary_string, 2)) except ValueError: - # print("Warn: Invalid binary data: ", binary_string) return '' + + +def string_to_binary(data): + data_list = [] + for char in data: + binary_representation = format(ord(char), 'b').zfill(8) + data_list.append(binary_representation) + return data_list
\ No newline at end of file |