├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .cargo └── config ├── .gitattributes ├── assets ├── Geist-Regular.otf └── GeistMono-Regular.otf ├── xtask ├── src │ └── main.rs └── Cargo.toml ├── bundler.toml ├── .gitignore ├── debug.ps1 ├── Cargo.toml ├── README.md ├── src ├── lib.rs ├── editor.rs ├── params.rs ├── buffer.rs └── dsp.rs ├── faust └── dsp.dsp ├── faust2params.py └── LICENSE /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: azur1s 2 | ko-fi: azur1s -------------------------------------------------------------------------------- /.cargo/config: -------------------------------------------------------------------------------- 1 | [alias] 2 | xtask = "run --package xtask --release --" 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /assets/Geist-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azur1s/elysiera/HEAD/assets/Geist-Regular.otf -------------------------------------------------------------------------------- /xtask/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() -> nih_plug_xtask::Result<()> { 2 | nih_plug_xtask::main() 3 | } 4 | -------------------------------------------------------------------------------- /assets/GeistMono-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azur1s/elysiera/HEAD/assets/GeistMono-Regular.otf -------------------------------------------------------------------------------- /xtask/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xtask" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | nih_plug_xtask = { git = "https://github.com/robbert-vdh/nih-plug.git" } 8 | -------------------------------------------------------------------------------- /bundler.toml: -------------------------------------------------------------------------------- 1 | # This provides metadata for NIH-plug's `cargo xtask bundle ` plugin 2 | # bundler. This file's syntax is as follows: 3 | # 4 | # [package_name] 5 | # name = "Human Readable Plugin Name" # defaults to 6 | 7 | [elysiera] 8 | name = "Elysiera" 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/ 4 | target/ 5 | 6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries 7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html 8 | Cargo.lock 9 | 10 | # These are backup files generated by rustfmt 11 | **/*.rs.bk 12 | 13 | # MSVC Windows builds of rustc generate these, which store debugging information 14 | *.pdb 15 | 16 | # Plugin log 17 | elysiera.log -------------------------------------------------------------------------------- /debug.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | # Build 4 | cargo xtask bundle elysiera 5 | 6 | $plugin_name = "Elysiera" 7 | $vst3_name = "ElysieraDebug.vst3" 8 | 9 | # Rename file 10 | $build = Join-Path $pwd "target/bundled/$plugin_name.vst3/Contents/x86_64-win/$plugin_name.vst3" 11 | $build_to = Join-Path $pwd "target/bundled/$plugin_name.vst3/Contents/x86_64-win/$vst3_name" 12 | Write-Host "Renaming $build to $build_to" 13 | Move-Item $build $build_to -Force 14 | $build = $build_to 15 | 16 | # Move the VST3 file to the target directory 17 | $pwd = Get-Location 18 | $to = $env:VST3_DIR 19 | Write-Host "Moving $build to $to" 20 | if ($to -eq $null) { 21 | Write-Host "VST3_DIR is not set. Skipping moving the VST3 file." 22 | exit 0 23 | } 24 | gsudo Copy-Item $build $to -Force 25 | # Set "NIH_LOG" environment variable to a file path 26 | $env:NIH_LOG = "$pwd/elysiera.log" 27 | # Open plugin host 28 | Write-Host "Opening $env:VST3_TESTER" 29 | if ($env:VST3_TESTER -eq $null) { 30 | Write-Host "VST3_TESTER is not set. Skipping opening Ableton." 31 | exit 0 32 | } 33 | Start-Process -FilePath $env:VST3_TESTER -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "elysiera" 3 | version = "0.1.0" 4 | edition = "2021" 5 | authors = ["Natapat Samutpong "] 6 | license = "GPL-3.0-or-later" 7 | homepage = "https://azur.moe" 8 | description = "A plugin" 9 | 10 | [workspace] 11 | members = ["xtask"] 12 | 13 | [lib] 14 | crate-type = ["cdylib"] 15 | 16 | [dependencies] 17 | # Remove the `assert_process_allocs` feature to allow allocations on the audio 18 | # thread in debug builds. 19 | nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", features = ["assert_process_allocs"] } 20 | nih_plug_egui = { git = "https://github.com/robbert-vdh/nih-plug.git" } 21 | # Uncomment the below line to disable the on-by-default VST3 feature to remove 22 | # the GPL compatibility requirement 23 | # nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", default_features = false, features = ["assert_process_allocs"] } 24 | 25 | faust-types = { git = "https://github.com/Frando/rust-faust" } 26 | default-boxed = "0.2.0" 27 | atomic_float = "0.1.0" 28 | lazy_static = "1.4.0" 29 | parking_lot = "0.12.1" 30 | itertools = "0.12.1" 31 | 32 | [profile.dev] 33 | opt-level = 1 34 | 35 | [profile.release] 36 | lto = "thin" 37 | strip = "symbols" 38 | 39 | [profile.profiling] 40 | inherits = "release" 41 | debug = true 42 | strip = "none" 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # elysiera 2 | Source code for Elysiera, a shimmer reverb plugin. 3 | 4 | ## How 5 | Basically I was bored and stumbled upon [Eno/Lanois Shimmer Sound: How it is made](https://valhalladsp.wordpress.com/2010/05/11/enolanois-shimmer-sound-how-it-is-made/) by ValhallaDSP and I want to try it out. 6 | 7 | > *"The basic foundation of the Brian Eno / Daniel Lanois shimmer sound is fairly simple: Create a feedback loop, incorporating a pitch shifter set to +1 octave, and a reverb with a fairly long decay time."* 8 | 9 | And a bunch more googling led me to believe that shimmer reverb is just reverb with pitch-shifting and fancy stuff, so I did just that. 10 | 11 | The [DSP file](faust/dsp.dsp) is pretty self-explanatory on how it works: 12 | 1. Filter signal with low and high pass. 13 | 2. Echo because why not. 14 | 3. Run it through 2 pitch shifters. 15 | 4. Modulate first pitch shifter with sine oscillator and second with cosine oscillator so that it have that wavy sound. Do the opposite for the right channel because why not. 16 | 5. Run it through reverb (I use Fons Adriaensen's `zita-rev1` because it sounded cool). 17 | 18 | **** 19 | ## Installing 20 | WIP 21 | 22 | ## Contributing 23 | I personally use [`debug.ps1`](debug.ps1) to build and automatically open a DAW for debugging purpose. Use it if it works. 24 | ```shell 25 | # If you modified the faust file (faust/dsp.dsp) then you might have to 26 | # regenerate both dsp.rs and params.rs 27 | python faust2params.py faust/dsp.dsp 28 | 29 | # Debug build, huge file size 30 | cargo xtask bundle elysiera 31 | # Release build, small file size 32 | cargo xtask bundle elysiera --release 33 | ``` -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod params; 2 | mod dsp; 3 | mod buffer; 4 | mod editor; 5 | 6 | use std::sync::Arc; 7 | use nih_plug::prelude::*; 8 | use faust_types::FaustDsp; 9 | 10 | use params::*; 11 | use dsp::ElysieraDSP; 12 | use buffer::TempBuffer; 13 | 14 | struct Elysiera { 15 | dsp: Box, 16 | params: Arc, 17 | buffer: TempBuffer, 18 | } 19 | 20 | impl Default for Elysiera { 21 | fn default() -> Self { 22 | Self { 23 | dsp: Box::new(ElysieraDSP::new()), 24 | params: Arc::new(ElysieraParams::default()), 25 | buffer: TempBuffer::default(), 26 | } 27 | } 28 | } 29 | 30 | impl Plugin for Elysiera { 31 | const NAME: &'static str = "az.elysiera"; 32 | const VENDOR: &'static str = "Azur1s"; 33 | const URL: &'static str = env!("CARGO_PKG_HOMEPAGE"); 34 | const EMAIL: &'static str = "natapat.samutpong@gmail.com"; 35 | 36 | const VERSION: &'static str = env!("CARGO_PKG_VERSION"); 37 | 38 | const AUDIO_IO_LAYOUTS: &'static [AudioIOLayout] = &[AudioIOLayout { 39 | main_input_channels: NonZeroU32::new(2), 40 | main_output_channels: NonZeroU32::new(2), 41 | 42 | aux_input_ports: &[], 43 | aux_output_ports: &[], 44 | 45 | names: PortNames::const_default(), 46 | }]; 47 | 48 | const MIDI_INPUT: MidiConfig = MidiConfig::None; 49 | const MIDI_OUTPUT: MidiConfig = MidiConfig::None; 50 | 51 | const SAMPLE_ACCURATE_AUTOMATION: bool = true; 52 | 53 | type SysExMessage = (); 54 | type BackgroundTask = (); 55 | 56 | fn params(&self) -> Arc { 57 | self.params.clone() 58 | } 59 | 60 | fn editor(&mut self, _async_executor: AsyncExecutor) -> Option> { 61 | editor::editor(self.params.clone()) 62 | } 63 | 64 | fn initialize( 65 | &mut self, 66 | _audio_io_layout: &AudioIOLayout, 67 | buffer_config: &BufferConfig, 68 | _context: &mut impl InitContext, 69 | ) -> bool { 70 | self.dsp.init(buffer_config.sample_rate as i32); 71 | self.buffer.resize(2, 1024); 72 | true 73 | } 74 | 75 | fn reset(&mut self) { 76 | } 77 | 78 | fn process( 79 | &mut self, 80 | buffer: &mut Buffer, 81 | _aux: &mut AuxiliaryBuffers, 82 | _context: &mut impl ProcessContext, 83 | ) -> ProcessStatus { 84 | let count = buffer.samples() as i32; 85 | self.buffer.read_from_buffer(buffer); 86 | let output = buffer.as_slice(); 87 | 88 | self.params.dsp_set_params(&mut self.dsp); 89 | 90 | self.dsp 91 | .compute(count, &self.buffer.slice2d(), output); 92 | 93 | ProcessStatus::Normal 94 | } 95 | } 96 | 97 | impl ClapPlugin for Elysiera { 98 | const CLAP_ID: &'static str = "moe.azur.elysiera"; 99 | const CLAP_DESCRIPTION: Option<&'static str> = Some("A plugin"); 100 | const CLAP_MANUAL_URL: Option<&'static str> = Some(Self::URL); 101 | const CLAP_SUPPORT_URL: Option<&'static str> = None; 102 | 103 | const CLAP_FEATURES: &'static [ClapFeature] = &[ClapFeature::AudioEffect, ClapFeature::Stereo]; 104 | } 105 | 106 | impl Vst3Plugin for Elysiera { 107 | const VST3_CLASS_ID: [u8; 16] = *b"az.elysiera_____"; 108 | 109 | const VST3_SUBCATEGORIES: &'static [Vst3SubCategory] = 110 | &[Vst3SubCategory::Fx, Vst3SubCategory::Dynamics]; 111 | } 112 | 113 | nih_export_clap!(Elysiera); 114 | nih_export_vst3!(Elysiera); -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # https://github.com/robbert-vdh/nih-plug/blob/master/.github/workflows/build.yml 2 | 3 | name: Build plugin 4 | 5 | # on: 6 | # push: 7 | # branches: 8 | # - '**' 9 | # tags: 10 | # - '*' 11 | # pull_request: 12 | # branches: 13 | # - master 14 | on: workflow_dispatch 15 | 16 | defaults: 17 | run: 18 | shell: bash 19 | 20 | jobs: 21 | package: 22 | strategy: 23 | matrix: 24 | include: 25 | - { name: ubuntu-20.04, os: ubuntu-20.04, cross-target: '' } 26 | - { name: macos-universal, os: macos-11, cross-target: aarch64-apple-darwin } 27 | - { name: windows, os: windows-latest, cross-target: '' } 28 | name: Build plugin 29 | runs-on: ${{ matrix.os }} 30 | steps: 31 | - uses: actions/checkout@v3 32 | - name: Fetch all git history 33 | run: git fetch --force --prune --tags --unshallow 34 | 35 | - name: Install dependencies 36 | if: startsWith(matrix.os, 'ubuntu') 37 | run: | 38 | sudo apt-get update 39 | sudo apt-get install -y libasound2-dev libgl-dev libjack-dev libx11-xcb-dev libxcb1-dev libxcb-dri2-0-dev libxcb-icccm4-dev libxcursor-dev libxkbcommon-dev libxcb-shape0-dev libxcb-xfixes0-dev 40 | 41 | - uses: actions/cache@v3 42 | # FIXME: Caching `target/` causes the Windows runner to blow up after some time 43 | if: startsWith(matrix.os, 'windows') 44 | with: 45 | path: | 46 | ~/.cargo/registry/index/ 47 | ~/.cargo/registry/cache/ 48 | ~/.cargo/git/db/ 49 | key: ${{ matrix.name }}-${{ matrix.cross-target }} 50 | - uses: actions/cache@v3 51 | if: "!startsWith(matrix.os, 'windows')" 52 | with: 53 | path: | 54 | ~/.cargo/registry/index/ 55 | ~/.cargo/registry/cache/ 56 | ~/.cargo/git/db/ 57 | target/ 58 | key: ${{ matrix.name }}-${{ matrix.cross-target }} 59 | 60 | - name: Set up Rust toolchain 61 | # Needed for SIMD 62 | uses: dtolnay/rust-toolchain@nightly 63 | with: 64 | # The macOS AArch64 build is done from an x86_64 macOS CI runner, so 65 | # it needs to be cross compiled 66 | targets: ${{ matrix.cross-target }} 67 | 68 | - name: Build plugin 69 | run: | 70 | runner_name=${{ matrix.name }} 71 | if [[ runner_name = 'macos-universal' ]]; then 72 | export MACOSX_DEPLOYMENT_TARGET=10.13 73 | cargo xtask bundle-universal elysiera --release 74 | else 75 | cross_target=${{ matrix.cross-target }} 76 | args=() 77 | if [[ -n $cross_target ]]; then 78 | args+=("--target" "$cross_target") 79 | fi 80 | 81 | cargo xtask bundle elysiera "${args[@]}" --release 82 | fi 83 | 84 | - name: Run xattr for macOS build 85 | if: startsWith(matrix.os, 'macos') 86 | run: | 87 | # Run xattr to remove quarantine attribute 88 | xattr -cr target/bundled/elysiera.vst3 89 | xattr -cr target/bundled/elysiera.clap 90 | 91 | - name: Determine build archive name 92 | run: | 93 | # Run cargo pkgid 94 | pkgid=$(cargo pkgid) 95 | pkgid=(${pkgid//\#/ }) 96 | ver=${pkgid[1]} 97 | 98 | echo "ARCHIVE_NAME=elysiera-$ver-${{ matrix.name }}" >> "$GITHUB_ENV" 99 | 100 | - name: Move build into a directory 101 | run: | 102 | mkdir -p "$ARCHIVE_NAME" 103 | mv target/bundled/* "$ARCHIVE_NAME" 104 | 105 | - name: Add LICENSE file 106 | run: | 107 | cp LICENSE "$ARCHIVE_NAME" 108 | 109 | - uses: actions/upload-artifact@v3 110 | with: 111 | name: ${{ env.ARCHIVE_NAME }} 112 | path: ${{ env.ARCHIVE_NAME }} -------------------------------------------------------------------------------- /src/editor.rs: -------------------------------------------------------------------------------- 1 | use crate::ElysieraParams; 2 | use std::sync::Arc; 3 | use nih_plug::editor::Editor; 4 | use nih_plug_egui::{create_egui_editor, egui, widgets::ParamSlider, EguiState}; 5 | 6 | pub fn default_state() -> Arc { 7 | EguiState::from_size(400, 700) 8 | } 9 | 10 | pub fn editor( 11 | params: Arc 12 | ) -> Option> { 13 | create_egui_editor( 14 | params.editor_state.clone(), 15 | (), 16 | |egui_ctx, _| { 17 | let mut fonts = egui::FontDefinitions::default(); 18 | 19 | fonts.font_data.insert( 20 | "Geist".to_owned(), 21 | egui::FontData::from_static(include_bytes!("../assets/Geist-Regular.otf")), 22 | ); 23 | 24 | fonts 25 | .families 26 | .entry(egui::FontFamily::Proportional) 27 | .or_default() 28 | .insert(0, "Geist".to_owned()); 29 | 30 | egui_ctx.set_fonts(fonts); 31 | }, 32 | move |egui_ctx, setter, _state| { 33 | egui::CentralPanel::default().show(egui_ctx, |ui| { 34 | let params_list = vec![ 35 | ("Mix", vec![ 36 | ("Mix", ¶ms.mix), 37 | ("Pre Gain", ¶ms.pre_gain), 38 | ("Post Gain", ¶ms.post_gain), 39 | ]), 40 | 41 | ("Reverb", vec![ 42 | ("Low Decay", ¶ms.low_decay), 43 | ("Low Crossover", ¶ms.lf_crossover), 44 | ("Mid Decay", ¶ms.mid_decay), 45 | ("High Filter Damping", ¶ms.hf_damping), 46 | ("Reverb Delay", ¶ms.reverb_delay), 47 | ("Reverb Mix", ¶ms.reverb_mix), 48 | ]), 49 | 50 | ("Echo", vec![ 51 | ("Echo Delay", ¶ms.delay), 52 | ("Echo Feedback", ¶ms.feedback), 53 | ]), 54 | 55 | ("Filter", vec![ 56 | ("Lowpass", ¶ms.lowpass), 57 | ("Lowpass Q", ¶ms.lowpass_q), 58 | ("Highpass", ¶ms.highpass), 59 | ("Highpass Q", ¶ms.highpass_q), 60 | ]), 61 | 62 | ("Pitch", vec![ 63 | ("Pitch A", ¶ms.pitch_a), 64 | ("Pitch A Mix", ¶ms.pitch_a_mix), 65 | ("Pitch B", ¶ms.pitch_b), 66 | ("Pitch B Mix", ¶ms.pitch_b_mix), 67 | ]), 68 | 69 | ("Modulate", vec![ 70 | ("Pitch Mod Rate", ¶ms.pitch_mod_rate), 71 | ("Pitch Mod Mix", ¶ms.pitch_mod_mix), 72 | ("Volume Mod Rate", ¶ms.volume_mod_rate), 73 | ("Volume Mod Mix", ¶ms.volume_mod_mix), 74 | ]), 75 | ]; 76 | 77 | 78 | egui::Grid::new("params") 79 | .striped(true) 80 | .show(ui, |ui| { 81 | params_list.iter().for_each(|(section, params)| { 82 | ui.label(*section); 83 | ui.end_row(); 84 | 85 | params.iter().for_each(|(name, param)| { 86 | ui.add(ParamSlider::for_param(*param, setter)); 87 | ui.label(*name); 88 | ui.end_row(); 89 | }); 90 | }); 91 | }); 92 | // macro_rules! param { 93 | // ($name:expr, $param:expr) => { 94 | // ui.horizontal(|ui| { 95 | // ui.label($name); 96 | // ui.add(ParamSlider::for_param(&$param, setter)); 97 | // }) 98 | // }; 99 | // } 100 | 101 | // ui.label("Mix"); 102 | // param!("Mix", params.mix); 103 | // param!("Pre Gain", params.pre_gain); 104 | // param!("Post Gain", params.post_gain); 105 | 106 | // ui.label("Reverb"); 107 | // param!("Low Decay", params.low_decay); 108 | // param!("Low Crossover", params.lf_crossover); 109 | // param!("Mid Decay", params.mid_decay); 110 | // param!("High Filter Damping", params.hf_damping); 111 | // param!("Reverb Delay", params.reverb_delay); 112 | // param!("Reverb Mix", params.reverb_mix); 113 | }); 114 | } 115 | ) 116 | } -------------------------------------------------------------------------------- /faust/dsp.dsp: -------------------------------------------------------------------------------- 1 | declare name "elysiera"; 2 | declare version "1.0"; 3 | 4 | import("stdfaust.lib"); 5 | 6 | grp (x) = tgroup("", x); 7 | 8 | // Mix 9 | 10 | group_mix (x) = grp(hgroup("[0]Mix", x)); 11 | mix = group_mix(vslider("[0]Mix [style:knob] [unit:%]", 0.5, 0.0, 1.0, 0.01)); 12 | pre_gain = group_mix(vslider("[1]Pre Gain [style:knob] [unit:dB]", 0.0, -30.0, 10.0, 0.1)); 13 | post_gain = group_mix(vslider("[2]Post Gain [style:knob] [unit:dB]", 0.0, -30.0, 10.0, 0.1)); 14 | 15 | // - Reverb 16 | 17 | group_reverb (x) = grp(hgroup("[1]Reverb", x)); 18 | // T60 = Time (in seconds) to decay 60dB in low-frequency band 19 | low_decay = group_reverb(vslider("[0]Low decay [style:knob] [unit:s]", 3.7, 1.0, 60.0, 0.01)); 20 | // Crossover frequency (Hz) separating low and middle frequencies 21 | low_crossover = group_reverb(vslider("[1]LF Crossover [style:knob] [unit:Hz]", 440.0, 50.0, 1000.0, 1)); 22 | // T60 = Time (in seconds) to decay 60dB in middle band 23 | mid_decay = group_reverb(vslider("[2]Mid Decay [style:knob] [unit:s]", 4.68, 1.0, 60.0, 0.01)); 24 | // Frequency (Hz) at which the high-frequency T60 is half the middle-band's T60 25 | high_filter_damping = group_reverb(vslider("[3]HF Damping [style:knob] [unit:Hz]", 8600.0, 1500.0, 0.49 * 44100.0, 1)); 26 | // Time before reverb hits 27 | reverb_delay = group_reverb(vslider("[4]Reverb Delay [style:knob] [unit:ms]", 0.0, 0.0, 100.0, 0.01)); 28 | // Dry/wet mixer 29 | reverb_mix = group_reverb(vslider("[5]Reverb Mix [style:knob] [unit:%]", 1.0, 0.0, 1.0, 0.01)); 30 | zita_rev = re.zita_rev1_stereo( 31 | reverb_delay, low_crossover, high_filter_damping, low_decay, mid_decay, 44100.0 32 | ); 33 | 34 | // - Echo 35 | group_echo (x) = grp(hgroup("[2]Echo", x)); 36 | // Echo delay time (in seconds) 37 | echo_delay = group_echo(vslider("[0]Delay [style:knob] [unit:s]", 0.5, 0.0, 5.0, 0.01)); 38 | // Echo feedback (0.0 to 0.99) 39 | echo_feedback = group_echo(vslider("[1]Feedback [style:knob] [unit:%]", 0.5, 0.0, 0.99, 0.01)); 40 | 41 | // - Pre-Filter 42 | 43 | group_filter (x) = grp(hgroup("[3]Filter", x)); 44 | lp_filter_cutoff = group_filter(vslider("[0]Lowpass [style:knob] [unit:Hz]", 18000.0, 25.0, 22000.0, 0.01)); 45 | lp_filter_q = group_filter(vslider("[1]Lowpass Q [style:knob]", 0.71, 0.1, 2.0, 0.01)); 46 | hp_filter_cutoff = group_filter(vslider("[3]Highpass [style:knob] [unit:Hz]", 250.0, 25.0, 22000.0, 0.01)); 47 | hp_filter_q = group_filter(vslider("[4]Highpass Q [style:knob]", 0.71, 0.1, 2.0, 0.01)); 48 | 49 | // - Pitch 50 | 51 | group_pitch (x) = grp(hgroup("[4]Pitch", x)); 52 | pitch_a = group_pitch(vslider("[0]Pitch A [style:knob] [unit:st]", 12.0, -12.0, 12.0, 1)); 53 | pitch_a_vol = group_pitch(vslider("[1]Pitch A Mix [style:knob] [unit:%]", 0.6, 0.0, 1.0, 0.01)); 54 | pitch_b = group_pitch(vslider("[1]Pitch B [style:knob] [unit:st]", 5.0, -12.0, 12.0, 1)); 55 | pitch_b_vol = group_pitch(vslider("[2]Pitch B Mix [style:knob] [unit:%]", 0.6, 0.0, 1.0, 0.01)); 56 | 57 | // - Mod 58 | 59 | group_mod (x) = grp(hgroup("[5]Mod", x)); 60 | pitch_mod_hz = group_mod(vslider("[5]Pitch Mod Rate [style:knob] [unit:hz]", 3.1, 0.01, 10.0, 0.01)); 61 | pitch_mod_mix = group_mod(vslider("[6]Pitch Mod Mix [style:knob] [unit:%]", 1.0, 0.0, 1.0, 0.01)); 62 | mod_hz = group_mod(vslider("[7]Volume Mod Rate [style:knob] [unit:hz]", 3.1, 0.01, 10.0, 0.01)); 63 | mod_mix = group_mod(vslider("[8]Volume Mod Mix [style:knob] [unit:%]", 1.0, 0.0, 1.0, 0.01)); 64 | 65 | c_samples = 2048; 66 | c_xfade = 1024; 67 | 68 | process = _, _ : 69 | // Pre-gain 70 | par(i, 2, *(ba.db2linear(pre_gain))) 71 | : ef.dryWetMixerConstantPower(mix, (_ , _ 72 | : par(i, 2, 73 | // Lowpass 74 | fi.svf.lp(lp_filter_cutoff, lp_filter_q) 75 | // Highpass 76 | : fi.svf.hp(hp_filter_cutoff, hp_filter_q) 77 | // Echo 78 | : ef.echo(5.0, echo_delay, echo_feedback) 79 | ) 80 | : ( 81 | // Make pitch_a appears on sin, pitch_b appears on cos and invert for other channel 82 | (_ <: 83 | ef.transpose(c_samples, c_xfade, pitch_a) * (os.oscsin(pitch_mod_hz) * pitch_mod_mix + (1 - pitch_mod_mix)) * pitch_a_vol 84 | + ef.transpose(c_samples, c_xfade, pitch_b) * (os.osccos(pitch_mod_hz) * pitch_mod_mix + (1 - pitch_mod_mix)) * pitch_b_vol 85 | ), 86 | (_ <: 87 | ef.transpose(c_samples, c_xfade, pitch_a) * (os.osccos(pitch_mod_hz) * pitch_mod_mix + (1 - pitch_mod_mix)) * pitch_a_vol 88 | + ef.transpose(c_samples, c_xfade, pitch_b) * (os.oscsin(pitch_mod_hz) * pitch_mod_mix + (1 - pitch_mod_mix)) * pitch_b_vol 89 | ) 90 | ) 91 | // Modulate volume 92 | : ef.dryWetMixerConstantPower(mod_mix, (*(os.oscsin(mod_hz)), *(os.osccos(mod_hz)))) 93 | // Reverb 94 | :> ef.dryWetMixerConstantPower(reverb_mix, zita_rev) 95 | )) 96 | // Post-gain 97 | : par(i, 2, *(ba.db2linear(post_gain))); -------------------------------------------------------------------------------- /faust2params.py: -------------------------------------------------------------------------------- 1 | import re, subprocess 2 | 3 | # -- Generate dsp.rs 4 | 5 | cmd = "faust -lang rust ./faust/dsp.dsp -o ./src/dsp.rs" 6 | subprocess.run(cmd, shell=True) 7 | 8 | # add "mod dsp {" to the beginning of the file 9 | # add "}" to the end of the file 10 | 11 | pre = """\ 12 | mod dsp { 13 | #![allow(clippy::all)] 14 | #![allow(unused_parens)] 15 | #![allow(non_snake_case)] 16 | #![allow(non_camel_case_types)] 17 | #![allow(dead_code)] 18 | #![allow(unused_variables)] 19 | #![allow(unused_mut)] 20 | #![allow(non_upper_case_globals)] 21 | 22 | use faust_types::*; 23 | """ 24 | 25 | with open("src/dsp.rs", "r") as file: 26 | content = file.read() 27 | content = content.replace("F32", "f32") 28 | content = pre + content + "}\npub use dsp::mydsp as ElysieraDSP;" 29 | with open("src/dsp.rs", "w") as file: 30 | file.write(content) 31 | 32 | print("Generated dsp.rs") 33 | 34 | # -- Generate params.rs 35 | 36 | params = [] 37 | with open("src/dsp.rs", "r") as file: 38 | lines = file.readlines() 39 | for line in lines: 40 | if "_slider" in line: 41 | name = re.search(r'\"(.*?)\"', line).group(1) 42 | index = re.search(r'ParamIndex\((.*?)\)', line).group(1) 43 | params.append((name, index)) 44 | 45 | print(params) 46 | 47 | # Convert snake case to Rust's camel case 48 | def case(a): 49 | return a[0] + "".join([word.capitalize() for word in name.split("_")])[1:] 50 | 51 | def float_param(id): 52 | return f"""\ 53 | #[id = "{id}"] 54 | pub {id}: FloatParam, 55 | """ 56 | 57 | def search_name(line): 58 | # group_reverb(vslider("[0]Low decay [style:knob] [unit:s]", ... 59 | # ^----------^ but discard the [0] in the regex 60 | return re.search(r'(?:\[\d])([a-zA-Z0-9_ ]*)', line).group(1).strip() 61 | 62 | def search_unit(line): 63 | # group_reverb(vslider("[5]Reverb Mix [style:knob] [unit:%]", ... 64 | # get the unit after the colon ^------^ 65 | q = re.search(r'\[unit:(.*?)\]', line) 66 | if q: 67 | return q.group(1) 68 | else: 69 | # try search if it's a unit of a quality of an eq (Q) 70 | # group_filter(vslider("[1]Lowpass Q [style:knob]", ... 71 | # ^-^ 72 | q = re.search(r' Q ', line) 73 | if q: 74 | return "Q" 75 | else: 76 | # should be unreachable unless we add a new parameter type 77 | return "" 78 | 79 | 80 | path = "faust/dsp.dsp" 81 | content = """\ 82 | // Generated by scripts/build_param.py 83 | use std::sync::Arc; 84 | use nih_plug::prelude::*; 85 | use nih_plug_egui::EguiState; 86 | use faust_types::{FaustDsp, ParamIndex}; 87 | 88 | use crate::editor; 89 | \n""" 90 | param_fn = """ 91 | fn param_db(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 92 | FloatParam::new( 93 | name, util::db_to_gain(default), 94 | FloatRange::Skewed { 95 | min: util::db_to_gain(min), 96 | max: util::db_to_gain(max), 97 | factor: FloatRange::gain_skew_factor(-30.0, 30.0), 98 | } 99 | ) 100 | .with_smoother(SmoothingStyle::Logarithmic(50.0)) 101 | .with_unit("dB") 102 | .with_value_to_string(formatters::v2s_f32_gain_to_db(2)) 103 | .with_string_to_value(formatters::s2v_f32_gain_to_db()) 104 | } 105 | 106 | fn param_st(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 107 | FloatParam::new( 108 | name, default, 109 | FloatRange::Linear {min, max}, 110 | ) 111 | .with_unit(" st") 112 | .with_smoother(SmoothingStyle::Linear(50.0)) 113 | .with_value_to_string(formatters::v2s_f32_rounded(2)) 114 | } 115 | 116 | fn param_q(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 117 | FloatParam::new( 118 | name, default, 119 | FloatRange::Skewed { 120 | min, 121 | max, 122 | factor: FloatRange::skew_factor(-1.0), 123 | }, 124 | ) 125 | .with_smoother(SmoothingStyle::Logarithmic(100.0)) 126 | .with_value_to_string(formatters::v2s_f32_rounded(2)) 127 | } 128 | 129 | fn param_hz(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 130 | FloatParam::new( 131 | name, default, 132 | FloatRange::Skewed { 133 | min, 134 | max, 135 | factor: FloatRange::skew_factor(-1.0), 136 | }, 137 | ) 138 | .with_smoother(SmoothingStyle::Logarithmic(100.0)) 139 | .with_value_to_string(formatters::v2s_f32_hz_then_khz(0)) 140 | .with_string_to_value(formatters::s2v_f32_hz_then_khz()) 141 | } 142 | 143 | fn param_float(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 144 | FloatParam::new( 145 | name, default, 146 | FloatRange::Linear {min, max}, 147 | ) 148 | .with_smoother(SmoothingStyle::Linear(50.0)) 149 | .with_value_to_string(formatters::v2s_f32_rounded(2)) 150 | } 151 | 152 | fn param_percentage(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 153 | FloatParam::new( 154 | name, default, 155 | FloatRange::Linear {min, max}, 156 | ) 157 | .with_unit(" %") 158 | .with_smoother(SmoothingStyle::Linear(50.0)) 159 | .with_value_to_string(formatters::v2s_f32_percentage(2)) 160 | .with_string_to_value(formatters::s2v_f32_percentage()) 161 | } 162 | 163 | fn param_s(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 164 | FloatParam::new( 165 | name, default, 166 | FloatRange::Linear {min, max}, 167 | ) 168 | .with_unit(" s") 169 | .with_smoother(SmoothingStyle::Linear(50.0)) 170 | .with_value_to_string(formatters::v2s_f32_rounded(3)) 171 | } 172 | 173 | fn param_ms(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 174 | FloatParam::new( 175 | name, default, 176 | FloatRange::Linear {min, max}, 177 | ) 178 | .with_unit(" ms") 179 | .with_smoother(SmoothingStyle::Linear(50.0)) 180 | .with_value_to_string(formatters::v2s_f32_rounded(3)) 181 | } 182 | """ 183 | content += """#[derive(Params)] 184 | pub struct ElysieraParams { 185 | #[persist = "editor-state"] 186 | pub editor_state: Arc, 187 | \n""" 188 | with open(path, "r") as file: 189 | lines = file.readlines() 190 | for line in lines: 191 | if "slider" in line: 192 | name = search_name(line)\ 193 | .lower()\ 194 | .replace(' ', '_') 195 | content += float_param(name) 196 | content += "}\n\nimpl Default for ElysieraParams {\n" 197 | content += " fn default() -> Self {\n" 198 | content += " Self {\n" 199 | content += " editor_state: editor::default_state(),\n\n" 200 | 201 | max_len = 0 202 | sliders = [] 203 | 204 | for line in lines: 205 | if "slider" in line: 206 | name = search_name(line) 207 | name_case = name.lower().replace(' ', '_') 208 | 209 | unit = search_unit(line) 210 | unit_fn = unit.replace("%", "percentage").lower() 211 | 212 | # print(f"`{name_case}` - {unit_fn}") 213 | 214 | if len(name) > max_len: 215 | max_len = len(name) 216 | 217 | val = line.split(",") 218 | default = val[1].strip() 219 | min = val[2].strip() 220 | max = val[3].split(")")[0].strip() 221 | 222 | sliders.append(( 223 | f" {name_case}: param_{unit_fn}(\"{name}\", {default}, {min}, {max}),\n", 224 | name_case 225 | )) 226 | 227 | for (slider, name_case) in sliders: 228 | content += slider.replace(": ", ":" + " " * (max_len - len(name_case) + 1)) 229 | 230 | content += " }\n" 231 | content += " }\n" 232 | content += "}\n\n" 233 | 234 | content += f"impl ElysieraParams {{\n" 235 | content += f" pub fn dsp_set_params(&self, dsp: &mut Box) {{\n" 236 | for name, index in params: 237 | name = name\ 238 | .replace(' ', '_')\ 239 | .upper() 240 | content += f" dsp.set_param({name.upper().replace(' ', '_')}, self.{name.lower()}.value());\n" 241 | content += " }\n" 242 | content += "}\n\n" 243 | 244 | for name, index in params: 245 | name = name\ 246 | .replace(' ', '_')\ 247 | .upper() 248 | content += f"pub const {name.upper().replace(' ', '_')}: ParamIndex = ParamIndex({index});\n" 249 | 250 | content += param_fn 251 | 252 | with open("src/params.rs", "w") as file: 253 | file.write(content) 254 | 255 | print("Generated params.rs") -------------------------------------------------------------------------------- /src/params.rs: -------------------------------------------------------------------------------- 1 | // Generated by scripts/build_param.py 2 | use std::sync::Arc; 3 | use nih_plug::prelude::*; 4 | use nih_plug_egui::EguiState; 5 | use faust_types::{FaustDsp, ParamIndex}; 6 | 7 | use crate::editor; 8 | 9 | #[derive(Params)] 10 | pub struct ElysieraParams { 11 | #[persist = "editor-state"] 12 | pub editor_state: Arc, 13 | 14 | #[id = "mix"] 15 | pub mix: FloatParam, 16 | #[id = "pre_gain"] 17 | pub pre_gain: FloatParam, 18 | #[id = "post_gain"] 19 | pub post_gain: FloatParam, 20 | #[id = "low_decay"] 21 | pub low_decay: FloatParam, 22 | #[id = "lf_crossover"] 23 | pub lf_crossover: FloatParam, 24 | #[id = "mid_decay"] 25 | pub mid_decay: FloatParam, 26 | #[id = "hf_damping"] 27 | pub hf_damping: FloatParam, 28 | #[id = "reverb_delay"] 29 | pub reverb_delay: FloatParam, 30 | #[id = "reverb_mix"] 31 | pub reverb_mix: FloatParam, 32 | #[id = "delay"] 33 | pub delay: FloatParam, 34 | #[id = "feedback"] 35 | pub feedback: FloatParam, 36 | #[id = "lowpass"] 37 | pub lowpass: FloatParam, 38 | #[id = "lowpass_q"] 39 | pub lowpass_q: FloatParam, 40 | #[id = "highpass"] 41 | pub highpass: FloatParam, 42 | #[id = "highpass_q"] 43 | pub highpass_q: FloatParam, 44 | #[id = "pitch_a"] 45 | pub pitch_a: FloatParam, 46 | #[id = "pitch_a_mix"] 47 | pub pitch_a_mix: FloatParam, 48 | #[id = "pitch_b"] 49 | pub pitch_b: FloatParam, 50 | #[id = "pitch_b_mix"] 51 | pub pitch_b_mix: FloatParam, 52 | #[id = "pitch_mod_rate"] 53 | pub pitch_mod_rate: FloatParam, 54 | #[id = "pitch_mod_mix"] 55 | pub pitch_mod_mix: FloatParam, 56 | #[id = "volume_mod_rate"] 57 | pub volume_mod_rate: FloatParam, 58 | #[id = "volume_mod_mix"] 59 | pub volume_mod_mix: FloatParam, 60 | } 61 | 62 | impl Default for ElysieraParams { 63 | fn default() -> Self { 64 | Self { 65 | editor_state: editor::default_state(), 66 | 67 | mix: param_percentage("Mix", 0.5, 0.0, 1.0), 68 | pre_gain: param_db("Pre Gain", 0.0, -30.0, 10.0), 69 | post_gain: param_db("Post Gain", 0.0, -30.0, 10.0), 70 | low_decay: param_s("Low decay", 3.7, 1.0, 60.0), 71 | lf_crossover: param_hz("LF Crossover", 440.0, 50.0, 1000.0), 72 | mid_decay: param_s("Mid Decay", 4.68, 1.0, 60.0), 73 | hf_damping: param_hz("HF Damping", 8600.0, 1500.0, 0.49 * 44100.0), 74 | reverb_delay: param_ms("Reverb Delay", 0.0, 0.0, 100.0), 75 | reverb_mix: param_percentage("Reverb Mix", 1.0, 0.0, 1.0), 76 | delay: param_s("Delay", 0.5, 0.0, 5.0), 77 | feedback: param_percentage("Feedback", 0.5, 0.0, 0.99), 78 | lowpass: param_hz("Lowpass", 18000.0, 25.0, 22000.0), 79 | lowpass_q: param_q("Lowpass Q", 0.71, 0.1, 2.0), 80 | highpass: param_hz("Highpass", 250.0, 25.0, 22000.0), 81 | highpass_q: param_q("Highpass Q", 0.71, 0.1, 2.0), 82 | pitch_a: param_st("Pitch A", 12.0, -12.0, 12.0), 83 | pitch_a_mix: param_percentage("Pitch A Mix", 0.6, 0.0, 1.0), 84 | pitch_b: param_st("Pitch B", 5.0, -12.0, 12.0), 85 | pitch_b_mix: param_percentage("Pitch B Mix", 0.6, 0.0, 1.0), 86 | pitch_mod_rate: param_hz("Pitch Mod Rate", 3.1, 0.01, 10.0), 87 | pitch_mod_mix: param_percentage("Pitch Mod Mix", 1.0, 0.0, 1.0), 88 | volume_mod_rate: param_hz("Volume Mod Rate", 3.1, 0.01, 10.0), 89 | volume_mod_mix: param_percentage("Volume Mod Mix", 1.0, 0.0, 1.0), 90 | } 91 | } 92 | } 93 | 94 | impl ElysieraParams { 95 | pub fn dsp_set_params(&self, dsp: &mut Box) { 96 | dsp.set_param(MIX, self.mix.value()); 97 | dsp.set_param(PRE_GAIN, self.pre_gain.value()); 98 | dsp.set_param(POST_GAIN, self.post_gain.value()); 99 | dsp.set_param(LOW_DECAY, self.low_decay.value()); 100 | dsp.set_param(LF_CROSSOVER, self.lf_crossover.value()); 101 | dsp.set_param(MID_DECAY, self.mid_decay.value()); 102 | dsp.set_param(HF_DAMPING, self.hf_damping.value()); 103 | dsp.set_param(REVERB_DELAY, self.reverb_delay.value()); 104 | dsp.set_param(REVERB_MIX, self.reverb_mix.value()); 105 | dsp.set_param(DELAY, self.delay.value()); 106 | dsp.set_param(FEEDBACK, self.feedback.value()); 107 | dsp.set_param(LOWPASS, self.lowpass.value()); 108 | dsp.set_param(LOWPASS_Q, self.lowpass_q.value()); 109 | dsp.set_param(HIGHPASS, self.highpass.value()); 110 | dsp.set_param(HIGHPASS_Q, self.highpass_q.value()); 111 | dsp.set_param(PITCH_A, self.pitch_a.value()); 112 | dsp.set_param(PITCH_A_MIX, self.pitch_a_mix.value()); 113 | dsp.set_param(PITCH_B, self.pitch_b.value()); 114 | dsp.set_param(PITCH_B_MIX, self.pitch_b_mix.value()); 115 | dsp.set_param(PITCH_MOD_RATE, self.pitch_mod_rate.value()); 116 | dsp.set_param(PITCH_MOD_MIX, self.pitch_mod_mix.value()); 117 | dsp.set_param(VOLUME_MOD_RATE, self.volume_mod_rate.value()); 118 | dsp.set_param(VOLUME_MOD_MIX, self.volume_mod_mix.value()); 119 | } 120 | } 121 | 122 | pub const MIX: ParamIndex = ParamIndex(0); 123 | pub const PRE_GAIN: ParamIndex = ParamIndex(1); 124 | pub const POST_GAIN: ParamIndex = ParamIndex(2); 125 | pub const LOW_DECAY: ParamIndex = ParamIndex(3); 126 | pub const LF_CROSSOVER: ParamIndex = ParamIndex(4); 127 | pub const MID_DECAY: ParamIndex = ParamIndex(5); 128 | pub const HF_DAMPING: ParamIndex = ParamIndex(6); 129 | pub const REVERB_DELAY: ParamIndex = ParamIndex(7); 130 | pub const REVERB_MIX: ParamIndex = ParamIndex(8); 131 | pub const DELAY: ParamIndex = ParamIndex(9); 132 | pub const FEEDBACK: ParamIndex = ParamIndex(10); 133 | pub const LOWPASS: ParamIndex = ParamIndex(11); 134 | pub const LOWPASS_Q: ParamIndex = ParamIndex(12); 135 | pub const HIGHPASS: ParamIndex = ParamIndex(13); 136 | pub const HIGHPASS_Q: ParamIndex = ParamIndex(14); 137 | pub const PITCH_A: ParamIndex = ParamIndex(15); 138 | pub const PITCH_A_MIX: ParamIndex = ParamIndex(16); 139 | pub const PITCH_B: ParamIndex = ParamIndex(17); 140 | pub const PITCH_B_MIX: ParamIndex = ParamIndex(18); 141 | pub const PITCH_MOD_RATE: ParamIndex = ParamIndex(19); 142 | pub const PITCH_MOD_MIX: ParamIndex = ParamIndex(20); 143 | pub const VOLUME_MOD_RATE: ParamIndex = ParamIndex(21); 144 | pub const VOLUME_MOD_MIX: ParamIndex = ParamIndex(22); 145 | 146 | fn param_db(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 147 | FloatParam::new( 148 | name, util::db_to_gain(default), 149 | FloatRange::Skewed { 150 | min: util::db_to_gain(min), 151 | max: util::db_to_gain(max), 152 | factor: FloatRange::gain_skew_factor(-30.0, 30.0), 153 | } 154 | ) 155 | .with_smoother(SmoothingStyle::Logarithmic(50.0)) 156 | .with_unit("dB") 157 | .with_value_to_string(formatters::v2s_f32_gain_to_db(2)) 158 | .with_string_to_value(formatters::s2v_f32_gain_to_db()) 159 | } 160 | 161 | fn param_st(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 162 | FloatParam::new( 163 | name, default, 164 | FloatRange::Linear {min, max}, 165 | ) 166 | .with_unit(" st") 167 | .with_smoother(SmoothingStyle::Linear(50.0)) 168 | .with_value_to_string(formatters::v2s_f32_rounded(2)) 169 | } 170 | 171 | fn param_q(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 172 | FloatParam::new( 173 | name, default, 174 | FloatRange::Skewed { 175 | min, 176 | max, 177 | factor: FloatRange::skew_factor(-1.0), 178 | }, 179 | ) 180 | .with_smoother(SmoothingStyle::Logarithmic(100.0)) 181 | .with_value_to_string(formatters::v2s_f32_rounded(2)) 182 | } 183 | 184 | fn param_hz(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 185 | FloatParam::new( 186 | name, default, 187 | FloatRange::Skewed { 188 | min, 189 | max, 190 | factor: FloatRange::skew_factor(-1.0), 191 | }, 192 | ) 193 | .with_smoother(SmoothingStyle::Logarithmic(100.0)) 194 | .with_value_to_string(formatters::v2s_f32_hz_then_khz(0)) 195 | .with_string_to_value(formatters::s2v_f32_hz_then_khz()) 196 | } 197 | 198 | fn param_float(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 199 | FloatParam::new( 200 | name, default, 201 | FloatRange::Linear {min, max}, 202 | ) 203 | .with_smoother(SmoothingStyle::Linear(50.0)) 204 | .with_value_to_string(formatters::v2s_f32_rounded(2)) 205 | } 206 | 207 | fn param_percentage(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 208 | FloatParam::new( 209 | name, default, 210 | FloatRange::Linear {min, max}, 211 | ) 212 | .with_unit(" %") 213 | .with_smoother(SmoothingStyle::Linear(50.0)) 214 | .with_value_to_string(formatters::v2s_f32_percentage(2)) 215 | .with_string_to_value(formatters::s2v_f32_percentage()) 216 | } 217 | 218 | fn param_s(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 219 | FloatParam::new( 220 | name, default, 221 | FloatRange::Linear {min, max}, 222 | ) 223 | .with_unit(" s") 224 | .with_smoother(SmoothingStyle::Linear(50.0)) 225 | .with_value_to_string(formatters::v2s_f32_rounded(3)) 226 | } 227 | 228 | fn param_ms(name: &'static str, default: f32, min: f32, max: f32) -> FloatParam { 229 | FloatParam::new( 230 | name, default, 231 | FloatRange::Linear {min, max}, 232 | ) 233 | .with_unit(" ms") 234 | .with_smoother(SmoothingStyle::Linear(50.0)) 235 | .with_value_to_string(formatters::v2s_f32_rounded(3)) 236 | } 237 | -------------------------------------------------------------------------------- /src/buffer.rs: -------------------------------------------------------------------------------- 1 | /* 2 | ┏━━━┓╱╱╱╱╱┏┓╱╱┏┓╱╱╱╱╱┏┓╱╱ 3 | ┃┏━┓┃╱╱╱╱╱┃┃╱╱┃┃╱╱╱╱╱┃┃╱╱╱ 4 | ┃┗━┛┣┓┏┳━━┫┃┏┓┃┃╱╱┏━━┫┗━┳━━┓ 5 | ┃┏━━┫┃┃┃┏┓┃┗┛┃┃┃╱┏┫┏┓┃┏┓┃━━┫ 6 | ┃┃╱╱┃┗┛┃┃┃┃┏┓┃┃┗━┛┃┏┓┃┗┛┣━━┃ 7 | ┗┛╱╱┗━━┻┛┗┻┛┗┛┗━━━┻┛┗┻━━┻━━┛ 8 | ━━━━━━━━━━━━━━━━━━━━━━━━━━ 9 | 10 | Copyright (c) 2022 Punk Labs LLC 11 | 12 | This section is part of OneTrick 13 | 14 | OneTrick is free software: you can redistribute it and/or modify it 15 | under the terms of the GNU General Public License as published by the Free 16 | Software Foundation, either version 3 of the License, or (at your option) 17 | any later version. 18 | 19 | OneTrick is distributed in the hope that it will be useful, but WITHOUT 20 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 21 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 22 | more details. 23 | 24 | You should have received a copy of the GNU General Public License along with 25 | OneTrick. If not, see . 26 | */ 27 | use nih_plug::prelude::*; 28 | 29 | #[derive(Default)] 30 | pub struct TempBuffer { 31 | data: Vec>, 32 | } 33 | 34 | #[allow(unused)] 35 | impl TempBuffer { 36 | pub fn channel_count(&self) -> usize { 37 | self.data.len() 38 | } 39 | pub fn resize(&mut self, channel_count: usize, max_frames: usize) { 40 | if self.data.len() < channel_count || (channel_count > 0 && self.data[0].len() < max_frames) 41 | { 42 | self.data.clear(); 43 | for _i in 0..channel_count { 44 | self.data.push(vec![0.0; max_frames]); 45 | } 46 | } 47 | } 48 | pub fn data(&self) -> &Vec> { 49 | &self.data 50 | } 51 | 52 | pub fn data_mut(&mut self) -> &mut Vec> { 53 | &mut self.data 54 | } 55 | 56 | pub fn clear(&mut self) { 57 | for channel in self.data.iter_mut() { 58 | channel.fill(0.0); 59 | } 60 | } 61 | pub fn clear_frames(&mut self, frames: usize) { 62 | for channel in self.data.iter_mut() { 63 | channel[0..frames].fill(0.0); 64 | } 65 | } 66 | 67 | pub fn add_to_temp_buffer(&self, to_buffer: &mut TempBuffer) { 68 | for (self_channel, to_channel) in self.data.iter().zip(to_buffer.data_mut()) { 69 | for (to, from) in to_channel.iter_mut().zip(self_channel) { 70 | *to += *from; 71 | } 72 | } 73 | } 74 | pub fn add_to_temp_buffer_frames(&self, to_buffer: &mut TempBuffer, frames: usize) { 75 | for (self_channel, to_channel) in self.data.iter().zip(to_buffer.data_mut()) { 76 | for (to, from) in to_channel[0..frames].iter_mut().zip(self_channel) { 77 | *to += *from; 78 | } 79 | } 80 | } 81 | 82 | pub fn add_to_buffer(&self, to_buffer: &mut [&mut [f32]]) { 83 | for (self_channel, to_channel) in self.data.iter().zip(to_buffer.iter_mut()) { 84 | for (to, from) in to_channel.iter_mut().zip(self_channel) { 85 | *to += *from; 86 | } 87 | } 88 | } 89 | pub fn add_to_buffer_frames(&self, to_buffer: &mut [&mut [f32]], frames: usize) { 90 | for (self_channel, to_channel) in self.data.iter().zip(to_buffer.iter_mut()) { 91 | for (to, from) in to_channel[0..frames].iter_mut().zip(self_channel) { 92 | *to += *from; 93 | } 94 | } 95 | } 96 | 97 | pub fn write_to_buffer(&self, to_buffer: &mut [&mut [f32]]) { 98 | for (self_channel, to_channel) in self.data.iter().zip(to_buffer.iter_mut()) { 99 | to_channel.copy_from_slice(&self_channel[..to_channel.len().min(self_channel.len())]); 100 | } 101 | } 102 | pub fn write_to_buffer_frames(&self, to_buffer: &mut [&mut [f32]], frames: usize) { 103 | for (self_channel, to_channel) in self.data.iter().zip(to_buffer.iter_mut()) { 104 | to_channel.copy_from_slice( 105 | &self_channel[..to_channel.len().min(self_channel.len()).min(frames)], 106 | ); 107 | } 108 | } 109 | pub fn read_from_buffer(&mut self, from_buffer: &mut Buffer) { 110 | for (buffer_channel, self_channel) in from_buffer 111 | .as_slice_immutable() 112 | .iter() 113 | .zip(self.data.iter_mut()) 114 | { 115 | for (buffer_sample, self_sample) in buffer_channel.iter().zip(self_channel) { 116 | *self_sample = *buffer_sample; 117 | } 118 | } 119 | } 120 | /* 121 | pub fn read_from_buffer(&mut self, from_buffer: &mut Buffer) { 122 | for (buffer_channel, mut self_channel) in from_buffer.as_slice().iter().zip(self.data.iter_mut()) { 123 | let self_len = self_channel.len(); 124 | //self_channel.copy_from_slice( //Allocation 125 | // &buffer_channel[..self_len.min(buffer_channel.len())] 126 | //); 127 | } 128 | } 129 | */ 130 | pub fn read_from_slice(&mut self, from_buffer: &[&[f32]]) { 131 | for (self_channel, from_channel) in self.data.iter_mut().zip(from_buffer.iter()) { 132 | let self_len = self_channel.len(); 133 | self_channel.copy_from_slice(&from_channel[..self_len.min(from_channel.len())]); 134 | } 135 | } 136 | pub fn read_from_slice_frames(&mut self, from_buffer: &[&[f32]], frames: usize) { 137 | for (self_channel, from_channel) in self.data.iter_mut().zip(from_buffer.iter()) { 138 | let self_len = self_channel.len(); 139 | self_channel 140 | .copy_from_slice(&from_channel[..self_len.min(from_channel.len()).min(frames)]); 141 | } 142 | } 143 | pub fn read_from_mut_slice(&mut self, from_buffer: &mut [&mut [f32]]) { 144 | for (self_channel, from_channel) in self.data.iter_mut().zip(from_buffer.iter()) { 145 | let self_len = self_channel.len(); 146 | self_channel.copy_from_slice(&from_channel[..self_len.min(from_channel.len())]); 147 | } 148 | } 149 | pub fn read_from_mut_slice_frames(&mut self, from_buffer: &mut [&mut [f32]], frames: usize) { 150 | for (self_channel, from_channel) in self.data.iter_mut().zip(from_buffer.iter()) { 151 | let self_len = self_channel.len(); 152 | self_channel 153 | .copy_from_slice(&from_channel[..self_len.min(from_channel.len()).min(frames)]); 154 | } 155 | } 156 | /* 157 | // Allocates a Vec on the heap, so not suitable for DSP... 158 | // Relevant Discussion: https://internals.rust-lang.org/t/collecting-iterators-into-arrays/10330 159 | pub fn slice(&self) -> [&[f32]; N] { 160 | let slice = self.data.as_slice(); 161 | let mut sliced = slice.iter().map(|ch| ch.as_slice()); 162 | sliced.collect::>().try_into().unwrap() 163 | } 164 | */ 165 | pub fn slice1d(&self) -> [&[f32]; 1] { 166 | let slice = self.data.as_slice(); 167 | let mut sliced = slice.iter().map(|ch| ch.as_slice()); 168 | [sliced.next().unwrap()] 169 | } 170 | pub fn slice2d(&self) -> [&[f32]; 2] { 171 | let slice = self.data.as_slice(); 172 | let mut sliced = slice.iter().map(|ch| ch.as_slice()); 173 | [sliced.next().unwrap(), sliced.next().unwrap()] 174 | } 175 | pub fn slice3d(&self) -> [&[f32]; 3] { 176 | let slice = self.data.as_slice(); 177 | let mut sliced = slice.iter().map(|ch| ch.as_slice()); 178 | [ 179 | sliced.next().unwrap(), 180 | sliced.next().unwrap(), 181 | sliced.next().unwrap(), 182 | ] 183 | } 184 | pub fn slice4d(&self) -> [&[f32]; 4] { 185 | let slice = self.data.as_slice(); 186 | let mut sliced = slice.iter().map(|ch| ch.as_slice()); 187 | [ 188 | sliced.next().unwrap(), 189 | sliced.next().unwrap(), 190 | sliced.next().unwrap(), 191 | sliced.next().unwrap(), 192 | ] 193 | } 194 | } 195 | 196 | // pub trait BufferSlicer { 197 | // fn slice1d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 1]; 198 | // fn slice2d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 2]; 199 | // fn slice3d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 3]; 200 | // fn slice4d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 4]; 201 | // } 202 | 203 | // impl<'buffer> BufferSlicer for Buffer<'buffer> { 204 | // fn slice1d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 1] { 205 | // let slice = self.as_slice(); 206 | // let mut sliced = slice.iter_mut().map(|ch| &mut ch[start_index..end_index]); 207 | // [sliced.next().unwrap()] 208 | // } 209 | 210 | // fn slice2d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 2] { 211 | // let slice = self.as_slice(); 212 | // let mut sliced = slice.iter_mut().map(|ch| &mut ch[start_index..end_index]); 213 | // [sliced.next().unwrap(), sliced.next().unwrap()] 214 | // } 215 | 216 | // fn slice3d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 3] { 217 | // let slice = self.as_slice(); 218 | // let mut sliced = slice.iter_mut().map(|ch| &mut ch[start_index..end_index]); 219 | // [ 220 | // sliced.next().unwrap(), 221 | // sliced.next().unwrap(), 222 | // sliced.next().unwrap(), 223 | // ] 224 | // } 225 | // fn slice4d(&mut self, start_index: usize, end_index: usize) -> [&mut [f32]; 4] { 226 | // let slice = self.as_slice(); 227 | // let mut sliced = slice.iter_mut().map(|ch| &mut ch[start_index..end_index]); 228 | // [ 229 | // sliced.next().unwrap(), 230 | // sliced.next().unwrap(), 231 | // sliced.next().unwrap(), 232 | // sliced.next().unwrap(), 233 | // ] 234 | // } 235 | // } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /src/dsp.rs: -------------------------------------------------------------------------------- 1 | mod dsp { 2 | #![allow(clippy::all)] 3 | #![allow(unused_parens)] 4 | #![allow(non_snake_case)] 5 | #![allow(non_camel_case_types)] 6 | #![allow(dead_code)] 7 | #![allow(unused_variables)] 8 | #![allow(unused_mut)] 9 | #![allow(non_upper_case_globals)] 10 | 11 | use faust_types::*; 12 | /* ------------------------------------------------------------ 13 | name: "elysiera" 14 | version: "1.0" 15 | Code generated with Faust 2.70.3 (https://faust.grame.fr) 16 | Compilation options: -lang rust -ct 1 -es 1 -mcd 16 -mdd 1024 -mdy 33 -single -ftz 0 17 | ------------------------------------------------------------ */ 18 | 19 | 20 | pub struct mydspSIG0 { 21 | iVec0: [i32;2], 22 | iRec0: [i32;2], 23 | } 24 | 25 | impl mydspSIG0 { 26 | 27 | fn get_num_inputsmydspSIG0(&self) -> i32 { 28 | return 0; 29 | } 30 | fn get_num_outputsmydspSIG0(&self) -> i32 { 31 | return 1; 32 | } 33 | 34 | fn instance_initmydspSIG0(&mut self, sample_rate: i32) { 35 | for l0 in 0..2 { 36 | self.iVec0[l0 as usize] = 0; 37 | } 38 | for l1 in 0..2 { 39 | self.iRec0[l1 as usize] = 0; 40 | } 41 | } 42 | 43 | fn fillmydspSIG0(&mut self, count: i32, table: &mut[f32]) { 44 | for i1 in 0..count { 45 | self.iVec0[0] = 1; 46 | self.iRec0[0] = (i32::wrapping_add(self.iVec0[1], self.iRec0[1])) % 65536; 47 | table[i1 as usize] = f32::sin(9.58738e-05 * (self.iRec0[0]) as f32); 48 | self.iVec0[1] = self.iVec0[0]; 49 | self.iRec0[1] = self.iRec0[0]; 50 | } 51 | } 52 | 53 | } 54 | 55 | 56 | pub fn newmydspSIG0() -> mydspSIG0 { 57 | mydspSIG0 { 58 | iVec0: [0;2], 59 | iRec0: [0;2], 60 | } 61 | } 62 | 63 | pub struct mydspSIG1 { 64 | iVec2: [i32;2], 65 | iRec2: [i32;2], 66 | } 67 | 68 | impl mydspSIG1 { 69 | 70 | fn get_num_inputsmydspSIG1(&self) -> i32 { 71 | return 0; 72 | } 73 | fn get_num_outputsmydspSIG1(&self) -> i32 { 74 | return 1; 75 | } 76 | 77 | fn instance_initmydspSIG1(&mut self, sample_rate: i32) { 78 | for l4 in 0..2 { 79 | self.iVec2[l4 as usize] = 0; 80 | } 81 | for l5 in 0..2 { 82 | self.iRec2[l5 as usize] = 0; 83 | } 84 | } 85 | 86 | fn fillmydspSIG1(&mut self, count: i32, table: &mut[f32]) { 87 | for i2 in 0..count { 88 | self.iVec2[0] = 1; 89 | self.iRec2[0] = (i32::wrapping_add(self.iVec2[1], self.iRec2[1])) % 65536; 90 | table[i2 as usize] = f32::cos(9.58738e-05 * (self.iRec2[0]) as f32); 91 | self.iVec2[1] = self.iVec2[0]; 92 | self.iRec2[1] = self.iRec2[0]; 93 | } 94 | } 95 | 96 | } 97 | 98 | 99 | pub fn newmydspSIG1() -> mydspSIG1 { 100 | mydspSIG1 { 101 | iVec2: [0;2], 102 | iRec2: [0;2], 103 | } 104 | } 105 | static mut ftbl0mydspSIG0: [f32;65536] = [0.0;65536]; 106 | static mut ftbl1mydspSIG1: [f32;65536] = [0.0;65536]; 107 | fn mydsp_faustpower2_f(value: f32) -> f32 { 108 | return value * value; 109 | } 110 | 111 | #[cfg_attr(feature = "default-boxed", derive(default_boxed::DefaultBoxed))] 112 | #[repr(C)] 113 | pub struct mydsp { 114 | fVslider0: f32, 115 | fVslider1: f32, 116 | iVec1: [i32;2], 117 | fVslider2: f32, 118 | fSampleRate: i32, 119 | fConst0: f32, 120 | fConst1: f32, 121 | fRec1: [f32;2], 122 | fVslider3: f32, 123 | fVslider4: f32, 124 | fRec3: [f32;2], 125 | fVslider5: f32, 126 | fVslider6: f32, 127 | fRec4: [f32;2], 128 | fVslider7: f32, 129 | fConst2: f32, 130 | fVslider8: f32, 131 | fRec10: [f32;2], 132 | fRec11: [f32;2], 133 | fVslider9: f32, 134 | fVslider10: f32, 135 | fRec6: [f32;2], 136 | fRec7: [f32;2], 137 | IOTA0: i32, 138 | fConst3: f32, 139 | fVslider11: f32, 140 | fVslider12: f32, 141 | fRec5: [f32;1048576], 142 | fVslider13: f32, 143 | fVslider14: f32, 144 | fRec13: [f32;2], 145 | fVslider15: f32, 146 | fVec3: [f32;16384], 147 | fVslider16: f32, 148 | fRec29: [f32;2], 149 | fRec30: [f32;2], 150 | fRec25: [f32;2], 151 | fRec26: [f32;2], 152 | fRec24: [f32;1048576], 153 | fVec4: [f32;16384], 154 | fVslider17: f32, 155 | fConst4: f32, 156 | fVslider18: f32, 157 | fConst6: f32, 158 | fVslider19: f32, 159 | fConst7: f32, 160 | fVslider20: f32, 161 | fRec33: [f32;2], 162 | fVslider21: f32, 163 | fRec32: [f32;2], 164 | fVec5: [f32;32768], 165 | iConst9: i32, 166 | fVec6: [f32;4096], 167 | iConst10: i32, 168 | fRec22: [f32;2], 169 | fConst12: f32, 170 | fRec37: [f32;2], 171 | fRec36: [f32;2], 172 | fVec7: [f32;16384], 173 | iConst14: i32, 174 | fVec8: [f32;2048], 175 | iConst15: i32, 176 | fRec34: [f32;2], 177 | fConst17: f32, 178 | fRec41: [f32;2], 179 | fRec40: [f32;2], 180 | fVec9: [f32;16384], 181 | iConst19: i32, 182 | fVec10: [f32;2048], 183 | iConst20: i32, 184 | fRec38: [f32;2], 185 | fConst22: f32, 186 | fRec45: [f32;2], 187 | fRec44: [f32;2], 188 | fVec11: [f32;16384], 189 | iConst24: i32, 190 | fVec12: [f32;4096], 191 | iConst25: i32, 192 | fRec42: [f32;2], 193 | fConst27: f32, 194 | fRec49: [f32;2], 195 | fRec48: [f32;2], 196 | fVec13: [f32;16384], 197 | iConst29: i32, 198 | fVec14: [f32;2048], 199 | iConst30: i32, 200 | fRec46: [f32;2], 201 | fConst32: f32, 202 | fRec53: [f32;2], 203 | fRec52: [f32;2], 204 | fVec15: [f32;32768], 205 | iConst34: i32, 206 | fVec16: [f32;4096], 207 | iConst35: i32, 208 | fRec50: [f32;2], 209 | fConst37: f32, 210 | fRec57: [f32;2], 211 | fRec56: [f32;2], 212 | fVec17: [f32;16384], 213 | iConst39: i32, 214 | fVec18: [f32;4096], 215 | iConst40: i32, 216 | fRec54: [f32;2], 217 | fConst42: f32, 218 | fRec61: [f32;2], 219 | fRec60: [f32;2], 220 | fVec19: [f32;32768], 221 | iConst44: i32, 222 | fVec20: [f32;2048], 223 | iConst45: i32, 224 | fRec58: [f32;2], 225 | fRec14: [f32;3], 226 | fRec15: [f32;3], 227 | fRec16: [f32;3], 228 | fRec17: [f32;3], 229 | fRec18: [f32;3], 230 | fRec19: [f32;3], 231 | fRec20: [f32;3], 232 | fRec21: [f32;3], 233 | fVslider22: f32, 234 | } 235 | 236 | impl FaustDsp for mydsp { 237 | type T = f32; 238 | 239 | fn new() -> mydsp { 240 | mydsp { 241 | fVslider0: 0.0, 242 | fVslider1: 0.0, 243 | iVec1: [0;2], 244 | fVslider2: 0.0, 245 | fSampleRate: 0, 246 | fConst0: 0.0, 247 | fConst1: 0.0, 248 | fRec1: [0.0;2], 249 | fVslider3: 0.0, 250 | fVslider4: 0.0, 251 | fRec3: [0.0;2], 252 | fVslider5: 0.0, 253 | fVslider6: 0.0, 254 | fRec4: [0.0;2], 255 | fVslider7: 0.0, 256 | fConst2: 0.0, 257 | fVslider8: 0.0, 258 | fRec10: [0.0;2], 259 | fRec11: [0.0;2], 260 | fVslider9: 0.0, 261 | fVslider10: 0.0, 262 | fRec6: [0.0;2], 263 | fRec7: [0.0;2], 264 | IOTA0: 0, 265 | fConst3: 0.0, 266 | fVslider11: 0.0, 267 | fVslider12: 0.0, 268 | fRec5: [0.0;1048576], 269 | fVslider13: 0.0, 270 | fVslider14: 0.0, 271 | fRec13: [0.0;2], 272 | fVslider15: 0.0, 273 | fVec3: [0.0;16384], 274 | fVslider16: 0.0, 275 | fRec29: [0.0;2], 276 | fRec30: [0.0;2], 277 | fRec25: [0.0;2], 278 | fRec26: [0.0;2], 279 | fRec24: [0.0;1048576], 280 | fVec4: [0.0;16384], 281 | fVslider17: 0.0, 282 | fConst4: 0.0, 283 | fVslider18: 0.0, 284 | fConst6: 0.0, 285 | fVslider19: 0.0, 286 | fConst7: 0.0, 287 | fVslider20: 0.0, 288 | fRec33: [0.0;2], 289 | fVslider21: 0.0, 290 | fRec32: [0.0;2], 291 | fVec5: [0.0;32768], 292 | iConst9: 0, 293 | fVec6: [0.0;4096], 294 | iConst10: 0, 295 | fRec22: [0.0;2], 296 | fConst12: 0.0, 297 | fRec37: [0.0;2], 298 | fRec36: [0.0;2], 299 | fVec7: [0.0;16384], 300 | iConst14: 0, 301 | fVec8: [0.0;2048], 302 | iConst15: 0, 303 | fRec34: [0.0;2], 304 | fConst17: 0.0, 305 | fRec41: [0.0;2], 306 | fRec40: [0.0;2], 307 | fVec9: [0.0;16384], 308 | iConst19: 0, 309 | fVec10: [0.0;2048], 310 | iConst20: 0, 311 | fRec38: [0.0;2], 312 | fConst22: 0.0, 313 | fRec45: [0.0;2], 314 | fRec44: [0.0;2], 315 | fVec11: [0.0;16384], 316 | iConst24: 0, 317 | fVec12: [0.0;4096], 318 | iConst25: 0, 319 | fRec42: [0.0;2], 320 | fConst27: 0.0, 321 | fRec49: [0.0;2], 322 | fRec48: [0.0;2], 323 | fVec13: [0.0;16384], 324 | iConst29: 0, 325 | fVec14: [0.0;2048], 326 | iConst30: 0, 327 | fRec46: [0.0;2], 328 | fConst32: 0.0, 329 | fRec53: [0.0;2], 330 | fRec52: [0.0;2], 331 | fVec15: [0.0;32768], 332 | iConst34: 0, 333 | fVec16: [0.0;4096], 334 | iConst35: 0, 335 | fRec50: [0.0;2], 336 | fConst37: 0.0, 337 | fRec57: [0.0;2], 338 | fRec56: [0.0;2], 339 | fVec17: [0.0;16384], 340 | iConst39: 0, 341 | fVec18: [0.0;4096], 342 | iConst40: 0, 343 | fRec54: [0.0;2], 344 | fConst42: 0.0, 345 | fRec61: [0.0;2], 346 | fRec60: [0.0;2], 347 | fVec19: [0.0;32768], 348 | iConst44: 0, 349 | fVec20: [0.0;2048], 350 | iConst45: 0, 351 | fRec58: [0.0;2], 352 | fRec14: [0.0;3], 353 | fRec15: [0.0;3], 354 | fRec16: [0.0;3], 355 | fRec17: [0.0;3], 356 | fRec18: [0.0;3], 357 | fRec19: [0.0;3], 358 | fRec20: [0.0;3], 359 | fRec21: [0.0;3], 360 | fVslider22: 0.0, 361 | } 362 | } 363 | fn metadata(&self, m: &mut dyn Meta) { 364 | m.declare("basics.lib/name", r"Faust Basic Element Library"); 365 | m.declare("basics.lib/tabulateNd", r"Copyright (C) 2023 Bart Brouns "); 366 | m.declare("basics.lib/version", r"1.12.0"); 367 | m.declare("compile_options", r"-lang rust -ct 1 -es 1 -mcd 16 -mdd 1024 -mdy 33 -single -ftz 0"); 368 | m.declare("delays.lib/name", r"Faust Delay Library"); 369 | m.declare("delays.lib/version", r"1.1.0"); 370 | m.declare("filename", r"dsp"); 371 | m.declare("filters.lib/allpass_comb:author", r"Julius O. Smith III"); 372 | m.declare("filters.lib/allpass_comb:copyright", r"Copyright (C) 2003-2019 by Julius O. Smith III "); 373 | m.declare("filters.lib/allpass_comb:license", r"MIT-style STK-4.3 license"); 374 | m.declare("filters.lib/lowpass0_highpass1", r"MIT-style STK-4.3 license"); 375 | m.declare("filters.lib/lowpass0_highpass1:author", r"Julius O. Smith III"); 376 | m.declare("filters.lib/lowpass:author", r"Julius O. Smith III"); 377 | m.declare("filters.lib/lowpass:copyright", r"Copyright (C) 2003-2019 by Julius O. Smith III "); 378 | m.declare("filters.lib/lowpass:license", r"MIT-style STK-4.3 license"); 379 | m.declare("filters.lib/name", r"Faust Filters Library"); 380 | m.declare("filters.lib/svf:author", r"Oleg Nesterov"); 381 | m.declare("filters.lib/svf:copyright", r"Copyright (C) 2020 Oleg Nesterov "); 382 | m.declare("filters.lib/svf:license", r"MIT-style STK-4.3 license"); 383 | m.declare("filters.lib/tf1:author", r"Julius O. Smith III"); 384 | m.declare("filters.lib/tf1:copyright", r"Copyright (C) 2003-2019 by Julius O. Smith III "); 385 | m.declare("filters.lib/tf1:license", r"MIT-style STK-4.3 license"); 386 | m.declare("filters.lib/tf1s:author", r"Julius O. Smith III"); 387 | m.declare("filters.lib/tf1s:copyright", r"Copyright (C) 2003-2019 by Julius O. Smith III "); 388 | m.declare("filters.lib/tf1s:license", r"MIT-style STK-4.3 license"); 389 | m.declare("filters.lib/version", r"1.3.0"); 390 | m.declare("maths.lib/author", r"GRAME"); 391 | m.declare("maths.lib/copyright", r"GRAME"); 392 | m.declare("maths.lib/license", r"LGPL with exception"); 393 | m.declare("maths.lib/name", r"Faust Math Library"); 394 | m.declare("maths.lib/version", r"2.7.0"); 395 | m.declare("misceffects.lib/dryWetMixerConstantPower:author", r"David Braun, revised by Stéphane Letz"); 396 | m.declare("misceffects.lib/echo:author", r"Romain Michon"); 397 | m.declare("misceffects.lib/name", r"Misc Effects Library"); 398 | m.declare("misceffects.lib/version", r"2.4.0"); 399 | m.declare("name", r"elysiera"); 400 | m.declare("oscillators.lib/name", r"Faust Oscillator Library"); 401 | m.declare("oscillators.lib/version", r"1.5.0"); 402 | m.declare("platform.lib/name", r"Generic Platform Library"); 403 | m.declare("platform.lib/version", r"1.3.0"); 404 | m.declare("reverbs.lib/name", r"Faust Reverb Library"); 405 | m.declare("reverbs.lib/version", r"1.2.1"); 406 | m.declare("routes.lib/hadamard:author", r"Remy Muller, revised by Romain Michon"); 407 | m.declare("routes.lib/name", r"Faust Signal Routing Library"); 408 | m.declare("routes.lib/version", r"1.2.0"); 409 | m.declare("signals.lib/name", r"Faust Signal Routing Library"); 410 | m.declare("signals.lib/version", r"1.5.0"); 411 | m.declare("version", r"1.0"); 412 | } 413 | 414 | fn get_sample_rate(&self) -> i32 { 415 | return self.fSampleRate; 416 | } 417 | fn get_num_inputs(&self) -> i32 { 418 | return 2; 419 | } 420 | fn get_num_outputs(&self) -> i32 { 421 | return 2; 422 | } 423 | 424 | fn class_init(sample_rate: i32) { 425 | let mut sig0: mydspSIG0 = newmydspSIG0(); 426 | sig0.instance_initmydspSIG0(sample_rate); 427 | sig0.fillmydspSIG0(65536, unsafe { &mut ftbl0mydspSIG0 }); 428 | let mut sig1: mydspSIG1 = newmydspSIG1(); 429 | sig1.instance_initmydspSIG1(sample_rate); 430 | sig1.fillmydspSIG1(65536, unsafe { &mut ftbl1mydspSIG1 }); 431 | } 432 | fn instance_reset_params(&mut self) { 433 | self.fVslider0 = 0.0; 434 | self.fVslider1 = 0.5; 435 | self.fVslider2 = 3.1; 436 | self.fVslider3 = 1.0; 437 | self.fVslider4 = 3.1; 438 | self.fVslider5 = 1.0; 439 | self.fVslider6 = 5.0; 440 | self.fVslider7 = 1.8e+04; 441 | self.fVslider8 = 0.71; 442 | self.fVslider9 = 2.5e+02; 443 | self.fVslider10 = 0.71; 444 | self.fVslider11 = 0.5; 445 | self.fVslider12 = 0.5; 446 | self.fVslider13 = 0.6; 447 | self.fVslider14 = 12.0; 448 | self.fVslider15 = 0.6; 449 | self.fVslider16 = 1.0; 450 | self.fVslider17 = 0.0; 451 | self.fVslider18 = 4.68; 452 | self.fVslider19 = 8.6e+03; 453 | self.fVslider20 = 4.4e+02; 454 | self.fVslider21 = 3.7; 455 | self.fVslider22 = 0.0; 456 | } 457 | fn instance_clear(&mut self) { 458 | for l2 in 0..2 { 459 | self.iVec1[l2 as usize] = 0; 460 | } 461 | for l3 in 0..2 { 462 | self.fRec1[l3 as usize] = 0.0; 463 | } 464 | for l6 in 0..2 { 465 | self.fRec3[l6 as usize] = 0.0; 466 | } 467 | for l7 in 0..2 { 468 | self.fRec4[l7 as usize] = 0.0; 469 | } 470 | for l8 in 0..2 { 471 | self.fRec10[l8 as usize] = 0.0; 472 | } 473 | for l9 in 0..2 { 474 | self.fRec11[l9 as usize] = 0.0; 475 | } 476 | for l10 in 0..2 { 477 | self.fRec6[l10 as usize] = 0.0; 478 | } 479 | for l11 in 0..2 { 480 | self.fRec7[l11 as usize] = 0.0; 481 | } 482 | self.IOTA0 = 0; 483 | for l12 in 0..1048576 { 484 | self.fRec5[l12 as usize] = 0.0; 485 | } 486 | for l13 in 0..2 { 487 | self.fRec13[l13 as usize] = 0.0; 488 | } 489 | for l14 in 0..16384 { 490 | self.fVec3[l14 as usize] = 0.0; 491 | } 492 | for l15 in 0..2 { 493 | self.fRec29[l15 as usize] = 0.0; 494 | } 495 | for l16 in 0..2 { 496 | self.fRec30[l16 as usize] = 0.0; 497 | } 498 | for l17 in 0..2 { 499 | self.fRec25[l17 as usize] = 0.0; 500 | } 501 | for l18 in 0..2 { 502 | self.fRec26[l18 as usize] = 0.0; 503 | } 504 | for l19 in 0..1048576 { 505 | self.fRec24[l19 as usize] = 0.0; 506 | } 507 | for l20 in 0..16384 { 508 | self.fVec4[l20 as usize] = 0.0; 509 | } 510 | for l21 in 0..2 { 511 | self.fRec33[l21 as usize] = 0.0; 512 | } 513 | for l22 in 0..2 { 514 | self.fRec32[l22 as usize] = 0.0; 515 | } 516 | for l23 in 0..32768 { 517 | self.fVec5[l23 as usize] = 0.0; 518 | } 519 | for l24 in 0..4096 { 520 | self.fVec6[l24 as usize] = 0.0; 521 | } 522 | for l25 in 0..2 { 523 | self.fRec22[l25 as usize] = 0.0; 524 | } 525 | for l26 in 0..2 { 526 | self.fRec37[l26 as usize] = 0.0; 527 | } 528 | for l27 in 0..2 { 529 | self.fRec36[l27 as usize] = 0.0; 530 | } 531 | for l28 in 0..16384 { 532 | self.fVec7[l28 as usize] = 0.0; 533 | } 534 | for l29 in 0..2048 { 535 | self.fVec8[l29 as usize] = 0.0; 536 | } 537 | for l30 in 0..2 { 538 | self.fRec34[l30 as usize] = 0.0; 539 | } 540 | for l31 in 0..2 { 541 | self.fRec41[l31 as usize] = 0.0; 542 | } 543 | for l32 in 0..2 { 544 | self.fRec40[l32 as usize] = 0.0; 545 | } 546 | for l33 in 0..16384 { 547 | self.fVec9[l33 as usize] = 0.0; 548 | } 549 | for l34 in 0..2048 { 550 | self.fVec10[l34 as usize] = 0.0; 551 | } 552 | for l35 in 0..2 { 553 | self.fRec38[l35 as usize] = 0.0; 554 | } 555 | for l36 in 0..2 { 556 | self.fRec45[l36 as usize] = 0.0; 557 | } 558 | for l37 in 0..2 { 559 | self.fRec44[l37 as usize] = 0.0; 560 | } 561 | for l38 in 0..16384 { 562 | self.fVec11[l38 as usize] = 0.0; 563 | } 564 | for l39 in 0..4096 { 565 | self.fVec12[l39 as usize] = 0.0; 566 | } 567 | for l40 in 0..2 { 568 | self.fRec42[l40 as usize] = 0.0; 569 | } 570 | for l41 in 0..2 { 571 | self.fRec49[l41 as usize] = 0.0; 572 | } 573 | for l42 in 0..2 { 574 | self.fRec48[l42 as usize] = 0.0; 575 | } 576 | for l43 in 0..16384 { 577 | self.fVec13[l43 as usize] = 0.0; 578 | } 579 | for l44 in 0..2048 { 580 | self.fVec14[l44 as usize] = 0.0; 581 | } 582 | for l45 in 0..2 { 583 | self.fRec46[l45 as usize] = 0.0; 584 | } 585 | for l46 in 0..2 { 586 | self.fRec53[l46 as usize] = 0.0; 587 | } 588 | for l47 in 0..2 { 589 | self.fRec52[l47 as usize] = 0.0; 590 | } 591 | for l48 in 0..32768 { 592 | self.fVec15[l48 as usize] = 0.0; 593 | } 594 | for l49 in 0..4096 { 595 | self.fVec16[l49 as usize] = 0.0; 596 | } 597 | for l50 in 0..2 { 598 | self.fRec50[l50 as usize] = 0.0; 599 | } 600 | for l51 in 0..2 { 601 | self.fRec57[l51 as usize] = 0.0; 602 | } 603 | for l52 in 0..2 { 604 | self.fRec56[l52 as usize] = 0.0; 605 | } 606 | for l53 in 0..16384 { 607 | self.fVec17[l53 as usize] = 0.0; 608 | } 609 | for l54 in 0..4096 { 610 | self.fVec18[l54 as usize] = 0.0; 611 | } 612 | for l55 in 0..2 { 613 | self.fRec54[l55 as usize] = 0.0; 614 | } 615 | for l56 in 0..2 { 616 | self.fRec61[l56 as usize] = 0.0; 617 | } 618 | for l57 in 0..2 { 619 | self.fRec60[l57 as usize] = 0.0; 620 | } 621 | for l58 in 0..32768 { 622 | self.fVec19[l58 as usize] = 0.0; 623 | } 624 | for l59 in 0..2048 { 625 | self.fVec20[l59 as usize] = 0.0; 626 | } 627 | for l60 in 0..2 { 628 | self.fRec58[l60 as usize] = 0.0; 629 | } 630 | for l61 in 0..3 { 631 | self.fRec14[l61 as usize] = 0.0; 632 | } 633 | for l62 in 0..3 { 634 | self.fRec15[l62 as usize] = 0.0; 635 | } 636 | for l63 in 0..3 { 637 | self.fRec16[l63 as usize] = 0.0; 638 | } 639 | for l64 in 0..3 { 640 | self.fRec17[l64 as usize] = 0.0; 641 | } 642 | for l65 in 0..3 { 643 | self.fRec18[l65 as usize] = 0.0; 644 | } 645 | for l66 in 0..3 { 646 | self.fRec19[l66 as usize] = 0.0; 647 | } 648 | for l67 in 0..3 { 649 | self.fRec20[l67 as usize] = 0.0; 650 | } 651 | for l68 in 0..3 { 652 | self.fRec21[l68 as usize] = 0.0; 653 | } 654 | } 655 | fn instance_constants(&mut self, sample_rate: i32) { 656 | self.fSampleRate = sample_rate; 657 | self.fConst0 = f32::min(1.92e+05, f32::max(1.0, (self.fSampleRate) as f32)); 658 | self.fConst1 = 1.0 / self.fConst0; 659 | self.fConst2 = 3.1415927 / self.fConst0; 660 | self.fConst3 = 5.0 * self.fConst0; 661 | self.fConst4 = 0.001 * self.fConst0; 662 | let mut fConst5: f32 = f32::floor(0.256891 * self.fConst0 + 0.5); 663 | self.fConst6 = 6.9077554 * (fConst5 / self.fConst0); 664 | self.fConst7 = 6.2831855 / self.fConst0; 665 | let mut fConst8: f32 = f32::floor(0.027333 * self.fConst0 + 0.5); 666 | self.iConst9 = (f32::min(16384.0, f32::max(0.0, fConst5 - fConst8))) as i32; 667 | self.iConst10 = (f32::min(2048.0, f32::max(0.0, fConst8 + -1.0))) as i32; 668 | let mut fConst11: f32 = f32::floor(0.153129 * self.fConst0 + 0.5); 669 | self.fConst12 = 6.9077554 * (fConst11 / self.fConst0); 670 | let mut fConst13: f32 = f32::floor(0.020346 * self.fConst0 + 0.5); 671 | self.iConst14 = (f32::min(8192.0, f32::max(0.0, fConst11 - fConst13))) as i32; 672 | self.iConst15 = (f32::min(1024.0, f32::max(0.0, fConst13 + -1.0))) as i32; 673 | let mut fConst16: f32 = f32::floor(0.174713 * self.fConst0 + 0.5); 674 | self.fConst17 = 6.9077554 * (fConst16 / self.fConst0); 675 | let mut fConst18: f32 = f32::floor(0.022904 * self.fConst0 + 0.5); 676 | self.iConst19 = (f32::min(8192.0, f32::max(0.0, fConst16 - fConst18))) as i32; 677 | self.iConst20 = (f32::min(1024.0, f32::max(0.0, fConst18 + -1.0))) as i32; 678 | let mut fConst21: f32 = f32::floor(0.127837 * self.fConst0 + 0.5); 679 | self.fConst22 = 6.9077554 * (fConst21 / self.fConst0); 680 | let mut fConst23: f32 = f32::floor(0.031604 * self.fConst0 + 0.5); 681 | self.iConst24 = (f32::min(8192.0, f32::max(0.0, fConst21 - fConst23))) as i32; 682 | self.iConst25 = (f32::min(2048.0, f32::max(0.0, fConst23 + -1.0))) as i32; 683 | let mut fConst26: f32 = f32::floor(0.125 * self.fConst0 + 0.5); 684 | self.fConst27 = 6.9077554 * (fConst26 / self.fConst0); 685 | let mut fConst28: f32 = f32::floor(0.013458 * self.fConst0 + 0.5); 686 | self.iConst29 = (f32::min(8192.0, f32::max(0.0, fConst26 - fConst28))) as i32; 687 | self.iConst30 = (f32::min(1024.0, f32::max(0.0, fConst28 + -1.0))) as i32; 688 | let mut fConst31: f32 = f32::floor(0.210389 * self.fConst0 + 0.5); 689 | self.fConst32 = 6.9077554 * (fConst31 / self.fConst0); 690 | let mut fConst33: f32 = f32::floor(0.024421 * self.fConst0 + 0.5); 691 | self.iConst34 = (f32::min(16384.0, f32::max(0.0, fConst31 - fConst33))) as i32; 692 | self.iConst35 = (f32::min(2048.0, f32::max(0.0, fConst33 + -1.0))) as i32; 693 | let mut fConst36: f32 = f32::floor(0.192303 * self.fConst0 + 0.5); 694 | self.fConst37 = 6.9077554 * (fConst36 / self.fConst0); 695 | let mut fConst38: f32 = f32::floor(0.029291 * self.fConst0 + 0.5); 696 | self.iConst39 = (f32::min(8192.0, f32::max(0.0, fConst36 - fConst38))) as i32; 697 | self.iConst40 = (f32::min(2048.0, f32::max(0.0, fConst38 + -1.0))) as i32; 698 | let mut fConst41: f32 = f32::floor(0.219991 * self.fConst0 + 0.5); 699 | self.fConst42 = 6.9077554 * (fConst41 / self.fConst0); 700 | let mut fConst43: f32 = f32::floor(0.019123 * self.fConst0 + 0.5); 701 | self.iConst44 = (f32::min(16384.0, f32::max(0.0, fConst41 - fConst43))) as i32; 702 | self.iConst45 = (f32::min(1024.0, f32::max(0.0, fConst43 + -1.0))) as i32; 703 | } 704 | fn instance_init(&mut self, sample_rate: i32) { 705 | self.instance_constants(sample_rate); 706 | self.instance_reset_params(); 707 | self.instance_clear(); 708 | } 709 | fn init(&mut self, sample_rate: i32) { 710 | mydsp::class_init(sample_rate); 711 | self.instance_init(sample_rate); 712 | } 713 | 714 | fn build_user_interface(&self, ui_interface: &mut dyn UI) { 715 | Self::build_user_interface_static(ui_interface); 716 | } 717 | 718 | fn build_user_interface_static(ui_interface: &mut dyn UI) { 719 | ui_interface.open_tab_box("elysiera"); 720 | ui_interface.declare(None, "0", ""); 721 | ui_interface.open_horizontal_box("Mix"); 722 | ui_interface.declare(Some(ParamIndex(0)), "0", ""); 723 | ui_interface.declare(Some(ParamIndex(0)), "style", "knob"); 724 | ui_interface.declare(Some(ParamIndex(0)), "unit", "%"); 725 | ui_interface.add_vertical_slider("Mix", ParamIndex(0), 0.5, 0.0, 1.0, 0.01); 726 | ui_interface.declare(Some(ParamIndex(1)), "1", ""); 727 | ui_interface.declare(Some(ParamIndex(1)), "style", "knob"); 728 | ui_interface.declare(Some(ParamIndex(1)), "unit", "dB"); 729 | ui_interface.add_vertical_slider("Pre Gain", ParamIndex(1), 0.0, -3e+01, 1e+01, 0.1); 730 | ui_interface.declare(Some(ParamIndex(2)), "2", ""); 731 | ui_interface.declare(Some(ParamIndex(2)), "style", "knob"); 732 | ui_interface.declare(Some(ParamIndex(2)), "unit", "dB"); 733 | ui_interface.add_vertical_slider("Post Gain", ParamIndex(2), 0.0, -3e+01, 1e+01, 0.1); 734 | ui_interface.close_box(); 735 | ui_interface.declare(None, "1", ""); 736 | ui_interface.open_horizontal_box("Reverb"); 737 | ui_interface.declare(Some(ParamIndex(3)), "0", ""); 738 | ui_interface.declare(Some(ParamIndex(3)), "style", "knob"); 739 | ui_interface.declare(Some(ParamIndex(3)), "unit", "s"); 740 | ui_interface.add_vertical_slider("Low decay", ParamIndex(3), 3.7, 1.0, 6e+01, 0.01); 741 | ui_interface.declare(Some(ParamIndex(4)), "1", ""); 742 | ui_interface.declare(Some(ParamIndex(4)), "style", "knob"); 743 | ui_interface.declare(Some(ParamIndex(4)), "unit", "Hz"); 744 | ui_interface.add_vertical_slider("LF Crossover", ParamIndex(4), 4.4e+02, 5e+01, 1e+03, 1.0); 745 | ui_interface.declare(Some(ParamIndex(5)), "2", ""); 746 | ui_interface.declare(Some(ParamIndex(5)), "style", "knob"); 747 | ui_interface.declare(Some(ParamIndex(5)), "unit", "s"); 748 | ui_interface.add_vertical_slider("Mid Decay", ParamIndex(5), 4.68, 1.0, 6e+01, 0.01); 749 | ui_interface.declare(Some(ParamIndex(6)), "3", ""); 750 | ui_interface.declare(Some(ParamIndex(6)), "style", "knob"); 751 | ui_interface.declare(Some(ParamIndex(6)), "unit", "Hz"); 752 | ui_interface.add_vertical_slider("HF Damping", ParamIndex(6), 8.6e+03, 1.5e+03, 21609.0, 1.0); 753 | ui_interface.declare(Some(ParamIndex(7)), "4", ""); 754 | ui_interface.declare(Some(ParamIndex(7)), "style", "knob"); 755 | ui_interface.declare(Some(ParamIndex(7)), "unit", "ms"); 756 | ui_interface.add_vertical_slider("Reverb Delay", ParamIndex(7), 0.0, 0.0, 1e+02, 0.01); 757 | ui_interface.declare(Some(ParamIndex(8)), "5", ""); 758 | ui_interface.declare(Some(ParamIndex(8)), "style", "knob"); 759 | ui_interface.declare(Some(ParamIndex(8)), "unit", "%"); 760 | ui_interface.add_vertical_slider("Reverb Mix", ParamIndex(8), 1.0, 0.0, 1.0, 0.01); 761 | ui_interface.close_box(); 762 | ui_interface.declare(None, "2", ""); 763 | ui_interface.open_horizontal_box("Echo"); 764 | ui_interface.declare(Some(ParamIndex(9)), "0", ""); 765 | ui_interface.declare(Some(ParamIndex(9)), "style", "knob"); 766 | ui_interface.declare(Some(ParamIndex(9)), "unit", "s"); 767 | ui_interface.add_vertical_slider("Delay", ParamIndex(9), 0.5, 0.0, 5.0, 0.01); 768 | ui_interface.declare(Some(ParamIndex(10)), "1", ""); 769 | ui_interface.declare(Some(ParamIndex(10)), "style", "knob"); 770 | ui_interface.declare(Some(ParamIndex(10)), "unit", "%"); 771 | ui_interface.add_vertical_slider("Feedback", ParamIndex(10), 0.5, 0.0, 0.99, 0.01); 772 | ui_interface.close_box(); 773 | ui_interface.declare(None, "3", ""); 774 | ui_interface.open_horizontal_box("Filter"); 775 | ui_interface.declare(Some(ParamIndex(11)), "0", ""); 776 | ui_interface.declare(Some(ParamIndex(11)), "style", "knob"); 777 | ui_interface.declare(Some(ParamIndex(11)), "unit", "Hz"); 778 | ui_interface.add_vertical_slider("Lowpass", ParamIndex(11), 1.8e+04, 25.0, 2.2e+04, 0.01); 779 | ui_interface.declare(Some(ParamIndex(12)), "1", ""); 780 | ui_interface.declare(Some(ParamIndex(12)), "style", "knob"); 781 | ui_interface.add_vertical_slider("Lowpass Q", ParamIndex(12), 0.71, 0.1, 2.0, 0.01); 782 | ui_interface.declare(Some(ParamIndex(13)), "3", ""); 783 | ui_interface.declare(Some(ParamIndex(13)), "style", "knob"); 784 | ui_interface.declare(Some(ParamIndex(13)), "unit", "Hz"); 785 | ui_interface.add_vertical_slider("Highpass", ParamIndex(13), 2.5e+02, 25.0, 2.2e+04, 0.01); 786 | ui_interface.declare(Some(ParamIndex(14)), "4", ""); 787 | ui_interface.declare(Some(ParamIndex(14)), "style", "knob"); 788 | ui_interface.add_vertical_slider("Highpass Q", ParamIndex(14), 0.71, 0.1, 2.0, 0.01); 789 | ui_interface.close_box(); 790 | ui_interface.declare(None, "4", ""); 791 | ui_interface.open_horizontal_box("Pitch"); 792 | ui_interface.declare(Some(ParamIndex(15)), "0", ""); 793 | ui_interface.declare(Some(ParamIndex(15)), "style", "knob"); 794 | ui_interface.declare(Some(ParamIndex(15)), "unit", "st"); 795 | ui_interface.add_vertical_slider("Pitch A", ParamIndex(15), 12.0, -12.0, 12.0, 1.0); 796 | ui_interface.declare(Some(ParamIndex(16)), "1", ""); 797 | ui_interface.declare(Some(ParamIndex(16)), "style", "knob"); 798 | ui_interface.declare(Some(ParamIndex(16)), "unit", "%"); 799 | ui_interface.add_vertical_slider("Pitch A Mix", ParamIndex(16), 0.6, 0.0, 1.0, 0.01); 800 | ui_interface.declare(Some(ParamIndex(17)), "1", ""); 801 | ui_interface.declare(Some(ParamIndex(17)), "style", "knob"); 802 | ui_interface.declare(Some(ParamIndex(17)), "unit", "st"); 803 | ui_interface.add_vertical_slider("Pitch B", ParamIndex(17), 5.0, -12.0, 12.0, 1.0); 804 | ui_interface.declare(Some(ParamIndex(18)), "2", ""); 805 | ui_interface.declare(Some(ParamIndex(18)), "style", "knob"); 806 | ui_interface.declare(Some(ParamIndex(18)), "unit", "%"); 807 | ui_interface.add_vertical_slider("Pitch B Mix", ParamIndex(18), 0.6, 0.0, 1.0, 0.01); 808 | ui_interface.close_box(); 809 | ui_interface.declare(None, "5", ""); 810 | ui_interface.open_horizontal_box("Mod"); 811 | ui_interface.declare(Some(ParamIndex(19)), "5", ""); 812 | ui_interface.declare(Some(ParamIndex(19)), "style", "knob"); 813 | ui_interface.declare(Some(ParamIndex(19)), "unit", "hz"); 814 | ui_interface.add_vertical_slider("Pitch Mod Rate", ParamIndex(19), 3.1, 0.01, 1e+01, 0.01); 815 | ui_interface.declare(Some(ParamIndex(20)), "6", ""); 816 | ui_interface.declare(Some(ParamIndex(20)), "style", "knob"); 817 | ui_interface.declare(Some(ParamIndex(20)), "unit", "%"); 818 | ui_interface.add_vertical_slider("Pitch Mod Mix", ParamIndex(20), 1.0, 0.0, 1.0, 0.01); 819 | ui_interface.declare(Some(ParamIndex(21)), "7", ""); 820 | ui_interface.declare(Some(ParamIndex(21)), "style", "knob"); 821 | ui_interface.declare(Some(ParamIndex(21)), "unit", "hz"); 822 | ui_interface.add_vertical_slider("Volume Mod Rate", ParamIndex(21), 3.1, 0.01, 1e+01, 0.01); 823 | ui_interface.declare(Some(ParamIndex(22)), "8", ""); 824 | ui_interface.declare(Some(ParamIndex(22)), "style", "knob"); 825 | ui_interface.declare(Some(ParamIndex(22)), "unit", "%"); 826 | ui_interface.add_vertical_slider("Volume Mod Mix", ParamIndex(22), 1.0, 0.0, 1.0, 0.01); 827 | ui_interface.close_box(); 828 | ui_interface.close_box(); 829 | } 830 | 831 | fn get_param(&self, param: ParamIndex) -> Option { 832 | match param.0 { 833 | 1 => Some(self.fVslider0), 834 | 0 => Some(self.fVslider1), 835 | 14 => Some(self.fVslider10), 836 | 9 => Some(self.fVslider11), 837 | 10 => Some(self.fVslider12), 838 | 18 => Some(self.fVslider13), 839 | 15 => Some(self.fVslider14), 840 | 16 => Some(self.fVslider15), 841 | 8 => Some(self.fVslider16), 842 | 7 => Some(self.fVslider17), 843 | 5 => Some(self.fVslider18), 844 | 6 => Some(self.fVslider19), 845 | 21 => Some(self.fVslider2), 846 | 4 => Some(self.fVslider20), 847 | 3 => Some(self.fVslider21), 848 | 2 => Some(self.fVslider22), 849 | 22 => Some(self.fVslider3), 850 | 19 => Some(self.fVslider4), 851 | 20 => Some(self.fVslider5), 852 | 17 => Some(self.fVslider6), 853 | 11 => Some(self.fVslider7), 854 | 12 => Some(self.fVslider8), 855 | 13 => Some(self.fVslider9), 856 | _ => None, 857 | } 858 | } 859 | 860 | fn set_param(&mut self, param: ParamIndex, value: Self::T) { 861 | match param.0 { 862 | 1 => { self.fVslider0 = value } 863 | 0 => { self.fVslider1 = value } 864 | 14 => { self.fVslider10 = value } 865 | 9 => { self.fVslider11 = value } 866 | 10 => { self.fVslider12 = value } 867 | 18 => { self.fVslider13 = value } 868 | 15 => { self.fVslider14 = value } 869 | 16 => { self.fVslider15 = value } 870 | 8 => { self.fVslider16 = value } 871 | 7 => { self.fVslider17 = value } 872 | 5 => { self.fVslider18 = value } 873 | 6 => { self.fVslider19 = value } 874 | 21 => { self.fVslider2 = value } 875 | 4 => { self.fVslider20 = value } 876 | 3 => { self.fVslider21 = value } 877 | 2 => { self.fVslider22 = value } 878 | 22 => { self.fVslider3 = value } 879 | 19 => { self.fVslider4 = value } 880 | 20 => { self.fVslider5 = value } 881 | 17 => { self.fVslider6 = value } 882 | 11 => { self.fVslider7 = value } 883 | 12 => { self.fVslider8 = value } 884 | 13 => { self.fVslider9 = value } 885 | _ => {} 886 | } 887 | } 888 | 889 | fn compute(&mut self, count: i32, inputs: &[&[Self::T]], outputs: &mut[&mut[Self::T]]) { 890 | let (inputs0, inputs1) = if let [inputs0, inputs1, ..] = inputs { 891 | let inputs0 = inputs0[..count as usize].iter(); 892 | let inputs1 = inputs1[..count as usize].iter(); 893 | (inputs0, inputs1) 894 | } else { 895 | panic!("wrong number of inputs"); 896 | }; 897 | let (outputs0, outputs1) = if let [outputs0, outputs1, ..] = outputs { 898 | let outputs0 = outputs0[..count as usize].iter_mut(); 899 | let outputs1 = outputs1[..count as usize].iter_mut(); 900 | (outputs0, outputs1) 901 | } else { 902 | panic!("wrong number of outputs"); 903 | }; 904 | let mut fSlow0: f32 = f32::powf(1e+01, 0.05 * self.fVslider0); 905 | let mut fSlow1: f32 = 1.5707964 * self.fVslider1; 906 | let mut fSlow2: f32 = f32::cos(fSlow1) * fSlow0; 907 | let mut fSlow3: f32 = self.fConst1 * self.fVslider2; 908 | let mut fSlow4: f32 = 1.5707964 * self.fVslider3; 909 | let mut fSlow5: f32 = f32::sin(fSlow4); 910 | let mut fSlow6: f32 = f32::cos(fSlow4); 911 | let mut fSlow7: f32 = self.fConst1 * self.fVslider4; 912 | let mut fSlow8: f32 = self.fVslider5; 913 | let mut fSlow9: f32 = f32::powf(2.0, 0.083333336 * self.fVslider6); 914 | let mut fSlow10: f32 = f32::tan(self.fConst2 * self.fVslider7); 915 | let mut fSlow11: f32 = fSlow10 * (1.0 / self.fVslider8 + fSlow10) + 1.0; 916 | let mut fSlow12: f32 = 2.0 / fSlow11; 917 | let mut fSlow13: f32 = fSlow10 / fSlow11; 918 | let mut fSlow14: f32 = f32::tan(self.fConst2 * self.fVslider9); 919 | let mut fSlow15: f32 = 1.0 / self.fVslider10; 920 | let mut fSlow16: f32 = fSlow14 * (fSlow15 + fSlow14) + 1.0; 921 | let mut fSlow17: f32 = 2.0 / fSlow16; 922 | let mut fSlow18: f32 = fSlow14 / fSlow16; 923 | let mut fSlow19: f32 = 1.0 / fSlow16; 924 | let mut iSlow20: i32 = i32::wrapping_add((f32::min(self.fConst3, f32::max(0.0, self.fConst0 * self.fVslider11))) as i32, 1); 925 | let mut fSlow21: f32 = self.fVslider12; 926 | let mut fSlow22: f32 = self.fVslider13; 927 | let mut fSlow23: f32 = f32::powf(2.0, 0.083333336 * self.fVslider14); 928 | let mut fSlow24: f32 = self.fVslider15; 929 | let mut fSlow25: f32 = 1.5707964 * self.fVslider16; 930 | let mut fSlow26: f32 = 0.5 * f32::cos(fSlow25); 931 | let mut iSlow27: i32 = (f32::min(8192.0, f32::max(0.0, self.fConst4 * self.fVslider17))) as i32; 932 | let mut fSlow28: f32 = self.fVslider18; 933 | let mut fSlow29: f32 = f32::exp(-(self.fConst6 / fSlow28)); 934 | let mut fSlow30: f32 = mydsp_faustpower2_f(fSlow29); 935 | let mut fSlow31: f32 = 1.0 - fSlow30; 936 | let mut fSlow32: f32 = f32::cos(self.fConst7 * self.fVslider19); 937 | let mut fSlow33: f32 = 1.0 - fSlow32 * fSlow30; 938 | let mut fSlow34: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow33) / mydsp_faustpower2_f(fSlow31) + -1.0)); 939 | let mut fSlow35: f32 = fSlow33 / fSlow31; 940 | let mut fSlow36: f32 = fSlow35 - fSlow34; 941 | let mut fSlow37: f32 = 1.0 / f32::tan(self.fConst2 * self.fVslider20); 942 | let mut fSlow38: f32 = 1.0 - fSlow37; 943 | let mut fSlow39: f32 = 1.0 / (fSlow37 + 1.0); 944 | let mut fSlow40: f32 = self.fVslider21; 945 | let mut fSlow41: f32 = f32::exp(-(self.fConst6 / fSlow40)) / fSlow29 + -1.0; 946 | let mut fSlow42: f32 = fSlow29 * (fSlow34 + (1.0 - fSlow35)); 947 | let mut fSlow43: f32 = f32::exp(-(self.fConst12 / fSlow28)); 948 | let mut fSlow44: f32 = mydsp_faustpower2_f(fSlow43); 949 | let mut fSlow45: f32 = 1.0 - fSlow44; 950 | let mut fSlow46: f32 = 1.0 - fSlow44 * fSlow32; 951 | let mut fSlow47: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow46) / mydsp_faustpower2_f(fSlow45) + -1.0)); 952 | let mut fSlow48: f32 = fSlow46 / fSlow45; 953 | let mut fSlow49: f32 = fSlow48 - fSlow47; 954 | let mut fSlow50: f32 = f32::exp(-(self.fConst12 / fSlow40)) / fSlow43 + -1.0; 955 | let mut fSlow51: f32 = fSlow43 * (fSlow47 + (1.0 - fSlow48)); 956 | let mut fSlow52: f32 = f32::exp(-(self.fConst17 / fSlow28)); 957 | let mut fSlow53: f32 = mydsp_faustpower2_f(fSlow52); 958 | let mut fSlow54: f32 = 1.0 - fSlow53; 959 | let mut fSlow55: f32 = 1.0 - fSlow32 * fSlow53; 960 | let mut fSlow56: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow55) / mydsp_faustpower2_f(fSlow54) + -1.0)); 961 | let mut fSlow57: f32 = fSlow55 / fSlow54; 962 | let mut fSlow58: f32 = fSlow57 - fSlow56; 963 | let mut fSlow59: f32 = f32::exp(-(self.fConst17 / fSlow40)) / fSlow52 + -1.0; 964 | let mut fSlow60: f32 = fSlow52 * (fSlow56 + (1.0 - fSlow57)); 965 | let mut fSlow61: f32 = f32::exp(-(self.fConst22 / fSlow28)); 966 | let mut fSlow62: f32 = mydsp_faustpower2_f(fSlow61); 967 | let mut fSlow63: f32 = 1.0 - fSlow62; 968 | let mut fSlow64: f32 = 1.0 - fSlow32 * fSlow62; 969 | let mut fSlow65: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow64) / mydsp_faustpower2_f(fSlow63) + -1.0)); 970 | let mut fSlow66: f32 = fSlow64 / fSlow63; 971 | let mut fSlow67: f32 = fSlow66 - fSlow65; 972 | let mut fSlow68: f32 = f32::exp(-(self.fConst22 / fSlow40)) / fSlow61 + -1.0; 973 | let mut fSlow69: f32 = fSlow61 * (fSlow65 + (1.0 - fSlow66)); 974 | let mut fSlow70: f32 = f32::exp(-(self.fConst27 / fSlow28)); 975 | let mut fSlow71: f32 = mydsp_faustpower2_f(fSlow70); 976 | let mut fSlow72: f32 = 1.0 - fSlow71; 977 | let mut fSlow73: f32 = 1.0 - fSlow32 * fSlow71; 978 | let mut fSlow74: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow73) / mydsp_faustpower2_f(fSlow72) + -1.0)); 979 | let mut fSlow75: f32 = fSlow73 / fSlow72; 980 | let mut fSlow76: f32 = fSlow75 - fSlow74; 981 | let mut fSlow77: f32 = f32::exp(-(self.fConst27 / fSlow40)) / fSlow70 + -1.0; 982 | let mut fSlow78: f32 = fSlow70 * (fSlow74 + (1.0 - fSlow75)); 983 | let mut fSlow79: f32 = f32::exp(-(self.fConst32 / fSlow28)); 984 | let mut fSlow80: f32 = mydsp_faustpower2_f(fSlow79); 985 | let mut fSlow81: f32 = 1.0 - fSlow80; 986 | let mut fSlow82: f32 = 1.0 - fSlow32 * fSlow80; 987 | let mut fSlow83: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow82) / mydsp_faustpower2_f(fSlow81) + -1.0)); 988 | let mut fSlow84: f32 = fSlow82 / fSlow81; 989 | let mut fSlow85: f32 = fSlow84 - fSlow83; 990 | let mut fSlow86: f32 = f32::exp(-(self.fConst32 / fSlow40)) / fSlow79 + -1.0; 991 | let mut fSlow87: f32 = fSlow79 * (fSlow83 + (1.0 - fSlow84)); 992 | let mut fSlow88: f32 = f32::exp(-(self.fConst37 / fSlow28)); 993 | let mut fSlow89: f32 = mydsp_faustpower2_f(fSlow88); 994 | let mut fSlow90: f32 = 1.0 - fSlow89; 995 | let mut fSlow91: f32 = 1.0 - fSlow32 * fSlow89; 996 | let mut fSlow92: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow91) / mydsp_faustpower2_f(fSlow90) + -1.0)); 997 | let mut fSlow93: f32 = fSlow91 / fSlow90; 998 | let mut fSlow94: f32 = fSlow93 - fSlow92; 999 | let mut fSlow95: f32 = f32::exp(-(self.fConst37 / fSlow40)) / fSlow88 + -1.0; 1000 | let mut fSlow96: f32 = fSlow88 * (fSlow92 + (1.0 - fSlow93)); 1001 | let mut fSlow97: f32 = f32::exp(-(self.fConst42 / fSlow28)); 1002 | let mut fSlow98: f32 = mydsp_faustpower2_f(fSlow97); 1003 | let mut fSlow99: f32 = 1.0 - fSlow98; 1004 | let mut fSlow100: f32 = 1.0 - fSlow32 * fSlow98; 1005 | let mut fSlow101: f32 = f32::sqrt(f32::max(0.0, mydsp_faustpower2_f(fSlow100) / mydsp_faustpower2_f(fSlow99) + -1.0)); 1006 | let mut fSlow102: f32 = fSlow100 / fSlow99; 1007 | let mut fSlow103: f32 = fSlow102 - fSlow101; 1008 | let mut fSlow104: f32 = f32::exp(-(self.fConst42 / fSlow40)) / fSlow97 + -1.0; 1009 | let mut fSlow105: f32 = fSlow97 * (fSlow101 + (1.0 - fSlow102)); 1010 | let mut fSlow106: f32 = 0.26162952 * f32::sin(fSlow25); 1011 | let mut fSlow107: f32 = f32::sin(fSlow1); 1012 | let mut fSlow108: f32 = 0.70710677 * f32::powf(1e+01, 0.05 * self.fVslider22); 1013 | let zipped_iterators = inputs0.zip(inputs1).zip(outputs0).zip(outputs1); 1014 | for (((input0, input1), output0), output1) in zipped_iterators { 1015 | let mut fTemp0: f32 = *input0; 1016 | self.iVec1[0] = 1; 1017 | let mut iTemp1: i32 = i32::wrapping_sub(1, self.iVec1[1]); 1018 | let mut fTemp2: f32 = if iTemp1 != 0 {0.0} else {fSlow3 + self.fRec1[1]}; 1019 | self.fRec1[0] = fTemp2 - f32::floor(fTemp2); 1020 | let mut iTemp3: i32 = std::cmp::max(0, std::cmp::min((65536.0 * self.fRec1[0]) as i32, 65535)); 1021 | let mut fTemp4: f32 = if iTemp1 != 0 {0.0} else {fSlow7 + self.fRec3[1]}; 1022 | self.fRec3[0] = fTemp4 - f32::floor(fTemp4); 1023 | let mut iTemp5: i32 = std::cmp::max(0, std::cmp::min((65536.0 * self.fRec3[0]) as i32, 65535)); 1024 | let mut fTemp6: f32 = 1.0 - fSlow8 * (1.0 - unsafe { ftbl1mydspSIG1[iTemp5 as usize] }); 1025 | self.fRec4[0] = (self.fRec4[1] + 2049.0 - fSlow9) % 2048.0; 1026 | let mut fTemp7: f32 = f32::min(0.0009765625 * self.fRec4[0], 1.0); 1027 | let mut fTemp8: f32 = 1.0 - fTemp7; 1028 | let mut fTemp9: f32 = fSlow0 * fTemp0; 1029 | let mut fTemp10: f32 = self.fRec10[1] + fSlow10 * (fTemp9 - self.fRec11[1]); 1030 | self.fRec10[0] = fSlow12 * fTemp10 - self.fRec10[1]; 1031 | let mut fTemp11: f32 = self.fRec11[1] + fSlow13 * fTemp10; 1032 | self.fRec11[0] = 2.0 * fTemp11 - self.fRec11[1]; 1033 | let mut fRec12: f32 = fTemp11; 1034 | let mut fTemp12: f32 = self.fRec6[1] + fSlow14 * (fRec12 - self.fRec7[1]); 1035 | self.fRec6[0] = fSlow17 * fTemp12 - self.fRec6[1]; 1036 | let mut fTemp13: f32 = self.fRec7[1] + fSlow18 * fTemp12; 1037 | self.fRec7[0] = 2.0 * fTemp13 - self.fRec7[1]; 1038 | let mut fRec8: f32 = fSlow19 * fTemp12; 1039 | let mut fRec9: f32 = fTemp13; 1040 | self.fRec5[(self.IOTA0 & 1048575) as usize] = fRec12 + fSlow21 * self.fRec5[((i32::wrapping_sub(self.IOTA0, iSlow20)) & 1048575) as usize] - (fRec9 + fSlow15 * fRec8); 1041 | let mut fTemp14: f32 = self.fRec4[0] + 2048.0; 1042 | let mut iTemp15: i32 = (fTemp14) as i32; 1043 | let mut iTemp16: i32 = std::cmp::min(65537, std::cmp::max(0, i32::wrapping_add(iTemp15, 1))); 1044 | let mut fTemp17: f32 = f32::floor(fTemp14); 1045 | let mut fTemp18: f32 = self.fRec4[0] + (2048.0 - fTemp17); 1046 | let mut fTemp19: f32 = fTemp17 + (-2047.0 - self.fRec4[0]); 1047 | let mut iTemp20: i32 = std::cmp::min(65537, std::cmp::max(0, iTemp15)); 1048 | let mut iTemp21: i32 = (self.fRec4[0]) as i32; 1049 | let mut iTemp22: i32 = std::cmp::min(65537, std::cmp::max(0, i32::wrapping_add(iTemp21, 1))); 1050 | let mut fTemp23: f32 = f32::floor(self.fRec4[0]); 1051 | let mut fTemp24: f32 = self.fRec4[0] - fTemp23; 1052 | let mut fTemp25: f32 = fTemp23 + (1.0 - self.fRec4[0]); 1053 | let mut iTemp26: i32 = std::cmp::min(65537, std::cmp::max(0, iTemp21)); 1054 | let mut fTemp27: f32 = 1.0 - fSlow8 * (1.0 - unsafe { ftbl0mydspSIG0[iTemp5 as usize] }); 1055 | self.fRec13[0] = (self.fRec13[1] + 2049.0 - fSlow23) % 2048.0; 1056 | let mut fTemp28: f32 = f32::min(0.0009765625 * self.fRec13[0], 1.0); 1057 | let mut fTemp29: f32 = 1.0 - fTemp28; 1058 | let mut fTemp30: f32 = self.fRec13[0] + 2048.0; 1059 | let mut iTemp31: i32 = (fTemp30) as i32; 1060 | let mut iTemp32: i32 = std::cmp::min(65537, std::cmp::max(0, i32::wrapping_add(iTemp31, 1))); 1061 | let mut fTemp33: f32 = f32::floor(fTemp30); 1062 | let mut fTemp34: f32 = self.fRec13[0] + (2048.0 - fTemp33); 1063 | let mut fTemp35: f32 = fTemp33 + (-2047.0 - self.fRec13[0]); 1064 | let mut iTemp36: i32 = std::cmp::min(65537, std::cmp::max(0, iTemp31)); 1065 | let mut iTemp37: i32 = (self.fRec13[0]) as i32; 1066 | let mut iTemp38: i32 = std::cmp::min(65537, std::cmp::max(0, i32::wrapping_add(iTemp37, 1))); 1067 | let mut fTemp39: f32 = f32::floor(self.fRec13[0]); 1068 | let mut fTemp40: f32 = self.fRec13[0] - fTemp39; 1069 | let mut fTemp41: f32 = fTemp39 + (1.0 - self.fRec13[0]); 1070 | let mut iTemp42: i32 = std::cmp::min(65537, std::cmp::max(0, iTemp37)); 1071 | let mut fTemp43: f32 = (fSlow24 * ((self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp42)) & 1048575) as usize] * fTemp41 + fTemp40 * self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp38)) & 1048575) as usize]) * fTemp28 + (self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp36)) & 1048575) as usize] * fTemp35 + fTemp34 * self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp32)) & 1048575) as usize]) * fTemp29) * fTemp27 + fSlow22 * ((self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp26)) & 1048575) as usize] * fTemp25 + fTemp24 * self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp22)) & 1048575) as usize]) * fTemp7 + (self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp20)) & 1048575) as usize] * fTemp19 + fTemp18 * self.fRec5[((i32::wrapping_sub(self.IOTA0, iTemp16)) & 1048575) as usize]) * fTemp8) * fTemp6) * (fSlow6 + fSlow5 * unsafe { ftbl0mydspSIG0[iTemp3 as usize] }); 1072 | self.fVec3[(self.IOTA0 & 16383) as usize] = fTemp43; 1073 | let mut fTemp44: f32 = *input1; 1074 | let mut fTemp45: f32 = fSlow0 * fTemp44; 1075 | let mut fTemp46: f32 = self.fRec29[1] + fSlow10 * (fTemp45 - self.fRec30[1]); 1076 | self.fRec29[0] = fSlow12 * fTemp46 - self.fRec29[1]; 1077 | let mut fTemp47: f32 = self.fRec30[1] + fSlow13 * fTemp46; 1078 | self.fRec30[0] = 2.0 * fTemp47 - self.fRec30[1]; 1079 | let mut fRec31: f32 = fTemp47; 1080 | let mut fTemp48: f32 = self.fRec25[1] + fSlow14 * (fRec31 - self.fRec26[1]); 1081 | self.fRec25[0] = fSlow17 * fTemp48 - self.fRec25[1]; 1082 | let mut fTemp49: f32 = self.fRec26[1] + fSlow18 * fTemp48; 1083 | self.fRec26[0] = 2.0 * fTemp49 - self.fRec26[1]; 1084 | let mut fRec27: f32 = fSlow19 * fTemp48; 1085 | let mut fRec28: f32 = fTemp49; 1086 | self.fRec24[(self.IOTA0 & 1048575) as usize] = fRec31 + fSlow21 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iSlow20)) & 1048575) as usize] - (fRec28 + fSlow15 * fRec27); 1087 | let mut fTemp50: f32 = (fSlow24 * fTemp6 * (fTemp28 * (fTemp41 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp42)) & 1048575) as usize] + fTemp40 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp38)) & 1048575) as usize]) + fTemp29 * (fTemp35 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp36)) & 1048575) as usize] + fTemp34 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp32)) & 1048575) as usize])) + fSlow22 * fTemp27 * (fTemp7 * (fTemp25 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp26)) & 1048575) as usize] + fTemp24 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp22)) & 1048575) as usize]) + fTemp8 * (fTemp19 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp20)) & 1048575) as usize] + fTemp18 * self.fRec24[((i32::wrapping_sub(self.IOTA0, iTemp16)) & 1048575) as usize]))) * (fSlow6 + fSlow5 * unsafe { ftbl1mydspSIG1[iTemp3 as usize] }); 1088 | self.fVec4[(self.IOTA0 & 16383) as usize] = fTemp50; 1089 | let mut fTemp51: f32 = 0.21213204 * self.fVec4[((i32::wrapping_sub(self.IOTA0, iSlow27)) & 16383) as usize]; 1090 | self.fRec33[0] = -(fSlow39 * (fSlow38 * self.fRec33[1] - (self.fRec17[1] + self.fRec17[2]))); 1091 | self.fRec32[0] = fSlow42 * (self.fRec17[1] + fSlow41 * self.fRec33[0]) + fSlow36 * self.fRec32[1]; 1092 | self.fVec5[(self.IOTA0 & 32767) as usize] = 0.35355338 * self.fRec32[0] + 1e-20; 1093 | let mut fTemp52: f32 = 0.6 * self.fRec22[1] + self.fVec5[((i32::wrapping_sub(self.IOTA0, self.iConst9)) & 32767) as usize]; 1094 | self.fVec6[(self.IOTA0 & 4095) as usize] = fTemp52 - fTemp51; 1095 | self.fRec22[0] = self.fVec6[((i32::wrapping_sub(self.IOTA0, self.iConst10)) & 4095) as usize]; 1096 | let mut fRec23: f32 = 0.6 * (fTemp51 - fTemp52); 1097 | let mut fTemp53: f32 = 0.21213204 * self.fVec3[((i32::wrapping_sub(self.IOTA0, iSlow27)) & 16383) as usize]; 1098 | self.fRec37[0] = -(fSlow39 * (fSlow38 * self.fRec37[1] - (self.fRec14[1] + self.fRec14[2]))); 1099 | self.fRec36[0] = fSlow51 * (self.fRec14[1] + fSlow50 * self.fRec37[0]) + fSlow49 * self.fRec36[1]; 1100 | self.fVec7[(self.IOTA0 & 16383) as usize] = 0.35355338 * self.fRec36[0] + 1e-20; 1101 | let mut fTemp54: f32 = self.fVec7[((i32::wrapping_sub(self.IOTA0, self.iConst14)) & 16383) as usize] + fTemp53 - 0.6 * self.fRec34[1]; 1102 | self.fVec8[(self.IOTA0 & 2047) as usize] = fTemp54; 1103 | self.fRec34[0] = self.fVec8[((i32::wrapping_sub(self.IOTA0, self.iConst15)) & 2047) as usize]; 1104 | let mut fRec35: f32 = 0.6 * fTemp54; 1105 | let mut fTemp55: f32 = fRec35 + fRec23; 1106 | self.fRec41[0] = -(fSlow39 * (fSlow38 * self.fRec41[1] - (self.fRec18[1] + self.fRec18[2]))); 1107 | self.fRec40[0] = fSlow60 * (self.fRec18[1] + fSlow59 * self.fRec41[0]) + fSlow58 * self.fRec40[1]; 1108 | self.fVec9[(self.IOTA0 & 16383) as usize] = 0.35355338 * self.fRec40[0] + 1e-20; 1109 | let mut fTemp56: f32 = fTemp53 + self.fVec9[((i32::wrapping_sub(self.IOTA0, self.iConst19)) & 16383) as usize] - 0.6 * self.fRec38[1]; 1110 | self.fVec10[(self.IOTA0 & 2047) as usize] = fTemp56; 1111 | self.fRec38[0] = self.fVec10[((i32::wrapping_sub(self.IOTA0, self.iConst20)) & 2047) as usize]; 1112 | let mut fRec39: f32 = 0.6 * fTemp56; 1113 | let mut fTemp57: f32 = fRec39 + fTemp55; 1114 | self.fRec45[0] = fSlow39 * (self.fRec16[1] + self.fRec16[2] - fSlow38 * self.fRec45[1]); 1115 | self.fRec44[0] = fSlow69 * (self.fRec16[1] + fSlow68 * self.fRec45[0]) + fSlow67 * self.fRec44[1]; 1116 | self.fVec11[(self.IOTA0 & 16383) as usize] = 0.35355338 * self.fRec44[0] + 1e-20; 1117 | let mut fTemp58: f32 = self.fVec11[((i32::wrapping_sub(self.IOTA0, self.iConst24)) & 16383) as usize] - (fTemp53 + 0.6 * self.fRec42[1]); 1118 | self.fVec12[(self.IOTA0 & 4095) as usize] = fTemp58; 1119 | self.fRec42[0] = self.fVec12[((i32::wrapping_sub(self.IOTA0, self.iConst25)) & 4095) as usize]; 1120 | let mut fRec43: f32 = 0.6 * fTemp58; 1121 | self.fRec49[0] = -(fSlow39 * (fSlow38 * self.fRec49[1] - (self.fRec20[1] + self.fRec20[2]))); 1122 | self.fRec48[0] = fSlow78 * (self.fRec20[1] + fSlow77 * self.fRec49[0]) + fSlow76 * self.fRec48[1]; 1123 | self.fVec13[(self.IOTA0 & 16383) as usize] = 0.35355338 * self.fRec48[0] + 1e-20; 1124 | let mut fTemp59: f32 = self.fVec13[((i32::wrapping_sub(self.IOTA0, self.iConst29)) & 16383) as usize] - (fTemp53 + 0.6 * self.fRec46[1]); 1125 | self.fVec14[(self.IOTA0 & 2047) as usize] = fTemp59; 1126 | self.fRec46[0] = self.fVec14[((i32::wrapping_sub(self.IOTA0, self.iConst30)) & 2047) as usize]; 1127 | let mut fRec47: f32 = 0.6 * fTemp59; 1128 | self.fRec53[0] = -(fSlow39 * (fSlow38 * self.fRec53[1] - (self.fRec15[1] + self.fRec15[2]))); 1129 | self.fRec52[0] = fSlow87 * (self.fRec15[1] + fSlow86 * self.fRec53[0]) + fSlow85 * self.fRec52[1]; 1130 | self.fVec15[(self.IOTA0 & 32767) as usize] = 0.35355338 * self.fRec52[0] + 1e-20; 1131 | let mut fTemp60: f32 = fTemp51 + 0.6 * self.fRec50[1] + self.fVec15[((i32::wrapping_sub(self.IOTA0, self.iConst34)) & 32767) as usize]; 1132 | self.fVec16[(self.IOTA0 & 4095) as usize] = fTemp60; 1133 | self.fRec50[0] = self.fVec16[((i32::wrapping_sub(self.IOTA0, self.iConst35)) & 4095) as usize]; 1134 | let mut fRec51: f32 = -(0.6 * fTemp60); 1135 | self.fRec57[0] = -(fSlow39 * (fSlow38 * self.fRec57[1] - (self.fRec19[1] + self.fRec19[2]))); 1136 | self.fRec56[0] = fSlow96 * (self.fRec19[1] + fSlow95 * self.fRec57[0]) + fSlow94 * self.fRec56[1]; 1137 | self.fVec17[(self.IOTA0 & 16383) as usize] = 0.35355338 * self.fRec56[0] + 1e-20; 1138 | let mut fTemp61: f32 = fTemp51 + 0.6 * self.fRec54[1] + self.fVec17[((i32::wrapping_sub(self.IOTA0, self.iConst39)) & 16383) as usize]; 1139 | self.fVec18[(self.IOTA0 & 4095) as usize] = fTemp61; 1140 | self.fRec54[0] = self.fVec18[((i32::wrapping_sub(self.IOTA0, self.iConst40)) & 4095) as usize]; 1141 | let mut fRec55: f32 = -(0.6 * fTemp61); 1142 | self.fRec61[0] = -(fSlow39 * (fSlow38 * self.fRec61[1] - (self.fRec21[1] + self.fRec21[2]))); 1143 | self.fRec60[0] = fSlow105 * (self.fRec21[1] + fSlow104 * self.fRec61[0]) + fSlow103 * self.fRec60[1]; 1144 | self.fVec19[(self.IOTA0 & 32767) as usize] = 0.35355338 * self.fRec60[0] + 1e-20; 1145 | let mut fTemp62: f32 = 0.6 * self.fRec58[1] + self.fVec19[((i32::wrapping_sub(self.IOTA0, self.iConst44)) & 32767) as usize]; 1146 | self.fVec20[(self.IOTA0 & 2047) as usize] = fTemp62 - fTemp51; 1147 | self.fRec58[0] = self.fVec20[((i32::wrapping_sub(self.IOTA0, self.iConst45)) & 2047) as usize]; 1148 | let mut fRec59: f32 = 0.6 * (fTemp51 - fTemp62); 1149 | self.fRec14[0] = self.fRec58[1] + self.fRec22[1] + self.fRec54[1] + self.fRec50[1] + self.fRec46[1] + self.fRec42[1] + self.fRec38[1] + self.fRec34[1] + fRec59 + fRec55 + fRec51 + fRec47 + fRec43 + fTemp57; 1150 | let mut fTemp63: f32 = fRec35 + fRec39; 1151 | self.fRec15[0] = self.fRec46[1] + self.fRec42[1] + self.fRec38[1] + self.fRec34[1] + fRec47 + fRec43 + fTemp63 - (self.fRec58[1] + self.fRec22[1] + self.fRec54[1] + self.fRec50[1] + fRec59 + fRec55 + fRec51 + fRec23); 1152 | self.fRec16[0] = self.fRec54[1] + self.fRec50[1] + self.fRec38[1] + self.fRec34[1] + fRec55 + fRec51 + fTemp63 - (self.fRec58[1] + self.fRec22[1] + self.fRec46[1] + self.fRec42[1] + fRec59 + fRec47 + fRec43 + fRec23); 1153 | self.fRec17[0] = self.fRec58[1] + self.fRec22[1] + self.fRec38[1] + self.fRec34[1] + fRec59 + fTemp57 - (self.fRec54[1] + self.fRec50[1] + self.fRec46[1] + self.fRec42[1] + fRec55 + fRec51 + fRec43 + fRec47); 1154 | self.fRec18[0] = self.fRec22[1] + self.fRec50[1] + self.fRec42[1] + self.fRec34[1] + fRec51 + fRec43 + fTemp55 - (self.fRec58[1] + self.fRec54[1] + self.fRec46[1] + self.fRec38[1] + fRec59 + fRec55 + fRec39 + fRec47); 1155 | let mut fTemp64: f32 = fRec39 + fRec23; 1156 | self.fRec19[0] = self.fRec58[1] + self.fRec54[1] + self.fRec42[1] + self.fRec34[1] + fRec59 + fRec55 + fRec35 + fRec43 - (self.fRec22[1] + self.fRec50[1] + self.fRec46[1] + self.fRec38[1] + fRec51 + fRec47 + fTemp64); 1157 | self.fRec20[0] = self.fRec58[1] + self.fRec50[1] + self.fRec46[1] + self.fRec34[1] + fRec59 + fRec51 + fRec35 + fRec47 - (self.fRec22[1] + self.fRec54[1] + self.fRec42[1] + self.fRec38[1] + fRec55 + fRec43 + fTemp64); 1158 | self.fRec21[0] = self.fRec22[1] + self.fRec54[1] + self.fRec46[1] + self.fRec34[1] + fRec55 + fRec47 + fTemp55 - (self.fRec58[1] + self.fRec50[1] + self.fRec42[1] + self.fRec38[1] + fRec59 + fRec51 + fRec39 + fRec43); 1159 | *output0 = fSlow108 * (fSlow107 * (fSlow106 * (self.fRec15[0] + self.fRec16[0]) + fSlow26 * fTemp43) + fSlow2 * fTemp0); 1160 | *output1 = fSlow108 * (fSlow107 * (fSlow106 * (self.fRec15[0] - self.fRec16[0]) + fSlow26 * fTemp50) + fSlow2 * fTemp44); 1161 | self.iVec1[1] = self.iVec1[0]; 1162 | self.fRec1[1] = self.fRec1[0]; 1163 | self.fRec3[1] = self.fRec3[0]; 1164 | self.fRec4[1] = self.fRec4[0]; 1165 | self.fRec10[1] = self.fRec10[0]; 1166 | self.fRec11[1] = self.fRec11[0]; 1167 | self.fRec6[1] = self.fRec6[0]; 1168 | self.fRec7[1] = self.fRec7[0]; 1169 | self.IOTA0 = i32::wrapping_add(self.IOTA0, 1); 1170 | self.fRec13[1] = self.fRec13[0]; 1171 | self.fRec29[1] = self.fRec29[0]; 1172 | self.fRec30[1] = self.fRec30[0]; 1173 | self.fRec25[1] = self.fRec25[0]; 1174 | self.fRec26[1] = self.fRec26[0]; 1175 | self.fRec33[1] = self.fRec33[0]; 1176 | self.fRec32[1] = self.fRec32[0]; 1177 | self.fRec22[1] = self.fRec22[0]; 1178 | self.fRec37[1] = self.fRec37[0]; 1179 | self.fRec36[1] = self.fRec36[0]; 1180 | self.fRec34[1] = self.fRec34[0]; 1181 | self.fRec41[1] = self.fRec41[0]; 1182 | self.fRec40[1] = self.fRec40[0]; 1183 | self.fRec38[1] = self.fRec38[0]; 1184 | self.fRec45[1] = self.fRec45[0]; 1185 | self.fRec44[1] = self.fRec44[0]; 1186 | self.fRec42[1] = self.fRec42[0]; 1187 | self.fRec49[1] = self.fRec49[0]; 1188 | self.fRec48[1] = self.fRec48[0]; 1189 | self.fRec46[1] = self.fRec46[0]; 1190 | self.fRec53[1] = self.fRec53[0]; 1191 | self.fRec52[1] = self.fRec52[0]; 1192 | self.fRec50[1] = self.fRec50[0]; 1193 | self.fRec57[1] = self.fRec57[0]; 1194 | self.fRec56[1] = self.fRec56[0]; 1195 | self.fRec54[1] = self.fRec54[0]; 1196 | self.fRec61[1] = self.fRec61[0]; 1197 | self.fRec60[1] = self.fRec60[0]; 1198 | self.fRec58[1] = self.fRec58[0]; 1199 | self.fRec14[2] = self.fRec14[1]; 1200 | self.fRec14[1] = self.fRec14[0]; 1201 | self.fRec15[2] = self.fRec15[1]; 1202 | self.fRec15[1] = self.fRec15[0]; 1203 | self.fRec16[2] = self.fRec16[1]; 1204 | self.fRec16[1] = self.fRec16[0]; 1205 | self.fRec17[2] = self.fRec17[1]; 1206 | self.fRec17[1] = self.fRec17[0]; 1207 | self.fRec18[2] = self.fRec18[1]; 1208 | self.fRec18[1] = self.fRec18[0]; 1209 | self.fRec19[2] = self.fRec19[1]; 1210 | self.fRec19[1] = self.fRec19[0]; 1211 | self.fRec20[2] = self.fRec20[1]; 1212 | self.fRec20[1] = self.fRec20[0]; 1213 | self.fRec21[2] = self.fRec21[1]; 1214 | self.fRec21[1] = self.fRec21[0]; 1215 | } 1216 | } 1217 | 1218 | } 1219 | 1220 | } 1221 | pub use dsp::mydsp as ElysieraDSP; --------------------------------------------------------------------------------