1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2020 Takashi Sakamoto

//! Data of reverb effect in protocol defined by TC Electronic for Konnekt series.
//!
//! The module includes structure, trait and its implementation for data of reverb effect in
//! protocol defined by TC Electronic for Konnekt series. It's called as `Fabrik R`.

use super::*;

/// Algorithm of reverb effect.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ReverbAlgorithm {
    Live1,
    Hall,
    Plate,
    Club,
    ConcertHall,
    Cathedral,
    Church,
    Room,
    SmallRoom,
    Box,
    Ambient,
    Live2,
    Live3,
    Spring,
}

impl Default for ReverbAlgorithm {
    fn default() -> Self {
        Self::Live1
    }
}

const REVERB_ALGORITHMS: &[ReverbAlgorithm] = &[
    ReverbAlgorithm::Live1,
    ReverbAlgorithm::Hall,
    ReverbAlgorithm::Plate,
    ReverbAlgorithm::Club,
    ReverbAlgorithm::ConcertHall,
    ReverbAlgorithm::Cathedral,
    ReverbAlgorithm::Church,
    ReverbAlgorithm::Room,
    ReverbAlgorithm::SmallRoom,
    ReverbAlgorithm::Box,
    ReverbAlgorithm::Ambient,
    ReverbAlgorithm::Live2,
    ReverbAlgorithm::Live3,
    ReverbAlgorithm::Spring,
];

const REVERB_ALGORITHM_LABEL: &str = "reverb algorithm";

fn serialize_algorithm(algo: &ReverbAlgorithm, raw: &mut [u8]) -> Result<(), String> {
    serialize_position(REVERB_ALGORITHMS, algo, raw, REVERB_ALGORITHM_LABEL)
}

fn deserialize_algorithm(algo: &mut ReverbAlgorithm, raw: &[u8]) -> Result<(), String> {
    deserialize_position(REVERB_ALGORITHMS, algo, raw, REVERB_ALGORITHM_LABEL)
}

/// State of reverb effect.
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct ReverbState {
    /// The level of input. -24..0 (-24.0..0.0 dB).
    pub input_level: i32,
    pub bypass: bool,
    pub kill_wet: bool,
    pub kill_dry: bool,
    /// The level of output. -24..12 (-24.0..12.0 dB).
    pub output_level: i32,
    /// The decay of time. 1..290.
    pub time_decay: i32,
    /// The pre decay of time. 1..100.
    pub time_pre_decay: i32,
    // blank
    /// The color at low frequency. -50..50.
    pub color_low: i32,
    /// The color at high frequency. -50..50.
    pub color_high: i32,
    /// The factor of color at high frequency. -25..25.
    pub color_high_factor: i32,
    /// The rate of modulation. -25..25.
    pub mod_rate: i32,
    /// The depth of modulation. -25..25.
    pub mod_depth: i32,
    /// The level of early reflection. -48..0.
    pub level_early: i32,
    /// The level of reverb. -48..0.
    pub level_reverb: i32,
    /// The level of dry. -48..0.
    pub level_dry: i32,
    /// The algorithm of reverb.
    pub algorithm: ReverbAlgorithm,
}

impl ReverbState {
    pub(crate) const SIZE: usize = 68;
}

pub(crate) fn serialize_reverb_state(state: &ReverbState, raw: &mut [u8]) -> Result<(), String> {
    assert!(raw.len() >= ReverbState::SIZE);

    serialize_i32(&state.input_level, &mut raw[..4]);
    serialize_bool(&state.bypass, &mut raw[4..8]);
    serialize_bool(&state.kill_wet, &mut raw[8..12]);
    serialize_bool(&state.kill_dry, &mut raw[12..16]);
    serialize_i32(&state.output_level, &mut raw[16..20]);
    serialize_i32(&state.time_decay, &mut raw[20..24]);
    serialize_i32(&state.time_pre_decay, &mut raw[24..28]);
    // blank
    serialize_i32(&state.color_low, &mut raw[32..36]);
    serialize_i32(&state.color_high, &mut raw[36..40]);
    serialize_i32(&state.color_high_factor, &mut raw[40..44]);
    serialize_i32(&state.mod_rate, &mut raw[44..48]);
    serialize_i32(&state.mod_depth, &mut raw[48..52]);
    serialize_i32(&state.level_early, &mut raw[52..56]);
    serialize_i32(&state.level_dry, &mut raw[60..64]);
    serialize_algorithm(&state.algorithm, &mut raw[64..])?;

    Ok(())
}

pub(crate) fn deserialize_reverb_state(state: &mut ReverbState, raw: &[u8]) -> Result<(), String> {
    assert!(raw.len() >= ReverbState::SIZE);

    deserialize_i32(&mut state.input_level, &raw[..4]);
    deserialize_bool(&mut state.bypass, &raw[4..8]);
    deserialize_bool(&mut state.kill_wet, &raw[8..12]);
    deserialize_bool(&mut state.kill_dry, &raw[12..16]);
    deserialize_i32(&mut state.output_level, &raw[16..20]);
    deserialize_i32(&mut state.time_decay, &raw[20..24]);
    deserialize_i32(&mut state.time_pre_decay, &raw[24..28]);
    // blank
    deserialize_i32(&mut state.color_low, &raw[32..36]);
    deserialize_i32(&mut state.color_high, &raw[36..40]);
    deserialize_i32(&mut state.color_high_factor, &raw[40..44]);
    deserialize_i32(&mut state.mod_rate, &raw[44..48]);
    deserialize_i32(&mut state.mod_depth, &raw[48..52]);
    deserialize_i32(&mut state.level_early, &raw[52..56]);
    deserialize_i32(&mut state.level_dry, &raw[60..64]);
    deserialize_algorithm(&mut state.algorithm, &raw[64..])?;

    Ok(())
}

/// Meter of reverb effect.
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct ReverbMeter {
    /// The meter of left and right outputs. -1000..500 (-24.0..12.0 dB)
    pub outputs: [i32; 2],
    /// The meter of left and right inputs. -1000..0 (-24.0..0.0 dB)
    pub inputs: [i32; 2],
}

impl ReverbMeter {
    pub(crate) const SIZE: usize = 24;
}

pub(crate) fn serialize_reverb_meter(meter: &ReverbMeter, raw: &mut [u8]) -> Result<(), String> {
    assert!(raw.len() >= ReverbMeter::SIZE);

    serialize_i32(&meter.outputs[0], &mut raw[..4]);
    serialize_i32(&meter.outputs[1], &mut raw[4..8]);
    serialize_i32(&meter.inputs[0], &mut raw[8..12]);
    serialize_i32(&meter.inputs[1], &mut raw[12..16]);

    Ok(())
}

pub(crate) fn deserialize_reverb_meter(meter: &mut ReverbMeter, raw: &[u8]) -> Result<(), String> {
    assert!(raw.len() >= ReverbMeter::SIZE);

    deserialize_i32(&mut meter.outputs[0], &raw[..4]);
    deserialize_i32(&mut meter.outputs[1], &raw[4..8]);
    deserialize_i32(&mut meter.inputs[0], &raw[8..12]);
    deserialize_i32(&mut meter.inputs[1], &raw[12..16]);

    Ok(())
}