voicemeeter\interface\parameters/
vban.rs

1//! VBAN
2use super::*;
3
4/// Vban parameters
5pub struct VoicemeeterVban<'a> {
6    remote: &'a VoicemeeterRemote,
7}
8
9// vban.Enable 0 (off) or 1 (on) VBAN functions 1
10// vban.instream[i].on 0 (off) or 1 (on) Stream On/Off 1
11// vban.instream[i].name String Stream Name 1
12// vban.instream[i].ip String IP Address from 1
13// vban.instream[i].port 16 bit range PORT (Ethernet) 1
14// vban.instream[i].sr 11025 to 96 kHz Read only 1
15// vban.instream[i].channel 1 to 8 Read only 1
16// vban.instream[i].bit VBAN data type Read only 1
17// vban.instream[i].quality 0 to 4 0 = Optimal 1
18// vban.instream[i].route 0 to 8 Strip Selector 1
19// vban.outstream[i].on 0 (off) or 1 (on) Stream On/Off 1
20// vban.outstream[i].name String Stream Name 1
21// vban.outstream[i].ip String IP Address To 1
22// vban.outstream[i].port 16 bit range PORT (Ethernet) 1
23// vban.outstream[i].sr 11025 to 96 kHz 1
24// vban.outstream[i].channel 1 to 8 1
25// vban.outstream[i].bit VBAN data type 1 = 16 bits PCM 1
26// vban.outstream[i].quality 0 to 4 0 = Optimal 1
27// vban.outstream[i].route 0 to 8 BUS selector 1
28
29impl<'a> VoicemeeterVban<'a> {
30    #[doc(hidden)]
31    pub fn new(remote: &'a VoicemeeterRemote) -> Self {
32        Self { remote }
33    }
34    /// Get the identifier for an option: `Recorder.mode.{dot}`
35    pub fn param(&self, dot: impl Display) -> Cow<'static, ParameterNameRef> {
36        Cow::Owned(format!("{VBAN}.{dot}").into())
37    }
38
39    /// Turn VBAN on or off
40    pub fn enable(&self) -> BoolParameter<'_> {
41        BoolParameter::new(self.param("Enable"), self.remote)
42    }
43
44    /// Incoming VBAN stream
45    pub fn incoming_stream(
46        &self,
47        index: impl Into<ZIndex>,
48    ) -> Result<VoicemeeterVbanStream<'a, true>, ParameterError> {
49        let index = index.into();
50        const VALID: &[(VoicemeeterApplication, std::ops::RangeInclusive<u8>)] = &[
51            (VoicemeeterApplication::Voicemeeter, 0..=3),
52            (VoicemeeterApplication::VoicemeeterBanana, 0..=7),
53            (VoicemeeterApplication::VoicemeeterPotato, 0..=7),
54            (VoicemeeterApplication::PotatoX64Bits, 0..=7),
55        ];
56        let param = format!("{VBAN}.instream");
57        match VALID.iter().find(|(app, _)| self.remote.program == *app) {
58            None => Err(ParameterError::Version(InvalidVoicemeeterVersion {
59                expected: &[
60                    VoicemeeterApplication::Voicemeeter,
61                    VoicemeeterApplication::VoicemeeterBanana,
62                    VoicemeeterApplication::VoicemeeterPotato,
63                    VoicemeeterApplication::PotatoX64Bits,
64                ],
65                found: self.remote.program,
66                parameter: param,
67            })),
68            Some((_, i)) if i.contains(&(index.0 as u8)) => {
69                Ok(VoicemeeterVbanStream::<'a, true>::new(self.remote, index))
70            }
71            _ => Err(ParameterError::OutOfRange(OutOfRangeError {
72                name: param.to_string(),
73                index,
74                program: self.remote.program,
75            })),
76        }
77    }
78
79    /// Outgoing VBAN stream
80    pub fn outgoing_stream(
81        &self,
82        index: impl Into<ZIndex>,
83    ) -> Result<VoicemeeterVbanStream<'a, false>, ParameterError> {
84        let index = index.into();
85        const VALID: &[(VoicemeeterApplication, std::ops::RangeInclusive<u8>)] = &[
86            (VoicemeeterApplication::Voicemeeter, 0..=3),
87            (VoicemeeterApplication::VoicemeeterBanana, 0..=7),
88            (VoicemeeterApplication::VoicemeeterPotato, 0..=7),
89            (VoicemeeterApplication::PotatoX64Bits, 0..=7),
90        ];
91        let param = format!("{VBAN}.outstream");
92        match VALID.iter().find(|(app, _)| self.remote.program == *app) {
93            None => Err(ParameterError::Version(InvalidVoicemeeterVersion {
94                expected: &[
95                    VoicemeeterApplication::Voicemeeter,
96                    VoicemeeterApplication::VoicemeeterBanana,
97                    VoicemeeterApplication::VoicemeeterPotato,
98                    VoicemeeterApplication::PotatoX64Bits,
99                ],
100                found: self.remote.program,
101                parameter: param,
102            })),
103            Some((_, i)) if i.contains(&(index.0 as u8)) => {
104                Ok(VoicemeeterVbanStream::<'a, false>::new(self.remote, index))
105            }
106            _ => Err(ParameterError::OutOfRange(OutOfRangeError {
107                name: param.to_string(),
108                index,
109                program: self.remote.program,
110            })),
111        }
112    }
113}
114
115/// A VBAN stream, input or output
116pub struct VoicemeeterVbanStream<'a, const INPUT: bool> {
117    remote: &'a VoicemeeterRemote,
118    index: ZIndex,
119}
120
121impl<'a, const INPUT: bool> VoicemeeterVbanStream<'a, INPUT> {
122    #[doc(hidden)]
123    pub fn new(remote: &'a VoicemeeterRemote, index: ZIndex) -> Self {
124        Self { remote, index }
125    }
126
127    /// Get the identifier for an option: `Vban.{input}stream.{dot}`
128    pub fn param(&self, dot: impl Display) -> Cow<'static, ParameterNameRef> {
129        Cow::Owned(
130            format!(
131                "{VBAN}.{}stream[{}].{}",
132                match INPUT {
133                    true => "in",
134                    false => "out",
135                },
136                self.index,
137                dot
138            )
139            .into(),
140        )
141    }
142    /// Stream On/Off
143    pub fn on(&self) -> BoolParameter<'_> {
144        BoolParameter::new(self.param("on"), self.remote)
145    }
146    /// Stream name
147    pub fn name(&self) -> StringParameter<'_> {
148        StringParameter::new(self.param("name"), self.remote)
149    }
150    /// IP Address
151    pub fn ip(&self) -> StringParameter<'_> {
152        StringParameter::new(self.param("ip"), self.remote)
153    }
154
155    /// Port
156    pub fn port(&self) -> IntParameter<'_> {
157        IntParameter::new(self.param("port"), self.remote, 0..=u16::MAX as i32)
158    }
159
160    /// Quality
161    pub fn quality(&self) -> IntParameter<'_> {
162        IntParameter::new(self.param("quality"), self.remote, 0..=4)
163    }
164    /// Strip Selector
165    pub fn route(&self) -> IntParameter<'_> {
166        IntParameter::new(self.param("route"), self.remote, 0..=8)
167    }
168}
169
170impl<'a> VoicemeeterVbanStream<'a, true> {
171    /// Sample rate
172    pub fn sample_rate(&self) -> IntParameter<'a, false, true> {
173        IntParameter::new(self.param("sr"), self.remote, 11025..=96000)
174    }
175
176    /// Channel
177    ///
178    /// 1 to 8
179    pub fn channel(&self) -> IntParameter<'a, false, true> {
180        IntParameter::new(self.param("channel"), self.remote, 1..=8)
181    }
182    /// VBAN data type
183    ///
184    /// |type|format|
185    /// |----|------|
186    /// |1|16 bits PCM|
187    /// |2|24 bits PCM|
188    pub fn bit(&self) -> IntParameter<'a, false, true> {
189        IntParameter::new(self.param("bit"), self.remote, 1..=2)
190    }
191}
192
193impl<'a> VoicemeeterVbanStream<'a, false> {
194    /// Sample rate
195    pub fn sample_rate(&self) -> IntParameter<'_> {
196        IntParameter::new(self.param("sr"), self.remote, 11025..=96000)
197    }
198    /// Channel
199    ///
200    /// 1 to 8
201    pub fn channel(&self) -> IntParameter<'_> {
202        IntParameter::new(self.param("channel"), self.remote, 1..=8)
203    }
204    /// VBAN data type
205    ///
206    /// |type|format|
207    /// |----|------|
208    /// |1|16 bits PCM|
209    /// |2|24 bits PCM|
210    pub fn bit(&self) -> IntParameter<'_> {
211        IntParameter::new(self.param("bit"), self.remote, 1..=2)
212    }
213}