403 lines
8.6 KiB
Rust
403 lines
8.6 KiB
Rust
use dsp_thomann::dsp408::types::DelayUnit;
|
|
use tauri::State;
|
|
use crate::state::{AppState, DSPDevice};
|
|
use dsp_thomann::dsp408::{DSP408, types};
|
|
use std::{net::IpAddr, str::FromStr};
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
impl AppState {
|
|
pub fn with_device_mut<F, R>(
|
|
&self,
|
|
id: u64,
|
|
f: F,
|
|
) -> Result<R, String>
|
|
where
|
|
F: FnOnce(&mut DSPDevice) -> Result<R, String>,
|
|
{
|
|
let device = {
|
|
let devices = self
|
|
.devices
|
|
.lock()
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
devices
|
|
.get(&id)
|
|
.cloned()
|
|
.ok_or_else(|| "DSP not found".to_string())?
|
|
};
|
|
|
|
let mut device = device
|
|
.lock()
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
f(&mut device)
|
|
}
|
|
|
|
pub fn remove_device(
|
|
&self,
|
|
id: u64,
|
|
) -> Result<(), String> {
|
|
|
|
let device = {
|
|
let mut devices = self.devices
|
|
.lock()
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
devices
|
|
.remove(&id)
|
|
.ok_or_else(|| format!("DSP {} not found", id))?
|
|
};
|
|
|
|
// Drop happens here.
|
|
// DSPDevice owns DSP408.
|
|
drop(device);
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub fn create_dsp408(
|
|
state: State<AppState>,
|
|
ip: String,
|
|
port: u16,
|
|
device_id: u8,
|
|
) -> Result<u64, String> {
|
|
|
|
let ip = IpAddr::from_str(&ip)
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let dsp = DSP408::new(ip, port, device_id)
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let mut next_id = state
|
|
.next_id
|
|
.lock()
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let id = *next_id;
|
|
*next_id += 1;
|
|
|
|
let device = DSPDevice {
|
|
dsp,
|
|
};
|
|
|
|
let mut devices = state
|
|
.devices
|
|
.lock()
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
devices.insert(
|
|
id,
|
|
Arc::new(Mutex::new(device)),
|
|
);
|
|
|
|
Ok(id)
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn remove_dsp408(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
) -> Result<(), String> {
|
|
|
|
state.with_device_mut(id, |device| {
|
|
|
|
if device.dsp.connected() {
|
|
device.dsp
|
|
.disconnect()
|
|
.map_err(|e| e.to_string())?;
|
|
}
|
|
|
|
Ok(())
|
|
})?;
|
|
|
|
state.remove_device(id)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn connect_dsp408(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
) -> Result<(), String> {
|
|
|
|
state.with_device_mut(id, |device| {
|
|
device.dsp
|
|
.connect()
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn disconnect_dsp408(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
) -> Result<(), String> {
|
|
|
|
state.with_device_mut(id, |device| {
|
|
device.dsp
|
|
.disconnect()
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn get_dsp_state(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
) -> Result<dsp_thomann::dsp408::types::DSPState, String> {
|
|
|
|
state.with_device_mut(id, |device| {
|
|
let dsp_state = device.dsp
|
|
.state()
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(dsp_state.clone())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_channel_gain(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
channel: dsp_thomann::dsp408::types::Channel,
|
|
db: f32,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
let r = device.dsp
|
|
.set_channel_gain(channel, db)
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(r)
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_mute(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
channel: dsp_thomann::dsp408::types::Channel,
|
|
muted: bool,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
let r = device.dsp
|
|
.set_mute(channel, muted)
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(r)
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_channel_inverse_gain(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
channel: dsp_thomann::dsp408::types::Channel,
|
|
inverted: bool,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
let r = device.dsp
|
|
.set_channel_inverse_gain(channel, inverted)
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(r)
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn recall_preset(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
preset_index: usize,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
let success = device
|
|
.dsp
|
|
.recall_preset(preset_index)
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
Ok(success)
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn get_meter_levels(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
) -> Result<dsp_thomann::dsp408::types::Meters, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.get_meter_levels()
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_current_preset_name(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
name: String,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_current_preset_name(&name)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_gate(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
channel: types::InputChannel,
|
|
threshold: f32,
|
|
attack: u16,
|
|
hold: u16,
|
|
release: u16,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_gate(channel, threshold, attack, hold, release)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_compressor(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
channel: types::OutputChannel,
|
|
ratio: types::Ratio,
|
|
attack: u16,
|
|
release: u16,
|
|
knee: u16,
|
|
threshold: f32,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_compressor(
|
|
channel,
|
|
ratio,
|
|
attack,
|
|
release,
|
|
knee,
|
|
threshold,
|
|
)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_limiter(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
channel: types::OutputChannel,
|
|
threshold: f32,
|
|
attack: u16,
|
|
release: u16,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_limiter(channel, threshold, attack, release)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_delay_unit(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
unit: types::DelayUnit,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_delay_unit(unit)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_delay(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
channel: types::Channel,
|
|
delay: f32,
|
|
unit: DelayUnit
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_delay(channel, delay, unit)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_matrix_routing(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
output: types::OutputChannel,
|
|
inputs: Vec<types::InputChannel>,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_matrix_routing(output, inputs)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_matrix_gain(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
input_channel: types::InputChannel,
|
|
output_channel: types::OutputChannel,
|
|
gain: f32,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_matrix_gain(input_channel, output_channel, gain)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_geq_band(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
input_channel: types::InputChannel,
|
|
frequency_band: types::DiscreteFrequency,
|
|
gain: f32,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_geq_band(input_channel, frequency_band, gain)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
pub async fn set_geq_bypass(
|
|
state: State<'_, AppState>,
|
|
id: u64,
|
|
input_channel: types::InputChannel,
|
|
bypass: bool,
|
|
) -> Result<bool, String> {
|
|
state.with_device_mut(id, |device| {
|
|
device
|
|
.dsp
|
|
.set_geq_bypass(input_channel, bypass)
|
|
.map_err(|e| e.to_string())
|
|
})
|
|
} |