+120
-349
@@ -14,14 +14,10 @@ use crate::{
|
||||
dsp408::{
|
||||
mapper::{
|
||||
self,
|
||||
constants::{PRESET_INDEX_MAX, CONFIG_CHUNK_INDEX_MAX},
|
||||
constants::{CONFIG_CHUNK_INDEX_MAX, PRESET_INDEX_MAX},
|
||||
response::map_response,
|
||||
},
|
||||
protocol::{
|
||||
commands,
|
||||
config::decode_config,
|
||||
frame::extract_frame,
|
||||
},
|
||||
protocol::{commands, config::decode_config, frame::extract_frame},
|
||||
types,
|
||||
},
|
||||
};
|
||||
@@ -44,33 +40,21 @@ pub struct DSP408 {
|
||||
}
|
||||
|
||||
impl DSP408 {
|
||||
|
||||
pub fn new(
|
||||
host: IpAddr,
|
||||
port: u16,
|
||||
device_id: u8,
|
||||
) -> Result<Self, DSPError> {
|
||||
|
||||
pub fn new(host: IpAddr, port: u16, device_id: u8) -> Result<Self, DSPError> {
|
||||
if matches!(host, IpAddr::V6(_)) {
|
||||
return Err(DSPError::InvalidHost(
|
||||
"DSP doesn't support IPv6"
|
||||
));
|
||||
return Err(DSPError::InvalidHost("DSP doesn't support IPv6"));
|
||||
}
|
||||
|
||||
if port == 0 {
|
||||
return Err(DSPError::InvalidPort(
|
||||
"Port must be between 1 and 65535"
|
||||
));
|
||||
return Err(DSPError::InvalidPort("Port must be between 1 and 65535"));
|
||||
}
|
||||
|
||||
|
||||
if device_id == 0 || device_id > 254 {
|
||||
return Err(DSPError::InvalidDeviceId(
|
||||
"Device ID must be between 1 and 254"
|
||||
"Device ID must be between 1 and 254",
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
Ok(Self {
|
||||
connection: types::DeviceConnection {
|
||||
host,
|
||||
@@ -88,83 +72,43 @@ impl DSP408 {
|
||||
})
|
||||
}
|
||||
|
||||
fn send_raw(
|
||||
&mut self,
|
||||
data: &[u8],
|
||||
) -> Result<(), DSPError> {
|
||||
|
||||
|
||||
let _guard =
|
||||
self.lock.lock().unwrap();
|
||||
|
||||
|
||||
let socket =
|
||||
self.socket
|
||||
.as_mut()
|
||||
.ok_or(
|
||||
DSPError::NotConnected
|
||||
)?;
|
||||
fn send_raw(&mut self, data: &[u8]) -> Result<(), DSPError> {
|
||||
let _guard = self.lock.lock().unwrap();
|
||||
|
||||
let socket = self.socket.as_mut().ok_or(DSPError::NotConnected)?;
|
||||
|
||||
socket.write_all(data)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn recv_raw(
|
||||
&mut self
|
||||
) -> Result<Vec<u8>, DSPError> {
|
||||
|
||||
let socket =
|
||||
self.socket
|
||||
.as_mut()
|
||||
.ok_or(
|
||||
DSPError::NotConnected
|
||||
)?;
|
||||
|
||||
|
||||
let mut buffer =
|
||||
vec![0u8; RECV_BUFSIZE];
|
||||
fn recv_raw(&mut self) -> Result<Vec<u8>, DSPError> {
|
||||
let socket = self.socket.as_mut().ok_or(DSPError::NotConnected)?;
|
||||
|
||||
let mut buffer = vec![0u8; RECV_BUFSIZE];
|
||||
|
||||
match socket.read(&mut buffer) {
|
||||
|
||||
Ok(0) =>
|
||||
Err(DSPError::ConnectionClosed),
|
||||
Ok(0) => Err(DSPError::ConnectionClosed),
|
||||
|
||||
Ok(size) => {
|
||||
buffer.truncate(size);
|
||||
Ok(buffer)
|
||||
},
|
||||
}
|
||||
|
||||
Err(e)
|
||||
if e.kind()
|
||||
==
|
||||
std::io::ErrorKind::TimedOut =>
|
||||
{
|
||||
Err(DSPError::Timeout)
|
||||
},
|
||||
Err(e) if e.kind() == std::io::ErrorKind::TimedOut => Err(DSPError::Timeout),
|
||||
|
||||
Err(e) =>
|
||||
Err(DSPError::Io(e)),
|
||||
Err(e) => Err(DSPError::Io(e)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_recv(
|
||||
&mut self,
|
||||
command: &[u8],
|
||||
) -> Result<types::DeviceResponseType, DSPError> {
|
||||
|
||||
pub fn send_recv(&mut self, command: &[u8]) -> Result<types::DeviceResponseType, DSPError> {
|
||||
self.send_raw(command)?;
|
||||
|
||||
let raw =
|
||||
self.recv_raw()?;
|
||||
let raw = self.recv_raw()?;
|
||||
|
||||
let frame =
|
||||
extract_frame(&raw)?;
|
||||
let frame = extract_frame(&raw)?;
|
||||
|
||||
let response =
|
||||
map_response(&frame)?;
|
||||
let response = map_response(&frame)?;
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
@@ -174,46 +118,29 @@ impl DSP408 {
|
||||
}
|
||||
|
||||
pub fn state(&self) -> Result<&types::DSPState, DSPError> {
|
||||
self.state
|
||||
.as_ref()
|
||||
.ok_or(DSPError::NotConnected)
|
||||
self.state.as_ref().ok_or(DSPError::NotConnected)
|
||||
}
|
||||
|
||||
fn state_mut(&mut self) -> Result<&mut types::DSPState, DSPError> {
|
||||
self.state
|
||||
.as_mut()
|
||||
.ok_or(DSPError::NotConnected)
|
||||
self.state.as_mut().ok_or(DSPError::NotConnected)
|
||||
}
|
||||
|
||||
// ---------- Commands ----------
|
||||
// Command `0x10`
|
||||
pub fn connect(&mut self) -> Result<(), DSPError> {
|
||||
|
||||
let key = (
|
||||
self.connection.host,
|
||||
self.connection.device_id
|
||||
);
|
||||
let key = (self.connection.host, self.connection.device_id);
|
||||
|
||||
{
|
||||
let map = instances()
|
||||
.lock()
|
||||
.unwrap();
|
||||
let map = instances().lock().unwrap();
|
||||
|
||||
if map.contains_key(&key) {
|
||||
return Err(DSPError::AlreadyConnected);
|
||||
}
|
||||
}
|
||||
|
||||
let addr = SocketAddr::new(
|
||||
self.connection.host,
|
||||
self.connection.port
|
||||
);
|
||||
let addr = SocketAddr::new(self.connection.host, self.connection.port);
|
||||
|
||||
let stream =
|
||||
TcpStream::connect_timeout(
|
||||
&addr,
|
||||
SOCKET_TIMEOUT
|
||||
)?;
|
||||
let stream = TcpStream::connect_timeout(&addr, SOCKET_TIMEOUT)?;
|
||||
|
||||
stream.set_read_timeout(Some(SOCKET_TIMEOUT))?;
|
||||
|
||||
@@ -226,18 +153,12 @@ impl DSP408 {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
while start.elapsed() < SOCKET_TIMEOUT {
|
||||
|
||||
let raw = self.recv_raw()?;
|
||||
let frame = extract_frame(&raw)?;
|
||||
let response = map_response(&frame)?;
|
||||
|
||||
if matches!(response, types::DeviceResponseType::HandshakeAck(_)) {
|
||||
|
||||
instances()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(key, ());
|
||||
|
||||
instances().lock().unwrap().insert(key, ());
|
||||
|
||||
self.connected = true;
|
||||
|
||||
@@ -248,9 +169,7 @@ impl DSP408 {
|
||||
let mut preset_names = Vec::with_capacity(PRESET_INDEX_MAX);
|
||||
|
||||
for i in 0..PRESET_INDEX_MAX {
|
||||
preset_names.push(
|
||||
self.get_preset_name(i + 1)?
|
||||
);
|
||||
preset_names.push(self.get_preset_name(i + 1)?);
|
||||
}
|
||||
|
||||
let state = self.read_config_state()?;
|
||||
@@ -277,31 +196,15 @@ impl DSP408 {
|
||||
|
||||
// Command `0x11`
|
||||
pub fn disconnect(&mut self) {
|
||||
|
||||
let key = (
|
||||
self.connection.host,
|
||||
self.connection.device_id
|
||||
);
|
||||
let key = (self.connection.host, self.connection.device_id);
|
||||
|
||||
if let Some(mut socket) = self.socket.take() {
|
||||
let _ = socket.write_all(&commands::build_disconnect());
|
||||
|
||||
let _ =
|
||||
socket.write_all(
|
||||
&commands::build_disconnect()
|
||||
);
|
||||
|
||||
let _ =
|
||||
socket.shutdown(
|
||||
std::net::Shutdown::Both
|
||||
);
|
||||
let _ = socket.shutdown(std::net::Shutdown::Both);
|
||||
}
|
||||
|
||||
|
||||
instances()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.remove(&key);
|
||||
|
||||
instances().lock().unwrap().remove(&key);
|
||||
|
||||
self.connected = false;
|
||||
}
|
||||
@@ -309,9 +212,9 @@ impl DSP408 {
|
||||
// Command `0x12`
|
||||
fn request_acknowledgement(&mut self) -> Result<bool, DSPError> {
|
||||
let request = commands::build_acknowledgement();
|
||||
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
|
||||
match resp {
|
||||
types::DeviceResponseType::Acknowledgement(ack) => Ok(ack.success),
|
||||
other => Err(DSPError::UnexpectedResponse(format!(
|
||||
@@ -428,7 +331,7 @@ impl DSP408 {
|
||||
|
||||
if !self.request_acknowledgement()? {
|
||||
return Err(DSPError::OperationFailed(
|
||||
"Store Configuration fails".into()
|
||||
"Store Configuration fails".into(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -470,9 +373,7 @@ impl DSP408 {
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
match resp {
|
||||
types::DeviceResponseType::Acknowledgement(ack) => {
|
||||
Ok(ack.success)
|
||||
}
|
||||
types::DeviceResponseType::Acknowledgement(ack) => Ok(ack.success),
|
||||
other => Err(DSPError::UnexpectedResponse(format!(
|
||||
"Expected Acknowledgement, got {:?}",
|
||||
other
|
||||
@@ -516,9 +417,7 @@ impl DSP408 {
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
match resp {
|
||||
types::DeviceResponseType::ConfigChunk(config) => {
|
||||
Ok(config)
|
||||
}
|
||||
types::DeviceResponseType::ConfigChunk(config) => Ok(config),
|
||||
other => Err(DSPError::UnexpectedResponse(format!(
|
||||
"Expected ConfigChunk, got {:?}",
|
||||
other
|
||||
@@ -549,20 +448,14 @@ impl DSP408 {
|
||||
channel_1: types::Channel,
|
||||
channel_2: types::Channel,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let (raw_channel_1, raw_channel_2) = mapper::copy_channel_to_raw(channel_1, channel_2)?;
|
||||
|
||||
let request = commands::build_copy_channel(
|
||||
raw_channel_1,
|
||||
raw_channel_2,
|
||||
)?;
|
||||
let request = commands::build_copy_channel(raw_channel_1, raw_channel_2)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
match resp {
|
||||
types::DeviceResponseType::Acknowledgement(ack) => {
|
||||
Ok(ack.success)
|
||||
}
|
||||
types::DeviceResponseType::Acknowledgement(ack) => Ok(ack.success),
|
||||
other => Err(DSPError::UnexpectedResponse(format!(
|
||||
"Expected Acknowledgement, got {:?}",
|
||||
other
|
||||
@@ -647,7 +540,6 @@ impl DSP408 {
|
||||
knee: u16,
|
||||
threshold: f32,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::output_channel_to_raw(channel)?;
|
||||
let raw_ratio = mapper::ratio_to_raw(ratio)?;
|
||||
let raw_attack = mapper::attack_ms_to_raw(attack)?;
|
||||
@@ -674,16 +566,13 @@ impl DSP408 {
|
||||
|
||||
let state = self.state_mut()?;
|
||||
|
||||
state
|
||||
.current_config
|
||||
.output_state_mut(channel)
|
||||
.compressor = types::Compressor {
|
||||
threshold,
|
||||
ratio,
|
||||
attack,
|
||||
release,
|
||||
knee,
|
||||
};
|
||||
state.current_config.output_state_mut(channel).compressor = types::Compressor {
|
||||
threshold,
|
||||
ratio,
|
||||
attack,
|
||||
release,
|
||||
knee,
|
||||
};
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
@@ -701,16 +590,11 @@ impl DSP408 {
|
||||
freq: f32,
|
||||
filter_type: types::CrossoverFilter,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
let raw_freq = mapper::frequency_hz_to_raw(freq)?;
|
||||
let raw_filter = mapper::crossover_filter_to_raw(filter_type)?;
|
||||
|
||||
let request = commands::build_low_pass(
|
||||
raw_channel,
|
||||
raw_freq,
|
||||
raw_filter,
|
||||
)?;
|
||||
let request = commands::build_low_pass(raw_channel, raw_freq, raw_filter)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -729,9 +613,9 @@ impl DSP408 {
|
||||
.input_state_mut(input)
|
||||
.crossover
|
||||
.low_pass = types::Crossover {
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
@@ -740,9 +624,9 @@ impl DSP408 {
|
||||
.output_state_mut(output)
|
||||
.crossover
|
||||
.low_pass = types::Crossover {
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,16 +647,11 @@ impl DSP408 {
|
||||
freq: f32,
|
||||
filter_type: types::CrossoverFilter,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
let raw_freq = mapper::frequency_hz_to_raw(freq)?;
|
||||
let raw_filter = mapper::crossover_filter_to_raw(filter_type)?;
|
||||
|
||||
let request = commands::build_high_pass(
|
||||
raw_channel,
|
||||
raw_freq,
|
||||
raw_filter,
|
||||
)?;
|
||||
let request = commands::build_high_pass(raw_channel, raw_freq, raw_filter)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -791,9 +670,9 @@ impl DSP408 {
|
||||
.input_state_mut(input)
|
||||
.crossover
|
||||
.high_pass = types::Crossover {
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
@@ -802,9 +681,9 @@ impl DSP408 {
|
||||
.output_state_mut(output)
|
||||
.crossover
|
||||
.high_pass = types::Crossover {
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
frequency: freq,
|
||||
slope: filter_type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,7 +709,6 @@ impl DSP408 {
|
||||
filter_type: types::PEQFilter,
|
||||
bypass: bool,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
let raw_band = mapper::peq_band_to_raw(band, channel)?;
|
||||
let raw_gain = mapper::eq_gain_db_to_raw(gain_db)?;
|
||||
@@ -868,11 +746,8 @@ impl DSP408 {
|
||||
|
||||
match channel {
|
||||
types::Channel::Input(input) => {
|
||||
state
|
||||
.current_config
|
||||
.input_state_mut(input)
|
||||
.peq_chain
|
||||
.bands[band as usize] = peq;
|
||||
state.current_config.input_state_mut(input).peq_chain.bands
|
||||
[band as usize] = peq;
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
@@ -895,19 +770,11 @@ impl DSP408 {
|
||||
}
|
||||
|
||||
// Command `0x34` (Set Gain)
|
||||
pub fn set_channel_gain(
|
||||
&mut self,
|
||||
channel: types::Channel,
|
||||
db: f32,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
pub fn set_channel_gain(&mut self, channel: types::Channel, db: f32) -> Result<bool, DSPError> {
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
let raw_db = mapper::gain_db_to_raw(db)?;
|
||||
|
||||
let request = commands::build_gain(
|
||||
raw_channel,
|
||||
raw_db,
|
||||
)?;
|
||||
let request = commands::build_gain(raw_channel, raw_db)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -921,17 +788,11 @@ impl DSP408 {
|
||||
|
||||
match channel {
|
||||
types::Channel::Input(input) => {
|
||||
state
|
||||
.current_config
|
||||
.input_state_mut(input)
|
||||
.gain = db;
|
||||
state.current_config.input_state_mut(input).gain = db;
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
state
|
||||
.current_config
|
||||
.output_state_mut(output)
|
||||
.gain = db;
|
||||
state.current_config.output_state_mut(output).gain = db;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -946,18 +807,10 @@ impl DSP408 {
|
||||
}
|
||||
|
||||
// Command `0x35` (Set Mute)
|
||||
pub fn set_mute(
|
||||
&mut self,
|
||||
channel: types::Channel,
|
||||
muted: bool,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
pub fn set_mute(&mut self, channel: types::Channel, muted: bool) -> Result<bool, DSPError> {
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
|
||||
let request = commands::build_mute(
|
||||
raw_channel,
|
||||
muted as u8,
|
||||
)?;
|
||||
let request = commands::build_mute(raw_channel, muted as u8)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -971,17 +824,11 @@ impl DSP408 {
|
||||
|
||||
match channel {
|
||||
types::Channel::Input(input) => {
|
||||
state
|
||||
.current_config
|
||||
.input_state_mut(input)
|
||||
.mute = muted;
|
||||
state.current_config.input_state_mut(input).mute = muted;
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
state
|
||||
.current_config
|
||||
.output_state_mut(output)
|
||||
.mute = muted;
|
||||
state.current_config.output_state_mut(output).mute = muted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1001,13 +848,9 @@ impl DSP408 {
|
||||
channel: types::Channel,
|
||||
inverted: bool,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
|
||||
let request = commands::build_inverted_gain(
|
||||
raw_channel,
|
||||
inverted as u8,
|
||||
)?;
|
||||
let request = commands::build_inverted_gain(raw_channel, inverted as u8)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1021,17 +864,11 @@ impl DSP408 {
|
||||
|
||||
match channel {
|
||||
types::Channel::Input(input) => {
|
||||
state
|
||||
.current_config
|
||||
.input_state_mut(input)
|
||||
.phase_inverted = inverted;
|
||||
state.current_config.input_state_mut(input).phase_inverted = inverted;
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
state
|
||||
.current_config
|
||||
.output_state_mut(output)
|
||||
.phase_inverted = inverted;
|
||||
state.current_config.output_state_mut(output).phase_inverted = inverted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1052,14 +889,10 @@ impl DSP408 {
|
||||
delay: f32,
|
||||
unit: types::DelayUnit,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
let raw_delay = mapper::delay_to_raw(delay, unit)?;
|
||||
|
||||
let request = commands::build_set_delay(
|
||||
raw_channel,
|
||||
raw_delay,
|
||||
)?;
|
||||
let request = commands::build_set_delay(raw_channel, raw_delay)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1075,17 +908,11 @@ impl DSP408 {
|
||||
|
||||
match channel {
|
||||
types::Channel::Input(input) => {
|
||||
state
|
||||
.current_config
|
||||
.input_state_mut(input)
|
||||
.delay = delay;
|
||||
state.current_config.input_state_mut(input).delay = delay;
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
state
|
||||
.current_config
|
||||
.output_state_mut(output)
|
||||
.delay = delay;
|
||||
state.current_config.output_state_mut(output).delay = delay;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,18 +927,11 @@ impl DSP408 {
|
||||
}
|
||||
|
||||
// Command `0x39` (Set Input Source)
|
||||
pub fn set_input_source(
|
||||
&mut self,
|
||||
input_source: types::InputSource,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
pub fn set_input_source(&mut self, input_source: types::InputSource) -> Result<bool, DSPError> {
|
||||
let raw_source = mapper::input_source_to_raw(input_source.r#type)?;
|
||||
let raw_frequency = mapper::frequency_value_to_raw(input_source.frequency)?;
|
||||
|
||||
let request = commands::build_set_input_source(
|
||||
raw_source,
|
||||
raw_frequency,
|
||||
)?;
|
||||
let request = commands::build_set_input_source(raw_source, raw_frequency)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1140,14 +960,10 @@ impl DSP408 {
|
||||
output: types::OutputChannel,
|
||||
inputs: Vec<types::InputChannel>,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_output = mapper::output_channel_to_raw(output)?;
|
||||
let raw_inputs = mapper::matrix_to_raw(&inputs)?;
|
||||
|
||||
let request = commands::build_matrix_routing(
|
||||
raw_output,
|
||||
raw_inputs,
|
||||
)?;
|
||||
let request = commands::build_matrix_routing(raw_output, raw_inputs)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1181,7 +997,6 @@ impl DSP408 {
|
||||
source: types::Channel,
|
||||
destinations: Vec<types::Channel>,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_source = mapper::channel_to_raw(source)?;
|
||||
let bitmask = mapper::link_channels_to_raw(source, &destinations)?;
|
||||
|
||||
@@ -1197,10 +1012,7 @@ impl DSP408 {
|
||||
}
|
||||
|
||||
// Link source
|
||||
let request = commands::build_link_channel(
|
||||
raw_source,
|
||||
bitmask,
|
||||
)?;
|
||||
let request = commands::build_link_channel(raw_source, bitmask)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1219,7 +1031,6 @@ impl DSP408 {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clear destination links
|
||||
for destination in &destinations {
|
||||
if *destination == source {
|
||||
@@ -1228,10 +1039,7 @@ impl DSP408 {
|
||||
|
||||
let raw_destination = mapper::channel_to_raw(*destination)?;
|
||||
|
||||
let request = commands::build_link_channel(
|
||||
raw_destination,
|
||||
0x00,
|
||||
)?;
|
||||
let request = commands::build_link_channel(raw_destination, 0x00)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1268,13 +1076,9 @@ impl DSP408 {
|
||||
channel: types::Channel,
|
||||
bypass: bool,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
|
||||
let request = commands::build_bypass_peq(
|
||||
raw_channel,
|
||||
bypass as u8,
|
||||
)?;
|
||||
let request = commands::build_bypass_peq(raw_channel, bypass as u8)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1288,13 +1092,13 @@ impl DSP408 {
|
||||
|
||||
match channel {
|
||||
types::Channel::Input(input) => {
|
||||
state.current_config.input_state_mut(input)
|
||||
.peq_chain
|
||||
.bypass = bypass;
|
||||
state.current_config.input_state_mut(input).peq_chain.bypass = bypass;
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
state.current_config.output_state_mut(output)
|
||||
state
|
||||
.current_config
|
||||
.output_state_mut(output)
|
||||
.peq_chain
|
||||
.bypass = bypass;
|
||||
}
|
||||
@@ -1316,14 +1120,10 @@ impl DSP408 {
|
||||
channel: types::Channel,
|
||||
name: &str,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::channel_to_raw(channel)?;
|
||||
let raw_name = mapper::channel_name_to_raw(name)?;
|
||||
|
||||
let request = commands::build_store_channel_name(
|
||||
raw_channel,
|
||||
&raw_name,
|
||||
)?;
|
||||
let request = commands::build_store_channel_name(raw_channel, &raw_name)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1337,13 +1137,11 @@ impl DSP408 {
|
||||
|
||||
match channel {
|
||||
types::Channel::Input(input) => {
|
||||
state.current_config.input_state_mut(input)
|
||||
.name = name.to_string();
|
||||
state.current_config.input_state_mut(input).name = name.to_string();
|
||||
}
|
||||
|
||||
types::Channel::Output(output) => {
|
||||
state.current_config.output_state_mut(output)
|
||||
.name = name.to_string();
|
||||
state.current_config.output_state_mut(output).name = name.to_string();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1366,7 +1164,6 @@ impl DSP408 {
|
||||
hold: u16,
|
||||
release: u16,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::input_channel_to_raw(channel)?;
|
||||
let raw_threshold = mapper::gate_threshold_db_to_raw(threshold)?;
|
||||
let raw_attack = mapper::attack_ms_to_raw(attack)?;
|
||||
@@ -1391,15 +1188,12 @@ impl DSP408 {
|
||||
|
||||
let state = self.state_mut()?;
|
||||
|
||||
state
|
||||
.current_config
|
||||
.input_state_mut(channel)
|
||||
.gate = types::Gate {
|
||||
attack,
|
||||
release,
|
||||
hold,
|
||||
threshold,
|
||||
};
|
||||
state.current_config.input_state_mut(channel).gate = types::Gate {
|
||||
attack,
|
||||
release,
|
||||
hold,
|
||||
threshold,
|
||||
};
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
@@ -1419,18 +1213,13 @@ impl DSP408 {
|
||||
attack: u16,
|
||||
release: u16,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_channel = mapper::output_channel_to_raw(channel)?;
|
||||
let raw_threshold = mapper::threshold_db_to_raw(threshold)?;
|
||||
let raw_attack = mapper::attack_ms_to_raw(attack)?;
|
||||
let raw_release = mapper::release_ms_to_raw(release)?;
|
||||
|
||||
let request = commands::build_set_limiter(
|
||||
raw_channel,
|
||||
raw_threshold,
|
||||
raw_attack,
|
||||
raw_release,
|
||||
)?;
|
||||
let request =
|
||||
commands::build_set_limiter(raw_channel, raw_threshold, raw_attack, raw_release)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1442,14 +1231,11 @@ impl DSP408 {
|
||||
|
||||
let state = self.state_mut()?;
|
||||
|
||||
state
|
||||
.current_config
|
||||
.output_state_mut(channel)
|
||||
.limiter = types::Limiter {
|
||||
threshold,
|
||||
attack,
|
||||
release,
|
||||
};
|
||||
state.current_config.output_state_mut(channel).limiter = types::Limiter {
|
||||
threshold,
|
||||
attack,
|
||||
release,
|
||||
};
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
@@ -1462,10 +1248,7 @@ impl DSP408 {
|
||||
}
|
||||
|
||||
// Command `0x40` (Get Level Meters)
|
||||
pub fn get_meter_levels(
|
||||
&mut self,
|
||||
) -> Result<types::Meters, DSPError> {
|
||||
|
||||
pub fn get_meter_levels(&mut self) -> Result<types::Meters, DSPError> {
|
||||
let request = commands::build_get_meter_levels();
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
@@ -1487,16 +1270,11 @@ impl DSP408 {
|
||||
output_channel: types::OutputChannel,
|
||||
gain: f32,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_input_channel = mapper::input_channel_to_raw(input_channel)?;
|
||||
let raw_output_channel = mapper::output_channel_to_raw(output_channel)?;
|
||||
let raw_gain = mapper::matrix_gain_db_to_raw(gain)?;
|
||||
|
||||
let request = commands::build_matrix_gain(
|
||||
raw_input_channel,
|
||||
raw_output_channel,
|
||||
raw_gain,
|
||||
)?;
|
||||
let request = commands::build_matrix_gain(raw_input_channel, raw_output_channel, raw_gain)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1510,9 +1288,11 @@ impl DSP408 {
|
||||
|
||||
let index = types::InputChannel::iter()
|
||||
.position(|x| x == input_channel)
|
||||
.ok_or_else(|| DSPError::Validation(ValidationError::Value(
|
||||
"Invalid input channel".to_string()
|
||||
)))?;
|
||||
.ok_or_else(|| {
|
||||
DSPError::Validation(ValidationError::Value(
|
||||
"Invalid input channel".to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
state
|
||||
.current_config
|
||||
@@ -1537,16 +1317,12 @@ impl DSP408 {
|
||||
frequency_band: types::DiscreteFrequency,
|
||||
gain: f32,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_input_channel = mapper::input_channel_to_raw(input_channel)?;
|
||||
let raw_frequency_band = mapper::frequency_value_to_raw(frequency_band)?;
|
||||
let raw_gain = mapper::eq_gain_db_to_raw(gain)?;
|
||||
|
||||
let request = commands::build_set_geq_band(
|
||||
raw_input_channel,
|
||||
raw_frequency_band,
|
||||
raw_gain,
|
||||
)?;
|
||||
let request =
|
||||
commands::build_set_geq_band(raw_input_channel, raw_frequency_band, raw_gain)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1560,17 +1336,19 @@ impl DSP408 {
|
||||
|
||||
let index = types::DiscreteFrequency::iter()
|
||||
.position(|x| x == frequency_band)
|
||||
.ok_or_else(|| DSPError::Validation(ValidationError::Value(
|
||||
"Invalid GEQ frequency band".to_string()
|
||||
)))?;
|
||||
.ok_or_else(|| {
|
||||
DSPError::Validation(ValidationError::Value(
|
||||
"Invalid GEQ frequency band".to_string(),
|
||||
))
|
||||
})?;
|
||||
|
||||
state
|
||||
.current_config
|
||||
.input_state_mut(input_channel)
|
||||
.geq
|
||||
.gains[index] = gain;
|
||||
Ok(true)
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
other => Err(DSPError::UnexpectedResponse(format!(
|
||||
"Expected Acknowledgement, got {:?}",
|
||||
@@ -1585,13 +1363,9 @@ impl DSP408 {
|
||||
input_channel: types::InputChannel,
|
||||
bypass: bool,
|
||||
) -> Result<bool, DSPError> {
|
||||
|
||||
let raw_input_channel = mapper::input_channel_to_raw(input_channel)?;
|
||||
|
||||
let request = commands::build_set_geq_bypass(
|
||||
raw_input_channel,
|
||||
bypass as u8,
|
||||
)?;
|
||||
let request = commands::build_set_geq_bypass(raw_input_channel, bypass as u8)?;
|
||||
|
||||
let resp = self.send_recv(&request)?;
|
||||
|
||||
@@ -1630,14 +1404,11 @@ impl DSP408 {
|
||||
let config = decode_config(&raw)?;
|
||||
|
||||
if !self.request_acknowledgement()? {
|
||||
return Err(DSPError::OperationFailed(
|
||||
"DSP initialization".into()
|
||||
));
|
||||
return Err(DSPError::OperationFailed("DSP initialization".into()));
|
||||
}
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Drop for DSP408 {
|
||||
|
||||
Reference in New Issue
Block a user