firefly_rust/audio/
modulators.rs

1use super::*;
2
3pub trait Modulator {
4    fn modulate(self, node_id: u32, param: u32);
5}
6
7/// Linear (ramp up or down) envelope.
8///
9/// It looks like this: `⎽╱⎺` or `⎺╲⎽`.
10///
11/// The value before `start_at` is `start`, the value after `end_at` is `end`,
12/// and the value between `start_at` and `end_at` changes linearly from `start` to `end`.
13pub struct LinearModulator {
14    pub start: f32,
15    pub end: f32,
16    pub start_at: Time,
17    pub end_at: Time,
18}
19
20impl Modulator for LinearModulator {
21    fn modulate(self, node_id: u32, param: u32) {
22        unsafe {
23            bindings::mod_linear(
24                node_id,
25                param,
26                self.start,
27                self.end,
28                self.start_at.0,
29                self.end_at.0,
30            );
31        }
32    }
33}
34
35/// Hold envelope.
36///
37/// It looks like this: `⎽│⎺` or `⎺│⎽`.
38///
39/// The value before `time` is `before` and the value after `time` is `after`.
40/// Equivalent to [`LinearModulator`] with `start_at` being equal to `end_at`.
41pub struct HoldModulator {
42    pub before: f32,
43    pub after: f32,
44    pub time: Time,
45}
46
47impl Modulator for HoldModulator {
48    fn modulate(self, node_id: u32, param: u32) {
49        unsafe {
50            bindings::mod_hold(node_id, param, self.before, self.after, self.time.0);
51        }
52    }
53}
54
55/// Sine wave low-frequency oscillator.
56///
57/// It looks like this: `∿`.
58///
59/// `low` is the lowest produced value, `high` is the highest.
60pub struct SineModulator {
61    pub freq: Freq,
62    pub low: f32,
63    pub high: f32,
64}
65
66impl Modulator for SineModulator {
67    fn modulate(self, node_id: u32, param: u32) {
68        unsafe {
69            bindings::mod_sine(node_id, param, self.freq.0, self.low, self.high);
70        }
71    }
72}
73
74mod bindings {
75    #[link(wasm_import_module = "audio")]
76    extern {
77        pub(super) fn mod_linear(
78            node_id: u32,
79            param: u32,
80            start: f32,
81            end: f32,
82            start_at: u32,
83            end_at: u32,
84        );
85        pub(super) fn mod_hold(node_id: u32, param: u32, v1: f32, v2: f32, time: u32);
86        pub(super) fn mod_sine(node_id: u32, param: u32, freq: f32, low: f32, high: f32);
87    }
88}