#[repr(transparent)]pub struct SoundBufferResource(pub Resource<SoundBufferState, SoundBufferResourceLoadError>);Expand description
A shared sound buffer resource.
Tuple Fields§
§0: Resource<SoundBufferState, SoundBufferResourceLoadError>Implementations§
Source§impl SoundBufferResource
impl SoundBufferResource
Sourcepub fn new_streaming(data_source: DataSource) -> Result<Self, DataSource>
pub fn new_streaming(data_source: DataSource) -> Result<Self, DataSource>
Tries to create new streaming sound buffer from a given data source. Returns sound source wrapped into Arc<Mutex<>> that can be directly used with sound sources.
Examples found in repository?
53fn main() {
54 // Initialize sound engine with default output device.
55 let engine = SoundEngine::new();
56
57 // Initialize new sound context.
58 let context = SoundContext::new();
59
60 engine.lock().unwrap().add_context(context.clone());
61
62 // Create sine wave generator
63 let sine_wave = DataSource::RawStreaming(Box::new(SamplesGenerator::new()));
64
65 let sine_wave_buffer = SoundBufferResource::new_streaming(sine_wave).unwrap();
66
67 // Create generic source (without spatial effects) using that buffer.
68 let source = GenericSourceBuilder::new()
69 .with_buffer(sine_wave_buffer)
70 .with_status(Status::Playing)
71 .build_source()
72 .unwrap();
73
74 context.state().add_source(source);
75
76 // Play sound for some time.
77 thread::sleep(Duration::from_secs(10));
78}More examples
11fn main() {
12 // Initialize sound engine with default output device.
13 let engine = SoundEngine::new();
14
15 // Initialize new sound context.
16 let context = SoundContext::new();
17
18 engine.lock().unwrap().add_context(context.clone());
19
20 // Load sound buffer.
21 let waterfall_buffer = SoundBufferResource::new_streaming(
22 block_on(DataSource::from_file("examples/data/waterfall.ogg")).unwrap(),
23 )
24 .unwrap();
25
26 // Create flat source (without spatial effects) using that buffer.
27 let source = GenericSourceBuilder::new()
28 .with_buffer(waterfall_buffer)
29 .with_status(Status::Playing)
30 .with_looping(true)
31 .build_source()
32 .unwrap();
33
34 // Each sound sound must be added to context, context takes ownership on source
35 // and returns pool handle to it by which it can be accessed later on if needed.
36 let _source_handle: Handle<SoundSource> = context.state().add_source(source);
37
38 thread::sleep(Duration::from_secs(30))
39}Sourcepub fn new_generic(data_source: DataSource) -> Result<Self, DataSource>
pub fn new_generic(data_source: DataSource) -> Result<Self, DataSource>
Tries to create new generic sound buffer from a given data source. Returns sound source wrapped into Arc<Mutex<>> that can be directly used with sound sources.
Examples found in repository?
10fn main() {
11 // Initialize sound engine with default output device.
12 let engine = SoundEngine::new();
13
14 // Create new context.
15 let context = SoundContext::new();
16
17 // Register context in the engine.
18 engine.lock().unwrap().add_context(context.clone());
19
20 // Load sound buffer.
21 let door_open_buffer = SoundBufferResource::new_generic(
22 rg3d_sound::futures::executor::block_on(DataSource::from_file(
23 "examples/data/door_open.wav",
24 ))
25 .unwrap(),
26 )
27 .unwrap();
28
29 // Create generic source (without spatial effects) using that buffer.
30 let source = GenericSourceBuilder::new()
31 .with_buffer(door_open_buffer)
32 .with_status(Status::Playing)
33 .build_source()
34 .unwrap();
35
36 // Each sound sound must be added to context, context takes ownership on source
37 // and returns pool handle to it by which it can be accessed later on if needed.
38 let _source_handle: Handle<SoundSource> = context.state().add_source(source);
39
40 // Wait until sound will play completely.
41 thread::sleep(Duration::from_secs(3));
42}More examples
9fn main() {
10 // Initialize sound engine with default output device.
11 let engine = SoundEngine::new();
12
13 // Initialize new sound context.
14 let context = SoundContext::new();
15
16 engine.lock().unwrap().add_context(context.clone());
17
18 // Create sine wave.
19 let sample_rate = 44100;
20 let sine_wave = DataSource::Raw {
21 sample_rate,
22 channel_count: 1,
23 samples: {
24 let frequency = 440.0;
25 let amplitude = 0.75;
26 (0..44100)
27 .map(|i| {
28 amplitude
29 * ((2.0 * std::f32::consts::PI * i as f32 * frequency) / sample_rate as f32)
30 .sin()
31 })
32 .collect()
33 },
34 };
35
36 let sine_wave_buffer = SoundBufferResource::new_generic(sine_wave).unwrap();
37
38 // Create generic source (without spatial effects) using that buffer.
39 let source = GenericSourceBuilder::new()
40 .with_buffer(sine_wave_buffer)
41 .with_status(Status::Playing)
42 .with_looping(true)
43 .build_source()
44 .unwrap();
45
46 context.state().add_source(source);
47
48 // Play sound for some time.
49 thread::sleep(Duration::from_secs(10));
50}15fn main() {
16 // Initialize sound engine with default output device.
17 let engine = SoundEngine::new();
18
19 // Initialize new sound context.
20 let context = SoundContext::new();
21
22 engine.lock().unwrap().add_context(context.clone());
23
24 // Load sound buffer.
25 let drop_buffer = SoundBufferResource::new_generic(
26 block_on(DataSource::from_file("examples/data/drop.wav")).unwrap(),
27 )
28 .unwrap();
29
30 // Create spatial source - spatial sources can be positioned in space.
31 let source = SpatialSourceBuilder::new(
32 GenericSourceBuilder::new()
33 .with_buffer(drop_buffer)
34 .with_looping(true)
35 .with_status(Status::Playing)
36 .build()
37 .unwrap(),
38 )
39 .build_source();
40
41 // Each sound sound must be added to context, context takes ownership on source
42 // and returns pool handle to it by which it can be accessed later on if needed.
43 let source_handle: Handle<SoundSource> = context.state().add_source(source);
44
45 // Move sound around listener for some time.
46 let start_time = time::Instant::now();
47 let mut angle = 0.0f32;
48 while (time::Instant::now() - start_time).as_secs() < 11 {
49 if let SoundSource::Spatial(spatial) = context.state().source_mut(source_handle) {
50 let axis = Vector3::y_axis();
51 let rotation_matrix =
52 UnitQuaternion::from_axis_angle(&axis, angle.to_radians()).to_homogeneous();
53 spatial.set_position(
54 rotation_matrix
55 .transform_point(&Point3::new(0.0, 0.0, 3.0))
56 .coords,
57 );
58 }
59 angle += 3.6;
60
61 // Limit rate of updates.
62 thread::sleep(Duration::from_millis(100));
63 }
64}9fn main() {
10 // Initialize sound engine without output device.
11 let engine = SoundEngine::without_device();
12
13 // Create new context.
14 let context = SoundContext::new();
15
16 // Register context in the engine.
17 engine.lock().unwrap().add_context(context.clone());
18
19 // Load sound buffer.
20 let door_open_buffer = SoundBufferResource::new_generic(
21 rg3d_sound::futures::executor::block_on(DataSource::from_file(
22 "examples/data/door_open.wav",
23 ))
24 .unwrap(),
25 )
26 .unwrap();
27
28 // Create generic source (without spatial effects) using that buffer.
29 let source = GenericSourceBuilder::new()
30 .with_buffer(door_open_buffer)
31 .with_status(Status::Playing)
32 .build_source()
33 .unwrap();
34
35 // Each sound sound must be added to context, context takes ownership on source
36 // and returns pool handle to it by which it can be accessed later on if needed.
37 let _source_handle: Handle<SoundSource> = context.state().add_source(source);
38
39 // Create output wav file. The sample rate is currently fixed.
40 let wav_spec = hound::WavSpec {
41 channels: 2,
42 sample_rate: rg3d_sound::context::SAMPLE_RATE,
43 bits_per_sample: 32,
44 sample_format: hound::SampleFormat::Float,
45 };
46 let mut wav_writer = hound::WavWriter::create("output.wav", wav_spec).unwrap();
47
48 // Create an output buffer.
49 let buf_len = SoundEngine::render_buffer_len();
50 let mut buf = vec![(0.0f32, 0.0f32); buf_len];
51 let mut samples_written = 0;
52
53 // Wait until sound will play completely.
54 while samples_written < 3 * rg3d_sound::context::SAMPLE_RATE {
55 engine.lock().unwrap().render(&mut buf);
56 for &(l, r) in buf.iter() {
57 wav_writer.write_sample(l).unwrap();
58 wav_writer.write_sample(r).unwrap();
59 }
60 samples_written += buf_len as u32;
61 }
62
63 wav_writer.finalize().unwrap();
64}15fn main() {
16 // Initialize sound engine with default output device.
17 let engine = SoundEngine::new();
18
19 // Initialize new sound context.
20 let context = SoundContext::new();
21
22 engine.lock().unwrap().add_context(context.clone());
23
24 // Load sound buffer.
25 let drop_buffer = SoundBufferResource::new_generic(
26 block_on(DataSource::from_file("examples/data/drop.wav")).unwrap(),
27 )
28 .unwrap();
29
30 // Create spatial source - spatial sources can be positioned in space.
31 let source = SpatialSourceBuilder::new(
32 GenericSourceBuilder::new()
33 .with_buffer(drop_buffer)
34 .with_looping(true)
35 .with_status(Status::Playing)
36 .build()
37 .unwrap(),
38 )
39 .build_source();
40
41 // Each sound sound must be added to context, context takes ownership on source
42 // and returns pool handle to it by which it can be accessed later on if needed.
43 context.state().add_source(source);
44
45 // Rotate listener for some time.
46 let start_time = time::Instant::now();
47 let mut angle = 0.0f32;
48 while (time::Instant::now() - start_time).as_secs() < 20 {
49 // Separate scope for update to make sure that mutex lock will be released before
50 // thread::sleep will be called so context can actually work in background thread.
51 {
52 let mut context = context.state();
53
54 let listener = context.listener_mut();
55
56 // Define up-axis of listener.
57 let up = Vector3::y_axis();
58
59 // And rotate look axis.
60 let rotation_matrix =
61 UnitQuaternion::from_axis_angle(&up, angle.to_radians()).to_homogeneous();
62 let look = rotation_matrix
63 .transform_point(&Point3::new(0.0, 0.0, 1.0))
64 .coords;
65
66 // Finally combine axes. _lh suffix here means that we using left-handed coordinate system.
67 // there is also _rh (right handed) version. Also basis can be set directly by using `set_basis`
68 listener.set_orientation_lh(look, *up);
69
70 // Move listener a bit back from sound source.
71 listener.set_position(Vector3::new(0.0, 0.0, -2.0));
72
73 // Continue rotation.
74 angle += 2.0;
75 }
76
77 // Limit rate of updates.
78 thread::sleep(Duration::from_millis(100));
79 }
80}17fn main() {
18 // Initialize sound engine with default output device.
19 let engine = SoundEngine::new();
20
21 let hrir_sphere =
22 HrirSphere::from_file("examples/data/IRC_1002_C.bin", context::SAMPLE_RATE).unwrap();
23
24 // Initialize new sound context with default output device.
25 let context = SoundContext::new();
26
27 engine.lock().unwrap().add_context(context.clone());
28
29 // Set HRTF renderer instead of default.
30 context
31 .state()
32 .set_renderer(Renderer::HrtfRenderer(HrtfRenderer::new(hrir_sphere)));
33
34 // Create some sounds.
35 let sound_buffer = SoundBufferResource::new_generic(
36 block_on(DataSource::from_file("examples/data/door_open.wav")).unwrap(),
37 )
38 .unwrap();
39 let source = SpatialSourceBuilder::new(
40 GenericSourceBuilder::new()
41 .with_buffer(sound_buffer)
42 .with_status(Status::Playing)
43 .build()
44 .unwrap(),
45 )
46 .build_source();
47 context.state().add_source(source);
48
49 let sound_buffer = SoundBufferResource::new_generic(
50 block_on(DataSource::from_file("examples/data/helicopter.wav")).unwrap(),
51 )
52 .unwrap();
53 let source = SpatialSourceBuilder::new(
54 GenericSourceBuilder::new()
55 .with_buffer(sound_buffer)
56 .with_status(Status::Playing)
57 .with_looping(true)
58 .build()
59 .unwrap(),
60 )
61 .build_source();
62 let source_handle = context.state().add_source(source);
63
64 // Move source sound around listener for some time.
65 let start_time = time::Instant::now();
66 let mut angle = 0.0f32;
67 while (time::Instant::now() - start_time).as_secs() < 360 {
68 // Separate scope for update to make sure that mutex lock will be released before
69 // thread::sleep will be called so context can actually work in background thread.
70 {
71 if let SoundSource::Spatial(spatial) = context.state().source_mut(source_handle) {
72 let axis = Vector3::y_axis();
73 let rotation_matrix =
74 UnitQuaternion::from_axis_angle(&axis, angle.to_radians()).to_homogeneous();
75 spatial.set_position(
76 rotation_matrix
77 .transform_point(&Point3::new(0.0, 0.0, 3.0))
78 .coords,
79 );
80 }
81
82 angle += 1.6;
83
84 println!(
85 "Sound render time {:?}",
86 context.state().full_render_duration()
87 );
88 }
89
90 // Limit rate of updates.
91 thread::sleep(Duration::from_millis(100));
92 }
93}Methods from Deref<Target = Resource<SoundBufferState, SoundBufferResourceLoadError>>§
Sourcepub fn state(&self) -> MutexGuard<'_, RawMutex, ResourceState<T, E>>
pub fn state(&self) -> MutexGuard<'_, RawMutex, ResourceState<T, E>>
Locks internal mutex provides access to the state.
Sourcepub fn try_acquire_state(
&self,
) -> Option<MutexGuard<'_, RawMutex, ResourceState<T, E>>>
pub fn try_acquire_state( &self, ) -> Option<MutexGuard<'_, RawMutex, ResourceState<T, E>>>
Tries to lock internal mutex provides access to the state.
Sourcepub fn data_ref(&self) -> ResourceDataRef<'_, T, E>
pub fn data_ref(&self) -> ResourceDataRef<'_, T, E>
Allows you to obtain reference to the resource data.
§Panic
An attempt to use method result will panic if resource is not loaded yet, or
there was load error. Usually this is ok because normally you’d chain this call
like this resource.await?.data_ref(). Every resource implements Future trait
and it returns Result, so if you’ll await future then you’ll get Result, so
call to data_ref will be fine.
Trait Implementations§
Source§impl Clone for SoundBufferResource
impl Clone for SoundBufferResource
Source§impl Debug for SoundBufferResource
impl Debug for SoundBufferResource
Source§impl Default for SoundBufferResource
impl Default for SoundBufferResource
Source§impl Deref for SoundBufferResource
impl Deref for SoundBufferResource
Source§type Target = Resource<SoundBufferState, SoundBufferResourceLoadError>
type Target = Resource<SoundBufferState, SoundBufferResourceLoadError>
Source§impl DerefMut for SoundBufferResource
impl DerefMut for SoundBufferResource
Source§impl Future for SoundBufferResource
impl Future for SoundBufferResource
Source§type Output = Result<SoundBufferResource, Option<Arc<SoundBufferResourceLoadError>>>
type Output = Result<SoundBufferResource, Option<Arc<SoundBufferResourceLoadError>>>
Source§impl PartialEq for SoundBufferResource
impl PartialEq for SoundBufferResource
Source§fn eq(&self, other: &SoundBufferResource) -> bool
fn eq(&self, other: &SoundBufferResource) -> bool
self and other values to be equal, and is used by ==.Source§impl Visit for SoundBufferResource
impl Visit for SoundBufferResource
impl StructuralPartialEq for SoundBufferResource
Auto Trait Implementations§
impl Freeze for SoundBufferResource
impl !RefUnwindSafe for SoundBufferResource
impl Send for SoundBufferResource
impl Sync for SoundBufferResource
impl Unpin for SoundBufferResource
impl UnsafeUnpin for SoundBufferResource
impl !UnwindSafe for SoundBufferResource
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn map<U, F>(self, f: F) -> Map<Self, F>
fn map<U, F>(self, f: F) -> Map<Self, F>
Source§fn map_into<U>(self) -> MapInto<Self, U>
fn map_into<U>(self) -> MapInto<Self, U>
Source§fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
f. Read moreSource§fn left_future<B>(self) -> Either<Self, B>
fn left_future<B>(self) -> Either<Self, B>
Source§fn right_future<A>(self) -> Either<A, Self>
fn right_future<A>(self) -> Either<A, Self>
Source§fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
fn into_stream(self) -> IntoStream<Self>where
Self: Sized,
Source§fn flatten(self) -> Flatten<Self>
fn flatten(self) -> Flatten<Self>
Source§fn flatten_stream(self) -> FlattenStream<Self>
fn flatten_stream(self) -> FlattenStream<Self>
Source§fn fuse(self) -> Fuse<Self>where
Self: Sized,
fn fuse(self) -> Fuse<Self>where
Self: Sized,
poll will never again be called once it has
completed. This method can be used to turn any Future into a
FusedFuture. Read moreSource§fn inspect<F>(self, f: F) -> Inspect<Self, F>
fn inspect<F>(self, f: F) -> Inspect<Self, F>
Source§fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
fn catch_unwind(self) -> CatchUnwind<Self>where
Self: Sized + UnwindSafe,
Source§fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)where
Self: Sized,
fn remote_handle(self) -> (Remote<Self>, RemoteHandle<Self::Output>)where
Self: Sized,
() on completion and sends
its output to another future on a separate task. Read moreSource§fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
Source§fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>where
Self: Sized + 'a,
fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>where
Self: Sized + 'a,
Source§fn unit_error(self) -> UnitError<Self>where
Self: Sized,
fn unit_error(self) -> UnitError<Self>where
Self: Sized,
Future<Output = T> into a
TryFuture<Ok = T, Error = ()>.Source§fn never_error(self) -> NeverError<Self>where
Self: Sized,
fn never_error(self) -> NeverError<Self>where
Self: Sized,
Future<Output = T> into a
TryFuture<Ok = T, Error = Never>.Source§impl<F> IntoFuture for Fwhere
F: Future,
impl<F> IntoFuture for Fwhere
F: Future,
Source§type IntoFuture = F
type IntoFuture = F
Source§fn into_future(self) -> <F as IntoFuture>::IntoFuture
fn into_future(self) -> <F as IntoFuture>::IntoFuture
Source§impl<T> PropertyValue for Twhere
T: Debug + 'static,
impl<T> PropertyValue for Twhere
T: Debug + 'static,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.