pub struct Synth { /* private fields */ }Expand description
Builds a sound from waves and envelopes. Pass it to
Audio::register or
Ui::set_sound_data, or call Synth::build.
Settings like volume and decay apply to the part they are called on; parts added
with Synth::then and Synth::with keep their own settings.
use audio_code::audio::Synth;
// A short, soft click.
let click = Synth::sine(1500.0).length(0.03).decay(120.0).volume(0.4).build();
// A rising "pling" made of two notes.
let pling = Synth::triangle(660.0).length(0.06)
.then(Synth::triangle(990.0).length(0.12).decay(25.0))
.build();
// A noisy thump: noise layered with a low sine sweep.
let thump = Synth::sine(150.0).sweep_to(50.0).length(0.15).decay(30.0)
.with(Synth::noise().length(0.05).decay(80.0).volume(0.3))
.build();Implementations§
Source§impl Synth
impl Synth
Sourcepub fn new(wave: Wave, frequency: f32) -> Self
pub fn new(wave: Wave, frequency: f32) -> Self
A synth with the given wave and frequency, 0.1 seconds long.
Sourcepub fn sine(frequency: f32) -> Self
pub fn sine(frequency: f32) -> Self
Sine wave.
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn square(frequency: f32) -> Self
pub fn square(frequency: f32) -> Self
Square wave.
Examples found in repository?
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }More examples
19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn triangle(frequency: f32) -> Self
pub fn triangle(frequency: f32) -> Self
Triangle wave.
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn saw(frequency: f32) -> Self
pub fn saw(frequency: f32) -> Self
Sawtooth wave.
Examples found in repository?
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}More examples
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn noise() -> Self
pub fn noise() -> Self
White noise.
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn silence(seconds: f32) -> Self
pub fn silence(seconds: f32) -> Self
Silence, useful as a pause between parts: a.then(Synth::silence(0.1)).then(b).
Examples found in repository?
32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }More examples
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn length(self, seconds: f32) -> Self
pub fn length(self, seconds: f32) -> Self
Length in seconds.
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn sweep_to(self, frequency: f32) -> Self
pub fn sweep_to(self, frequency: f32) -> Self
Glide the frequency linearly to frequency (in hertz) over the whole length.
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn attack(self, seconds: f32) -> Self
pub fn attack(self, seconds: f32) -> Self
Fade-in time in seconds (default 2 ms).
Examples found in repository?
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }Sourcepub fn decay(self, rate: f32) -> Self
pub fn decay(self, rate: f32) -> Self
Exponential fade out speed: the volume is multiplied by e^(-rate * seconds).
0 = none (default), 10 rings for about 0.7 s, 30 is a pluck (0.2 s), 120 a click
(60 ms), 300 a tick (20 ms).
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn release(self, seconds: f32) -> Self
pub fn release(self, seconds: f32) -> Self
Linear fade-out at the end in seconds (default 5 ms, prevents clicks).
Examples found in repository?
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }Sourcepub fn volume(self, volume: f32) -> Self
pub fn volume(self, volume: f32) -> Self
Linear loudness, 0.0 (silent) to 1.0 (full scale), default 0.5.
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn with(self, other: Synth) -> Self
pub fn with(self, other: Synth) -> Self
Plays other at the same time (mixed in).
Examples found in repository?
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}More examples
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn then(self, other: Synth) -> Self
pub fn then(self, other: Synth) -> Self
Plays other after this one.
Examples found in repository?
36 fn start(&mut self, ctx: &mut Context) {
37 // Own interface sounds, designed in code. Files work too:
38 // ctx.ui.set_sound(UiSound::Navigate, Some("ui/click"));
39 ctx.ui.set_sound_data(UiSound::Navigate, Synth::triangle(1800.0).length(0.025).decay(150.0).volume(0.4));
40 ctx.ui.set_sound_data(UiSound::Wrap, Synth::triangle(1800.0).sweep_to(2600.0).length(0.06).decay(60.0).volume(0.4));
41 ctx.ui.set_sound_data(UiSound::Typing, Synth::noise().length(0.012).decay(300.0).volume(0.25));
42 ctx.ui.set_sound_data(
43 UiSound::Activate,
44 Synth::sine(880.0).length(0.04).volume(0.35).then(Synth::sine(1320.0).length(0.08).decay(40.0).volume(0.35)),
45 );
46 ctx.insert(Settings { volume: 0.8, difficulty: 1, name: "Player".into() });
47 ctx.ui.open(main_menu());
48 }More examples
22fn main() -> audio_code::Result<()> {
23 Engine::new("Bell Catcher").run_with(|ctx| {
24 ctx.audio.register("bell", Synth::sine(1568.0).with(Synth::sine(3136.0).volume(0.3)).length(0.35).decay(9.0).volume(0.6));
25 ctx.audio.register("step", Synth::noise().length(0.05).decay(80.0).volume(0.5));
26 ctx.audio.register("edge", Synth::sine(110.0).length(0.12).decay(30.0).volume(0.8));
27 ctx.audio.register(
28 "catch",
29 Synth::sine(784.0).length(0.08).then(Synth::sine(1047.0).length(0.08)).then(Synth::sine(1568.0).length(0.2).decay(12.0)).volume(0.4),
30 );
31 ctx.audio.register("miss", Synth::saw(220.0).sweep_to(80.0).length(0.5).decay(5.0).volume(0.35));
32
33 // Restore the speech settings from the last session.
34 if let Some(voice) = ctx.storage.get::<String>("voice") {
35 ctx.speech.set_voice(voice);
36 }
37 let rate: f32 = ctx.storage.get_or("rate", 50.0);
38 if rate != 50.0 {
39 ctx.speech.set_rate(rate / 100.0);
40 }
41 Title
42 })
43}32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Trait Implementations§
Auto Trait Implementations§
impl Freeze for Synth
impl RefUnwindSafe for Synth
impl Send for Synth
impl Sync for Synth
impl Unpin for Synth
impl UnsafeUnpin for Synth
impl UnwindSafe for Synth
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.