Skip to main content

listener/
listener.rs

1use rg3d_core::algebra::Point3;
2use rg3d_sound::{
3    algebra::{UnitQuaternion, Vector3},
4    buffer::{DataSource, SoundBufferResource},
5    context::SoundContext,
6    engine::SoundEngine,
7    futures::executor::block_on,
8    source::{generic::GenericSourceBuilder, spatial::SpatialSourceBuilder, Status},
9};
10use std::{
11    thread,
12    time::{self, Duration},
13};
14
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}