Awell00 commited on
Commit
a8c8bb7
·
1 Parent(s): 1fa1e1b

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +214 -0
  2. packages.txt +1 -0
  3. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import sounddevice as sd
3
+ from scipy.io.wavfile import read, write
4
+ from scipy.signal import find_peaks
5
+ from scipy.fft import fft
6
+ from tqdm import tqdm
7
+ import time
8
+ import matplotlib.pyplot as plt
9
+ from scipy.io.wavfile import read
10
+ from scipy import signal
11
+ import gradio as gr
12
+ import reedsolo
13
+ import wavio
14
+ from scipy.signal import butter, lfilter
15
+
16
+ low_frequency = 18000
17
+ high_frequency = 19000
18
+ bit_duration = 0.007
19
+ sample_rate = 44100
20
+ amplitude_scaling_factor = 10.0
21
+
22
+ #-----------------Record-----------------#
23
+
24
+ def record(audio):
25
+ try:
26
+ sr, data = audio
27
+ wavio.write("recorded.wav", data, sr)
28
+ main()
29
+ return f"Audio receive correctly"
30
+ except Exception as e:
31
+ return f"Error: {e}"
32
+
33
+ #-----------------Filter-----------------#
34
+
35
+ def butter_bandpass(lowcut, highcut, fs, order=5):
36
+ nyquist = 0.5 * fs
37
+ low = lowcut / nyquist
38
+ high = highcut / nyquist
39
+ coef = butter(order, [low, high], btype='band')
40
+ b = coef[0]
41
+ a = coef[1]
42
+ return b, a
43
+
44
+ def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
45
+ b, a = butter_bandpass(lowcut, highcut, fs, order=order)
46
+ y = lfilter(b, a, data)
47
+ return y
48
+
49
+ def main():
50
+ input_file = 'recorded.wav'
51
+ output_file = 'output_filtered_receiver.wav'
52
+ lowcut = 18000
53
+ highcut = 19000
54
+
55
+ fs, data = read(input_file)
56
+
57
+ filtered_data = butter_bandpass_filter(data, lowcut, highcut, 44100)
58
+ write(output_file, fs, np.int16(filtered_data))
59
+ return "Filtered Audio Generated"
60
+
61
+ #-----------------Frame-----------------#
62
+
63
+ def calculate_snr(data, start, end, target_frequency, sample_rate):
64
+
65
+ segment = data[start:end]
66
+ spectrum = np.fft.fft(segment)
67
+ frequencies = np.fft.fftfreq(len(spectrum), 1 / sample_rate)
68
+ target_index = np.abs(frequencies - target_frequency).argmin()
69
+ amplitude = np.abs(spectrum[target_index])
70
+
71
+ noise_segment = data[100:1000+len(segment)]
72
+ noise_spectrum = np.fft.fft(noise_segment)
73
+ noise_amplitude = np.abs(noise_spectrum[target_index])
74
+
75
+ snr = 10 * np.log10(amplitude / noise_amplitude)
76
+ return snr
77
+
78
+ filename = 'output_filtered_receiver.wav'
79
+
80
+ def frame_analyse(filename):
81
+ fs, y = read(filename)
82
+
83
+ first_part_start = 0
84
+ first_part_end = len(y) // 2
85
+
86
+ second_part_start = len(y) // 2
87
+ second_part_end = len(y)
88
+
89
+ nperseg = 256
90
+ noverlap = 128
91
+
92
+ f, t, Sxx = signal.spectrogram(y, fs, nperseg=nperseg, noverlap=noverlap)
93
+
94
+ plt.figure()
95
+ plt.pcolormesh(t, f, Sxx, shading="gouraud")
96
+ plt.xlabel("Time [s]")
97
+ plt.ylabel("Frequency [Hz]")
98
+ plt.title("Spectrogram of the signal")
99
+ plt.show()
100
+
101
+ f0 = 18000
102
+
103
+ f_idx = np.argmin(np.abs(f - f0))
104
+
105
+ thresholds_start = calculate_snr(y, first_part_start, first_part_end, low_frequency, sample_rate)
106
+ thresholds_end = calculate_snr(y, second_part_start, second_part_end, high_frequency, sample_rate)
107
+
108
+ t_idx_start = np.argmax(Sxx[f_idx] > thresholds_start)
109
+
110
+ t_start = t[t_idx_start]
111
+
112
+ t_idx_end = t_idx_start
113
+ while t_idx_end < len(t) and np.max(Sxx[f_idx, t_idx_end:]) > thresholds_end:
114
+ t_idx_end += 1
115
+
116
+ t_end = t[t_idx_end]
117
+
118
+ return t_start, t_end
119
+
120
+ #-----------------Receiver-----------------#
121
+
122
+ def dominant_frequency(signal, sample_rate=44100):
123
+ yf = fft(signal)
124
+ xf = np.linspace(0.0, sample_rate / 2.0, len(signal) // 2)
125
+ peaks, _ = find_peaks(np.abs(yf[0:len(signal) // 2]))
126
+ return xf[peaks[np.argmax(np.abs(yf[0:len(signal) // 2][peaks]))]]
127
+
128
+ def binary_to_text(binary):
129
+ try:
130
+ return ''.join(chr(int(binary[i:i + 8], 2)) for i in range(0, len(binary), 8))
131
+ except Exception as e:
132
+ return f"Except: {e}"
133
+
134
+ def decode_rs(binary_string, ecc_bytes):
135
+ byte_data = bytearray(int(binary_string[i:i+8], 2) for i in range(0, len(binary_string), 8))
136
+ rs = reedsolo.RSCodec(ecc_bytes)
137
+ corrected_data_tuple = rs.decode(byte_data)
138
+ corrected_data = corrected_data_tuple[0]
139
+
140
+ corrected_data = corrected_data.rstrip(b'\x00')
141
+
142
+ corrected_binary_string = ''.join(format(byte, '08b') for byte in corrected_data)
143
+
144
+ return corrected_binary_string
145
+
146
+ def manchester_decoding(binary_string):
147
+ decoded_string = ''
148
+ for i in tqdm(range(0, len(binary_string), 2), desc="Decoding"):
149
+ if i + 1 < len(binary_string):
150
+ if binary_string[i] == '0' and binary_string[i + 1] == '1':
151
+ decoded_string += '0'
152
+ elif binary_string[i] == '1' and binary_string[i + 1] == '0':
153
+ decoded_string += '1'
154
+ else:
155
+ print("Error: Invalid Manchester Encoding")
156
+ return None
157
+ return decoded_string
158
+
159
+ def signal_to_binary_between_times(filename):
160
+ start_time, end_time = frame_analyse(filename)
161
+
162
+ sample_rate, data = read(filename)
163
+
164
+ start_sample = int((start_time - 0.007) * sample_rate)
165
+ end_sample = int((end_time - 0.007) * sample_rate)
166
+ binary_string = ''
167
+
168
+ start_analyse_time = time.time()
169
+
170
+ for i in tqdm(range(start_sample, end_sample, int(sample_rate * bit_duration))):
171
+ signal = data[i:i + int(sample_rate * bit_duration)]
172
+ frequency = dominant_frequency(signal, sample_rate)
173
+ if np.abs(frequency - low_frequency) < np.abs(frequency - high_frequency):
174
+ binary_string += '0'
175
+ else:
176
+ binary_string += '1'
177
+
178
+ index_start = binary_string.find("1000001")
179
+ substrings = ["0111110", "011110"]
180
+ index_end = -1
181
+
182
+ for substring in substrings:
183
+ index = binary_string.find(substring)
184
+ if index != -1:
185
+ index_end = index
186
+ break
187
+
188
+ print("Binary String:", binary_string)
189
+ binary_string_decoded = manchester_decoding(binary_string[index_start+7:index_end])
190
+
191
+ #decoded_binary_string = decode_rs(binary_string_decoded, 20)
192
+
193
+ return binary_string_decoded
194
+
195
+ #-----------------Interface-----------------#
196
+
197
+ def receive():
198
+ try:
199
+ audio_receive = signal_to_binary_between_times('recorded.wav')
200
+ return binary_to_text(audio_receive)
201
+ except Exception as e:
202
+ return f"Error: {e}"
203
+
204
+ with gr.Blocks() as demo:
205
+ input_audio = gr.Audio(sources=["upload"])
206
+ output = gr.Textbox(label="Record Sound")
207
+ btn = gr.Button(value="Send")
208
+ btn.click(fn=record, inputs=input_audio, outputs=output)
209
+
210
+ output_third = gr.Textbox(label="Received Text")
211
+ btn_3 = gr.Button(value="Play WAV")
212
+ btn_3.click(fn=receive, outputs=output_third)
213
+
214
+ demo.launch()
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ libportaudio2
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ numpy~=1.24.3
2
+ sounddevice~=0.4.6
3
+ gradio~=4.8.0
4
+ reedsolo~=1.7.0
5
+ scipy~=1.11.4
6
+ tqdm~=4.66.1
7
+ ipython~=8.12.2
8
+ matplotlib~=3.5.1
9
+ wavio~=0.0.4