geng_web_audio_api/
lib.rs

1mod platform;
2
3// TODO: OfflineAudioContext
4
5pub trait AudioNode {
6    #[doc(hidden)]
7    fn raw(&self) -> platform::AudioNodeRef<'_>;
8
9    fn connect<'a>(&self, to: &'a dyn AudioNode) -> &'a dyn AudioNode {
10        platform::connect(self.raw(), to.raw());
11        to
12    }
13
14    /// Disconnects all outgoing connections from the AudioNode.
15    fn disconnect(&self) {
16        platform::disconnect(self.raw());
17    }
18}
19
20pub struct AudioParam(platform::AudioParam);
21
22impl AudioParam {
23    pub fn set_value(&self, value: f32) {
24        self.0.set_value(value);
25    }
26
27    pub fn linear_ramp_to_value_at_time(&self, value: f32, end_time: f64) {
28        self.0.linear_ramp_to_value_at_time(value, end_time);
29    }
30
31    pub fn exponential_ramp_to_value_at_time(&self, value: f32, end_time: f64) {
32        self.0.exponential_ramp_to_value_at_time(value, end_time);
33    }
34
35    pub fn cancel_scheduled_changes(&self, cancel_time: f64) {
36        self.0.cancel_scheduled_changes(cancel_time);
37    }
38
39    pub fn value(&self) -> f32 {
40        self.0.value()
41    }
42}
43
44pub struct AudioContext(platform::AudioContext);
45
46impl AudioContext {
47    pub fn new() -> anyhow::Result<Self> {
48        Ok(Self(platform::AudioContext::new()))
49    }
50
51    pub fn destination(&self) -> AudioDestinationNode {
52        AudioDestinationNode(self.0.destination())
53    }
54
55    pub fn listener(&self) -> AudioListener {
56        AudioListener(self.0.listener())
57    }
58
59    pub async fn decode(&self, data: Vec<u8>) -> anyhow::Result<AudioBuffer> {
60        Ok(AudioBuffer(self.0.decode(data).await?))
61    }
62
63    pub fn current_time(&self) -> f64 {
64        self.0.current_time()
65    }
66}
67
68pub struct AudioListener(platform::AudioListener);
69
70impl AudioListener {
71    pub fn set_position(&self, pos: [f32; 3]) {
72        self.0.set_position(pos);
73    }
74    pub fn set_orientation(&self, forward: [f32; 3], up: [f32; 3]) {
75        self.0.set_orientation(forward, up);
76    }
77}
78
79pub struct AudioDestinationNode(platform::AudioDestinationNode);
80
81impl AudioNode for AudioDestinationNode {
82    fn raw(&self) -> platform::AudioNodeRef<'_> {
83        self.0.get_ref()
84    }
85}
86
87pub struct GainNode(platform::GainNode);
88
89impl GainNode {
90    pub fn new(context: &AudioContext) -> Self {
91        Self(platform::GainNode::new(&context.0))
92    }
93
94    pub fn gain(&self) -> AudioParam {
95        AudioParam(self.0.gain())
96    }
97}
98
99impl AudioNode for GainNode {
100    fn raw(&self) -> platform::AudioNodeRef<'_> {
101        self.0.get_ref()
102    }
103}
104
105#[derive(Debug, Copy, Clone, PartialEq, Eq, Default, Hash)]
106pub enum DistanceModel {
107    Linear,
108    #[default]
109    Inverse,
110    Exponential,
111}
112
113pub struct PannerNode(platform::PannerNode);
114
115impl PannerNode {
116    pub fn new(context: &AudioContext) -> Self {
117        Self(platform::PannerNode::new(&context.0))
118    }
119
120    pub fn set_distance_model(&mut self, model: DistanceModel) {
121        self.0.set_distance_model(model);
122    }
123
124    pub fn set_position(&mut self, pos: [f32; 3]) {
125        self.0.set_position(pos);
126    }
127
128    pub fn set_ref_distance(&mut self, ref_distance: f64) {
129        self.0.set_ref_distance(ref_distance);
130    }
131
132    pub fn set_max_distance(&mut self, max_distance: f64) {
133        self.0.set_max_distance(max_distance);
134    }
135}
136
137impl AudioNode for PannerNode {
138    fn raw(&self) -> platform::AudioNodeRef<'_> {
139        self.0.get_ref()
140    }
141}
142
143#[derive(Clone)]
144pub struct AudioBuffer(platform::AudioBuffer);
145
146impl AudioBuffer {
147    pub fn duration(&self) -> f64 {
148        self.0.duration()
149    }
150}
151
152pub struct AudioBufferSourceNode(platform::AudioBufferSourceNode);
153
154impl AudioBufferSourceNode {
155    pub fn new(context: &AudioContext) -> Self {
156        Self(platform::AudioBufferSourceNode::new(&context.0))
157    }
158
159    pub fn start_with_offset(&mut self, offset: f64) {
160        self.0.start_with_offset(offset);
161    }
162
163    pub fn stop(&mut self) {
164        self.0.stop();
165    }
166
167    pub fn stop_at(&mut self, when: f64) {
168        self.0.stop_at(when);
169    }
170
171    pub fn set_loop(&mut self, looped: bool) {
172        self.0.set_loop(looped);
173    }
174
175    pub fn set_buffer(&mut self, buffer: AudioBuffer) {
176        self.0.set_buffer(buffer.0);
177    }
178
179    pub fn playback_rate(&self) -> AudioParam {
180        AudioParam(self.0.playback_rate())
181    }
182
183    pub fn position(&self) -> f64 {
184        self.0.position()
185    }
186}
187
188impl AudioNode for AudioBufferSourceNode {
189    fn raw(&self) -> platform::AudioNodeRef<'_> {
190        self.0.get_ref()
191    }
192}