aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Doan <daviddoan@Davids-MacBook-Pro-193.local>2023-12-15 03:12:09 -0500
committerDavid Doan <daviddoan@Davids-MacBook-Pro-193.local>2023-12-15 03:12:09 -0500
commit5c191f4ac00c28b5fa9e971bda68ead235a8fcc0 (patch)
tree22f48dbc0f2d72dde54c7fb9e6373d15641df973
parentdb626076acc73fbcd499b3235bf4503c22b47e2b (diff)
code cleanup
-rw-r--r--Recv.py26
-rw-r--r--Sender.py155
-rw-r--r--__pycache__/utils.cpython-38.pycbin2403 -> 2605 bytes
-rw-r--r--utils.py19
4 files changed, 34 insertions, 166 deletions
diff --git a/Recv.py b/Recv.py
index b1708a4..82eb7bf 100644
--- a/Recv.py
+++ b/Recv.py
@@ -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()
diff --git a/Sender.py b/Sender.py
index d1463d7..8c6a3f9 100644
--- a/Sender.py
+++ b/Sender.py
@@ -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
index 690b063..8685b58 100644
--- a/__pycache__/utils.cpython-38.pyc
+++ b/__pycache__/utils.cpython-38.pyc
Binary files differ
diff --git a/utils.py b/utils.py
index 253bad6..d6651b3 100644
--- a/utils.py
+++ b/utils.py
@@ -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