diff --git a/dsp408-protocol.md.md b/dsp408-protocol.md similarity index 100% rename from dsp408-protocol.md.md rename to dsp408-protocol.md diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..8803f60 --- /dev/null +++ b/readme.md @@ -0,0 +1,361 @@ +# 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 + +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> { + + 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 +``` + +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 | ✅ | \ No newline at end of file