106 lines
3.4 KiB
Rust
106 lines
3.4 KiB
Rust
use crate::settings;
|
|
use cpal::traits::{DeviceTrait, HostTrait};
|
|
use rodio::OutputStreamBuilder;
|
|
use std::fs::File;
|
|
use std::io::BufReader;
|
|
use std::thread;
|
|
use tauri::{AppHandle, Manager};
|
|
|
|
/// 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
|
|
let settings = settings::get_settings(app);
|
|
if !settings.audio_feedback {
|
|
return;
|
|
}
|
|
|
|
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
|
|
thread::spawn(move || {
|
|
// Get the path to the audio file in resources
|
|
let audio_path = match app_handle
|
|
.path()
|
|
.resolve(&resource_path, tauri::path::BaseDirectory::Resource)
|
|
{
|
|
Ok(path) => path.to_path_buf(),
|
|
Err(e) => {
|
|
eprintln!(
|
|
"Failed to resolve audio file path '{}': {}",
|
|
resource_path, e
|
|
);
|
|
return;
|
|
}
|
|
};
|
|
|
|
// Get the selected output device from settings
|
|
let settings = settings::get_settings(&app_handle);
|
|
let selected_device = settings.selected_output_device.clone();
|
|
|
|
// Try to play the audio file
|
|
if let Err(e) = play_audio_file(&audio_path, selected_device) {
|
|
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,
|
|
selected_device: Option<String>,
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
let stream_builder = if let Some(device_name) = selected_device {
|
|
if device_name == "Default" {
|
|
println!("Using default device");
|
|
// Use default device
|
|
OutputStreamBuilder::from_default_device()?
|
|
} else {
|
|
// Try to find the device by name
|
|
let host = cpal::default_host();
|
|
let devices = host.output_devices()?;
|
|
|
|
let mut found_device = None;
|
|
for device in devices {
|
|
if device.name()? == device_name {
|
|
found_device = Some(device);
|
|
break;
|
|
}
|
|
}
|
|
|
|
match found_device {
|
|
Some(device) => OutputStreamBuilder::from_device(device)?,
|
|
None => {
|
|
eprintln!("Device '{}' not found, using default device", device_name);
|
|
OutputStreamBuilder::from_default_device()?
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
println!("Using default device");
|
|
// Use default device
|
|
OutputStreamBuilder::from_default_device()?
|
|
};
|
|
|
|
let stream_handle = stream_builder.open_stream()?;
|
|
let mixer = stream_handle.mixer();
|
|
|
|
// Load the audio file
|
|
let file = File::open(path)?;
|
|
let buf_reader = BufReader::new(file);
|
|
|
|
let sink = rodio::play(mixer, buf_reader)?;
|
|
sink.sleep_until_end();
|
|
|
|
Ok(())
|
|
}
|