sfml/audio/
sound_stream.rs1use {
2 crate::{
3 audio::{SoundSource, SoundStatus},
4 ffi::audio::*,
5 system::{Time, Vector3f},
6 },
7 std::{marker::PhantomData, os::raw::c_void, panic, ptr::NonNull},
8};
9
10pub trait SoundStream: Send {
15 fn get_data(&mut self) -> (&[i16], bool);
20 fn seek(&mut self, offset: Time);
22 fn channel_count(&self) -> u32;
24 fn sample_rate(&self) -> u32;
26}
27
28#[derive(Debug)]
30pub struct SoundStreamPlayer<'a, S: SoundStream + 'a> {
31 handle: NonNull<sfCustomSoundStream>,
32 stream: *mut S,
37 _borrow: PhantomData<&'a mut S>,
38}
39
40unsafe extern "C" fn get_data_callback<S: SoundStream>(
41 chunk: *mut crate::ffi::audio::sfSoundStreamChunk,
42 user_data: *mut c_void,
43) -> bool {
44 let stream: *mut S = user_data.cast();
45 unsafe {
46 let (data, keep_playing) =
47 match panic::catch_unwind(panic::AssertUnwindSafe(|| (*stream).get_data())) {
48 Ok(ret) => ret,
49 Err(_) => {
50 eprintln!("sound_stream: Stopping playback beacuse `get_data` panicked.");
51 (&[][..], false)
52 }
53 };
54 (*chunk).samples = data.as_ptr();
55 (*chunk).sample_count = data.len();
56 keep_playing
57 }
58}
59
60unsafe extern "C" fn seek_callback<S: SoundStream>(
61 offset: crate::ffi::system::sfTime,
62 user_data: *mut c_void,
63) {
64 let stream: *mut S = user_data.cast();
65 let result = unsafe {
66 panic::catch_unwind(panic::AssertUnwindSafe(|| {
67 (*stream).seek(Time::from_raw(offset))
68 }))
69 };
70 if result.is_err() {
71 eprintln!("sound_stream: Failed to seek because `seek` panicked.");
72 }
73}
74
75impl<'a, S: SoundStream> SoundStreamPlayer<'a, S> {
76 pub fn new(sound_stream: &'a mut S) -> Self {
82 let channel_count = sound_stream.channel_count();
83 let sample_rate = sound_stream.sample_rate();
84 let sound_stream: *mut S = sound_stream;
85 Self {
86 handle: unsafe {
87 NonNull::new(sfCustomSoundStream_new(
88 Some(get_data_callback::<S>),
89 Some(seek_callback::<S>),
90 channel_count,
91 sample_rate,
92 sound_stream.cast(),
93 ))
94 .expect("Failed to create SoundStreamPlayer")
95 },
96 stream: sound_stream,
97 _borrow: PhantomData,
98 }
99 }
100 pub fn play(&mut self) {
102 unsafe {
103 sfCustomSoundStream_play(self.handle.as_ptr());
104 }
105 }
106 pub fn pause(&mut self) {
111 unsafe {
112 sfCustomSoundStream_pause(self.handle.as_ptr());
113 }
114 }
115 #[must_use]
117 pub fn status(&self) -> SoundStatus {
118 unsafe { SoundStatus(sfCustomSoundStream_getStatus(self.handle.as_ptr())) }
119 }
120 pub fn stop(&mut self) -> &mut S {
129 unsafe {
130 sfCustomSoundStream_stop(self.handle.as_ptr());
131 &mut *self.stream
132 }
133 }
134 #[must_use]
136 pub fn playing_offset(&self) -> Time {
137 unsafe { Time::from_raw(sfCustomSoundStream_getPlayingOffset(self.handle.as_ptr())) }
138 }
139 pub fn set_playing_offset(&mut self, offset: Time) {
145 unsafe { sfCustomSoundStream_setPlayingOffset(self.handle.as_ptr(), offset.raw()) }
146 }
147 #[must_use]
151 pub fn channel_count(&self) -> u32 {
152 unsafe { sfCustomSoundStream_getChannelCount(self.handle.as_ptr()) }
153 }
154 #[must_use]
159 pub fn sample_rate(&self) -> u32 {
160 unsafe { sfCustomSoundStream_getSampleRate(self.handle.as_ptr()) }
161 }
162 #[must_use]
164 pub fn is_looping(&self) -> bool {
165 unsafe { sfCustomSoundStream_getLoop(self.handle.as_ptr()) }
166 }
167 pub fn set_looping(&mut self, looping: bool) {
173 unsafe { sfCustomSoundStream_setLoop(self.handle.as_ptr(), looping) }
174 }
175}
176
177impl<S: SoundStream> SoundSource for SoundStreamPlayer<'_, S> {
178 fn set_pitch(&mut self, pitch: f32) {
179 unsafe { sfCustomSoundStream_setPitch(self.handle.as_ptr(), pitch) }
180 }
181 fn set_volume(&mut self, volume: f32) {
182 unsafe { sfCustomSoundStream_setVolume(self.handle.as_ptr(), volume) }
183 }
184 fn set_position<P: Into<Vector3f>>(&mut self, position: P) {
185 unsafe { sfCustomSoundStream_setPosition(self.handle.as_ptr(), position.into()) }
186 }
187 fn set_relative_to_listener(&mut self, relative: bool) {
188 unsafe { sfCustomSoundStream_setRelativeToListener(self.handle.as_ptr(), relative) }
189 }
190 fn set_min_distance(&mut self, distance: f32) {
191 unsafe { sfCustomSoundStream_setMinDistance(self.handle.as_ptr(), distance) }
192 }
193 fn set_attenuation(&mut self, attenuation: f32) {
194 unsafe { sfCustomSoundStream_setAttenuation(self.handle.as_ptr(), attenuation) }
195 }
196 fn pitch(&self) -> f32 {
197 unsafe { sfCustomSoundStream_getPitch(self.handle.as_ptr()) }
198 }
199 fn volume(&self) -> f32 {
200 unsafe { sfCustomSoundStream_getVolume(self.handle.as_ptr()) }
201 }
202 fn position(&self) -> Vector3f {
203 unsafe { sfCustomSoundStream_getPosition(self.handle.as_ptr()) }
204 }
205 fn is_relative_to_listener(&self) -> bool {
206 unsafe { sfCustomSoundStream_isRelativeToListener(self.handle.as_ptr()) }
207 }
208 fn min_distance(&self) -> f32 {
209 unsafe { sfCustomSoundStream_getMinDistance(self.handle.as_ptr()) }
210 }
211 fn attenuation(&self) -> f32 {
212 unsafe { sfCustomSoundStream_getAttenuation(self.handle.as_ptr()) }
213 }
214}
215
216impl<S: SoundStream> Drop for SoundStreamPlayer<'_, S> {
217 fn drop(&mut self) {
218 unsafe {
219 sfCustomSoundStream_stop(self.handle.as_ptr());
222 sfCustomSoundStream_del(self.handle.as_ptr());
223 }
224 }
225}