oxframe_core/sound.rs
1//! A sound effect scheduled while a scene runs.
2//!
3//! The scene records *when* the clip starts. Decoding and mixing happen
4//! later, so this module stays free of audio codecs and works in the browser.
5
6use crate::runtime;
7
8/// One sound effect placed on the scene timeline.
9#[derive(Debug, Clone, PartialEq)]
10pub struct SoundClip {
11 /// Audio file, relative to the project root.
12 pub file: String,
13 /// Start, in seconds from the beginning of the scene.
14 pub at: f64,
15 /// Linear gain. `1.0` is unity.
16 pub volume: f32,
17 /// Fade in at the start of the clip, in seconds.
18 pub fade_in: f64,
19 /// Fade out at the end of the clip, in seconds.
20 pub fade_out: f64,
21 /// Seconds skipped from the start of the file.
22 pub trim_start: f64,
23 /// End point in the file, in seconds. `None` plays through to the end.
24 pub trim_end: Option<f64>,
25 /// Ducks the music while this clip is audible.
26 pub priority: bool,
27 /// This clip is a spoken line. The timeline shows the line, not a second bar.
28 pub speech: bool,
29}
30
31/// A spoken line recorded while a scene runs.
32#[derive(Debug, Clone, PartialEq)]
33pub struct VoiceLine {
34 /// The line, as written in the scene.
35 pub text: String,
36 /// Start, in seconds from the beginning of the scene.
37 pub at: f64,
38 /// Length in seconds.
39 pub seconds: f64,
40}
41
42/// Records `clip` on the running scene. Called by `sound()`.
43pub fn record_sound(clip: SoundClip) -> usize {
44 runtime::with(|rt| {
45 let mut sounds = rt.sounds.borrow_mut();
46 sounds.push(clip);
47 sounds.len() - 1
48 })
49}
50
51/// Sets the end point in the file of clip `index` (from [`record_sound`]),
52/// for a clip whose length is known only later, such as the sound of a
53/// video that is paused.
54pub fn end_sound(index: usize, trim_end: f64) {
55 runtime::with(|rt| {
56 if let Some(clip) = rt.sounds.borrow_mut().get_mut(index) {
57 clip.trim_end = Some(trim_end.max(clip.trim_start));
58 }
59 });
60}
61
62/// Records a spoken line. Called by `voice()`.
63pub fn record_voice(line: VoiceLine) {
64 runtime::with(|rt| rt.voices.borrow_mut().push(line));
65}