daasime Claude Opus 4.6 commited on
Commit
ebe2991
·
1 Parent(s): 2884e37

Add 3 new demo scenarios + Coming Soon badge + lazy generation

Browse files

New demos: Wake Word (Alexa + beep), Synthetic/Robotic Voice,
Two Different Speakers. Total 6 demo scenarios. Demos generate
on first app startup instead of build time. Added Batch Analysis
Coming Soon badge below Upload section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. app.py +4 -1
  2. generate_demos.py +100 -0
app.py CHANGED
@@ -298,7 +298,10 @@ def render_analyzer_tab():
298
  demo_files = {
299
  "Clean Exam (No Fraud)": "demo_clean_exam.wav",
300
  "Reading Pattern + Long Pause": "demo_reading_fraud.wav",
301
- "Multiple Speakers + Whisper": "demo_coaching_fraud.wav",
 
 
 
302
  }
303
  available_demos = {
304
  name: os.path.join(samples_dir, fname)
 
298
  demo_files = {
299
  "Clean Exam (No Fraud)": "demo_clean_exam.wav",
300
  "Reading Pattern + Long Pause": "demo_reading_fraud.wav",
301
+ "Coaching (Whispered Prompts)": "demo_coaching_fraud.wav",
302
+ "Wake Word (Alexa + Beep)": "demo_wake_word.wav",
303
+ "Synthetic / Robotic Voice": "demo_synthetic_voice.wav",
304
+ "Two Different Speakers": "demo_two_speakers.wav",
305
  }
306
  available_demos = {
307
  name: os.path.join(samples_dir, fname)
generate_demos.py CHANGED
@@ -85,6 +85,103 @@ def generate_coaching_fraud():
85
  )
86
 
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  def main():
89
  os.makedirs(OUTPUT_DIR, exist_ok=True)
90
 
@@ -92,6 +189,9 @@ def main():
92
  "demo_clean_exam.wav": generate_clean_exam,
93
  "demo_reading_fraud.wav": generate_reading_fraud,
94
  "demo_coaching_fraud.wav": generate_coaching_fraud,
 
 
 
95
  }
96
 
97
  for filename, generator in demos.items():
 
85
  )
86
 
87
 
88
+ def generate_wake_word():
89
+ """Scenario 4: Wake word - someone asks Alexa mid-exam."""
90
+ import numpy as np
91
+
92
+ main1 = _tts("I think the most important factor in choosing a career is job satisfaction.")
93
+ main2 = _tts("Because if you enjoy what you do, you'll be more productive and motivated.")
94
+ main3 = _tts("Sorry, what was I saying? Oh yes, career satisfaction is crucial for long term happiness.")
95
+ main4 = _tts("And that's why I believe people should follow their passion when choosing a career.")
96
+
97
+ # "Alexa" wake word spoken quietly
98
+ alexa_call = _tts("Alexa, what is career satisfaction", lang="en") - 12
99
+
100
+ # Synthetic beep tone (1kHz, 0.3s) to simulate device response
101
+ sample_rate = 16000
102
+ t = np.linspace(0, 0.3, int(sample_rate * 0.3))
103
+ beep = (np.sin(2 * np.pi * 1000 * t) * 0.15 * 32767).astype(np.int16)
104
+ beep_seg = AudioSegment(beep.tobytes(), frame_rate=sample_rate, sample_width=2, channels=1)
105
+
106
+ return (
107
+ main1
108
+ + _silence(1000)
109
+ + main2
110
+ + _silence(1500)
111
+ + alexa_call
112
+ + _silence(400)
113
+ + beep_seg
114
+ + _silence(2000)
115
+ + main3
116
+ + _silence(800)
117
+ + main4
118
+ )
119
+
120
+
121
+ def generate_synthetic_voice():
122
+ """Scenario 5: Synthetic/robotic voice with beep tones."""
123
+ import numpy as np
124
+
125
+ # Use slow TTS to sound more robotic
126
+ robo1 = _tts("The answer to question number one is as follows.", slow=True)
127
+ robo2 = _tts("Climate change is caused by greenhouse gas emissions from human activities.", slow=True)
128
+ robo3 = _tts("The main sources include transportation, industry, and agriculture.", slow=True)
129
+ robo4 = _tts("In conclusion, reducing emissions requires global cooperation.", slow=True)
130
+
131
+ # Generate beep tones between segments (synthetic indicator)
132
+ sample_rate = 16000
133
+ def make_beep(freq, dur):
134
+ t = np.linspace(0, dur, int(sample_rate * dur))
135
+ tone = (np.sin(2 * np.pi * freq * t) * 0.2 * 32767).astype(np.int16)
136
+ return AudioSegment(tone.tobytes(), frame_rate=sample_rate, sample_width=2, channels=1)
137
+
138
+ beep_hi = make_beep(880, 0.15)
139
+ beep_lo = make_beep(440, 0.15)
140
+ double_beep = beep_hi + _silence(100) + beep_lo
141
+
142
+ return (
143
+ double_beep
144
+ + _silence(300)
145
+ + robo1
146
+ + _silence(400)
147
+ + robo2
148
+ + double_beep
149
+ + _silence(500)
150
+ + robo3
151
+ + _silence(400)
152
+ + robo4
153
+ + _silence(200)
154
+ + double_beep
155
+ )
156
+
157
+
158
+ def generate_two_speakers():
159
+ """Scenario 6: Two distinct speakers taking turns (impersonation/proxy)."""
160
+ # Speaker A - normal pace, English
161
+ a1 = _tts("Hello, my name is John and I'm here to take the speaking test today.")
162
+ a2 = _tts("I think that learning a second language is very important in today's world.")
163
+ a3 = _tts("For example, it helps you communicate with people from different countries.")
164
+
165
+ # Speaker B - different accent (UK English) to sound like a different person
166
+ b1 = _tts("Right, so the next topic is about technology in education.", lang="en-uk")
167
+ b2 = _tts("Technology has completely changed the way students learn and interact with content.", lang="en-uk")
168
+ b3 = _tts("Online courses and digital tools make education more accessible to everyone.", lang="en-uk")
169
+
170
+ return (
171
+ a1
172
+ + _silence(1000)
173
+ + a2
174
+ + _silence(800)
175
+ + a3
176
+ + _silence(2500) # Longer pause as speakers switch
177
+ + b1
178
+ + _silence(700)
179
+ + b2
180
+ + _silence(600)
181
+ + b3
182
+ )
183
+
184
+
185
  def main():
186
  os.makedirs(OUTPUT_DIR, exist_ok=True)
187
 
 
189
  "demo_clean_exam.wav": generate_clean_exam,
190
  "demo_reading_fraud.wav": generate_reading_fraud,
191
  "demo_coaching_fraud.wav": generate_coaching_fraud,
192
+ "demo_wake_word.wav": generate_wake_word,
193
+ "demo_synthetic_voice.wav": generate_synthetic_voice,
194
+ "demo_two_speakers.wav": generate_two_speakers,
195
  }
196
 
197
  for filename, generator in demos.items():