Skip to main content

audio_clip_instance_demo/
audio-clip-instance-demo.rs

1// audio-clip-instance-demo
2//
3// Cloned from `audio-music-demo`. Same scene, but demonstrates
4// `.instance()` on a live AudioClip handle: two extra voices share the
5// AmenBreak decoded buffer, each starting at a different point in the
6// sample (0.25 / 0.5 beats in). The keyframes target those clone
7// handles directly instead of routing through MusicContext voice names.
8//
9// See docs/draft/audio-clip-instance-cloning.md.
10
11use mittens_engine::{engine, engine::ecs::SignalEmitter, scripting, utils};
12
13fn main() {
14    mittens_engine::example_support::ensure_model_assets();
15    utils::logger::init();
16
17    println!("[audio-clip-instance-demo] start");
18
19    let world = engine::ecs::World::default();
20    let mut universe = engine::Universe::new(world);
21
22    // Minimal camera so the window opens.
23    let input = universe
24        .world
25        .add_component(engine::ecs::component::InputComponent::new().with_speed(2.0));
26    let rig = universe.world.add_component(
27        engine::ecs::component::TransformComponent::new().with_position(0.0, 0.0, 3.0),
28    );
29    let input_mode = universe.world.add_component(
30        engine::ecs::component::InputTransformModeComponent::forward_z().with_roll_axis_y(),
31    );
32    let cam = universe
33        .world
34        .add_component(engine::ecs::component::Camera3DComponent::new().with_fov(60.0));
35    let _ = universe.attach(input, input_mode);
36    let _ = universe.attach(input, rig);
37    let _ = universe.attach(rig, cam);
38    universe.add(input);
39
40    let clear = universe
41        .world
42        .add_component(engine::ecs::component::BackgroundColorComponent::new());
43    let clear_c = universe
44        .world
45        .add_component(engine::ecs::component::ColorComponent::rgba(
46            0.06, 0.07, 0.10, 1.0,
47        ));
48    let _ = universe.world.add_child(clear, clear_c);
49    universe.add(clear);
50
51    let source = include_str!("audio-clip-instance-demo.mms");
52    let output = scripting::MeowMeowRunner::eval_with_world_at_path(
53        source,
54        Some("examples/audio-clip-instance-demo.mms"),
55        &mut universe.world,
56        &mut universe.systems.rx,
57        &mut universe.command_queue,
58    );
59
60    for error in &output.errors {
61        eprintln!("[mms] {error}");
62    }
63    println!(
64        "[audio-clip-instance-demo] mms ok: {} intent(s)",
65        output.intents.len()
66    );
67
68    for intent in output.intents {
69        universe
70            .command_queue
71            .push_intent_now(engine::ecs::ComponentId::default(), intent);
72    }
73
74    universe.systems.process_commands(
75        &mut universe.world,
76        &mut universe.visuals,
77        &mut universe.render_assets,
78        &mut universe.command_queue,
79    );
80
81    universe.enable_repl();
82    engine::Windowing::run_app(universe).expect("Windowing failed");
83}