Skip to content

Commit 984252b

Browse files
author
Danielle Jenkins
committed
Ensure that the terminal stays open if there's an error
1 parent 6f69811 commit 984252b

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

src/main.rs

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ use rosc::{encoder::encode, OscMessage, OscPacket, OscType};
55
use serde::{Deserialize, Serialize};
66
use std::error::Error;
77
use std::fs;
8-
use std::io::Cursor;
8+
use std::io::{self, Cursor, Write};
99
use std::sync::{Arc, Mutex};
1010
use std::time::{Duration, Instant};
1111
use tokio::sync::mpsc;
1212
use tokio::time::sleep;
1313

14-
1514
#[derive(Deserialize, Clone)]
1615
struct Config {
1716
osc: OscConfig,
@@ -63,7 +62,6 @@ struct ChatGptChoice {
6362
message: ChatGptMessage,
6463
}
6564

66-
6765
#[derive(Deserialize, Clone)]
6866
struct AudioConfig {
6967
silence_threshold: u32,
@@ -72,7 +70,6 @@ struct AudioConfig {
7270
min_transcription_duration: f32,
7371
}
7472

75-
7673
#[derive(Deserialize, Clone)]
7774
struct RateLimitConfig {
7875
requests_per_minute: usize,
@@ -132,7 +129,7 @@ impl NoiseGate {
132129

133130
fn process(&mut self, samples: &[f32]) -> bool {
134131
let max_amplitude = samples.iter().map(|&s| s.abs()).fold(0.0f32, f32::max);
135-
132+
136133
if max_amplitude > self.threshold {
137134
self.last_active = Instant::now();
138135
self.is_active = true;
@@ -240,7 +237,7 @@ async fn send_to_chatbox(message: &str, config: &Config, socket: &UdpSocket) ->
240237

241238
async fn transcribe_audio(audio_data: Vec<u8>, config: &OpenAiConfig, rate_limiter: &mut RateLimiter) -> Result<String, Box<dyn Error>> {
242239
println!("Starting audio transcription. Audio data size: {} bytes", audio_data.len());
243-
240+
244241
if audio_data.is_empty() {
245242
return Err("Audio data is empty".into());
246243
}
@@ -293,11 +290,11 @@ async fn process_audio(
293290
) -> Result<(), Box<dyn Error>> {
294291
// Calculate audio duration
295292
let audio_duration = calculate_audio_duration(&audio_data)?;
296-
293+
297294
// Check if audio is shorter than the minimum transcription duration
298295
let min_duration = Duration::from_secs_f32(config.audio.min_transcription_duration);
299296
if audio_duration < min_duration {
300-
println!("Audio too short ({:.2}s). Minimum duration is {:.2}s. Skipping transcription.",
297+
println!("Audio too short ({:.2}s). Minimum duration is {:.2}s. Skipping transcription.",
301298
audio_duration.as_secs_f32(), min_duration.as_secs_f32());
302299
typing_indicator.set_typing(false).await;
303300
return Ok(());
@@ -335,7 +332,6 @@ enum AudioEvent {
335332
AudioData(Vec<u8>),
336333
}
337334

338-
339335
fn start_audio_recording(
340336
config: &Config,
341337
tx: mpsc::Sender<AudioEvent>,
@@ -371,22 +367,22 @@ fn start_audio_recording(
371367
move |data: &[f32], _: &cpal::InputCallbackInfo| {
372368
if noise_gate.process(data) {
373369
let mut buffer = audio_data_clone.lock().unwrap();
374-
370+
375371
if !is_recording {
376372
is_recording = true;
377373
println!("Sound detected. Starting recording...");
378374
let _ = tx_clone.try_send(AudioEvent::StartRecording);
379375
}
380-
376+
381377
buffer.extend_from_slice(data);
382378
silent_frames = 0;
383379
} else if is_recording {
384380
silent_frames += 1;
385-
381+
386382
if silent_frames >= silence_threshold {
387383
is_recording = false;
388384
silent_frames = 0;
389-
385+
390386
let mut buffer = audio_data_clone.lock().unwrap();
391387
if !buffer.is_empty() {
392388
println!("Silence detected. Stopping recording and processing audio...");
@@ -411,7 +407,7 @@ fn start_audio_recording(
411407
let _ = tx_clone.try_send(AudioEvent::AudioData(wav_buffer));
412408
buffer.clear();
413409
}
414-
410+
415411
let _ = tx_clone.try_send(AudioEvent::StopRecording);
416412
} else {
417413
// Keep recording during short pauses
@@ -437,6 +433,27 @@ fn start_audio_recording(
437433

438434
#[tokio::main]
439435
async fn main() -> Result<(), Box<dyn Error>> {
436+
// Set a panic hook to handle panics and prevent the program from closing immediately
437+
std::panic::set_hook(Box::new(|panic_info| {
438+
eprintln!("Panic occurred: {}", panic_info);
439+
440+
// Ensure this is always executed after a panic
441+
println!("Press Enter to exit...");
442+
io::stdout().flush().unwrap();
443+
let _ = io::stdin().read_line(&mut String::new());
444+
}));
445+
446+
let result = run_main().await;
447+
448+
// Ensure this is always executed
449+
println!("Press Enter to exit...");
450+
io::stdout().flush().unwrap();
451+
let _ = io::stdin().read_line(&mut String::new());
452+
453+
result
454+
}
455+
456+
async fn run_main() -> Result<(), Box<dyn Error>> {
440457
let config_data = fs::read_to_string("config.toml")?;
441458
let config: Config = toml::from_str(&config_data)?;
442459
let config = Arc::new(config);

0 commit comments

Comments
 (0)