Skip to main content

browser_protocol/webaudio/
mod.rs

1//! This domain allows inspection of Web Audio API.
2//! https://webaudio.github.io/web-audio-api/
3
4
5use serde::{Serialize, Deserialize};
6use serde_json::Value as JsonValue;
7use std::borrow::Cow;
8
9/// An unique ID for a graph object (AudioContext, AudioNode, AudioParam) in Web Audio API
10
11pub type GraphObjectId<'a> = Cow<'a, str>;
12
13/// Enum of BaseAudioContext types
14
15#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
16pub enum ContextType {
17    #[default]
18    #[serde(rename = "realtime")]
19    Realtime,
20    #[serde(rename = "offline")]
21    Offline,
22}
23
24/// Enum of AudioContextState from the spec
25
26#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
27pub enum ContextState {
28    #[default]
29    #[serde(rename = "suspended")]
30    Suspended,
31    #[serde(rename = "running")]
32    Running,
33    #[serde(rename = "closed")]
34    Closed,
35    #[serde(rename = "interrupted")]
36    Interrupted,
37}
38
39/// Enum of AudioNode types
40
41pub type NodeType<'a> = Cow<'a, str>;
42
43/// Enum of AudioNode::ChannelCountMode from the spec
44
45#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
46pub enum ChannelCountMode {
47    #[default]
48    #[serde(rename = "clamped-max")]
49    ClampedMax,
50    #[serde(rename = "explicit")]
51    Explicit,
52    #[serde(rename = "max")]
53    Max,
54}
55
56/// Enum of AudioNode::ChannelInterpretation from the spec
57
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
59pub enum ChannelInterpretation {
60    #[default]
61    #[serde(rename = "discrete")]
62    Discrete,
63    #[serde(rename = "speakers")]
64    Speakers,
65}
66
67/// Enum of AudioParam types
68
69pub type ParamType<'a> = Cow<'a, str>;
70
71/// Enum of AudioParam::AutomationRate from the spec
72
73#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
74pub enum AutomationRate {
75    #[default]
76    #[serde(rename = "a-rate")]
77    ARate,
78    #[serde(rename = "k-rate")]
79    KRate,
80}
81
82/// Fields in AudioContext that change in real-time.
83
84#[derive(Debug, Clone, Serialize, Deserialize, Default)]
85#[serde(rename_all = "camelCase")]
86pub struct ContextRealtimeData {
87    /// The current context time in second in BaseAudioContext.
88    currentTime: f64,
89    /// The time spent on rendering graph divided by render quantum duration,
90    /// and multiplied by 100. 100 means the audio renderer reached the full
91    /// capacity and glitch may occur.
92    renderCapacity: f64,
93    /// A running mean of callback interval.
94    callbackIntervalMean: f64,
95    /// A running variance of callback interval.
96    callbackIntervalVariance: f64,
97}
98
99impl ContextRealtimeData {
100    pub fn builder(currentTime: f64, renderCapacity: f64, callbackIntervalMean: f64, callbackIntervalVariance: f64) -> ContextRealtimeDataBuilder {
101        ContextRealtimeDataBuilder {
102            currentTime: currentTime,
103            renderCapacity: renderCapacity,
104            callbackIntervalMean: callbackIntervalMean,
105            callbackIntervalVariance: callbackIntervalVariance,
106        }
107    }
108    pub fn currentTime(&self) -> f64 { self.currentTime }
109    pub fn renderCapacity(&self) -> f64 { self.renderCapacity }
110    pub fn callbackIntervalMean(&self) -> f64 { self.callbackIntervalMean }
111    pub fn callbackIntervalVariance(&self) -> f64 { self.callbackIntervalVariance }
112}
113
114
115pub struct ContextRealtimeDataBuilder {
116    currentTime: f64,
117    renderCapacity: f64,
118    callbackIntervalMean: f64,
119    callbackIntervalVariance: f64,
120}
121
122impl ContextRealtimeDataBuilder {
123    pub fn build(self) -> ContextRealtimeData {
124        ContextRealtimeData {
125            currentTime: self.currentTime,
126            renderCapacity: self.renderCapacity,
127            callbackIntervalMean: self.callbackIntervalMean,
128            callbackIntervalVariance: self.callbackIntervalVariance,
129        }
130    }
131}
132
133/// Protocol object for BaseAudioContext
134
135#[derive(Debug, Clone, Serialize, Deserialize, Default)]
136#[serde(rename_all = "camelCase")]
137pub struct BaseAudioContext<'a> {
138    contextId: GraphObjectId<'a>,
139    contextType: ContextType,
140    contextState: ContextState,
141    #[serde(skip_serializing_if = "Option::is_none")]
142    realtimeData: Option<ContextRealtimeData>,
143    /// Platform-dependent callback buffer size.
144    callbackBufferSize: f64,
145    /// Number of output channels supported by audio hardware in use.
146    maxOutputChannelCount: f64,
147    /// Context sample rate.
148    sampleRate: f64,
149}
150
151impl<'a> BaseAudioContext<'a> {
152    pub fn builder(contextId: GraphObjectId<'a>, contextType: ContextType, contextState: ContextState, callbackBufferSize: f64, maxOutputChannelCount: f64, sampleRate: f64) -> BaseAudioContextBuilder<'a> {
153        BaseAudioContextBuilder {
154            contextId: contextId,
155            contextType: contextType,
156            contextState: contextState,
157            realtimeData: None,
158            callbackBufferSize: callbackBufferSize,
159            maxOutputChannelCount: maxOutputChannelCount,
160            sampleRate: sampleRate,
161        }
162    }
163    pub fn contextId(&self) -> &GraphObjectId<'a> { &self.contextId }
164    pub fn contextType(&self) -> &ContextType { &self.contextType }
165    pub fn contextState(&self) -> &ContextState { &self.contextState }
166    pub fn realtimeData(&self) -> Option<&ContextRealtimeData> { self.realtimeData.as_ref() }
167    pub fn callbackBufferSize(&self) -> f64 { self.callbackBufferSize }
168    pub fn maxOutputChannelCount(&self) -> f64 { self.maxOutputChannelCount }
169    pub fn sampleRate(&self) -> f64 { self.sampleRate }
170}
171
172
173pub struct BaseAudioContextBuilder<'a> {
174    contextId: GraphObjectId<'a>,
175    contextType: ContextType,
176    contextState: ContextState,
177    realtimeData: Option<ContextRealtimeData>,
178    callbackBufferSize: f64,
179    maxOutputChannelCount: f64,
180    sampleRate: f64,
181}
182
183impl<'a> BaseAudioContextBuilder<'a> {
184    pub fn realtimeData(mut self, realtimeData: ContextRealtimeData) -> Self { self.realtimeData = Some(realtimeData); self }
185    pub fn build(self) -> BaseAudioContext<'a> {
186        BaseAudioContext {
187            contextId: self.contextId,
188            contextType: self.contextType,
189            contextState: self.contextState,
190            realtimeData: self.realtimeData,
191            callbackBufferSize: self.callbackBufferSize,
192            maxOutputChannelCount: self.maxOutputChannelCount,
193            sampleRate: self.sampleRate,
194        }
195    }
196}
197
198/// Protocol object for AudioListener
199
200#[derive(Debug, Clone, Serialize, Deserialize, Default)]
201#[serde(rename_all = "camelCase")]
202pub struct AudioListener<'a> {
203    listenerId: GraphObjectId<'a>,
204    contextId: GraphObjectId<'a>,
205}
206
207impl<'a> AudioListener<'a> {
208    pub fn builder(listenerId: GraphObjectId<'a>, contextId: GraphObjectId<'a>) -> AudioListenerBuilder<'a> {
209        AudioListenerBuilder {
210            listenerId: listenerId,
211            contextId: contextId,
212        }
213    }
214    pub fn listenerId(&self) -> &GraphObjectId<'a> { &self.listenerId }
215    pub fn contextId(&self) -> &GraphObjectId<'a> { &self.contextId }
216}
217
218
219pub struct AudioListenerBuilder<'a> {
220    listenerId: GraphObjectId<'a>,
221    contextId: GraphObjectId<'a>,
222}
223
224impl<'a> AudioListenerBuilder<'a> {
225    pub fn build(self) -> AudioListener<'a> {
226        AudioListener {
227            listenerId: self.listenerId,
228            contextId: self.contextId,
229        }
230    }
231}
232
233/// Protocol object for AudioNode
234
235#[derive(Debug, Clone, Serialize, Deserialize, Default)]
236#[serde(rename_all = "camelCase")]
237pub struct AudioNode<'a> {
238    nodeId: GraphObjectId<'a>,
239    contextId: GraphObjectId<'a>,
240    nodeType: NodeType<'a>,
241    numberOfInputs: f64,
242    numberOfOutputs: f64,
243    channelCount: f64,
244    channelCountMode: ChannelCountMode,
245    channelInterpretation: ChannelInterpretation,
246}
247
248impl<'a> AudioNode<'a> {
249    pub fn builder(nodeId: GraphObjectId<'a>, contextId: GraphObjectId<'a>, nodeType: NodeType<'a>, numberOfInputs: f64, numberOfOutputs: f64, channelCount: f64, channelCountMode: ChannelCountMode, channelInterpretation: ChannelInterpretation) -> AudioNodeBuilder<'a> {
250        AudioNodeBuilder {
251            nodeId: nodeId,
252            contextId: contextId,
253            nodeType: nodeType,
254            numberOfInputs: numberOfInputs,
255            numberOfOutputs: numberOfOutputs,
256            channelCount: channelCount,
257            channelCountMode: channelCountMode,
258            channelInterpretation: channelInterpretation,
259        }
260    }
261    pub fn nodeId(&self) -> &GraphObjectId<'a> { &self.nodeId }
262    pub fn contextId(&self) -> &GraphObjectId<'a> { &self.contextId }
263    pub fn nodeType(&self) -> &NodeType<'a> { &self.nodeType }
264    pub fn numberOfInputs(&self) -> f64 { self.numberOfInputs }
265    pub fn numberOfOutputs(&self) -> f64 { self.numberOfOutputs }
266    pub fn channelCount(&self) -> f64 { self.channelCount }
267    pub fn channelCountMode(&self) -> &ChannelCountMode { &self.channelCountMode }
268    pub fn channelInterpretation(&self) -> &ChannelInterpretation { &self.channelInterpretation }
269}
270
271
272pub struct AudioNodeBuilder<'a> {
273    nodeId: GraphObjectId<'a>,
274    contextId: GraphObjectId<'a>,
275    nodeType: NodeType<'a>,
276    numberOfInputs: f64,
277    numberOfOutputs: f64,
278    channelCount: f64,
279    channelCountMode: ChannelCountMode,
280    channelInterpretation: ChannelInterpretation,
281}
282
283impl<'a> AudioNodeBuilder<'a> {
284    pub fn build(self) -> AudioNode<'a> {
285        AudioNode {
286            nodeId: self.nodeId,
287            contextId: self.contextId,
288            nodeType: self.nodeType,
289            numberOfInputs: self.numberOfInputs,
290            numberOfOutputs: self.numberOfOutputs,
291            channelCount: self.channelCount,
292            channelCountMode: self.channelCountMode,
293            channelInterpretation: self.channelInterpretation,
294        }
295    }
296}
297
298/// Protocol object for AudioParam
299
300#[derive(Debug, Clone, Serialize, Deserialize, Default)]
301#[serde(rename_all = "camelCase")]
302pub struct AudioParam<'a> {
303    paramId: GraphObjectId<'a>,
304    nodeId: GraphObjectId<'a>,
305    contextId: GraphObjectId<'a>,
306    paramType: ParamType<'a>,
307    rate: AutomationRate,
308    defaultValue: f64,
309    minValue: f64,
310    maxValue: f64,
311}
312
313impl<'a> AudioParam<'a> {
314    pub fn builder(paramId: GraphObjectId<'a>, nodeId: GraphObjectId<'a>, contextId: GraphObjectId<'a>, paramType: ParamType<'a>, rate: AutomationRate, defaultValue: f64, minValue: f64, maxValue: f64) -> AudioParamBuilder<'a> {
315        AudioParamBuilder {
316            paramId: paramId,
317            nodeId: nodeId,
318            contextId: contextId,
319            paramType: paramType,
320            rate: rate,
321            defaultValue: defaultValue,
322            minValue: minValue,
323            maxValue: maxValue,
324        }
325    }
326    pub fn paramId(&self) -> &GraphObjectId<'a> { &self.paramId }
327    pub fn nodeId(&self) -> &GraphObjectId<'a> { &self.nodeId }
328    pub fn contextId(&self) -> &GraphObjectId<'a> { &self.contextId }
329    pub fn paramType(&self) -> &ParamType<'a> { &self.paramType }
330    pub fn rate(&self) -> &AutomationRate { &self.rate }
331    pub fn defaultValue(&self) -> f64 { self.defaultValue }
332    pub fn minValue(&self) -> f64 { self.minValue }
333    pub fn maxValue(&self) -> f64 { self.maxValue }
334}
335
336
337pub struct AudioParamBuilder<'a> {
338    paramId: GraphObjectId<'a>,
339    nodeId: GraphObjectId<'a>,
340    contextId: GraphObjectId<'a>,
341    paramType: ParamType<'a>,
342    rate: AutomationRate,
343    defaultValue: f64,
344    minValue: f64,
345    maxValue: f64,
346}
347
348impl<'a> AudioParamBuilder<'a> {
349    pub fn build(self) -> AudioParam<'a> {
350        AudioParam {
351            paramId: self.paramId,
352            nodeId: self.nodeId,
353            contextId: self.contextId,
354            paramType: self.paramType,
355            rate: self.rate,
356            defaultValue: self.defaultValue,
357            minValue: self.minValue,
358            maxValue: self.maxValue,
359        }
360    }
361}
362
363#[derive(Debug, Clone, Serialize, Deserialize, Default)]
364pub struct EnableParams {}
365
366impl EnableParams { pub const METHOD: &'static str = "WebAudio.enable"; }
367
368impl<'a> crate::CdpCommand<'a> for EnableParams {
369    const METHOD: &'static str = "WebAudio.enable";
370    type Response = crate::EmptyReturns;
371}
372
373#[derive(Debug, Clone, Serialize, Deserialize, Default)]
374pub struct DisableParams {}
375
376impl DisableParams { pub const METHOD: &'static str = "WebAudio.disable"; }
377
378impl<'a> crate::CdpCommand<'a> for DisableParams {
379    const METHOD: &'static str = "WebAudio.disable";
380    type Response = crate::EmptyReturns;
381}
382
383/// Fetch the realtime data from the registered contexts.
384
385#[derive(Debug, Clone, Serialize, Deserialize, Default)]
386#[serde(rename_all = "camelCase")]
387pub struct GetRealtimeDataParams<'a> {
388    contextId: GraphObjectId<'a>,
389}
390
391impl<'a> GetRealtimeDataParams<'a> {
392    pub fn builder(contextId: GraphObjectId<'a>) -> GetRealtimeDataParamsBuilder<'a> {
393        GetRealtimeDataParamsBuilder {
394            contextId: contextId,
395        }
396    }
397    pub fn contextId(&self) -> &GraphObjectId<'a> { &self.contextId }
398}
399
400
401pub struct GetRealtimeDataParamsBuilder<'a> {
402    contextId: GraphObjectId<'a>,
403}
404
405impl<'a> GetRealtimeDataParamsBuilder<'a> {
406    pub fn build(self) -> GetRealtimeDataParams<'a> {
407        GetRealtimeDataParams {
408            contextId: self.contextId,
409        }
410    }
411}
412
413/// Fetch the realtime data from the registered contexts.
414
415#[derive(Debug, Clone, Serialize, Deserialize, Default)]
416#[serde(rename_all = "camelCase")]
417pub struct GetRealtimeDataReturns {
418    realtimeData: ContextRealtimeData,
419}
420
421impl GetRealtimeDataReturns {
422    pub fn builder(realtimeData: ContextRealtimeData) -> GetRealtimeDataReturnsBuilder {
423        GetRealtimeDataReturnsBuilder {
424            realtimeData: realtimeData,
425        }
426    }
427    pub fn realtimeData(&self) -> &ContextRealtimeData { &self.realtimeData }
428}
429
430
431pub struct GetRealtimeDataReturnsBuilder {
432    realtimeData: ContextRealtimeData,
433}
434
435impl GetRealtimeDataReturnsBuilder {
436    pub fn build(self) -> GetRealtimeDataReturns {
437        GetRealtimeDataReturns {
438            realtimeData: self.realtimeData,
439        }
440    }
441}
442
443impl<'a> GetRealtimeDataParams<'a> { pub const METHOD: &'static str = "WebAudio.getRealtimeData"; }
444
445impl<'a> crate::CdpCommand<'a> for GetRealtimeDataParams<'a> {
446    const METHOD: &'static str = "WebAudio.getRealtimeData";
447    type Response = GetRealtimeDataReturns;
448}