1use super::*;
2
3impl GameAudioContext {
5 pub fn create() -> GameAudioContext {
11 let context: AudioContext = AudioContext::new().expect("should create audio context");
12 let master_gain: GainNode = context
13 .create_gain()
14 .expect("should create master gain node");
15 let _: Result<AudioNode, JsValue> =
16 master_gain.connect_with_audio_node(&context.destination());
17 master_gain.gain().set_value(AUDIO_DEFAULT_VOLUME as f32);
18 GameAudioContext::new(context, master_gain, AUDIO_DEFAULT_VOLUME)
19 }
20
21 pub fn apply_master_volume(&self, volume: f64) {
27 let clamped: f64 = Numeric::clamp(volume, 0.0, 1.0);
28 self.get_master_gain().gain().set_value(clamped as f32);
29 }
30
31 pub fn resume(&self) {
33 let _: Result<Promise, JsValue> = self.get_context().resume();
34 }
35
36 pub fn suspend(&self) {
38 let _: Result<Promise, JsValue> = self.get_context().suspend();
39 }
40
41 pub fn close(&self) {
43 let _: Result<Promise, JsValue> = self.get_context().close();
44 }
45
46 pub fn sample_rate(&self) -> f64 {
52 self.get_context().sample_rate() as f64
53 }
54
55 pub fn current_time(&self) -> f64 {
61 self.get_context().current_time()
62 }
63}
64
65impl Default for GameAudioContext {
67 fn default() -> GameAudioContext {
68 GameAudioContext::create()
69 }
70}
71
72impl AudioClip {
74 pub fn create(buffer: AudioBuffer, name: String) -> AudioClip {
85 AudioClip::new(
86 buffer,
87 name,
88 AudioPlayState::Stopped,
89 AUDIO_DEFAULT_LOOP,
90 AUDIO_DEFAULT_VOLUME,
91 AUDIO_DEFAULT_PLAYBACK_RATE,
92 )
93 }
94
95 pub fn play(&mut self, audio_context: &GameAudioContext) {
104 if self.get_state() == AudioPlayState::Playing {
105 return;
106 }
107 let source: AudioBufferSourceNode = audio_context
108 .get_context()
109 .create_buffer_source()
110 .expect("should create buffer source");
111 source.set_buffer(Some(self.get_buffer()));
112 source.set_loop(self.get_looping());
113 source
114 .playback_rate()
115 .set_value(self.get_playback_rate() as f32);
116 let gain: GainNode = audio_context
117 .get_context()
118 .create_gain()
119 .expect("should create gain node");
120 gain.gain().set_value(self.get_volume() as f32);
121 let _: Result<AudioNode, JsValue> = source.connect_with_audio_node(&gain);
122 let _: Result<AudioNode, JsValue> =
123 gain.connect_with_audio_node(audio_context.get_master_gain());
124 let _: Result<(), JsValue> = source.start();
125 self.set_source_node(Some(source));
126 self.set_state(AudioPlayState::Playing);
127 }
128
129 pub fn stop(&mut self) {
131 if let Some(source) = self.get_mut_source_node().take() {
132 let scheduled: &AudioScheduledSourceNode = source.as_ref();
133 let _: Result<(), JsValue> = scheduled.stop_with_when(0.0);
134 let _: Result<(), JsValue> = source.disconnect();
135 }
136 self.set_state(AudioPlayState::Stopped);
137 }
138
139 pub fn update_looping(&mut self, looping: bool) {
145 self.set_looping(looping);
146 if let Some(source) = self.get_mut_source_node() {
147 source.set_loop(looping);
148 }
149 }
150
151 pub fn update_volume(&mut self, volume: f64) {
157 self.set_volume(Numeric::clamp(volume, 0.0, 1.0));
158 }
159
160 pub fn update_playback_rate(&mut self, rate: f64) {
166 self.set_playback_rate(rate);
167 if let Some(source) = self.get_mut_source_node() {
168 source.playback_rate().set_value(rate as f32);
169 }
170 }
171
172 pub fn duration(&self) -> f64 {
178 self.get_buffer().duration()
179 }
180
181 pub fn channel_count(&self) -> u32 {
187 self.get_buffer().number_of_channels()
188 }
189}