Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -19,33 +19,29 @@ class GGWaveTransceiver:
|
|
19 |
def __init__(self):
|
20 |
self.sample_rate = 48000
|
21 |
self.protocols = {
|
22 |
-
'Normal':
|
23 |
-
'Fast':
|
24 |
-
'Fastest':
|
25 |
-
'Ultrasonic':
|
26 |
-
'
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
-
|
29 |
def encode_text_to_audio(self, text, protocol='Normal', volume=50):
|
30 |
"""Encode text to audio using ggwave"""
|
31 |
try:
|
32 |
-
protocol_id = self.protocols.get(protocol,
|
33 |
|
34 |
-
#
|
35 |
-
|
36 |
-
sample_rate=self.sample_rate,
|
37 |
-
samples_per_frame=1024,
|
38 |
-
sound_marker_threshold=0.1,
|
39 |
-
marker_duration=0.2
|
40 |
-
)
|
41 |
-
|
42 |
-
# Encode text to audio
|
43 |
-
audio_data = instance.encode(text.encode('utf-8'), protocol_id, volume)
|
44 |
|
45 |
if audio_data is None:
|
46 |
return None, "Failed to encode text"
|
47 |
|
48 |
-
# Convert to numpy array
|
49 |
audio_array = np.frombuffer(audio_data, dtype=np.float32)
|
50 |
|
51 |
# Create temporary WAV file
|
@@ -78,21 +74,35 @@ class GGWaveTransceiver:
|
|
78 |
# Convert to float32
|
79 |
audio_float = audio_data.astype(np.float32) / 32767.0
|
80 |
|
81 |
-
#
|
82 |
-
instance = ggwave.
|
83 |
-
sample_rate=self.sample_rate,
|
84 |
-
samples_per_frame=1024,
|
85 |
-
sound_marker_threshold=0.1,
|
86 |
-
marker_duration=0.2
|
87 |
-
)
|
88 |
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
except Exception as e:
|
98 |
return f"Error decoding: {str(e)}"
|
@@ -117,8 +127,30 @@ def decode_audio(audio_file):
|
|
117 |
def create_demo_audio():
|
118 |
"""Create a demo audio file"""
|
119 |
demo_text = "Hello from ggwave!"
|
120 |
-
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
|
123 |
# Phone integration helper functions
|
124 |
def get_twilio_webhook_code():
|
|
|
19 |
def __init__(self):
|
20 |
self.sample_rate = 48000
|
21 |
self.protocols = {
|
22 |
+
'Normal': 0, # Normal audible
|
23 |
+
'Fast': 1, # Fast audible
|
24 |
+
'Fastest': 2, # Fastest audible
|
25 |
+
'Ultrasonic Normal': 3, # Ultrasonic normal
|
26 |
+
'Ultrasonic Fast': 4, # Ultrasonic fast
|
27 |
+
'Ultrasonic Fastest': 5, # Ultrasonic fastest
|
28 |
+
'DT Normal': 6, # Data Transfer normal
|
29 |
+
'DT Fast': 7, # Data Transfer fast
|
30 |
+
'DT Fastest': 8, # Data Transfer fastest
|
31 |
}
|
32 |
+
|
33 |
def encode_text_to_audio(self, text, protocol='Normal', volume=50):
|
34 |
"""Encode text to audio using ggwave"""
|
35 |
try:
|
36 |
+
protocol_id = self.protocols.get(protocol, 0)
|
37 |
|
38 |
+
# Use the simple ggwave.encode function
|
39 |
+
audio_data = ggwave.encode(text, protocolId=protocol_id, volume=volume)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
if audio_data is None:
|
42 |
return None, "Failed to encode text"
|
43 |
|
44 |
+
# Convert bytes to numpy array (ggwave returns raw bytes)
|
45 |
audio_array = np.frombuffer(audio_data, dtype=np.float32)
|
46 |
|
47 |
# Create temporary WAV file
|
|
|
74 |
# Convert to float32
|
75 |
audio_float = audio_data.astype(np.float32) / 32767.0
|
76 |
|
77 |
+
# Initialize ggwave instance for decoding
|
78 |
+
instance = ggwave.init()
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
+
try:
|
81 |
+
# Decode audio in chunks
|
82 |
+
chunk_size = 1024
|
83 |
+
decoded_text = None
|
84 |
+
|
85 |
+
for i in range(0, len(audio_float), chunk_size):
|
86 |
+
chunk = audio_float[i:i+chunk_size]
|
87 |
+
|
88 |
+
# Convert chunk to bytes for ggwave
|
89 |
+
chunk_bytes = chunk.astype(np.float32).tobytes()
|
90 |
+
|
91 |
+
# Try to decode this chunk
|
92 |
+
result = ggwave.decode(instance, chunk_bytes)
|
93 |
+
|
94 |
+
if result is not None:
|
95 |
+
decoded_text = result.decode('utf-8')
|
96 |
+
break
|
97 |
+
|
98 |
+
if decoded_text:
|
99 |
+
return f"Decoded message: {decoded_text}"
|
100 |
+
else:
|
101 |
+
return "No valid ggwave signal detected in audio"
|
102 |
+
|
103 |
+
finally:
|
104 |
+
# Clean up the instance
|
105 |
+
ggwave.free(instance)
|
106 |
|
107 |
except Exception as e:
|
108 |
return f"Error decoding: {str(e)}"
|
|
|
127 |
def create_demo_audio():
|
128 |
"""Create a demo audio file"""
|
129 |
demo_text = "Hello from ggwave!"
|
130 |
+
try:
|
131 |
+
# Use the simple ggwave.encode function directly
|
132 |
+
audio_data = ggwave.encode(demo_text, protocolId=0, volume=50)
|
133 |
+
|
134 |
+
if audio_data is None:
|
135 |
+
return None
|
136 |
+
|
137 |
+
# Convert to numpy array and create WAV file
|
138 |
+
audio_array = np.frombuffer(audio_data, dtype=np.float32)
|
139 |
+
|
140 |
+
with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as tmp_file:
|
141 |
+
with wave.open(tmp_file.name, 'w') as wav_file:
|
142 |
+
wav_file.setnchannels(1)
|
143 |
+
wav_file.setsampwidth(2)
|
144 |
+
wav_file.setframerate(48000)
|
145 |
+
|
146 |
+
# Convert float32 to int16
|
147 |
+
audio_int16 = (audio_array * 32767).astype(np.int16)
|
148 |
+
wav_file.writeframes(audio_int16.tobytes())
|
149 |
+
|
150 |
+
return tmp_file.name
|
151 |
+
except Exception as e:
|
152 |
+
print(f"Error creating demo: {e}")
|
153 |
+
return None
|
154 |
|
155 |
# Phone integration helper functions
|
156 |
def get_twilio_webhook_code():
|