Spaces:
Build error
Build error
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():
|