use std::path::PathBuf; use crate::model::{InputSource, PhoenixGlobalConfig, PhoenixRtaConfig}; #[derive(Clone, Debug)] pub struct PhoenixConfig { pub listen_addr: String, pub alsa_card_index: u8, pub alsa_device_name: Option, #[cfg_attr(not(target_os = "linux"), allow(dead_code))] pub sample_rate: u32, #[cfg_attr(not(target_os = "linux"), allow(dead_code))] pub period_size: u32, #[cfg_attr(not(target_os = "linux"), allow(dead_code))] pub buffer_size: u32, pub global_config_path: PathBuf, pub frontend_presets_path: PathBuf, pub frontend_layouts_path: PathBuf, pub recordings_dir_analyzer: PathBuf, pub recordings_dir_volumio: PathBuf, pub max_recording_upload_bytes: u64, pub lr_fractional_delay_enabled: bool, pub lr_fractional_delay_samples: f32, } impl PhoenixConfig { pub fn from_env() -> Self { Self { listen_addr: std::env::var("PHOENIX_LISTEN") .unwrap_or_else(|_| "127.0.0.1:8789".to_string()), alsa_card_index: std::env::var("PHOENIX_ALSA_CARD") .ok() .and_then(|v| v.parse::().ok()) .unwrap_or(2), alsa_device_name: std::env::var("PHOENIX_ALSA_DEVICE") .ok() .map(|v| v.trim().to_string()) .filter(|v| !v.is_empty()), sample_rate: std::env::var("PHOENIX_SAMPLE_RATE") .ok() .and_then(|v| v.parse::().ok()) .unwrap_or(48_000), period_size: std::env::var("PHOENIX_PERIOD_SIZE") .ok() .and_then(|v| v.parse::().ok()) .unwrap_or(128), buffer_size: std::env::var("PHOENIX_BUFFER_SIZE") .ok() .and_then(|v| v.parse::().ok()) .unwrap_or(512), global_config_path: std::env::var("PHOENIX_GLOBAL_CONFIG_PATH") .ok() .map(|v| PathBuf::from(v.trim())) .filter(|v| !v.as_os_str().is_empty()) .unwrap_or_else(default_global_config_path), frontend_presets_path: std::env::var("PHOENIX_FRONTEND_PRESETS_PATH") .ok() .map(|v| PathBuf::from(v.trim())) .filter(|v| !v.as_os_str().is_empty()) .unwrap_or_else(default_frontend_presets_path), frontend_layouts_path: std::env::var("PHOENIX_FRONTEND_LAYOUTS_PATH") .ok() .map(|v| PathBuf::from(v.trim())) .filter(|v| !v.as_os_str().is_empty()) .unwrap_or_else(default_frontend_layouts_path), recordings_dir_analyzer: std::env::var("PHOENIX_RECORDINGS_DIR_ANALYZER") .ok() .map(|v| PathBuf::from(v.trim())) .filter(|v| !v.as_os_str().is_empty()) .unwrap_or_else(default_recordings_dir_analyzer), recordings_dir_volumio: std::env::var("PHOENIX_RECORDINGS_DIR_VOLUMIO") .ok() .map(|v| PathBuf::from(v.trim())) .filter(|v| !v.as_os_str().is_empty()) .unwrap_or_else(default_recordings_dir_volumio), max_recording_upload_bytes: std::env::var("PHOENIX_MAX_RECORDING_UPLOAD_BYTES") .ok() .and_then(|v| v.trim().parse::().ok()) .filter(|v| *v > 0) .unwrap_or(2 * 1024 * 1024 * 1024), lr_fractional_delay_enabled: std::env::var("PHOENIX_LR_FRAC_DELAY_ENABLED") .ok() .map(|v| { matches!( v.trim().to_ascii_lowercase().as_str(), "1" | "true" | "yes" | "on" ) }) .unwrap_or(true), lr_fractional_delay_samples: std::env::var("PHOENIX_LR_FRAC_DELAY_SAMPLES") .ok() .and_then(|v| v.parse::().ok()) .unwrap_or(0.996), } } pub fn alsa_device(&self) -> String { if let Some(device) = &self.alsa_device_name { return device.clone(); } format!("hw:{},0", self.alsa_card_index) } pub fn default_rta_config(&self) -> PhoenixRtaConfig { let mut config = PhoenixRtaConfig::default(); config.lr_fractional_delay_enabled = self.lr_fractional_delay_enabled; config.lr_fractional_delay_samples = self.lr_fractional_delay_samples; config } pub fn default_global_config(&self) -> PhoenixGlobalConfig { let mut config = PhoenixGlobalConfig::default(); config.input_source = InputSource::Line; config.lr_fractional_delay_enabled = self.lr_fractional_delay_enabled; config.lr_fractional_delay_samples = self.lr_fractional_delay_samples; config } } fn default_global_config_path() -> PathBuf { if let Some(home) = std::env::var_os("HOME") { let mut path = PathBuf::from(home); path.push(".config"); path.push("phoenix"); path.push("global-config.json"); return path; } PathBuf::from("phoenix-global-config.json") } fn default_frontend_presets_path() -> PathBuf { if let Some(home) = std::env::var_os("HOME") { let mut path = PathBuf::from(home); path.push(".config"); path.push("phoenix"); path.push("frontend-presets.json"); return path; } PathBuf::from("phoenix-frontend-presets.json") } fn default_frontend_layouts_path() -> PathBuf { if let Some(home) = std::env::var_os("HOME") { let mut path = PathBuf::from(home); path.push(".config"); path.push("phoenix"); path.push("frontend-layouts.json"); return path; } PathBuf::from("phoenix-frontend-layouts.json") } fn default_recordings_dir_analyzer() -> PathBuf { PathBuf::from("/home/analyzer/Aufnahmen") } fn default_recordings_dir_volumio() -> PathBuf { PathBuf::from("/home/volumio/Aufnahmen") }