aboutsummaryrefslogtreecommitdiff
path: root/utils.py
diff options
context:
space:
mode:
authorDavid Doan <daviddoan@Davids-MacBook-Pro-193.local>2023-12-14 21:40:35 -0500
committerDavid Doan <daviddoan@Davids-MacBook-Pro-193.local>2023-12-14 21:40:35 -0500
commitd7384329b2ae615ef7d637e31f214dbe648ae418 (patch)
tree7f0fb02210a2da8b820372f5ea3a78041f390433 /utils.py
parent0fef1fc043bddbcaf467d1f35027bde60326e227 (diff)
parentb66e659ba40b84dbf75e09d5463e2aef1a39b718 (diff)
pull
Diffstat (limited to 'utils.py')
-rw-r--r--utils.py138
1 files changed, 47 insertions, 91 deletions
diff --git a/utils.py b/utils.py
index d7ed7d8..503d289 100644
--- a/utils.py
+++ b/utils.py
@@ -3,10 +3,41 @@
# 1875 1924 +24, -25, range/2, 1, flipping new info 2 sending or not
import numpy as np
import pyaudio
-import struct
+import threading
from scipy.fftpack import fft
+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
+
+ # 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)
+ restricted_spectrum = spectrum[starting_range_index:ending_range_index + 1]
+
+ # get the n indices of the max peaks of amplitude greater than .125, within our confined spectrum
+ indices = np.argwhere(restricted_spectrum > .125)
+
+ freqs = [int((indices[i] + starting_range_index) / freq_to_index_ratio) for i in range(len(indices))]
+
+ # convert the frequencies to bits
+ data = frequencies_to_bits(freqs, calculate_send_frequencies(starting_freq, freq_range, bytes_per_transmit))
+
+ # TODO: remove
+ byte = data[:8]
+ if data[-1] == '1':
+ receive_string(byte)
+
+ return data
+
+
def calculate_send_frequencies(start_freq, freq_range, bytes_per_transmit):
bits_to_send = 8 * bytes_per_transmit + 2 # 8 bits per byte, 2 bits for flags
freq_interval = freq_range / (bits_to_send + 1) # +1 to not include endpoints of range
@@ -16,66 +47,46 @@ 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)
-
return freq_list
-def frequencies_to_bytes(frequencies, expected_freqs):
+def frequencies_to_bits(frequencies, expected_freqs):
# get the interval between frequencies, so we can clamp the range around them
freq_interval = expected_freqs[1] - expected_freqs[0]
plus_minus = freq_interval // 2
- byte_list = ['0'] * len(expected_freqs)
+ bit_list = ['0'] * len(expected_freqs)
for freq in frequencies:
for i in range(len(expected_freqs)):
# clamp the range around the frequency to the frequency
if expected_freqs[i] - plus_minus <= freq < expected_freqs[i] + plus_minus:
- byte_list[i] = '1'
+ bit_list[i] = '1'
- return byte_list
+ return bit_list
-def play_data(data, start_freq, freq_step, bytes_per_transmit, p):
+
+def play_data(data, start_freq, freq_step, bytes_per_transmit, stream):
freq_list = calculate_send_frequencies(start_freq, freq_step, bytes_per_transmit)
+ send_duration = 1.0
+
+ flip_flag = 0 # TODO: make this global between plays
for byte in data:
- # print(byte)
+ byte = byte + str(flip_flag) + '1'
+ print(byte)
samples = None
for i, bit in enumerate(byte):
if bit == '1':
- # print(freq_list[i])
- s = .125 * np.sin(2 * np.pi * np.arange(44100 * 10.0) * freq_list[i] / 44100)
+ print(freq_list[i])
+ s = .125 * np.sin(2 * np.pi * np.arange(44100 * send_duration) * freq_list[i] / 44100)
if samples is None:
samples = s
else:
samples = np.add(samples, s)
if samples is not None:
- # 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
+ flip_flag = (flip_flag + 1) % 2
+
def receive_string(binary):
binary_string = ''.join(binary)
@@ -84,58 +95,3 @@ def receive_string(binary):
return chr(int(binary_string, 2))
except ValueError:
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