aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Doan <daviddoan@Davids-MacBook-Pro-193.local>2023-12-14 21:37:53 -0500
committerDavid Doan <daviddoan@Davids-MacBook-Pro-193.local>2023-12-14 21:37:53 -0500
commit0fef1fc043bddbcaf467d1f35027bde60326e227 (patch)
tree169b0b92cca868367d5fdb3b3bdce62d966c5409
parent25c3b38b708bf467c40303083190409293452a33 (diff)
receiving
-rw-r--r--Recv.py47
-rw-r--r--Sender.py18
-rw-r--r--__pycache__/utils.cpython-38.pycbin1782 -> 3263 bytes
-rw-r--r--utils.py90
4 files changed, 135 insertions, 20 deletions
diff --git a/Recv.py b/Recv.py
index e69de29..7da9f06 100644
--- a/Recv.py
+++ b/Recv.py
@@ -0,0 +1,47 @@
+import utils as u
+import time
+from collections import Counter
+
+def main():
+ p = u.pyaudio.PyAudio()
+ start_freq = 19800
+ freq_range = 200
+ bytes_per_transmit = 1
+
+ stream = p.open(
+ format=u.pyaudio.paInt32,
+ channels=1,
+ rate=44100,
+ input=True,
+ output=True,
+ frames_per_buffer=2048 * 2,
+ )
+
+ char_counter = Counter()
+ start_time = time.time()
+ word = ''
+
+ try:
+ while True:
+ current_time = time.time()
+ if current_time - start_time >= 1: # Every second
+ # Find the most common character
+ most_common_char, _ = char_counter.most_common(1)[0] if char_counter else ('', 0)
+ print(f"Most common character in the last second: {most_common_char}")
+ word += most_common_char
+ print(f"Accumulated word: {word}")
+ char_counter.clear() # Reset for the next second
+ start_time = current_time
+
+ data, success = u.receive_data(stream, start_freq, freq_range, bytes_per_transmit)
+ if success:
+ char_counter[data] += 1
+
+ except KeyboardInterrupt:
+ print("Stopping...")
+ finally:
+ stream.stop_stream()
+ stream.close()
+ p.terminate()
+if __name__ == "__main__":
+ main() \ No newline at end of file
diff --git a/Sender.py b/Sender.py
index e46b84a..4656e6b 100644
--- a/Sender.py
+++ b/Sender.py
@@ -57,16 +57,6 @@ def play_frequencies_separately(freq_map, duration=1.0, samplingRate=44100):
# 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
"""
@@ -107,10 +97,10 @@ def receive_string(data, start_freq=18000, freq_step=250):
# Example usage
# data for the letter h
-# 01101000
-data = [18250, 18500, 19000]
-decoded_string = receive_string(data)
-print(decoded_string)
+# # 01101000
+# data = [18250, 18500, 19000]
+# decoded_string = receive_string(data)
+# print(decoded_string)
# transmit_string("h")
diff --git a/__pycache__/utils.cpython-38.pyc b/__pycache__/utils.cpython-38.pyc
index 2511512..6a8e2eb 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 3e7c50b..d7ed7d8 100644
--- a/utils.py
+++ b/utils.py
@@ -3,7 +3,8 @@
# 1875 1924 +24, -25, range/2, 1, flipping new info 2 sending or not
import numpy as np
import pyaudio
-import threading
+import struct
+from scipy.fftpack import fft
def calculate_send_frequencies(start_freq, freq_range, bytes_per_transmit):
@@ -15,7 +16,7 @@ def calculate_send_frequencies(start_freq, freq_range, bytes_per_transmit):
f = int(start_freq + (i + 1) * freq_interval)
freq_list.append(f)
- print(freq_list)
+ # print(freq_list)
return freq_list
@@ -38,26 +39,103 @@ def play_data(data, start_freq, freq_step, bytes_per_transmit, p):
freq_list = calculate_send_frequencies(start_freq, freq_step, bytes_per_transmit)
for byte in data:
- print(byte)
+ # print(byte)
samples = None
for i, bit in enumerate(byte):
if bit == '1':
- print(freq_list[i])
+ # print(freq_list[i])
s = .125 * np.sin(2 * np.pi * np.arange(44100 * 10.0) * freq_list[i] / 44100)
if samples is None:
samples = s
else:
samples = np.add(samples, s)
if samples is not None:
- print(samples)
+ # print(samples)
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=44100, output=True)
stream.write(samples.astype(np.float32).tobytes())
stream.stop_stream()
stream.close()
+ # listening_stream = p.open(
+ # format=pyaudio.paInt32,
+ # channels=1,
+ # rate=44100,
+ # input=True,
+ # output=True,
+ # frames_per_buffer=2048 * 2,
+ # )
+ # if receive_data(listening_stream, start_freq, freq_step, bytes_per_transmit):
+ # print("Success")
+
+"""
+: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
def receive_string(binary):
binary_string = ''.join(binary)
try:
print(chr(int(binary_string, 2)))
+ return chr(int(binary_string, 2))
except ValueError:
- print("Error: Invalid binary data") \ No newline at end of file
+ print("Error: Invalid binary data")
+
+CHUNK = 2048 * 2
+RATE = 44100
+
+def read_audio_stream(stream):
+ data = stream.read(CHUNK)
+ data_int = struct.unpack(str(CHUNK) + 'i', data)
+ return data_int
+
+def get_fundamental_frequency(audio_waveform, start_freq, freq_step, bytes_per_transmit):
+ spectrum = fft(audio_waveform)
+
+ # scale and normalize the spectrum, some are imaginary
+ scaled_spectrum = np.abs(spectrum)
+ scaled_spectrum = scaled_spectrum / (np.linalg.norm(scaled_spectrum) + 1e-16)
+
+ # FIXME: update to self values, given if ur a sender or receiver
+ starting_freq = 19800
+ end_freq = 20000
+ freq_to_index_ratio = CHUNK / RATE
+ # only accept the scaled spectrum from our starting range to 20000 Hz
+ starting_range_index = int(starting_freq * freq_to_index_ratio)
+ ending_range_index = int(end_freq * freq_to_index_ratio)
+ # print(starting_freq, end_freq, starting_range_index, ending_range_index)
+ restricted_spectrum = scaled_spectrum[starting_range_index:ending_range_index + 1]
+
+ # normalize the restricted spectrum
+ indices = np.argwhere(restricted_spectrum > .125)
+ # print(indices)
+
+ freqs = [int((indices[i] + starting_range_index) / freq_to_index_ratio) for i in range(len(indices))]
+ # print(freqs)
+
+ p = frequencies_to_bytes(freqs, calculate_send_frequencies(start_freq, freq_step, bytes_per_transmit))
+ data = p[:8]
+ # print(data)
+ data = receive_string(data)
+ return data
+
+
+def receive_data(stream, start_freq, freq_step, bytes_per_transmit):
+ # freq_list = calculate_send_frequencies(start_freq, freq_step, bytes_per_transmit)
+
+ data = []
+ while not data:
+ waveform = read_audio_stream(stream)
+ freqs = get_fundamental_frequency(waveform, start_freq, freq_step, bytes_per_transmit)
+ data.append(freqs)
+
+
+ # if we see the same data twice in a row, we stop receiving
+ # if data[-1] == data[-2]:
+ # break
+ # print(data)
+ return data[0], True