firewire_bebob_protocols/presonus/
firebox.rs1use super::*;
36
37#[derive(Default, Debug)]
39pub struct FireboxClkProtocol;
40
41impl MediaClockFrequencyOperation for FireboxClkProtocol {
42 const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000];
43}
44
45impl SamplingClockSourceOperation for FireboxClkProtocol {
46 const DST: SignalAddr = SignalAddr::Subunit(SignalSubunitAddr {
47 subunit: MUSIC_SUBUNIT_0,
48 plug_id: 0x05,
49 });
50
51 const SRC_LIST: &'static [SignalAddr] = &[
52 SignalAddr::Subunit(SignalSubunitAddr {
54 subunit: MUSIC_SUBUNIT_0,
55 plug_id: 0x06,
56 }),
57 SignalAddr::Unit(SignalUnitAddr::Ext(0x03)),
59 ];
60}
61
62#[derive(Default, Debug)]
64pub struct FireboxPhysOutputProtocol;
65
66impl AvcAudioFeatureSpecification for FireboxPhysOutputProtocol {
67 const ENTRIES: &'static [(u8, AudioCh)] = &[
68 (0x01, AudioCh::Each(0)),
69 (0x01, AudioCh::Each(1)),
70 (0x02, AudioCh::Each(0)),
71 (0x02, AudioCh::Each(1)),
72 (0x03, AudioCh::Each(0)),
73 (0x03, AudioCh::Each(1)),
74 ];
75}
76
77impl AvcLevelOperation for FireboxPhysOutputProtocol {}
78
79impl AvcMuteOperation for FireboxPhysOutputProtocol {}
80
81impl AvcSelectorOperation for FireboxPhysOutputProtocol {
82 const FUNC_BLOCK_ID_LIST: &'static [u8] = &[0x01, 0x02, 0x03, 0x05];
84 const INPUT_PLUG_ID_LIST: &'static [u8] = &[0x00, 0x01];
86}
87
88#[derive(Default, Debug)]
90pub struct FireboxHeadphoneProtocol;
91
92impl AvcAudioFeatureSpecification for FireboxHeadphoneProtocol {
93 const ENTRIES: &'static [(u8, AudioCh)] = &[(0x04, AudioCh::Each(0)), (0x04, AudioCh::Each(1))];
94}
95
96impl AvcLevelOperation for FireboxHeadphoneProtocol {}
97
98impl AvcMuteOperation for FireboxHeadphoneProtocol {}
99
100impl AvcSelectorOperation for FireboxHeadphoneProtocol {
101 const FUNC_BLOCK_ID_LIST: &'static [u8] = &[0x04];
103 const INPUT_PLUG_ID_LIST: &'static [u8] = &[0x00, 0x01, 0x02, 0x03, 0x04];
106}
107
108#[derive(Default, Debug)]
110pub struct FireboxMixerPhysSourceProtocol;
111
112impl AvcAudioFeatureSpecification for FireboxMixerPhysSourceProtocol {
113 const ENTRIES: &'static [(u8, AudioCh)] = &[
114 (0x05, AudioCh::Each(0)),
115 (0x05, AudioCh::Each(1)),
116 (0x06, AudioCh::Each(0)),
117 (0x06, AudioCh::Each(1)),
118 (0x07, AudioCh::Each(0)),
119 (0x07, AudioCh::Each(1)),
120 ];
121}
122
123impl AvcLevelOperation for FireboxMixerPhysSourceProtocol {}
124
125impl AvcLrBalanceOperation for FireboxMixerPhysSourceProtocol {}
126
127impl AvcMuteOperation for FireboxMixerPhysSourceProtocol {}
128
129#[derive(Default, Debug)]
131pub struct FireboxMixerStreamSourceProtocol;
132
133impl AvcAudioFeatureSpecification for FireboxMixerStreamSourceProtocol {
134 const ENTRIES: &'static [(u8, AudioCh)] = &[(0x08, AudioCh::Each(0))];
135}
136
137impl AvcLevelOperation for FireboxMixerStreamSourceProtocol {}
138
139impl AvcMuteOperation for FireboxMixerStreamSourceProtocol {}
140
141impl AvcSelectorOperation for FireboxMixerStreamSourceProtocol {
142 const FUNC_BLOCK_ID_LIST: &'static [u8] = &[0x06];
144 const INPUT_PLUG_ID_LIST: &'static [u8] = &[0x00, 0x01, 0x02, 0x03];
146}
147#[derive(Default, Debug)]
149pub struct FireboxMixerOutputProtocol;
150
151impl AvcAudioFeatureSpecification for FireboxMixerOutputProtocol {
152 const ENTRIES: &'static [(u8, AudioCh)] = &[(0x09, AudioCh::Each(0)), (0x09, AudioCh::Each(1))];
153}
154
155impl AvcLevelOperation for FireboxMixerOutputProtocol {}
156
157impl AvcLrBalanceOperation for FireboxMixerOutputProtocol {}
158
159impl AvcMuteOperation for FireboxMixerOutputProtocol {}
160
161#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
163pub struct FireboxAnalogInputParameters {
164 pub boosts: [bool; FireboxAnalogInputProtocol::CH_COUNT],
166}
167
168#[derive(Default, Debug)]
170pub struct FireboxAnalogInputProtocol;
171
172impl FireboxAnalogInputProtocol {
173 const BOOST_OFF: i16 = VolumeData::VALUE_MIN;
174 const BOOST_ON: i16 = VolumeData::VALUE_ZERO;
175
176 const FUNC_BLOCK_ID_LIST: &'static [u8] = &[0x0a, 0x0b];
177 const INPUT_PLUG_ID_LIST: &'static [u8] = &[0x00, 0x01];
178
179 const CH_COUNT: usize = 4;
180
181 pub fn cache(
183 avc: &BebobAvc,
184 params: &mut FireboxAnalogInputParameters,
185 timeout_ms: u32,
186 ) -> Result<(), Error> {
187 params
188 .boosts
189 .iter_mut()
190 .enumerate()
191 .try_for_each(|(i, boost)| {
192 let func_block_id = Self::FUNC_BLOCK_ID_LIST[i / 2];
193 let input_plug_id = Self::INPUT_PLUG_ID_LIST[i % 2];
194
195 let mut op = AudioFeature::new(
196 func_block_id,
197 CtlAttr::Current,
198 AudioCh::Each(input_plug_id),
199 FeatureCtl::Volume(VolumeData::new(1)),
200 );
201 avc.status(&AUDIO_SUBUNIT_0_ADDR, &mut op, timeout_ms)
202 .map(|_| {
203 if let FeatureCtl::Volume(data) = op.ctl {
204 *boost = data.0[0] == Self::BOOST_ON;
205 }
206 })
207 })
208 }
209
210 pub fn update(
212 avc: &BebobAvc,
213 params: &FireboxAnalogInputParameters,
214 prev: &mut FireboxAnalogInputParameters,
215 timeout_ms: u32,
216 ) -> Result<(), Error> {
217 prev.boosts
218 .iter_mut()
219 .zip(params.boosts.iter())
220 .enumerate()
221 .filter(|(_, (o, n))| !o.eq(n))
222 .try_for_each(|(i, (old, &new))| {
223 let func_block_id = Self::FUNC_BLOCK_ID_LIST[i / 2];
224 let input_plug_id = Self::INPUT_PLUG_ID_LIST[i % 2];
225
226 let mut op = AudioFeature::new(
227 func_block_id,
228 CtlAttr::Current,
229 AudioCh::Each(input_plug_id),
230 FeatureCtl::Volume(VolumeData(vec![if new {
231 Self::BOOST_ON
232 } else {
233 Self::BOOST_OFF
234 }])),
235 );
236 avc.control(&AUDIO_SUBUNIT_0_ADDR, &mut op, timeout_ms)
237 .map(|_| *old = new)
238 })
239 }
240}