Different start and stop sounds.

This commit is contained in:
CJ Pais 2025-06-26 17:20:36 -07:00
parent ab79f77747
commit 528bfc24e1
7 changed files with 27 additions and 10 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -2,7 +2,8 @@ use crate::managers::audio::AudioRecordingManager;
use crate::managers::transcription::TranscriptionManager; use crate::managers::transcription::TranscriptionManager;
use crate::utils; use crate::utils;
use crate::utils::change_tray_icon; use crate::utils::change_tray_icon;
use crate::utils::play_recording_sound; use crate::utils::play_recording_start_sound;
use crate::utils::play_recording_stop_sound;
use crate::utils::TrayIconState; use crate::utils::TrayIconState;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::collections::HashMap; use std::collections::HashMap;
@ -25,7 +26,7 @@ impl ShortcutAction for TranscribeAction {
change_tray_icon(app, TrayIconState::Recording); change_tray_icon(app, TrayIconState::Recording);
// Play audio feedback for recording start // Play audio feedback for recording start
play_recording_sound(app); play_recording_start_sound(app);
let rm = app.state::<Arc<AudioRecordingManager>>(); let rm = app.state::<Arc<AudioRecordingManager>>();
rm.try_start_recording(&binding_id); rm.try_start_recording(&binding_id);
@ -39,7 +40,7 @@ impl ShortcutAction for TranscribeAction {
change_tray_icon(app, TrayIconState::Idle); change_tray_icon(app, TrayIconState::Idle);
// Play audio feedback for recording stop // Play audio feedback for recording stop
play_recording_sound(app); play_recording_stop_sound(app);
let binding_id = binding_id.to_string(); // Clone binding_id for the async task let binding_id = binding_id.to_string(); // Clone binding_id for the async task

View file

@ -48,7 +48,7 @@ pub fn get_default_settings() -> AppSettings {
AppSettings { AppSettings {
bindings, bindings,
push_to_talk: true, push_to_talk: true,
audio_feedback: true, audio_feedback: false,
} }
} }

View file

@ -87,7 +87,9 @@ pub fn change_tray_icon(app: &AppHandle, icon: TrayIconState) {
)); ));
} }
pub fn play_recording_sound(app: &AppHandle) { /// Plays an audio resource from the resources directory.
/// Checks if audio feedback is enabled in settings before playing.
pub fn play_sound(app: &AppHandle, resource_path: &str) {
// Check if audio feedback is enabled // Check if audio feedback is enabled
let settings = settings::get_settings(app); let settings = settings::get_settings(app);
if !settings.audio_feedback { if !settings.audio_feedback {
@ -95,28 +97,42 @@ pub fn play_recording_sound(app: &AppHandle) {
} }
let app_handle = app.clone(); let app_handle = app.clone();
let resource_path = resource_path.to_string();
// Spawn a new thread to play the audio without blocking the main thread // Spawn a new thread to play the audio without blocking the main thread
thread::spawn(move || { thread::spawn(move || {
// Get the path to the rec.wav file in resources // Get the path to the audio file in resources
let audio_path = match app_handle let audio_path = match app_handle
.path() .path()
.resolve("resources/rec.wav", tauri::path::BaseDirectory::Resource) .resolve(&resource_path, tauri::path::BaseDirectory::Resource)
{ {
Ok(path) => path, Ok(path) => path,
Err(e) => { Err(e) => {
eprintln!("Failed to resolve audio file path: {}", e); eprintln!(
"Failed to resolve audio file path '{}': {}",
resource_path, e
);
return; return;
} }
}; };
// Try to play the audio file // Try to play the audio file
if let Err(e) = play_audio_file(&audio_path) { if let Err(e) = play_audio_file(&audio_path) {
eprintln!("Failed to play recording sound: {}", e); eprintln!("Failed to play sound '{}': {}", resource_path, e);
} }
}); });
} }
/// Convenience function to play the recording start sound
pub fn play_recording_start_sound(app: &AppHandle) {
play_sound(app, "resources/rec_start.wav");
}
/// Convenience function to play the recording stop sound
pub fn play_recording_stop_sound(app: &AppHandle) {
play_sound(app, "resources/rec_stop.wav");
}
fn play_audio_file(path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> { fn play_audio_file(path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
// Get a output stream handle to the default physical sound device // Get a output stream handle to the default physical sound device
let (_stream, stream_handle) = OutputStream::try_default()?; let (_stream, stream_handle) = OutputStream::try_default()?;

View file

@ -15,7 +15,7 @@ export const KeyboardShortcuts: React.FC = () => {
const [bindings, setBindings] = React.useState<ShortcutBindingsMap>({}); const [bindings, setBindings] = React.useState<ShortcutBindingsMap>({});
const [pttEnabled, setPttEnabled] = React.useState<boolean>(false); const [pttEnabled, setPttEnabled] = React.useState<boolean>(false);
const [audioFeedbackEnabled, setAudioFeedbackEnabled] = const [audioFeedbackEnabled, setAudioFeedbackEnabled] =
React.useState<boolean>(true); React.useState<boolean>(false);
const [keyPressed, setKeyPressed] = useState<string[]>([]); const [keyPressed, setKeyPressed] = useState<string[]>([]);
const [recordedKeys, setRecordedKeys] = useState<string[]>([]); const [recordedKeys, setRecordedKeys] = useState<string[]>([]);
const [editingShortcutId, setEditingShortcutId] = useState<string | null>( const [editingShortcutId, setEditingShortcutId] = useState<string | null>(