firewire_fireworks_protocols/
playback.rs1use super::*;
10
11const CATEGORY_PLAYBACK: u32 = 6;
12
13const CMD_SET_VOL: u32 = 0;
14const CMD_GET_VOL: u32 = 1;
15const CMD_SET_MUTE: u32 = 2;
16const CMD_GET_MUTE: u32 = 3;
17const CMD_SET_SOLO: u32 = 4;
18const CMD_GET_SOLO: u32 = 5;
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct EfwPlaybackParameters {
23 pub volumes: Vec<i32>,
26 pub mutes: Vec<bool>,
28}
29
30impl<O, P> EfwWhollyCachableParamsOperation<P, EfwPlaybackParameters> for O
31where
32 O: EfwHardwareSpecification,
33 P: EfwProtocolExtManual,
34{
35 fn cache_wholly(
36 proto: &mut P,
37 states: &mut EfwPlaybackParameters,
38 timeout_ms: u32,
39 ) -> Result<(), Error> {
40 assert_eq!(states.volumes.len(), Self::RX_CHANNEL_COUNTS[0]);
41 assert_eq!(states.mutes.len(), Self::RX_CHANNEL_COUNTS[0]);
42
43 states
44 .volumes
45 .iter_mut()
46 .enumerate()
47 .try_for_each(|(ch, vol)| {
48 let args = [ch as u32, 0];
49 let mut resps = vec![0; 2];
50 proto
51 .transaction(
52 CATEGORY_PLAYBACK,
53 CMD_GET_VOL,
54 &args,
55 &mut resps,
56 timeout_ms,
57 )
58 .map(|_| *vol = resps[1] as i32)
59 })?;
60
61 states
62 .mutes
63 .iter_mut()
64 .enumerate()
65 .try_for_each(|(ch, mute)| {
66 let args = [ch as u32, 0];
67 let mut resps = vec![0; 2];
68 proto
69 .transaction(
70 CATEGORY_PLAYBACK,
71 CMD_GET_MUTE,
72 &args,
73 &mut resps,
74 timeout_ms,
75 )
76 .map(|_| *mute = resps[1] > 0)
77 })?;
78
79 Ok(())
80 }
81}
82
83impl<O, P> EfwPartiallyUpdatableParamsOperation<P, EfwPlaybackParameters> for O
84where
85 O: EfwHardwareSpecification,
86 P: EfwProtocolExtManual,
87{
88 fn update_partially(
89 proto: &mut P,
90 states: &mut EfwPlaybackParameters,
91 updates: EfwPlaybackParameters,
92 timeout_ms: u32,
93 ) -> Result<(), Error> {
94 assert_eq!(states.volumes.len(), Self::RX_CHANNEL_COUNTS[0]);
95 assert_eq!(states.mutes.len(), Self::RX_CHANNEL_COUNTS[0]);
96 assert_eq!(updates.volumes.len(), Self::RX_CHANNEL_COUNTS[0]);
97 assert_eq!(updates.mutes.len(), Self::RX_CHANNEL_COUNTS[0]);
98
99 states
100 .volumes
101 .iter_mut()
102 .zip(updates.volumes.iter())
103 .enumerate()
104 .filter(|(_, (o, n))| !o.eq(n))
105 .try_for_each(|(ch, (curr, &vol))| {
106 let args = [ch as u32, vol as u32];
107 let mut params = vec![0; 2];
108 proto
109 .transaction(
110 CATEGORY_PLAYBACK,
111 CMD_SET_VOL,
112 &args,
113 &mut params,
114 timeout_ms,
115 )
116 .map(|_| *curr = vol)
117 })?;
118
119 states
120 .mutes
121 .iter_mut()
122 .zip(updates.mutes.iter())
123 .enumerate()
124 .filter(|(_, (o, n))| !o.eq(n))
125 .try_for_each(|(ch, (curr, &mute))| {
126 let args = [ch as u32, mute as u32];
127 let mut params = vec![0; 2];
128 proto
129 .transaction(
130 CATEGORY_PLAYBACK,
131 CMD_SET_MUTE,
132 &args,
133 &mut params,
134 timeout_ms,
135 )
136 .map(|_| *curr = mute)
137 })?;
138
139 Ok(())
140 }
141}
142
143#[derive(Debug, Clone, PartialEq, Eq)]
145pub struct EfwPlaybackSoloParameters {
146 pub solos: Vec<bool>,
148}
149
150pub trait EfwPlaybackSoloSpecification: EfwHardwareSpecification {
152 fn create_playback_solo_parameters() -> EfwPlaybackSoloParameters {
153 EfwPlaybackSoloParameters {
154 solos: vec![Default::default(); Self::RX_CHANNEL_COUNTS[0]],
155 }
156 }
157}
158
159impl<O, P> EfwWhollyCachableParamsOperation<P, EfwPlaybackSoloParameters> for O
160where
161 O: EfwPlaybackSoloSpecification,
162 P: EfwProtocolExtManual,
163{
164 fn cache_wholly(
165 proto: &mut P,
166 states: &mut EfwPlaybackSoloParameters,
167 timeout_ms: u32,
168 ) -> Result<(), Error> {
169 assert_eq!(states.solos.len(), Self::RX_CHANNEL_COUNTS[0]);
170
171 states
172 .solos
173 .iter_mut()
174 .enumerate()
175 .try_for_each(|(ch, solo)| {
176 let args = [ch as u32, 0];
177 let mut resps = vec![0; 2];
178 proto
179 .transaction(
180 CATEGORY_PLAYBACK,
181 CMD_GET_SOLO,
182 &args,
183 &mut resps,
184 timeout_ms,
185 )
186 .map(|_| *solo = resps[1] > 0)
187 })?;
188
189 Ok(())
190 }
191}
192
193impl<O, P> EfwPartiallyUpdatableParamsOperation<P, EfwPlaybackSoloParameters> for O
194where
195 O: EfwPlaybackSoloSpecification,
196 P: EfwProtocolExtManual,
197{
198 fn update_partially(
199 proto: &mut P,
200 states: &mut EfwPlaybackSoloParameters,
201 updates: EfwPlaybackSoloParameters,
202 timeout_ms: u32,
203 ) -> Result<(), Error> {
204 assert_eq!(states.solos.len(), Self::RX_CHANNEL_COUNTS[0]);
205 assert_eq!(updates.solos.len(), Self::RX_CHANNEL_COUNTS[0]);
206
207 states
208 .solos
209 .iter_mut()
210 .zip(updates.solos.iter())
211 .enumerate()
212 .filter(|(_, (o, n))| !o.eq(n))
213 .try_for_each(|(ch, (curr, &solo))| {
214 let args = [ch as u32, solo as u32];
215 let mut params = vec![0; 2];
216 proto
217 .transaction(
218 CATEGORY_PLAYBACK,
219 CMD_SET_SOLO,
220 &args,
221 &mut params,
222 timeout_ms,
223 )
224 .map(|_| *curr = solo)
225 })?;
226
227 Ok(())
228 }
229}