@@ -1,363 +1,363 @@
|
||||
# dsp_thomann
|
||||
|
||||
## TODO
|
||||
|
||||
- Existing but not implemented commands: 0x19, 0x25, 0x28, 0x2E, 0x50, 0x51, 0x52, 0x53
|
||||
- Commands 0x2E, 0x50, 0x51, 0x52, 0x53 seem to be used for firmware update: DO NOT SEND THEM WITHOUT KNOWLEDGE - RISK OF DEVICE BRICK (I brick my device)
|
||||
- Commands: 0x19, 0x24, 0x28 are triggered by upload preset
|
||||
- Identify: 0x2C parameters
|
||||
- Implement: if 2 DSP with same ip they need to share same socket since dsp dont accept multiples connections
|
||||
- In unlock check if first byte is device id
|
||||
- This library allows to send commands even if dsp is locked
|
||||
- Convert back data as in 0x38 to display real value
|
||||
- Figure out Meter level encoding
|
||||
- Full test of client (Improve existing one)
|
||||
- Write correct readme.md
|
||||
- Make client dsp408 thread safe
|
||||
- Absolutely, send command to avoid tcp keep alive, that make the dsp crash
|
||||
|
||||
Rust library for remote LAN control of Thomann DSP408 digital signal processors.
|
||||
|
||||
`dsp_thomann` provides a high-level Rust API to connect, configure and monitor a DSP408 device over TCP/IP.
|
||||
|
||||
## Features
|
||||
|
||||
- TCP LAN communication with DSP408
|
||||
- Automatic handshake and connection management
|
||||
- Device state synchronization
|
||||
- Preset management
|
||||
- Channel routing
|
||||
- Input/output processing control:
|
||||
- Gain
|
||||
- Mute
|
||||
- Phase inversion
|
||||
- Delay
|
||||
- PEQ
|
||||
- GEQ
|
||||
- Crossover filters
|
||||
- Compressor
|
||||
- Limiter
|
||||
- Gate
|
||||
- Matrix routing and channel linking
|
||||
- Level meter reading
|
||||
- Device locking/unlocking
|
||||
- Strong Rust type safety
|
||||
- Protocol frame decoding and validation
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Add the crate to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
dsp_thomann = "0.1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```rust
|
||||
use std::net::IpAddr;
|
||||
use dsp_thomann::dsp408::{DSP408, types};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let host: IpAddr = "192.168.49.30".parse()?;
|
||||
|
||||
let mut dsp = DSP408::new(
|
||||
host,
|
||||
9761,
|
||||
1
|
||||
)?;
|
||||
|
||||
dsp.connect()?;
|
||||
|
||||
println!("Connected!");
|
||||
|
||||
dsp.set_mute(
|
||||
types::Channel::Input(types::InputChannel::InA),
|
||||
true
|
||||
)?;
|
||||
|
||||
println!("{:#?}", dsp.state()?);
|
||||
|
||||
dsp.disconnect();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Connection
|
||||
|
||||
A DSP device is identified by:
|
||||
|
||||
| Parameter | Description |
|
||||
|---|---|
|
||||
| Host | DSP IP address |
|
||||
| Port | TCP control port |
|
||||
| Device ID | DSP device identifier |
|
||||
|
||||
Example:
|
||||
|
||||
```rust
|
||||
let mut dsp = DSP408::new(
|
||||
"192.168.49.30".parse()?,
|
||||
9761,
|
||||
1
|
||||
)?;
|
||||
```
|
||||
|
||||
The library performs:
|
||||
|
||||
- TCP connection
|
||||
- DSP handshake
|
||||
- Device information retrieval
|
||||
- Preset state loading
|
||||
- Configuration synchronization
|
||||
|
||||
---
|
||||
|
||||
# Device State
|
||||
|
||||
After connection:
|
||||
|
||||
```rust
|
||||
let state = dsp.state()?;
|
||||
```
|
||||
|
||||
The state contains:
|
||||
|
||||
- Device name
|
||||
- Lock status
|
||||
- Preset bank
|
||||
- Current DSP configuration
|
||||
|
||||
Including:
|
||||
|
||||
- Input channels
|
||||
- Output channels
|
||||
- Routing
|
||||
- EQ
|
||||
- Dynamics
|
||||
- Delay
|
||||
- Crossover configuration
|
||||
|
||||
---
|
||||
|
||||
# Channel Control
|
||||
|
||||
Channels are strongly typed:
|
||||
|
||||
```rust
|
||||
types::Channel::Input(
|
||||
types::InputChannel::InA
|
||||
)
|
||||
```
|
||||
|
||||
```rust
|
||||
types::Channel::Output(
|
||||
types::OutputChannel::Out1
|
||||
)
|
||||
```
|
||||
|
||||
## Available Channels
|
||||
|
||||
### Inputs
|
||||
|
||||
- InA
|
||||
- InB
|
||||
- InC
|
||||
- InD
|
||||
|
||||
### Outputs
|
||||
|
||||
- Out1
|
||||
- Out2
|
||||
- Out3
|
||||
- Out4
|
||||
- Out5
|
||||
- Out6
|
||||
- Out7
|
||||
- Out8
|
||||
|
||||
---
|
||||
|
||||
# Audio Processing
|
||||
|
||||
## Gain
|
||||
|
||||
```rust
|
||||
dsp.set_channel_gain(
|
||||
types::Channel::Output(types::OutputChannel::Out1),
|
||||
-3.0
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Delay
|
||||
|
||||
```rust
|
||||
dsp.set_channel_delay(
|
||||
channel,
|
||||
2.5,
|
||||
types::DelayUnit::Millisecond
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PEQ
|
||||
|
||||
```rust
|
||||
dsp.set_peq_band(
|
||||
channel,
|
||||
types::PEQBand::B1,
|
||||
3.0,
|
||||
1000.0,
|
||||
0.7,
|
||||
types::PEQFilter::Peak,
|
||||
false
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Compressor
|
||||
|
||||
```rust
|
||||
dsp.set_compressor(
|
||||
types::OutputChannel::Out1,
|
||||
types::Ratio::Ratio1_4,
|
||||
10,
|
||||
100,
|
||||
3,
|
||||
-10.0
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Presets
|
||||
|
||||
## Recall a preset
|
||||
|
||||
```rust
|
||||
dsp.recall_preset(1)?;
|
||||
```
|
||||
|
||||
## Store current configuration
|
||||
|
||||
```rust
|
||||
dsp.store_current_configuration(
|
||||
2,
|
||||
false
|
||||
)?;
|
||||
```
|
||||
|
||||
## Rename current preset
|
||||
|
||||
```rust
|
||||
dsp.set_current_preset_name(
|
||||
"Live Show"
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Routing
|
||||
|
||||
## Matrix routing
|
||||
|
||||
```rust
|
||||
dsp.set_matrix_routing(
|
||||
types::OutputChannel::Out1,
|
||||
vec![
|
||||
types::InputChannel::InA,
|
||||
types::InputChannel::InB,
|
||||
],
|
||||
)?;
|
||||
```
|
||||
|
||||
## Link channels
|
||||
|
||||
```rust
|
||||
dsp.link_channels(
|
||||
source,
|
||||
vec![destination]
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Metering
|
||||
|
||||
Read signal levels:
|
||||
|
||||
```rust
|
||||
let meters = dsp.get_meter_levels()?;
|
||||
|
||||
println!("{:?}", meters.levels);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Error Handling
|
||||
|
||||
All operations return:
|
||||
|
||||
```rust
|
||||
Result<T, DSPError>
|
||||
```
|
||||
|
||||
Possible errors include:
|
||||
|
||||
- Connection failure
|
||||
- Timeout
|
||||
- Invalid parameters
|
||||
- Protocol errors
|
||||
- Invalid responses
|
||||
- Encoding/decoding failures
|
||||
|
||||
Example:
|
||||
|
||||
```rust
|
||||
match dsp.connect() {
|
||||
Ok(_) => println!("Connected"),
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Thread Safety
|
||||
|
||||
The library internally protects socket access with a mutex.
|
||||
|
||||
- Only one command is transmitted at a time per DSP408 instance.
|
||||
- Multiple DSP devices can be controlled simultaneously.
|
||||
|
||||
---
|
||||
|
||||
# Supported DSP Features
|
||||
|
||||
| Feature | Supported |
|
||||
|---|---|
|
||||
| LAN connection | ✅ |
|
||||
| Handshake | ✅ |
|
||||
| Presets | ✅ |
|
||||
| Device lock | ✅ |
|
||||
| PEQ | ✅ |
|
||||
| GEQ | ✅ |
|
||||
| Compressor | ✅ |
|
||||
| Limiter | ✅ |
|
||||
| Gate | ✅ |
|
||||
| Delay | ✅ |
|
||||
| Crossover | ✅ |
|
||||
| Matrix routing | ✅ |
|
||||
# dsp_thomann
|
||||
|
||||
## TODO
|
||||
|
||||
- Existing but not implemented commands: 0x19, 0x25, 0x28, 0x2E, 0x50, 0x51, 0x52, 0x53
|
||||
- Commands 0x2E, 0x50, 0x51, 0x52, 0x53 seem to be used for firmware update: DO NOT SEND THEM WITHOUT KNOWLEDGE - RISK OF DEVICE BRICK (I brick my device)
|
||||
- Commands: 0x19, 0x24, 0x28 are triggered by upload preset
|
||||
- Identify: 0x2C parameters
|
||||
- Implement: if 2 DSP with same ip they need to share same socket since dsp dont accept multiples connections
|
||||
- In unlock check if first byte is device id
|
||||
- This library allows to send commands even if dsp is locked
|
||||
- Convert back data as in 0x38 to display real value
|
||||
- Figure out Meter level encoding
|
||||
- Full test of client (Improve existing one)
|
||||
- Write correct readme.md
|
||||
- Make client dsp408 thread safe
|
||||
- Absolutely, send command to avoid tcp keep alive, that make the dsp crash
|
||||
|
||||
Rust library for remote LAN control of Thomann DSP408 digital signal processors.
|
||||
|
||||
`dsp_thomann` provides a high-level Rust API to connect, configure and monitor a DSP408 device over TCP/IP.
|
||||
|
||||
## Features
|
||||
|
||||
- TCP LAN communication with DSP408
|
||||
- Automatic handshake and connection management
|
||||
- Device state synchronization
|
||||
- Preset management
|
||||
- Channel routing
|
||||
- Input/output processing control:
|
||||
- Gain
|
||||
- Mute
|
||||
- Phase inversion
|
||||
- Delay
|
||||
- PEQ
|
||||
- GEQ
|
||||
- Crossover filters
|
||||
- Compressor
|
||||
- Limiter
|
||||
- Gate
|
||||
- Matrix routing and channel linking
|
||||
- Level meter reading
|
||||
- Device locking/unlocking
|
||||
- Strong Rust type safety
|
||||
- Protocol frame decoding and validation
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Add the crate to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
dsp_thomann = "0.1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```rust
|
||||
use std::net::IpAddr;
|
||||
use dsp_thomann::dsp408::{DSP408, types};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let host: IpAddr = "192.168.49.30".parse()?;
|
||||
|
||||
let mut dsp = DSP408::new(
|
||||
host,
|
||||
9761,
|
||||
1
|
||||
)?;
|
||||
|
||||
dsp.connect()?;
|
||||
|
||||
println!("Connected!");
|
||||
|
||||
dsp.set_mute(
|
||||
types::Channel::Input(types::InputChannel::InA),
|
||||
true
|
||||
)?;
|
||||
|
||||
println!("{:#?}", dsp.state()?);
|
||||
|
||||
dsp.disconnect();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Connection
|
||||
|
||||
A DSP device is identified by:
|
||||
|
||||
| Parameter | Description |
|
||||
|---|---|
|
||||
| Host | DSP IP address |
|
||||
| Port | TCP control port |
|
||||
| Device ID | DSP device identifier |
|
||||
|
||||
Example:
|
||||
|
||||
```rust
|
||||
let mut dsp = DSP408::new(
|
||||
"192.168.49.30".parse()?,
|
||||
9761,
|
||||
1
|
||||
)?;
|
||||
```
|
||||
|
||||
The library performs:
|
||||
|
||||
- TCP connection
|
||||
- DSP handshake
|
||||
- Device information retrieval
|
||||
- Preset state loading
|
||||
- Configuration synchronization
|
||||
|
||||
---
|
||||
|
||||
# Device State
|
||||
|
||||
After connection:
|
||||
|
||||
```rust
|
||||
let state = dsp.state()?;
|
||||
```
|
||||
|
||||
The state contains:
|
||||
|
||||
- Device name
|
||||
- Lock status
|
||||
- Preset bank
|
||||
- Current DSP configuration
|
||||
|
||||
Including:
|
||||
|
||||
- Input channels
|
||||
- Output channels
|
||||
- Routing
|
||||
- EQ
|
||||
- Dynamics
|
||||
- Delay
|
||||
- Crossover configuration
|
||||
|
||||
---
|
||||
|
||||
# Channel Control
|
||||
|
||||
Channels are strongly typed:
|
||||
|
||||
```rust
|
||||
types::Channel::Input(
|
||||
types::InputChannel::InA
|
||||
)
|
||||
```
|
||||
|
||||
```rust
|
||||
types::Channel::Output(
|
||||
types::OutputChannel::Out1
|
||||
)
|
||||
```
|
||||
|
||||
## Available Channels
|
||||
|
||||
### Inputs
|
||||
|
||||
- InA
|
||||
- InB
|
||||
- InC
|
||||
- InD
|
||||
|
||||
### Outputs
|
||||
|
||||
- Out1
|
||||
- Out2
|
||||
- Out3
|
||||
- Out4
|
||||
- Out5
|
||||
- Out6
|
||||
- Out7
|
||||
- Out8
|
||||
|
||||
---
|
||||
|
||||
# Audio Processing
|
||||
|
||||
## Gain
|
||||
|
||||
```rust
|
||||
dsp.set_channel_gain(
|
||||
types::Channel::Output(types::OutputChannel::Out1),
|
||||
-3.0
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Delay
|
||||
|
||||
```rust
|
||||
dsp.set_channel_delay(
|
||||
channel,
|
||||
2.5,
|
||||
types::DelayUnit::Millisecond
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PEQ
|
||||
|
||||
```rust
|
||||
dsp.set_peq_band(
|
||||
channel,
|
||||
types::PEQBand::B1,
|
||||
3.0,
|
||||
1000.0,
|
||||
0.7,
|
||||
types::PEQFilter::Peak,
|
||||
false
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Compressor
|
||||
|
||||
```rust
|
||||
dsp.set_compressor(
|
||||
types::OutputChannel::Out1,
|
||||
types::Ratio::Ratio1_4,
|
||||
10,
|
||||
100,
|
||||
3,
|
||||
-10.0
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Presets
|
||||
|
||||
## Recall a preset
|
||||
|
||||
```rust
|
||||
dsp.recall_preset(1)?;
|
||||
```
|
||||
|
||||
## Store current configuration
|
||||
|
||||
```rust
|
||||
dsp.store_current_configuration(
|
||||
2,
|
||||
false
|
||||
)?;
|
||||
```
|
||||
|
||||
## Rename current preset
|
||||
|
||||
```rust
|
||||
dsp.set_current_preset_name(
|
||||
"Live Show"
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Routing
|
||||
|
||||
## Matrix routing
|
||||
|
||||
```rust
|
||||
dsp.set_matrix_routing(
|
||||
types::OutputChannel::Out1,
|
||||
vec![
|
||||
types::InputChannel::InA,
|
||||
types::InputChannel::InB,
|
||||
],
|
||||
)?;
|
||||
```
|
||||
|
||||
## Link channels
|
||||
|
||||
```rust
|
||||
dsp.link_channels(
|
||||
source,
|
||||
vec![destination]
|
||||
)?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Metering
|
||||
|
||||
Read signal levels:
|
||||
|
||||
```rust
|
||||
let meters = dsp.get_meter_levels()?;
|
||||
|
||||
println!("{:?}", meters.levels);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Error Handling
|
||||
|
||||
All operations return:
|
||||
|
||||
```rust
|
||||
Result<T, DSPError>
|
||||
```
|
||||
|
||||
Possible errors include:
|
||||
|
||||
- Connection failure
|
||||
- Timeout
|
||||
- Invalid parameters
|
||||
- Protocol errors
|
||||
- Invalid responses
|
||||
- Encoding/decoding failures
|
||||
|
||||
Example:
|
||||
|
||||
```rust
|
||||
match dsp.connect() {
|
||||
Ok(_) => println!("Connected"),
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Thread Safety
|
||||
|
||||
The library internally protects socket access with a mutex.
|
||||
|
||||
- Only one command is transmitted at a time per DSP408 instance.
|
||||
- Multiple DSP devices can be controlled simultaneously.
|
||||
|
||||
---
|
||||
|
||||
# Supported DSP Features
|
||||
|
||||
| Feature | Supported |
|
||||
|---|---|
|
||||
| LAN connection | ✅ |
|
||||
| Handshake | ✅ |
|
||||
| Presets | ✅ |
|
||||
| Device lock | ✅ |
|
||||
| PEQ | ✅ |
|
||||
| GEQ | ✅ |
|
||||
| Compressor | ✅ |
|
||||
| Limiter | ✅ |
|
||||
| Gate | ✅ |
|
||||
| Delay | ✅ |
|
||||
| Crossover | ✅ |
|
||||
| Matrix routing | ✅ |
|
||||
| Metering | ✅ |
|
||||
Reference in New Issue
Block a user