+38
-28
@@ -7,18 +7,16 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use strum::IntoEnumIterator;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::errors::{DSPError, ValidationError},
|
common::errors::DSPError,
|
||||||
dsp408::{
|
dsp408::{
|
||||||
mapper::{
|
mapper::{
|
||||||
self,
|
self,
|
||||||
constants::{CONFIG_CHUNK_INDEX_MAX, PRESET_INDEX_MAX},
|
constants::{CONFIG_CHUNK_INDEX_MAX, PRESET_INDEX_MAX, delay_range},
|
||||||
response::map_response,
|
response::map_response,
|
||||||
},
|
},
|
||||||
protocol::{commands, config::decode_config, frame::extract_frame},
|
protocol::{commands, config::decode_config, frame::extract_frame},
|
||||||
types,
|
types::{self},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,6 +152,13 @@ impl DSP408 {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn convert_delay_unit(value: f32, from: types::DelayUnit, to: types::DelayUnit) -> f32 {
|
||||||
|
let (_, from_max) = delay_range(from);
|
||||||
|
let (_, to_max) = delay_range(to);
|
||||||
|
|
||||||
|
(value / from_max) * to_max
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- Commands ----------
|
// ---------- Commands ----------
|
||||||
// Command `0x10`
|
// Command `0x10`
|
||||||
pub fn connect(&mut self) -> Result<(), DSPError> {
|
pub fn connect(&mut self) -> Result<(), DSPError> {
|
||||||
@@ -320,7 +325,20 @@ impl DSP408 {
|
|||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_mut()?.current_config.delay_unit = unit;
|
let state = self.state_mut()?;
|
||||||
|
let old_unit = state.current_config.delay_unit;
|
||||||
|
|
||||||
|
if old_unit != unit {
|
||||||
|
for input in state.current_config.input_states.values_mut() {
|
||||||
|
input.delay = Self::convert_delay_unit(input.delay, old_unit, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
for output in state.current_config.output_states.values_mut() {
|
||||||
|
output.delay = Self::convert_delay_unit(output.delay, old_unit, unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state.current_config.delay_unit = unit;
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@@ -810,8 +828,12 @@ impl DSP408 {
|
|||||||
|
|
||||||
match channel {
|
match channel {
|
||||||
types::Channel::Input(input) => {
|
types::Channel::Input(input) => {
|
||||||
state.current_config.input_state_mut(input).peq_chain.bands
|
state
|
||||||
[band as usize] = peq;
|
.current_config
|
||||||
|
.input_state_mut(input)
|
||||||
|
.peq_chain
|
||||||
|
.bands
|
||||||
|
.insert(band, peq);
|
||||||
}
|
}
|
||||||
|
|
||||||
types::Channel::Output(output) => {
|
types::Channel::Output(output) => {
|
||||||
@@ -819,7 +841,8 @@ impl DSP408 {
|
|||||||
.current_config
|
.current_config
|
||||||
.output_state_mut(output)
|
.output_state_mut(output)
|
||||||
.peq_chain
|
.peq_chain
|
||||||
.bands[band as usize] = peq;
|
.bands
|
||||||
|
.insert(band, peq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,7 +970,7 @@ impl DSP408 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Command `0x38` (Set Delay)
|
// Command `0x38` (Set Delay)
|
||||||
pub fn set_channel_delay(
|
pub fn set_delay(
|
||||||
&mut self,
|
&mut self,
|
||||||
channel: types::Channel,
|
channel: types::Channel,
|
||||||
delay: f32,
|
delay: f32,
|
||||||
@@ -1350,19 +1373,12 @@ impl DSP408 {
|
|||||||
|
|
||||||
let state = self.state_mut()?;
|
let state = self.state_mut()?;
|
||||||
|
|
||||||
let index = types::InputChannel::iter()
|
|
||||||
.position(|x| x == input_channel)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
DSPError::Validation(ValidationError::Value(
|
|
||||||
"Invalid input channel".to_string(),
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
state
|
state
|
||||||
.current_config
|
.current_config
|
||||||
.output_state_mut(output_channel)
|
.output_state_mut(output_channel)
|
||||||
.matrix_routes
|
.matrix_routes
|
||||||
.gains[index] = gain;
|
.gains
|
||||||
|
.insert(input_channel, gain);
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
@@ -1398,19 +1414,13 @@ impl DSP408 {
|
|||||||
|
|
||||||
let state = self.state_mut()?;
|
let state = self.state_mut()?;
|
||||||
|
|
||||||
let index = types::DiscreteFrequency::iter()
|
|
||||||
.position(|x| x == frequency_band)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
DSPError::Validation(ValidationError::Value(
|
|
||||||
"Invalid GEQ frequency band".to_string(),
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
state
|
state
|
||||||
.current_config
|
.current_config
|
||||||
.input_state_mut(input_channel)
|
.input_state_mut(input_channel)
|
||||||
.geq
|
.geq
|
||||||
.gains[index] = gain;
|
.gains
|
||||||
|
.insert(frequency_band, gain);
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,10 +85,6 @@ pub fn map_response(frame: &Frame) -> Result<DeviceResponseType, ProtocolError>
|
|||||||
|
|
||||||
// Command `0x24` (Get Config Chunk)
|
// Command `0x24` (Get Config Chunk)
|
||||||
if cmd == 0x24 {
|
if cmd == 0x24 {
|
||||||
// Mirrors Python's `int.from_bytes(payload[:1], "little")`, which
|
|
||||||
// is `0` for an empty payload rather than an error — Python slices
|
|
||||||
// never panic. `payload.get(1..)` below mirrors the same
|
|
||||||
// forgiving-slice behavior for the remainder.
|
|
||||||
let index = payload.first().copied().unwrap_or(0);
|
let index = payload.first().copied().unwrap_or(0);
|
||||||
|
|
||||||
if index > 0x1c {
|
if index > 0x1c {
|
||||||
@@ -163,8 +159,23 @@ pub fn map_response(frame: &Frame) -> Result<DeviceResponseType, ProtocolError>
|
|||||||
|
|
||||||
// Command `0x40` (Get Level Meters)
|
// Command `0x40` (Get Level Meters)
|
||||||
if cmd == 0x40 {
|
if cmd == 0x40 {
|
||||||
fn float_to_db(v: f32) -> f32 {
|
const X0: f32 = -25.0; // breakpoint, in dB
|
||||||
40.0 * v.abs().max(1e-12).log10()
|
const Y0: f32 = 1.0; // raw value at the breakpoint
|
||||||
|
const K1: f32 = 0.0104; // slope below breakpoint (raw < Y0)
|
||||||
|
const K2: f32 = 0.0208; // slope above breakpoint (raw >= Y0)
|
||||||
|
|
||||||
|
const MIN_DB: f32 = -60.0;
|
||||||
|
const MAX_DB: f32 = 12.0;
|
||||||
|
|
||||||
|
fn float_to_db(raw: f32) -> f32 {
|
||||||
|
let db = if raw < Y0 {
|
||||||
|
X0 + (raw - Y0) / K1
|
||||||
|
} else {
|
||||||
|
X0 + (raw - Y0) / K2
|
||||||
|
};
|
||||||
|
// Clamping naturally absorbs noise-floor outliers (e.g. raw ≈ 0.385
|
||||||
|
// resolves to well below -60 dB here, so it correctly floors to -60).
|
||||||
|
db.clamp(MIN_DB, MAX_DB)
|
||||||
}
|
}
|
||||||
|
|
||||||
if payload.len() != 38 {
|
if payload.len() != 38 {
|
||||||
|
|||||||
@@ -35,12 +35,14 @@ fn read_gate(r: &mut BinaryReader) -> Result<types::Gate, DSPError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_geq(r: &mut BinaryReader) -> Result<types::GraphicEQ, DSPError> {
|
fn read_geq(r: &mut BinaryReader) -> Result<types::GraphicEQ, DSPError> {
|
||||||
let gains = types::DiscreteFrequency::iter()
|
let mut gains = std::collections::HashMap::new();
|
||||||
.map(|_| {
|
|
||||||
|
for frequency in types::DiscreteFrequency::iter() {
|
||||||
let raw = r.read_u16()?;
|
let raw = r.read_u16()?;
|
||||||
Ok(mapper::raw_to_eq_gain(raw)?)
|
let gain = mapper::raw_to_eq_gain(raw)?;
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, DSPError>>()?;
|
gains.insert(frequency, gain);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(types::GraphicEQ {
|
Ok(types::GraphicEQ {
|
||||||
gains,
|
gains,
|
||||||
@@ -49,17 +51,20 @@ fn read_geq(r: &mut BinaryReader) -> Result<types::GraphicEQ, DSPError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_peq_chain(r: &mut BinaryReader, band_count: usize) -> Result<types::PEQChain, DSPError> {
|
fn read_peq_chain(r: &mut BinaryReader, band_count: usize) -> Result<types::PEQChain, DSPError> {
|
||||||
let bands = (0..band_count)
|
let bands = types::PEQBand::iter()
|
||||||
.map(|_| {
|
.take(band_count)
|
||||||
Ok(types::PEQ {
|
.map(|band| {
|
||||||
|
let peq = types::PEQ {
|
||||||
gain: mapper::raw_to_eq_gain(r.read_u16()?)?,
|
gain: mapper::raw_to_eq_gain(r.read_u16()?)?,
|
||||||
frequency: mapper::raw_to_frequency_hz(r.read_u16()?)?,
|
frequency: mapper::raw_to_frequency_hz(r.read_u16()?)?,
|
||||||
q: mapper::raw_to_peq_q(r.read_u8()?)?,
|
q: mapper::raw_to_peq_q(r.read_u8()?)?,
|
||||||
filter_type: mapper::raw_to_peq_filter(r.read_u8()?)?,
|
filter_type: mapper::raw_to_peq_filter(r.read_u8()?)?,
|
||||||
bypass: false,
|
bypass: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((band, peq))
|
||||||
})
|
})
|
||||||
})
|
.collect::<Result<HashMap<_, _>, DSPError>>()?;
|
||||||
.collect::<Result<Vec<_>, DSPError>>()?;
|
|
||||||
|
|
||||||
Ok(types::PEQChain {
|
Ok(types::PEQChain {
|
||||||
bands,
|
bands,
|
||||||
@@ -67,6 +72,21 @@ fn read_peq_chain(r: &mut BinaryReader, band_count: usize) -> Result<types::PEQC
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn apply_peq_bypass(
|
||||||
|
r: &mut BinaryReader,
|
||||||
|
bands: &mut HashMap<types::PEQBand, types::PEQ>,
|
||||||
|
) -> Result<(), DSPError> {
|
||||||
|
let bitmap = r.read_u16()?;
|
||||||
|
|
||||||
|
for (index, band) in types::PEQBand::iter().enumerate() {
|
||||||
|
if let Some(peq) = bands.get_mut(&band) {
|
||||||
|
peq.bypass = bitmap & (1 << index) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn read_crossover(r: &mut BinaryReader) -> Result<types::CrossoverFilters, DSPError> {
|
fn read_crossover(r: &mut BinaryReader) -> Result<types::CrossoverFilters, DSPError> {
|
||||||
let hp_freq = r.read_u16()?;
|
let hp_freq = r.read_u16()?;
|
||||||
let lp_freq = r.read_u16()?;
|
let lp_freq = r.read_u16()?;
|
||||||
@@ -152,7 +172,13 @@ pub fn decode_config(payload: &[u8]) -> Result<types::DSPConfigState, DSPError>
|
|||||||
inp.linked_channels = mapper::raw_to_link_channels(
|
inp.linked_channels = mapper::raw_to_link_channels(
|
||||||
mapper::channel_to_raw(types::Channel::Input(channel))?,
|
mapper::channel_to_raw(types::Channel::Input(channel))?,
|
||||||
r.read_u8()?,
|
r.read_u8()?,
|
||||||
)?;
|
)?
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|link| match link {
|
||||||
|
types::Channel::Input(input) => Some(input),
|
||||||
|
types::Channel::Output(_) => None,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
@@ -162,17 +188,26 @@ pub fn decode_config(payload: &[u8]) -> Result<types::DSPConfigState, DSPError>
|
|||||||
for (channel, out) in types::OutputChannel::iter().zip(output_channels.iter_mut()) {
|
for (channel, out) in types::OutputChannel::iter().zip(output_channels.iter_mut()) {
|
||||||
out.name = mapper::raw_to_channel_name(r.pop(constants::CHANNEL_NAME_LENGTH)?)?;
|
out.name = mapper::raw_to_channel_name(r.pop(constants::CHANNEL_NAME_LENGTH)?)?;
|
||||||
|
|
||||||
r.skip(1)?;
|
|
||||||
|
|
||||||
out.matrix_routes = types::MatrixRoutes {
|
out.matrix_routes = types::MatrixRoutes {
|
||||||
connected: mapper::raw_to_matrix(r.read_u8()?)?,
|
connected: mapper::raw_to_matrix(r.read_u8()?)?,
|
||||||
|
|
||||||
gains: (0..4)
|
gains: {
|
||||||
.map(|_| {
|
r.skip(1)?;
|
||||||
|
|
||||||
|
[
|
||||||
|
types::InputChannel::InA,
|
||||||
|
types::InputChannel::InB,
|
||||||
|
types::InputChannel::InC,
|
||||||
|
types::InputChannel::InD,
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(|input| {
|
||||||
let raw = r.read_u16()?;
|
let raw = r.read_u16()?;
|
||||||
Ok::<f32, DSPError>(mapper::raw_to_matrix_gain(raw)?)
|
let gain = mapper::raw_to_matrix_gain(raw)?;
|
||||||
|
Ok::<(types::InputChannel, f32), DSPError>((input, gain))
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?,
|
.collect::<Result<HashMap<_, _>, _>>()?
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
out.crossover = read_crossover(&mut r)?;
|
out.crossover = read_crossover(&mut r)?;
|
||||||
@@ -196,7 +231,13 @@ pub fn decode_config(payload: &[u8]) -> Result<types::DSPConfigState, DSPError>
|
|||||||
out.linked_channels = mapper::raw_to_link_channels(
|
out.linked_channels = mapper::raw_to_link_channels(
|
||||||
mapper::channel_to_raw(types::Channel::Output(channel))?,
|
mapper::channel_to_raw(types::Channel::Output(channel))?,
|
||||||
r.read_u8()?,
|
r.read_u8()?,
|
||||||
)?;
|
)?
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|link| match link {
|
||||||
|
types::Channel::Output(output) => Some(output),
|
||||||
|
types::Channel::Input(_) => None,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
@@ -212,15 +253,11 @@ pub fn decode_config(payload: &[u8]) -> Result<types::DSPConfigState, DSPError>
|
|||||||
// ============================
|
// ============================
|
||||||
|
|
||||||
for inp in &mut input_channels {
|
for inp in &mut input_channels {
|
||||||
apply_flag(&mut r, inp.peq_chain.bands.as_mut_slice(), |band, value| {
|
apply_peq_bypass(&mut r, &mut inp.peq_chain.bands)?;
|
||||||
band.bypass = value
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for out in &mut output_channels {
|
for out in &mut output_channels {
|
||||||
apply_flag(&mut r, out.peq_chain.bands.as_mut_slice(), |band, value| {
|
apply_peq_bypass(&mut r, &mut out.peq_chain.bands)?;
|
||||||
band.bypass = value
|
|
||||||
})?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================
|
// ============================
|
||||||
@@ -260,7 +297,7 @@ pub fn decode_config(payload: &[u8]) -> Result<types::DSPConfigState, DSPError>
|
|||||||
for (index, inp) in input_channels.iter_mut().enumerate() {
|
for (index, inp) in input_channels.iter_mut().enumerate() {
|
||||||
let bypass = input_peq_bitmap & (1 << index) != 0;
|
let bypass = input_peq_bitmap & (1 << index) != 0;
|
||||||
|
|
||||||
for peq in inp.peq_chain.bands.iter_mut() {
|
for peq in inp.peq_chain.bands.values_mut() {
|
||||||
peq.bypass = bypass;
|
peq.bypass = bypass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +307,7 @@ pub fn decode_config(payload: &[u8]) -> Result<types::DSPConfigState, DSPError>
|
|||||||
for (index, out) in output_channels.iter_mut().enumerate() {
|
for (index, out) in output_channels.iter_mut().enumerate() {
|
||||||
let bypass = output_peq_bitmap & (1 << index) != 0;
|
let bypass = output_peq_bitmap & (1 << index) != 0;
|
||||||
|
|
||||||
for peq in out.peq_chain.bands.iter_mut() {
|
for peq in out.peq_chain.bands.values_mut() {
|
||||||
peq.bypass = bypass;
|
peq.bypass = bypass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -92,6 +92,7 @@ pub enum CrossoverFilter {
|
|||||||
Bl48,
|
Bl48,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)]
|
||||||
pub enum PEQBand {
|
pub enum PEQBand {
|
||||||
B1 = 1,
|
B1 = 1,
|
||||||
@@ -291,7 +292,7 @@ pub struct Limiter {
|
|||||||
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
pub struct GraphicEQ {
|
pub struct GraphicEQ {
|
||||||
pub gains: Vec<f32>,
|
pub gains: HashMap<DiscreteFrequency, f32>,
|
||||||
pub bypass: bool,
|
pub bypass: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,13 +324,13 @@ pub struct Crossover {
|
|||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
pub struct MatrixRoutes {
|
pub struct MatrixRoutes {
|
||||||
pub connected: Vec<InputChannel>,
|
pub connected: Vec<InputChannel>,
|
||||||
pub gains: Vec<f32>,
|
pub gains: HashMap<InputChannel, f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
|
||||||
#[derive(Debug, Clone, PartialEq, Default)]
|
#[derive(Debug, Clone, PartialEq, Default)]
|
||||||
pub struct PEQChain {
|
pub struct PEQChain {
|
||||||
pub bands: Vec<PEQ>,
|
pub bands: HashMap<PEQBand, PEQ>,
|
||||||
pub bypass: bool,
|
pub bypass: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +361,7 @@ pub struct InputChannelState {
|
|||||||
pub geq: GraphicEQ,
|
pub geq: GraphicEQ,
|
||||||
pub peq_chain: PEQChain,
|
pub peq_chain: PEQChain,
|
||||||
pub crossover: CrossoverFilters,
|
pub crossover: CrossoverFilters,
|
||||||
pub linked_channels: Vec<Channel>,
|
pub linked_channels: Vec<InputChannel>,
|
||||||
pub mute: bool,
|
pub mute: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +377,7 @@ pub struct OutputChannelState {
|
|||||||
pub gain: f32,
|
pub gain: f32,
|
||||||
pub phase_inverted: bool,
|
pub phase_inverted: bool,
|
||||||
pub delay: f32,
|
pub delay: f32,
|
||||||
pub linked_channels: Vec<Channel>,
|
pub linked_channels: Vec<OutputChannel>,
|
||||||
pub mute: bool,
|
pub mute: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,6 +410,5 @@ pub struct DSPState {
|
|||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
pub(crate) flags: DeviceFlags,
|
pub(crate) flags: DeviceFlags,
|
||||||
pub(crate) presets: PresetBank,
|
pub(crate) presets: PresetBank,
|
||||||
|
|
||||||
pub(crate) current_config: DSPConfigState,
|
pub(crate) current_config: DSPConfigState,
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-2
@@ -3,6 +3,7 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use dsp_thomann::dsp408::DSP408;
|
use dsp_thomann::dsp408::DSP408;
|
||||||
use dsp_thomann::dsp408::types;
|
use dsp_thomann::dsp408::types;
|
||||||
|
use dsp_thomann::dsp408::types::InputChannel::InA;
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let host = IpAddr::from_str("192.168.49.30")?;
|
let host = IpAddr::from_str("192.168.49.30")?;
|
||||||
@@ -22,9 +23,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
println!("DSP connected.");
|
println!("DSP connected.");
|
||||||
|
|
||||||
dsp.set_mute(types::Channel::Input(types::InputChannel::InA), true)?;
|
// dsp.set_mute(types::Channel::Input(types::InputChannel::InA), true)?;
|
||||||
|
|
||||||
dbg!(dsp.state()?);
|
let r = dsp.set_peq_band(types::Channel::Input(InA), types::PEQBand::B1, 3.0, 1400.0, 2.1, types::PEQFilter::LowShelf, false)?;
|
||||||
|
dbg!(r);
|
||||||
|
|
||||||
|
// dbg!(dsp.state()?);
|
||||||
|
|
||||||
|
// let s = &dsp.state()?.current_config.input_states[&InputChannel::InA].peq_chain;
|
||||||
|
// dbg!(s)
|
||||||
|
|
||||||
println!("Disconnecting...");
|
println!("Disconnecting...");
|
||||||
dsp.disconnect()?;
|
dsp.disconnect()?;
|
||||||
|
|||||||
Reference in New Issue
Block a user