1#![allow(dead_code)]
4
5use crate::{file::load_file, get_context, Error};
6use std::sync::Arc;
7
8#[cfg(feature = "audio")]
9use quad_snd::{AudioContext as QuadSndContext, Sound as QuadSndSound};
10
11#[cfg(feature = "audio")]
12pub use quad_snd::PlaySoundParams;
13
14#[cfg(not(feature = "audio"))]
15mod dummy_audio {
16 use crate::audio::PlaySoundParams;
17
18 pub struct AudioContext {}
19
20 impl AudioContext {
21 pub fn new() -> AudioContext {
22 AudioContext {}
23 }
24
25 #[cfg(target_os = "android")]
26 pub fn pause(&mut self) {}
27
28 #[cfg(target_os = "android")]
29 pub fn resume(&mut self) {}
30 }
31
32 pub struct Sound {}
33
34 impl Sound {
35 pub fn load(_ctx: &mut AudioContext, _data: &[u8]) -> Sound {
36 Sound {}
37 }
38
39 pub fn play(&self, _ctx: &mut AudioContext, _params: PlaySoundParams) {
40 eprintln!("warn: macroquad's \"audio\" feature disabled.");
41 }
42
43 pub fn stop(&self, _ctx: &mut AudioContext) {}
44
45 pub fn set_volume(&self, _ctx: &mut AudioContext, _volume: f32) {}
46
47 #[allow(dead_code)]
48 pub fn is_loaded(&self) -> bool {
49 true
50 }
51
52 pub fn delete(&self, _ctx: &AudioContext) {}
53 }
54}
55
56#[cfg(not(feature = "audio"))]
57use dummy_audio::{AudioContext as QuadSndContext, Sound as QuadSndSound};
58
59#[cfg(not(feature = "audio"))]
60pub struct PlaySoundParams {
61 pub looped: bool,
62 pub volume: f32,
63}
64
65pub struct AudioContext {
66 native_ctx: QuadSndContext,
67}
68
69impl AudioContext {
70 pub fn new() -> AudioContext {
71 AudioContext {
72 native_ctx: QuadSndContext::new(),
73 }
74 }
75
76 #[cfg(target_os = "android")]
77 pub fn pause(&mut self) {
78 self.native_ctx.pause()
79 }
80
81 #[cfg(target_os = "android")]
82 pub fn resume(&mut self) {
83 self.native_ctx.resume()
84 }
85}
86
87struct QuadSndSoundGuarded(QuadSndSound);
88
89impl Drop for QuadSndSoundGuarded {
90 fn drop(&mut self) {
91 let ctx = &get_context().audio_context;
92 self.0.delete(&ctx.native_ctx);
93 }
94}
95
96#[derive(Clone)]
97pub struct Sound(Arc<QuadSndSoundGuarded>);
98
99impl std::fmt::Debug for Sound {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 f.debug_struct("Sound").finish()
102 }
103}
104
105pub async fn load_sound(path: &str) -> Result<Sound, Error> {
110 let data = load_file(path).await?;
111
112 load_sound_from_bytes(&data).await
113}
114
115pub async fn load_sound_from_bytes(data: &[u8]) -> Result<Sound, Error> {
119 let sound = {
120 let ctx = &mut get_context().audio_context;
121 QuadSndSound::load(&mut ctx.native_ctx, data)
122 };
123
124 #[cfg(target_arch = "wasm32")]
126 while sound.is_loaded() == false {
127 crate::window::next_frame().await;
128 }
129
130 Ok(Sound(Arc::new(QuadSndSoundGuarded(sound))))
131}
132
133pub fn play_sound_once(sound: &Sound) {
134 let ctx = &mut get_context().audio_context;
135
136 sound.0 .0.play(
137 &mut ctx.native_ctx,
138 PlaySoundParams {
139 looped: false,
140 volume: 1.0,
141 },
142 );
143}
144
145pub fn play_sound(sound: &Sound, params: PlaySoundParams) {
146 let ctx = &mut get_context().audio_context;
147 sound.0 .0.play(&mut ctx.native_ctx, params);
148}
149
150pub fn stop_sound(sound: &Sound) {
151 let ctx = &mut get_context().audio_context;
152 sound.0 .0.stop(&mut ctx.native_ctx);
153}
154
155pub fn set_sound_volume(sound: &Sound, volume: f32) {
156 let ctx = &mut get_context().audio_context;
157 sound.0 .0.set_volume(&mut ctx.native_ctx, volume);
158}