├── .github └── workflows │ └── build.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── LICENSE.md ├── Makefile ├── README.md ├── faust ├── adt.dsp └── arch │ ├── LICENSE-EXCEPTION.md │ ├── generic.cpp │ └── generic.hpp ├── patches └── dpf │ ├── fix-lv2-version-export.patch │ └── no-port-name-lv2-prefix.patch ├── plugins └── adt │ ├── ADT.cpp │ ├── ADT.hpp │ ├── DistrhoPluginInfo.h │ ├── Makefile │ ├── PluginADT.cpp │ └── PluginADT.hpp ├── screenshot-ardour8.png └── scripts ├── build-win32.sh ├── build-win64.sh └── bundle-source.sh /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build and test plugin 2 | 3 | on: 4 | push: 5 | branches: 6 | - "*" 7 | pull_request: 8 | branches: 9 | - "*" 10 | 11 | jobs: 12 | linux: 13 | strategy: 14 | matrix: 15 | target: 16 | - linux-arm64 17 | - linux-armhf 18 | - linux-i686 19 | - linux-riscv64 20 | - linux-x86_64 21 | runs-on: ubuntu-20.04 22 | steps: 23 | - uses: actions/checkout@v4 24 | with: 25 | submodules: recursive 26 | - uses: distrho/dpf-makefile-action@v1 27 | with: 28 | target: ${{ matrix.target }} 29 | release: true 30 | 31 | macos: 32 | strategy: 33 | matrix: 34 | target: 35 | - macos-intel 36 | - macos-universal 37 | runs-on: macos-13 38 | steps: 39 | - uses: actions/checkout@v4 40 | with: 41 | submodules: recursive 42 | - uses: distrho/dpf-makefile-action@v1 43 | with: 44 | target: ${{ matrix.target }} 45 | release: true 46 | 47 | windows: 48 | strategy: 49 | matrix: 50 | target: 51 | - win32 52 | - win64 53 | runs-on: ubuntu-20.04 54 | steps: 55 | - uses: actions/checkout@v4 56 | with: 57 | submodules: recursive 58 | - uses: distrho/dpf-makefile-action@v1 59 | with: 60 | target: ${{ matrix.target }} 61 | release: true 62 | 63 | pluginval: 64 | runs-on: ubuntu-20.04 65 | steps: 66 | - uses: actions/checkout@v4 67 | with: 68 | submodules: recursive 69 | - uses: distrho/dpf-makefile-action@v1 70 | with: 71 | target: pluginval 72 | 73 | source: 74 | runs-on: ubuntu-20.04 75 | steps: 76 | - uses: actions/checkout@v4 77 | with: 78 | submodules: recursive 79 | - uses: distrho/dpf-makefile-action@v1 80 | with: 81 | target: source 82 | release: true 83 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.d 3 | *.o 4 | 5 | *.exe 6 | *.dll 7 | *.dylib 8 | *.so 9 | *.zip 10 | 11 | .DS_Store 12 | 13 | bin-w32/adt-vst.* 14 | bin-w32/adt.clap 15 | bin-w32/adt.exe 16 | bin-w32/adt.lv2 17 | bin-w32/adt.vst3 18 | bin-w64/adt-vst.* 19 | bin-w64/adt.clap 20 | bin-w64/adt.exe 21 | bin-w64/adt.lv2 22 | bin-w64/adt.vst3 23 | bin/adt 24 | bin/adt-dssi.* 25 | bin/adt-ladspa.* 26 | bin/adt-vst.* 27 | bin/adt.clap 28 | bin/adt.lv2/ 29 | bin/adt.vst3 30 | build/ 31 | dist/ 32 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dpf"] 2 | path = dpf 3 | url = https://github.com/DISTRHO/DPF.git 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | 4 | ## 0.2.2 (2024-11-13) 5 | 6 | * Set param unit for pan spread to percent. 7 | * Fix CLAP id. 8 | * Several small readme improvements/fixes. 9 | 10 | 11 | ## 0.2.0 (2024-11-13) 12 | 13 | Initial release 14 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # LICENSE 2 | 3 | ## Automatic Double Tracking 4 | 5 | Automatic Double Tracking is released under the MIT license. 6 | 7 | Copyright (C) 2024 Christopher Arndt 8 | 9 | Permission to use, copy, modify, and/or distribute this software for any 10 | purpose with or without fee is hereby granted, provided that the above 11 | copyright notice and this permission notice appear in all copies. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 14 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 15 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 16 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 17 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 18 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 19 | PERFORMANCE OF THIS SOFTWARE. 20 | 21 | 22 | ## DPF 23 | 24 | DPF is released under the ISC license. Copyright 2012-2022 Filipe Coelho. 25 | 26 | 27 | ## faustpp 28 | 29 | faustpp is released under the Boost Software License 1.0. Copyright 2022 Jean 30 | Pierre Cimalando. 31 | 32 | 33 | ## For the CLAP format 34 | 35 | CLAP is released under the MIT license. Copyright 2021 Alexandre Bique. 36 | 37 | 38 | ## For the LADSPA format 39 | 40 | LADSPA is released under the LGPLv2.1+ license. Copyright 2000-2002 Richard W. 41 | E. Furse, Paul Barton-Davis, Stefan Westerfeld. 42 | 43 | 44 | ## For the LV2 format 45 | 46 | LV2 is released under the ISC license. Copyright 2006-2020 Steve Harris, David 47 | Robillard; 2000-2002 Richard W.E. Furse, Paul Barton-Davis, Stefan Westerfeld. 48 | 49 | 50 | ## For the VST2 format 51 | 52 | The Xaymar VST2SDK is relased under the BSD-3 license. Copyright 2020-2022 53 | Michael Fabian 'Xaymar' Dirks. 54 | 55 | 56 | ## For the VST3 format 57 | 58 | The travesty VST3 headers are part of DPF and also released under the ISC 59 | license. 60 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # Makefile for DISTRHO Plugins # 3 | # ---------------------------- # 4 | # Created by falkTX, Christopher Arndt, and Patrick Desaulniers 5 | # 6 | 7 | # error out if DPF is missing, unless the current rule is 'submodules' 8 | define MISSING_SUBMODULES_ERROR 9 | ============================================================================= 10 | DPF library not found in directory 'dpf'. 11 | Please run "make submodules" to clone the missing Git submodules, then retry. 12 | ============================================================================= 13 | endef 14 | 15 | ifneq ($(MAKECMDGOALS), submodules) 16 | ifeq (,$(wildcard dpf/Makefile.base.mk)) 17 | $(info $(MISSING_SUBMODULES_ERROR)) 18 | $(error Unable to continue) 19 | else 20 | include dpf/Makefile.base.mk 21 | endif 22 | endif 23 | 24 | # -------------------------------------------------------------- 25 | # Installation directories 26 | 27 | PREFIX ?= /usr/local 28 | BINDIR ?= $(PREFIX)/bin 29 | LIBDIR ?= $(PREFIX)/lib 30 | DSSI_DIR ?= $(LIBDIR)/dssi 31 | LADSPA_DIR ?= $(LIBDIR)/ladspa 32 | ifneq ($(MACOS_OR_WINDOWS),true) 33 | LV2_DIR ?= $(LIBDIR)/lv2 34 | VST2_DIR ?= $(LIBDIR)/vst 35 | VST3_DIR ?= $(LIBDIR)/vst3 36 | CLAP_DIR ?= $(LIBDIR)/clap 37 | endif 38 | ifeq ($(MACOS),true) 39 | LV2_DIR ?= /Library/Audio/Plug-Ins/LV2 40 | VST2_DIR ?= /Library/Audio/Plug-Ins/VST 41 | VST3_DIR ?= /Library/Audio/Plug-Ins/VST3 42 | CLAP_DIR ?= /Library/Audio/Plug-Ins/CLAP 43 | endif 44 | ifeq ($(WINDOWS),true) 45 | LV2_DIR ?= $(COMMONPROGRAMFILES)/LV2 46 | VST2_DIR ?= $(COMMONPROGRAMFILES)/VST2 47 | VST3_DIR ?= $(COMMONPROGRAMFILES)/VST3 48 | CLAP_DIR ?= $(COMMONPROGRAMFILES)/CLAP 49 | endif 50 | 51 | USER_DSSI_DIR ?= $(HOME)/.dssi 52 | USER_LADSPA_DIR ?= $(HOME)/.ladspa 53 | ifneq ($(MACOS_OR_WINDOWS),true) 54 | USER_CLAP_DIR ?= $(HOME)/.clap 55 | USER_LV2_DIR ?= $(HOME)/.lv2 56 | USER_VST2_DIR ?= $(HOME)/.vst 57 | USER_VST3_DIR ?= $(HOME)/.vst3 58 | endif 59 | ifeq ($(MACOS),true) 60 | USER_CLAP_DIR ?= $(HOME)/Library/Audio/Plug-Ins/CLAP 61 | USER_LV2_DIR ?= $(HOME)/Library/Audio/Plug-Ins/LV2 62 | USER_VST2_DIR ?= $(HOME)/Library/Audio/Plug-Ins/VST 63 | USER_VST3_DIR ?= $(HOME)/Library/Audio/Plug-Ins/VST3 64 | endif 65 | ifeq ($(WINDOWS),true) 66 | USER_CLAP_DIR ?= $(APPDATA)/CLAP 67 | USER_LV2_DIR ?= $(APPDATA)/LV2 68 | USER_VST2_DIR ?= $(APPDATA)/VST 69 | USER_VST3_DIR ?= $(APPDATA)/VST3 70 | endif 71 | 72 | export DESTDIR PREFIX BINDIR LIBDIR 73 | export CLAP_DIR DSSI_DIR LADSPA_DIR LV2_DIR VST2_DIR VST3_DIR 74 | export USER_CLAP_DIR USER_DSSI_DIR USER_LADSPA_DIR USER_LV2_DIR USER_VST2_DIR USER_VST3_DIR 75 | 76 | # -------------------------------------------------------------- 77 | # Targets 78 | 79 | all: libs plugins gen 80 | 81 | # -------------------------------------------------------------- 82 | 83 | PLUGINS = adt 84 | 85 | DPF_PATCHES = \ 86 | dpf/fix-lv2-version-export.patch \ 87 | dpf/no-port-name-lv2-prefix.patch 88 | 89 | submodules: 90 | -test -d .git && git submodule update --init --recursive 91 | 92 | libs: submodules patch 93 | 94 | patch: submodules 95 | @-for p in $(DPF_PATCHES); do \ 96 | echo "Applying patch '$${p}'..."; \ 97 | patch -d dpf -r - -p1 -N --no-backup-if-mismatch -i ../patches/$${p}; \ 98 | done 99 | 100 | plugins: $(PLUGINS) 101 | 102 | $(PLUGINS): 103 | $(MAKE) all -C plugins/$@ 104 | 105 | ifneq ($(CROSS_COMPILING),true) 106 | gen: plugins dpf/utils/lv2_ttl_generator 107 | @$(CURDIR)/dpf/utils/generate-ttl.sh 108 | ifeq ($(MACOS),true) 109 | @$(CURDIR)/dpf/utils/generate-vst-bundles.sh 110 | endif 111 | 112 | dpf/utils/lv2_ttl_generator: 113 | $(MAKE) -C dpf/utils/lv2-ttl-generator 114 | else 115 | gen: plugins dpf/utils/lv2_ttl_generator.exe 116 | @$(CURDIR)/dpf/utils/generate-ttl.sh 117 | 118 | dpf/utils/lv2_ttl_generator.exe: 119 | $(MAKE) -C dpf/utils/lv2-ttl-generator WINDOWS=true 120 | endif 121 | 122 | # -------------------------------------------------------------- 123 | 124 | lv2lint: gen 125 | @echo "Please make sure you have the https://github.com/KXStudio/LV2-Extensions bundles" 126 | @echo "installed somewhere on your LV2_PATH." 127 | @for plug in $(PLUGINS); do \ 128 | plugin_uri="$$(grep DISTRHO_PLUGIN_URI plugins/$$plug/DistrhoPluginInfo.h | cut -d '"' -f 2)"; \ 129 | lv2lint -Mpack -q -s lv2_generate_ttl -t "Plugin Author Email" \ 130 | -I bin/$${plug,,}.lv2/ "$$plugin_uri"; \ 131 | done 132 | 133 | # -------------------------------------------------------------- 134 | 135 | clean: 136 | $(MAKE) clean -C dpf/utils/lv2-ttl-generator 137 | @for plug in $(PLUGINS); do \ 138 | $(MAKE) clean -C plugins/$${plug}; \ 139 | done 140 | rm -rf bin build 141 | 142 | install: all 143 | @for plug in $(PLUGINS); do \ 144 | $(MAKE) install -C plugins/$${plug}; \ 145 | done 146 | 147 | install-user: all 148 | @for plug in $(PLUGINS); do \ 149 | $(MAKE) install-user -C plugins/$${plug}; \ 150 | done 151 | 152 | # -------------------------------------------------------------- 153 | 154 | .PHONY: all clean gen install install-user libs lv2lint patch plugins submodule 155 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Automatic Double Tracking 2 | 3 | [Automatic double tracking] (not only) for vocals. 4 | 5 | This plugin copies the input four times and pans the copies alternatively 6 | left and right by a set amount, delays each by up to 100 ms and also 7 | pitch-shifts each copy by up to 150 cents. The maximum pan, delay and 8 | pitch-shift spread can be independently controlled by parameters as well 9 | as the cutoff frequencies of a low- and high-pass filter applied to the 10 | stereo ouput. 11 | 12 | This effect can be used to thicken up lead or background vocals or other 13 | signals that need more presence in the mix. 14 | 15 | It can be used as either an insert effect or as a send effect in an 16 | auxilliary bus by providing separate dry and wet signal gain parameters. 17 | 18 |

19 | 20 | 21 | ## Formats 22 | 23 | This plugin is available in the following plug-in formats by default: 24 | 25 | * [CLAP] (`de.chrisarndt.adt`) 26 | * [LV2] (`https://chrisarndt.de/plugins/adt`) 27 | * [VST3][vst] (`adt.vst3`) 28 | 29 | The following formats are not built by default, but can be enabled when 30 | compiling (see ["Compiling"](#compiling)): 31 | 32 | * [LADSPA] (`adt-ladspa.so`) 33 | * [VST2][vst] (`adt-vst.so`) 34 | 35 | The plugin depends on the host to provide a generic UI to control parameters. 36 | 37 | 38 | ## Compiling 39 | 40 | Make sure you have installed the required build tools and libraries (see 41 | section "Prerequisites" below) and then clone this repository (including 42 | sub-modules) and simply run `make` in the project's root directory: 43 | 44 | $ git clone --recursive https://github.com/SpotlightKid/adt.git 45 | $ cd adt 46 | $ make 47 | 48 | To enable building additional plugin formats, which are not enabled by default 49 | (LADSPA, VST2), pass `BUILD_LADSPA=true` resp. `BUILD_VST2=true` to make. For 50 | example: 51 | 52 | make BUILD_VST2=true 53 | 54 | The same settings must be passed to `make install` to also install optional 55 | plugin formats. 56 | 57 | 58 | ## Installation 59 | 60 | To install all plugin formats to their appropriate system-wide location, run 61 | the following command (root priviledges may be required): 62 | 63 | make install 64 | 65 | The makefiles support the usual `PREFIX` and `DESTDIR` variables to change the 66 | installation prefix and set an installation root directory (defaulty: empty). 67 | `PREFIX` defaults to `/usr/local`, but on macOS and Windows it is not used, 68 | since the system-wide installation directories for plugins are fixed. 69 | 70 | Use make's `-n` option to see where the plugins would be installed without 71 | actually installing them. 72 | 73 | You can also set the installation directory for each plugin format with a 74 | dedicated makefile variable. 75 | 76 | * CLAP: `CLAP_DIR` (`/lib/clap`) 77 | * LADSPA: `LADSPA_DIR` (`/lib/ladspa`) 78 | * LV2: `LV2_DIR` (`/lib/lv2`) 79 | * VST2: `VST2_DIR` (`/lib/vst`) 80 | * VST3: `VST3_DIR` (`/lib/vst3`) 81 | 82 | Example: 83 | 84 | make DESTDIR=/tmp/build-root BUILD_VST2=true VST2_DIR=/usr/lib/lxvst install 85 | 86 | To install the plugins only for your current user account, run 87 | `make install-user`. 88 | 89 | Again, you can also set the installation directory for each plugin format with 90 | a dedicated makefile variable. 91 | 92 | * CLAP: `USER_CLAP_DIR` (`$HOME/.clap`) 93 | * LADSPA: `USER_LADSPA_DIR` (`$HOME/.ladspa`) 94 | * LV2: `USER_LV2_DIR` (`$HOME/.lv2`) 95 | * VST2: `USER_VST2_DIR` (`$HOME/.vst`) 96 | * VST3: `USER_VST3_DIR` (`$HOME/.vst3`) 97 | 98 | *Note: The given default values for all of the above listed makefile 99 | variables differ depending on the target OS.* 100 | 101 | 102 | ## Prerequisites 103 | 104 | * The GCC C++ compiler, library and the usual associated software build tools 105 | (`make`, etc.). 106 | 107 | Debian / Ubuntu users should install the `build-essential` package 108 | to get these, Arch users the `base-devel` meta package. 109 | 110 | * `patch` 111 | 112 | * [pkgconf] 113 | 114 | * The [faustpp] post-processor and [FAUST] (optional) 115 | 116 | The [CLAP], [LV2], [LADSPA], [VST2][vst] (Xaymar VST2SDK) and [VST3][vst] 117 | headers are included in the [DPF] framework, which is integrated as a Git 118 | sub-module. These need not be installed separately to build the software in 119 | the respective plug-in formats. 120 | 121 | `faustpp` and FAUST are only needed to re-generate C++ source and header files 122 | if the FAUST DSP source files in the `faust` directory are changed. 123 | 124 | 125 | ## Author 126 | 127 | This software was created by *Christopher Arndt*. 128 | 129 | 130 | ## License 131 | 132 | This plugin is released under the *MIT* license. Please see the 133 | [LICENSE.md](./LICENSE.md) file for details. 134 | 135 | 136 | ## Acknowledgements 137 | 138 | The DSP code is generated from the FAUST sources via the [faustpp] 139 | post-processor. 140 | 141 | The project is built using the DISTRHO Plugin Framework ([DPF]) and was created 142 | from the [dpf-faust-project-template] using [copier]. 143 | 144 | 145 | [automatic double tracking]: https://en.wikipedia.org/wiki/Automatic_double_tracking 146 | [clap]: https://cleveraudio.org/ 147 | [dpf-faust-project-template]: https://github.com/SpotlightKid/dpf-faust-project-template 148 | [copier]: https://copier.readthedocs.io/en/stable/ 149 | [dpf]: https://github.com/DISTRHO/DPF 150 | [faust]: https://faust.grame.fr/ 151 | [faustpp]: https://github.com/jpcima/faustpp 152 | [ladspa]: https://www.ladspa.org/ 153 | [lv2]: https://lv2plug.in/ 154 | [pkgconf]: https://github.com/pkgconf/pkgconf 155 | [vst]: https://en.wikipedia.org/wiki/Virtual_Studio_Technology 156 | -------------------------------------------------------------------------------- /faust/adt.dsp: -------------------------------------------------------------------------------- 1 | declare name "ADT"; 2 | declare description "Automatic double tracking (not only) for vocals"; 3 | declare version "0.1"; 4 | declare author "Christopher Arndt"; 5 | declare license "MIT License"; 6 | 7 | import("stdfaust.lib"); 8 | 9 | NVOICES = 4; 10 | MAX_DELAY = (ma.SR / 20) * NVOICES; 11 | WINDOW_SAMPLES = 256; 12 | XFADE_SAMPLES = 50; 13 | SMOOTH_SAMPLES = 1024; 14 | 15 | easeOutCubic(x) = 1 - pow(1 - x, 3); 16 | 17 | easeInOutCubic(x) = 4 * x * x * x, 1 - pow(-2 * x + 2, 3) / 2 : select2(x < 0.5); 18 | 19 | delay(ms) = de.sdelay(MAX_DELAY, SMOOTH_SAMPLES, ba.sec2samp(ms / 1000)); 20 | 21 | transpose(ct) = ef.transpose(WINDOW_SAMPLES, XFADE_SAMPLES, ct / 100); 22 | 23 | // Split input into four signals and: 24 | // 25 | // | Channel | Pan | Delay | Pitch Shift | 26 | // | ------- | ----------- | ---------------- | --------------------- | 27 | // | 1 | 0-100 left | 1/4 Delay Spread | 1/2 Pitch Spread down | 28 | // | 2 | 0- 50 left | 3/4 Delay Spread | 1/1 Pitch Spread up | 29 | // | 3 | 0- 50 right | 2/4 Delay Spread | 1/2 Pitch Spread up | 30 | // | 4 | 0-100 right | 1/1 Delay Spread | 1/1 Pitch Spread down | 31 | // 32 | channel(i, pan_spread, delay_spread, pitch_spread) = delay(delay_ms) : transpose(pitch) : sp.panner(pan) 33 | with { 34 | delay_factor(x) = 1 * (x==1), 3 * (x==2), 2 * (x==3), 4 * (x==4) :> _; 35 | pitch_factor(x) = -1 * (x==1), 2 * (x==2), 1 * (x==3), -2 * (x==4) :> _; 36 | pitch = pitch_spread * 0.5 * pitch_factor(i + 1); 37 | delay_ms = delay_spread * 0.25 * delay_factor(i + 1); 38 | pan_side = -1, 1 : select2(i<2); // channels 1/2 left, channels 3/4 right 39 | pan = 0.5 + (pan_spread * pan_side); 40 | }; 41 | 42 | adt4x = _ <: par(i, NVOICES, channel(i, pan_spread, delay_spread, pitch_spread)) :> /(NVOICES), /(NVOICES) 43 | with { 44 | // unit should be "pc", but DPF doesn't handle that correctly 45 | pan_spread = hslider("[1] Pan Spread [unit:%]", 100, 0, 100, 1) / 200 : si.smoo; 46 | delay_spread = hslider("[2] Delay Spread [unit:ms]", 40, 0, 100, 1); 47 | pitch_spread = hslider("[3] Pitch Spread [unit:ct]", 40, 0, 150, 1); 48 | }; 49 | 50 | out_mixer(fx, dry, wet, in) = fx(in) : *(wet), *(wet) : +(in / 2 * dry), +(in / 2 * dry); 51 | 52 | fc_lp = hslider("[4] Lowpass [unit:Hz] [scale:log]", 3500, 20, 20000, 0.1) : si.smoo; 53 | fc_hp = hslider("[5] Highpass [unit:Hz] [scale:log]", 20, 20, 20000, 0.1) : si.smoo; 54 | 55 | lpf = fi.lowpass(2, fc_lp); 56 | hpf = fi.highpass(2, fc_hp); 57 | 58 | lpf_stereo = lpf, lpf; 59 | hpf_stereo = hpf, hpf; 60 | 61 | process = out_mixer( 62 | adt4x : lpf_stereo : hpf_stereo, 63 | hslider("[6] Dry [unit:dB]", -3, -90, 10, 0.1) : ba.db2linear, 64 | hslider("[7] Wet [unit:dB]", -4, -90, 10, 0.1) : ba.db2linear 65 | ); 66 | -------------------------------------------------------------------------------- /faust/arch/LICENSE-EXCEPTION.md: -------------------------------------------------------------------------------- 1 | # License exception 2 | 3 | The architecture files under the `architectures/` directory are distributed 4 | under BSL-1.0 license, like the software itself. 5 | 6 | The following license exception applies: 7 | 8 | Is it not required to license, even partially, the code generated by `faustpp` 9 | using these architecture files under the BSL-1.0 to cover the code fragments, 10 | which are produced from the templates. It is allowed to retain in full the 11 | license which applies to the Faust source file which is processed. 12 | -------------------------------------------------------------------------------- /faust/arch/generic.cpp: -------------------------------------------------------------------------------- 1 | {% block ImplementationDescription %} 2 | //------------------------------------------------------------------------------ 3 | // This file was generated using the Faust compiler (https://faust.grame.fr), 4 | // and the Faust post-processor (https://github.com/jpcima/faustpp). 5 | // 6 | // Source: {{file_name}} 7 | // Name: {{name}} 8 | // Author: {{author}} 9 | // Copyright: {{copyright}} 10 | // License: {{license}} 11 | // Version: {{version}} 12 | //------------------------------------------------------------------------------ 13 | {% endblock %} 14 | 15 | {% block ImplementationPrologue %} 16 | {% if not (Identifier is defined and 17 | Identifier == cid(Identifier)) %} 18 | {{fail("`Identifier` is undefined or invalid.")}} 19 | {% endif %} 20 | {% endblock %} 21 | 22 | {% block ImplementationIncludeHeader %} 23 | #include "{{Identifier}}.hpp" 24 | {% endblock %} 25 | {% block ImplementationIncludeExtra %} 26 | {% endblock %} 27 | #include 28 | #include 29 | 30 | class {{Identifier}}::BasicDsp { 31 | public: 32 | virtual ~BasicDsp() {} 33 | }; 34 | 35 | //------------------------------------------------------------------------------ 36 | // Begin the Faust code section 37 | 38 | namespace { 39 | 40 | template inline T min(T a, T b) { return (a < b) ? a : b; } 41 | template inline T max(T a, T b) { return (a > b) ? a : b; } 42 | 43 | class Meta { 44 | public: 45 | // dummy 46 | void declare(...) {} 47 | }; 48 | 49 | class UI { 50 | public: 51 | // dummy 52 | void openHorizontalBox(...) {} 53 | void openVerticalBox(...) {} 54 | void closeBox(...) {} 55 | void declare(...) {} 56 | void addButton(...) {} 57 | void addCheckButton(...) {} 58 | void addVerticalSlider(...) {} 59 | void addHorizontalSlider(...) {} 60 | void addVerticalBargraph(...) {} 61 | void addHorizontalBargraph(...) {} 62 | }; 63 | 64 | typedef {{Identifier}}::BasicDsp dsp; 65 | 66 | } // namespace 67 | 68 | #define FAUSTPP_VIRTUAL // do not declare any methods virtual 69 | #define FAUSTPP_PRIVATE public // do not hide any members 70 | #define FAUSTPP_PROTECTED public // do not hide any members 71 | 72 | // define the DSP in the anonymous namespace 73 | #define FAUSTPP_BEGIN_NAMESPACE namespace { 74 | #define FAUSTPP_END_NAMESPACE } 75 | 76 | {% block ImplementationFaustCode %} 77 | {{class_code}} 78 | {% endblock %} 79 | 80 | //------------------------------------------------------------------------------ 81 | // End the Faust code section 82 | 83 | {% block ImplementationBeforeClassDefs %} 84 | {% endblock %} 85 | 86 | {{Identifier}}::{{Identifier}}() 87 | { 88 | {% block ImplementationSetupDsp %} 89 | {{class_name}} *dsp = new {{class_name}}; 90 | fDsp.reset(dsp); 91 | dsp->instanceResetUserInterface(); 92 | {% endblock %} 93 | } 94 | 95 | {{Identifier}}::~{{Identifier}}() 96 | { 97 | } 98 | 99 | void {{Identifier}}::init(float sample_rate) 100 | { 101 | {% block ImplementationInitDsp %} 102 | {{class_name}} &dsp = static_cast<{{class_name}} &>(*fDsp); 103 | dsp.classInit(sample_rate); 104 | dsp.instanceConstants(sample_rate); 105 | clear(); 106 | {% endblock %} 107 | } 108 | 109 | void {{Identifier}}::clear() noexcept 110 | { 111 | {% block ImplementationClearDsp %} 112 | {{class_name}} &dsp = static_cast<{{class_name}} &>(*fDsp); 113 | dsp.instanceClear(); 114 | {% endblock %} 115 | } 116 | 117 | void {{Identifier}}::process( 118 | {% for i in range(inputs) %}const float *in{{i}},{% endfor %} 119 | {% for i in range(outputs) %}float *out{{i}},{% endfor %} 120 | unsigned count) noexcept 121 | { 122 | {% block ImplementationProcessDsp %} 123 | {{class_name}} &dsp = static_cast<{{class_name}} &>(*fDsp); 124 | float *inputs[] = { 125 | {% for i in range(inputs) %}const_cast(in{{i}}),{% endfor %} 126 | }; 127 | float *outputs[] = { 128 | {% for i in range(outputs) %}out{{i}},{% endfor %} 129 | }; 130 | dsp.compute(count, inputs, outputs); 131 | {% endblock %} 132 | } 133 | 134 | const char *{{Identifier}}::parameter_label(unsigned index) noexcept 135 | { 136 | switch (index) { 137 | {% for w in active + passive %} 138 | case {{loop.index0}}: 139 | return {{cstr(w.label)}}; 140 | {% endfor %} 141 | default: 142 | return 0; 143 | } 144 | } 145 | 146 | const char *{{Identifier}}::parameter_short_label(unsigned index) noexcept 147 | { 148 | switch (index) { 149 | {% for w in active + passive %} 150 | case {{loop.index0}}: 151 | return {{cstr(w.meta.abbrev|default(""))}}; 152 | {% endfor %} 153 | default: 154 | return 0; 155 | } 156 | } 157 | 158 | const char *{{Identifier}}::parameter_symbol(unsigned index) noexcept 159 | { 160 | switch (index) { 161 | {% for w in active + passive %} 162 | case {{loop.index0}}: 163 | return {{cstr(cid(w.meta.symbol|default(w.label)))}}; 164 | {% endfor %} 165 | default: 166 | return 0; 167 | } 168 | } 169 | 170 | const char *{{Identifier}}::parameter_unit(unsigned index) noexcept 171 | { 172 | switch (index) { 173 | {% for w in active + passive %} 174 | case {{loop.index0}}: 175 | return {{cstr(w.unit)}}; 176 | {% endfor %} 177 | default: 178 | return 0; 179 | } 180 | } 181 | 182 | const {{Identifier}}::ParameterRange *{{Identifier}}::parameter_range(unsigned index) noexcept 183 | { 184 | switch (index) { 185 | {% for w in active + passive %} 186 | case {{loop.index0}}: { 187 | static const ParameterRange range = { {{w.init}}, {{w.min}}, {{w.max}} }; 188 | return ⦥ 189 | } 190 | {% endfor %} 191 | default: 192 | return 0; 193 | } 194 | } 195 | 196 | bool {{Identifier}}::parameter_is_trigger(unsigned index) noexcept 197 | { 198 | switch (index) { 199 | {% for w in active + passive %}{% if w.type in ["button"] or 200 | w.meta.trigger is defined %} 201 | case {{loop.index0}}: 202 | return true; 203 | {% endif %}{% endfor %} 204 | default: 205 | return false; 206 | } 207 | } 208 | 209 | bool {{Identifier}}::parameter_is_boolean(unsigned index) noexcept 210 | { 211 | switch (index) { 212 | {% for w in active + passive %}{% if w.type in ["button", "checkbox"] or 213 | w.meta.boolean is defined %} 214 | case {{loop.index0}}: 215 | return true; 216 | {% endif %}{% endfor %} 217 | default: 218 | return false; 219 | } 220 | } 221 | 222 | bool {{Identifier}}::parameter_is_integer(unsigned index) noexcept 223 | { 224 | switch (index) { 225 | {% for w in active + passive %}{% if w.type in ["button", "checkbox"] or 226 | w.meta.integer is defined or 227 | w.meta.boolean is defined %} 228 | case {{loop.index0}}: 229 | return true; 230 | {% endif %}{% endfor %} 231 | default: 232 | return false; 233 | } 234 | } 235 | 236 | bool {{Identifier}}::parameter_is_logarithmic(unsigned index) noexcept 237 | { 238 | switch (index) { 239 | {% for w in active + passive %}{% if w.scale == "log" %} 240 | case {{loop.index0}}: 241 | return true; 242 | {% endif %}{% endfor %} 243 | default: 244 | return false; 245 | } 246 | } 247 | 248 | float {{Identifier}}::get_parameter(unsigned index) const noexcept 249 | { 250 | {{class_name}} &dsp = static_cast<{{class_name}} &>(*fDsp); 251 | switch (index) { 252 | {% for w in active + passive %} 253 | case {{loop.index0}}: 254 | return dsp.{{w.var}}; 255 | {% endfor %} 256 | default: 257 | (void)dsp; 258 | return 0; 259 | } 260 | } 261 | 262 | void {{Identifier}}::set_parameter(unsigned index, float value) noexcept 263 | { 264 | {{class_name}} &dsp = static_cast<{{class_name}} &>(*fDsp); 265 | switch (index) { 266 | {% for w in active %} 267 | case {{loop.index0}}: 268 | dsp.{{w.var}} = value; 269 | break; 270 | {% endfor %} 271 | default: 272 | (void)dsp; 273 | (void)value; 274 | break; 275 | } 276 | } 277 | 278 | {% for w in active + passive %} 279 | float {{Identifier}}::get_{{cid(w.meta.symbol|default(w.label))}}() const noexcept 280 | { 281 | {{class_name}} &dsp = static_cast<{{class_name}} &>(*fDsp); 282 | return dsp.{{w.var}}; 283 | } 284 | {% endfor %} 285 | {% for w in active %} 286 | void {{Identifier}}::set_{{cid(w.meta.symbol|default(w.label))}}(float value) noexcept 287 | { 288 | {{class_name}} &dsp = static_cast<{{class_name}} &>(*fDsp); 289 | dsp.{{w.var}} = value; 290 | } 291 | {% endfor %} 292 | 293 | {% block ImplementationEpilogue %} 294 | {% endblock %} 295 | -------------------------------------------------------------------------------- /faust/arch/generic.hpp: -------------------------------------------------------------------------------- 1 | {% block HeaderDescription %} 2 | //------------------------------------------------------------------------------ 3 | // This file was generated using the Faust compiler (https://faust.grame.fr), 4 | // and the Faust post-processor (https://github.com/jpcima/faustpp). 5 | // 6 | // Source: {{file_name}} 7 | // Name: {{name}} 8 | // Author: {{author}} 9 | // Copyright: {{copyright}} 10 | // License: {{license}} 11 | // Version: {{version}} 12 | //------------------------------------------------------------------------------ 13 | {% endblock %} 14 | 15 | {% block HeaderPrologue %} 16 | {% if not (Identifier is defined and 17 | Identifier == cid(Identifier)) %} 18 | {{fail("`Identifier` is undefined or invalid.")}} 19 | {% endif %} 20 | {% endblock %} 21 | 22 | #pragma once 23 | #ifndef {{Identifier}}_Faust_pp_Gen_HPP_ 24 | #define {{Identifier}}_Faust_pp_Gen_HPP_ 25 | 26 | #include 27 | 28 | class {{Identifier}} { 29 | public: 30 | {{Identifier}}(); 31 | ~{{Identifier}}(); 32 | 33 | void init(float sample_rate); 34 | void clear() noexcept; 35 | 36 | void process( 37 | {% for i in range(inputs) %}const float *in{{i}},{% endfor %} 38 | {% for i in range(outputs) %}float *out{{i}},{% endfor %} 39 | unsigned count) noexcept; 40 | 41 | enum { NumInputs = {{inputs}} }; 42 | enum { NumOutputs = {{outputs}} }; 43 | enum { NumActives = {{active|length}} }; 44 | enum { NumPassives = {{passive|length}} }; 45 | enum { NumParameters = {{active|length + passive|length}} }; 46 | 47 | enum Parameter { 48 | {% for w in active + passive %}p_{{cid(w.meta.symbol|default(w.label))}}, 49 | {% endfor %} 50 | }; 51 | 52 | struct ParameterRange { 53 | float init; 54 | float min; 55 | float max; 56 | }; 57 | 58 | static const char *parameter_label(unsigned index) noexcept; 59 | static const char *parameter_short_label(unsigned index) noexcept; 60 | static const char *parameter_symbol(unsigned index) noexcept; 61 | static const char *parameter_unit(unsigned index) noexcept; 62 | static const ParameterRange *parameter_range(unsigned index) noexcept; 63 | static bool parameter_is_trigger(unsigned index) noexcept; 64 | static bool parameter_is_boolean(unsigned index) noexcept; 65 | static bool parameter_is_integer(unsigned index) noexcept; 66 | static bool parameter_is_logarithmic(unsigned index) noexcept; 67 | 68 | float get_parameter(unsigned index) const noexcept; 69 | void set_parameter(unsigned index, float value) noexcept; 70 | 71 | {% for w in active + passive %} 72 | float get_{{cid(w.meta.symbol|default(w.label))}}() const noexcept; 73 | {% endfor %} 74 | {% for w in active %} 75 | void set_{{cid(w.meta.symbol|default(w.label))}}(float value) noexcept; 76 | {% endfor %} 77 | 78 | public: 79 | class BasicDsp; 80 | 81 | private: 82 | std::unique_ptr fDsp; 83 | 84 | {% block ClassExtraDecls %} 85 | {% endblock %} 86 | }; 87 | 88 | {% block HeaderEpilogue %} 89 | {% endblock %} 90 | 91 | #endif // {{Identifier}}_Faust_pp_Gen_HPP_ 92 | -------------------------------------------------------------------------------- /patches/dpf/fix-lv2-version-export.patch: -------------------------------------------------------------------------------- 1 | diff --git a/distrho/src/DistrhoPluginLV2export.cpp b/distrho/src/DistrhoPluginLV2export.cpp 2 | index c074109..1bce6b0 100644 3 | --- a/distrho/src/DistrhoPluginLV2export.cpp 4 | +++ b/distrho/src/DistrhoPluginLV2export.cpp 5 | @@ -746,16 +746,11 @@ void lv2_generate_ttl(const char* const basename) 6 | { 7 | const uint32_t version(plugin.getVersion()); 8 | 9 | - const uint32_t majorVersion = (version & 0xFF0000) >> 16; 10 | - const uint32_t microVersion = (version & 0x00FF00) >> 8; 11 | - /* */ uint32_t minorVersion = (version & 0x0000FF) >> 0; 12 | + const uint32_t minorVersion = (version & 0x00FF00) >> 8; 13 | + const uint32_t microVersion = (version & 0x0000FF) >> 0; 14 | 15 | - // NOTE: LV2 ignores 'major' version and says 0 for minor is pre-release/unstable. 16 | - if (majorVersion > 0) 17 | - minorVersion += 2; 18 | - 19 | - pluginString += " lv2:microVersion " + String(microVersion) + " ;\n"; 20 | - pluginString += " lv2:minorVersion " + String(minorVersion) + " .\n"; 21 | + pluginString += " lv2:minorVersion " + String(minorVersion) + " ;\n"; 22 | + pluginString += " lv2:microVersion " + String(microVersion) + " .\n"; 23 | } 24 | 25 | pluginFile << pluginString << std::endl; 26 | -------------------------------------------------------------------------------- /patches/dpf/no-port-name-lv2-prefix.patch: -------------------------------------------------------------------------------- 1 | diff --git a/distrho/src/DistrhoPluginLV2export.cpp b/distrho/src/DistrhoPluginLV2export.cpp 2 | index c074109..b6b2875 100644 3 | --- a/distrho/src/DistrhoPluginLV2export.cpp 4 | +++ b/distrho/src/DistrhoPluginLV2export.cpp 5 | @@ -422,7 +422,7 @@ void lv2_generate_ttl(const char* const basename) 6 | pluginString += " a lv2:InputPort, lv2:AudioPort ;\n"; 7 | 8 | pluginString += " lv2:index " + String(portIndex) + " ;\n"; 9 | - pluginString += " lv2:symbol \"lv2_" + port.symbol + "\" ;\n"; 10 | + pluginString += " lv2:symbol \"" + port.symbol + "\" ;\n"; 11 | pluginString += " lv2:name \"" + port.name + "\" ;\n"; 12 | 13 | if (port.hints & kAudioPortIsSidechain) 14 | @@ -452,7 +452,7 @@ void lv2_generate_ttl(const char* const basename) 15 | pluginString += " a lv2:OutputPort, lv2:AudioPort ;\n"; 16 | 17 | pluginString += " lv2:index " + String(portIndex) + " ;\n"; 18 | - pluginString += " lv2:symbol \"lv2_" + port.symbol + "\" ;\n"; 19 | + pluginString += " lv2:symbol \"" + port.symbol + "\" ;\n"; 20 | pluginString += " lv2:name \"" + port.name + "\" ;\n"; 21 | 22 | if (port.hints & kAudioPortIsSidechain) 23 | @@ -471,7 +471,7 @@ void lv2_generate_ttl(const char* const basename) 24 | pluginString += " a lv2:InputPort, atom:AtomPort ;\n"; 25 | pluginString += " lv2:index " + String(portIndex) + " ;\n"; 26 | pluginString += " lv2:name \"Events Input\" ;\n"; 27 | - pluginString += " lv2:symbol \"lv2_events_in\" ;\n"; 28 | + pluginString += " lv2:symbol \"events_in\" ;\n"; 29 | pluginString += " rsz:minimumSize " + String(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n"; 30 | pluginString += " atom:bufferType atom:Sequence ;\n"; 31 | # if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) 32 | @@ -492,7 +492,7 @@ void lv2_generate_ttl(const char* const basename) 33 | pluginString += " a lv2:OutputPort, atom:AtomPort ;\n"; 34 | pluginString += " lv2:index " + String(portIndex) + " ;\n"; 35 | pluginString += " lv2:name \"Events Output\" ;\n"; 36 | - pluginString += " lv2:symbol \"lv2_events_out\" ;\n"; 37 | + pluginString += " lv2:symbol \"events_out\" ;\n"; 38 | pluginString += " rsz:minimumSize " + String(DISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE) + " ;\n"; 39 | pluginString += " atom:bufferType atom:Sequence ;\n"; 40 | # if (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI) 41 | @@ -510,7 +510,7 @@ void lv2_generate_ttl(const char* const basename) 42 | pluginString += " a lv2:OutputPort, lv2:ControlPort ;\n"; 43 | pluginString += " lv2:index " + String(portIndex) + " ;\n"; 44 | pluginString += " lv2:name \"Latency\" ;\n"; 45 | - pluginString += " lv2:symbol \"lv2_latency\" ;\n"; 46 | + pluginString += " lv2:symbol \"latency\" ;\n"; 47 | pluginString += " lv2:designation lv2:latency ;\n"; 48 | pluginString += " lv2:portProperty lv2:reportsLatency, lv2:integer, <" LV2_PORT_PROPS__notOnGUI "> ;\n"; 49 | pluginString += " ] ;\n\n"; 50 | @@ -561,7 +561,7 @@ void lv2_generate_ttl(const char* const basename) 51 | String symbol(plugin.getParameterSymbol(i)); 52 | 53 | if (symbol.isEmpty()) 54 | - symbol = "lv2_port_" + String(portIndex-1); 55 | + symbol = "port_" + String(portIndex-1); 56 | 57 | pluginString += " lv2:symbol \"" + symbol + "\" ;\n"; 58 | 59 | -------------------------------------------------------------------------------- /plugins/adt/ADT.cpp: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------------ 3 | // This file was generated using the Faust compiler (https://faust.grame.fr), 4 | // and the Faust post-processor (https://github.com/jpcima/faustpp). 5 | // 6 | // Source: adt.dsp 7 | // Name: ADT 8 | // Author: Christopher Arndt 9 | // Copyright: 10 | // License: MIT License 11 | // Version: 0.1 12 | //------------------------------------------------------------------------------ 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | #include "ADT.hpp" 21 | 22 | 23 | 24 | #include 25 | #include 26 | 27 | class ADT::BasicDsp { 28 | public: 29 | virtual ~BasicDsp() {} 30 | }; 31 | 32 | //------------------------------------------------------------------------------ 33 | // Begin the Faust code section 34 | 35 | namespace { 36 | 37 | template inline T min(T a, T b) { return (a < b) ? a : b; } 38 | template inline T max(T a, T b) { return (a > b) ? a : b; } 39 | 40 | class Meta { 41 | public: 42 | // dummy 43 | void declare(...) {} 44 | }; 45 | 46 | class UI { 47 | public: 48 | // dummy 49 | void openHorizontalBox(...) {} 50 | void openVerticalBox(...) {} 51 | void closeBox(...) {} 52 | void declare(...) {} 53 | void addButton(...) {} 54 | void addCheckButton(...) {} 55 | void addVerticalSlider(...) {} 56 | void addHorizontalSlider(...) {} 57 | void addVerticalBargraph(...) {} 58 | void addHorizontalBargraph(...) {} 59 | }; 60 | 61 | typedef ADT::BasicDsp dsp; 62 | 63 | } // namespace 64 | 65 | #define FAUSTPP_VIRTUAL // do not declare any methods virtual 66 | #define FAUSTPP_PRIVATE public // do not hide any members 67 | #define FAUSTPP_PROTECTED public // do not hide any members 68 | 69 | // define the DSP in the anonymous namespace 70 | #define FAUSTPP_BEGIN_NAMESPACE namespace { 71 | #define FAUSTPP_END_NAMESPACE } 72 | 73 | 74 | #if defined(__GNUC__) 75 | # pragma GCC diagnostic push 76 | # pragma GCC diagnostic ignored "-Wunused-parameter" 77 | #endif 78 | 79 | #ifndef FAUSTPP_PRIVATE 80 | # define FAUSTPP_PRIVATE private 81 | #endif 82 | #ifndef FAUSTPP_PROTECTED 83 | # define FAUSTPP_PROTECTED protected 84 | #endif 85 | #ifndef FAUSTPP_VIRTUAL 86 | # define FAUSTPP_VIRTUAL virtual 87 | #endif 88 | 89 | #ifndef FAUSTPP_BEGIN_NAMESPACE 90 | # define FAUSTPP_BEGIN_NAMESPACE 91 | #endif 92 | #ifndef FAUSTPP_END_NAMESPACE 93 | # define FAUSTPP_END_NAMESPACE 94 | #endif 95 | 96 | FAUSTPP_BEGIN_NAMESPACE 97 | 98 | #ifndef FAUSTFLOAT 99 | #define FAUSTFLOAT float 100 | #endif 101 | 102 | FAUSTPP_END_NAMESPACE 103 | #include 104 | #include 105 | #include 106 | #include 107 | FAUSTPP_BEGIN_NAMESPACE 108 | 109 | #ifndef FAUSTCLASS 110 | #define FAUSTCLASS mydsp 111 | #endif 112 | 113 | #ifdef __APPLE__ 114 | #define exp10f __exp10f 115 | #define exp10 __exp10 116 | #endif 117 | 118 | #if defined(_WIN32) 119 | #define RESTRICT __restrict 120 | #else 121 | #define RESTRICT __restrict__ 122 | #endif 123 | 124 | static float mydsp_faustpower2_f(float value) { 125 | return value * value; 126 | } 127 | 128 | class mydsp : public dsp { 129 | 130 | FAUSTPP_PRIVATE: 131 | 132 | int fSampleRate; 133 | float fConst0; 134 | float fConst1; 135 | float fConst2; 136 | FAUSTFLOAT fHslider0; 137 | float fRec0[2]; 138 | float fConst3; 139 | FAUSTFLOAT fHslider1; 140 | float fRec2[2]; 141 | FAUSTFLOAT fHslider2; 142 | float fRec4[2]; 143 | int IOTA0; 144 | float fVec0[65536]; 145 | float fConst4; 146 | FAUSTFLOAT fHslider3; 147 | float fConst5; 148 | float fRec5[2]; 149 | float fRec6[2]; 150 | float fRec7[2]; 151 | float fRec8[2]; 152 | float fVec1[131072]; 153 | float fRec9[2]; 154 | float fConst6; 155 | float fRec10[2]; 156 | float fRec11[2]; 157 | float fRec12[2]; 158 | float fRec13[2]; 159 | float fVec2[131072]; 160 | FAUSTFLOAT fHslider4; 161 | float fConst7; 162 | float fRec14[2]; 163 | float fRec15[2]; 164 | float fConst8; 165 | float fRec16[2]; 166 | float fRec17[2]; 167 | float fRec18[2]; 168 | float fRec19[2]; 169 | float fVec3[131072]; 170 | float fRec20[2]; 171 | float fConst9; 172 | float fRec21[2]; 173 | float fRec22[2]; 174 | float fRec23[2]; 175 | float fRec24[2]; 176 | float fVec4[131072]; 177 | float fRec3[3]; 178 | float fRec1[3]; 179 | FAUSTFLOAT fHslider5; 180 | FAUSTFLOAT fHslider6; 181 | float fRec26[3]; 182 | float fRec25[3]; 183 | 184 | public: 185 | mydsp() { 186 | } 187 | 188 | void metadata(Meta* m) { 189 | m->declare("author", "Christopher Arndt"); 190 | m->declare("basics.lib/name", "Faust Basic Element Library"); 191 | m->declare("basics.lib/tabulateNd", "Copyright (C) 2023 Bart Brouns "); 192 | m->declare("basics.lib/version", "1.19.1"); 193 | m->declare("compile_options", "-a /home/chris/tmp/tmpel522spj.cpp -lang cpp -ct 1 -es 1 -mcd 16 -mdd 1024 -mdy 33 -single -ftz 0"); 194 | m->declare("delays.lib/name", "Faust Delay Library"); 195 | m->declare("delays.lib/version", "1.1.0"); 196 | m->declare("description", "Automatic double tracking (not only) for vocals"); 197 | m->declare("filename", "adt.dsp"); 198 | m->declare("filters.lib/fir:author", "Julius O. Smith III"); 199 | m->declare("filters.lib/fir:copyright", "Copyright (C) 2003-2019 by Julius O. Smith III "); 200 | m->declare("filters.lib/fir:license", "MIT-style STK-4.3 license"); 201 | m->declare("filters.lib/highpass:author", "Julius O. Smith III"); 202 | m->declare("filters.lib/highpass:copyright", "Copyright (C) 2003-2019 by Julius O. Smith III "); 203 | m->declare("filters.lib/iir:author", "Julius O. Smith III"); 204 | m->declare("filters.lib/iir:copyright", "Copyright (C) 2003-2019 by Julius O. Smith III "); 205 | m->declare("filters.lib/iir:license", "MIT-style STK-4.3 license"); 206 | m->declare("filters.lib/lowpass0_highpass1", "MIT-style STK-4.3 license"); 207 | m->declare("filters.lib/lowpass0_highpass1:author", "Julius O. Smith III"); 208 | m->declare("filters.lib/lowpass:author", "Julius O. Smith III"); 209 | m->declare("filters.lib/lowpass:copyright", "Copyright (C) 2003-2019 by Julius O. Smith III "); 210 | m->declare("filters.lib/lowpass:license", "MIT-style STK-4.3 license"); 211 | m->declare("filters.lib/name", "Faust Filters Library"); 212 | m->declare("filters.lib/tf2:author", "Julius O. Smith III"); 213 | m->declare("filters.lib/tf2:copyright", "Copyright (C) 2003-2019 by Julius O. Smith III "); 214 | m->declare("filters.lib/tf2:license", "MIT-style STK-4.3 license"); 215 | m->declare("filters.lib/tf2s:author", "Julius O. Smith III"); 216 | m->declare("filters.lib/tf2s:copyright", "Copyright (C) 2003-2019 by Julius O. Smith III "); 217 | m->declare("filters.lib/tf2s:license", "MIT-style STK-4.3 license"); 218 | m->declare("filters.lib/version", "1.3.0"); 219 | m->declare("license", "MIT License"); 220 | m->declare("maths.lib/author", "GRAME"); 221 | m->declare("maths.lib/copyright", "GRAME"); 222 | m->declare("maths.lib/license", "LGPL with exception"); 223 | m->declare("maths.lib/name", "Faust Math Library"); 224 | m->declare("maths.lib/version", "2.8.0"); 225 | m->declare("misceffects.lib/name", "Misc Effects Library"); 226 | m->declare("misceffects.lib/version", "2.5.0"); 227 | m->declare("name", "ADT"); 228 | m->declare("platform.lib/name", "Generic Platform Library"); 229 | m->declare("platform.lib/version", "1.3.0"); 230 | m->declare("signals.lib/name", "Faust Signal Routing Library"); 231 | m->declare("signals.lib/version", "1.6.0"); 232 | m->declare("spats.lib/name", "Faust Spatialization Library"); 233 | m->declare("spats.lib/version", "1.1.0"); 234 | m->declare("version", "0.1"); 235 | } 236 | 237 | FAUSTPP_VIRTUAL int getNumInputs() { 238 | return 1; 239 | } 240 | FAUSTPP_VIRTUAL int getNumOutputs() { 241 | return 2; 242 | } 243 | 244 | static void classInit(int sample_rate) { 245 | } 246 | 247 | FAUSTPP_VIRTUAL void instanceConstants(int sample_rate) { 248 | fSampleRate = sample_rate; 249 | fConst0 = std::min(1.92e+05f, std::max(1.0f, float(fSampleRate))); 250 | fConst1 = 44.1f / fConst0; 251 | fConst2 = 1.0f - fConst1; 252 | fConst3 = 3.1415927f / fConst0; 253 | fConst4 = 0.2f * fConst0; 254 | fConst5 = 0.001f * fConst0; 255 | fConst6 = 0.0005f * fConst0; 256 | fConst7 = 0.2205f / fConst0; 257 | fConst8 = 0.00075f * fConst0; 258 | fConst9 = 0.00025f * fConst0; 259 | } 260 | 261 | FAUSTPP_VIRTUAL void instanceResetUserInterface() { 262 | fHslider0 = FAUSTFLOAT(2e+01f); 263 | fHslider1 = FAUSTFLOAT(3.5e+03f); 264 | fHslider2 = FAUSTFLOAT(4e+01f); 265 | fHslider3 = FAUSTFLOAT(4e+01f); 266 | fHslider4 = FAUSTFLOAT(1e+02f); 267 | fHslider5 = FAUSTFLOAT(-4.0f); 268 | fHslider6 = FAUSTFLOAT(-3.0f); 269 | } 270 | 271 | FAUSTPP_VIRTUAL void instanceClear() { 272 | for (int l0 = 0; l0 < 2; l0 = l0 + 1) { 273 | fRec0[l0] = 0.0f; 274 | } 275 | for (int l1 = 0; l1 < 2; l1 = l1 + 1) { 276 | fRec2[l1] = 0.0f; 277 | } 278 | for (int l2 = 0; l2 < 2; l2 = l2 + 1) { 279 | fRec4[l2] = 0.0f; 280 | } 281 | IOTA0 = 0; 282 | for (int l3 = 0; l3 < 65536; l3 = l3 + 1) { 283 | fVec0[l3] = 0.0f; 284 | } 285 | for (int l4 = 0; l4 < 2; l4 = l4 + 1) { 286 | fRec5[l4] = 0.0f; 287 | } 288 | for (int l5 = 0; l5 < 2; l5 = l5 + 1) { 289 | fRec6[l5] = 0.0f; 290 | } 291 | for (int l6 = 0; l6 < 2; l6 = l6 + 1) { 292 | fRec7[l6] = 0.0f; 293 | } 294 | for (int l7 = 0; l7 < 2; l7 = l7 + 1) { 295 | fRec8[l7] = 0.0f; 296 | } 297 | for (int l8 = 0; l8 < 131072; l8 = l8 + 1) { 298 | fVec1[l8] = 0.0f; 299 | } 300 | for (int l9 = 0; l9 < 2; l9 = l9 + 1) { 301 | fRec9[l9] = 0.0f; 302 | } 303 | for (int l10 = 0; l10 < 2; l10 = l10 + 1) { 304 | fRec10[l10] = 0.0f; 305 | } 306 | for (int l11 = 0; l11 < 2; l11 = l11 + 1) { 307 | fRec11[l11] = 0.0f; 308 | } 309 | for (int l12 = 0; l12 < 2; l12 = l12 + 1) { 310 | fRec12[l12] = 0.0f; 311 | } 312 | for (int l13 = 0; l13 < 2; l13 = l13 + 1) { 313 | fRec13[l13] = 0.0f; 314 | } 315 | for (int l14 = 0; l14 < 131072; l14 = l14 + 1) { 316 | fVec2[l14] = 0.0f; 317 | } 318 | for (int l15 = 0; l15 < 2; l15 = l15 + 1) { 319 | fRec14[l15] = 0.0f; 320 | } 321 | for (int l16 = 0; l16 < 2; l16 = l16 + 1) { 322 | fRec15[l16] = 0.0f; 323 | } 324 | for (int l17 = 0; l17 < 2; l17 = l17 + 1) { 325 | fRec16[l17] = 0.0f; 326 | } 327 | for (int l18 = 0; l18 < 2; l18 = l18 + 1) { 328 | fRec17[l18] = 0.0f; 329 | } 330 | for (int l19 = 0; l19 < 2; l19 = l19 + 1) { 331 | fRec18[l19] = 0.0f; 332 | } 333 | for (int l20 = 0; l20 < 2; l20 = l20 + 1) { 334 | fRec19[l20] = 0.0f; 335 | } 336 | for (int l21 = 0; l21 < 131072; l21 = l21 + 1) { 337 | fVec3[l21] = 0.0f; 338 | } 339 | for (int l22 = 0; l22 < 2; l22 = l22 + 1) { 340 | fRec20[l22] = 0.0f; 341 | } 342 | for (int l23 = 0; l23 < 2; l23 = l23 + 1) { 343 | fRec21[l23] = 0.0f; 344 | } 345 | for (int l24 = 0; l24 < 2; l24 = l24 + 1) { 346 | fRec22[l24] = 0.0f; 347 | } 348 | for (int l25 = 0; l25 < 2; l25 = l25 + 1) { 349 | fRec23[l25] = 0.0f; 350 | } 351 | for (int l26 = 0; l26 < 2; l26 = l26 + 1) { 352 | fRec24[l26] = 0.0f; 353 | } 354 | for (int l27 = 0; l27 < 131072; l27 = l27 + 1) { 355 | fVec4[l27] = 0.0f; 356 | } 357 | for (int l28 = 0; l28 < 3; l28 = l28 + 1) { 358 | fRec3[l28] = 0.0f; 359 | } 360 | for (int l29 = 0; l29 < 3; l29 = l29 + 1) { 361 | fRec1[l29] = 0.0f; 362 | } 363 | for (int l30 = 0; l30 < 3; l30 = l30 + 1) { 364 | fRec26[l30] = 0.0f; 365 | } 366 | for (int l31 = 0; l31 < 3; l31 = l31 + 1) { 367 | fRec25[l31] = 0.0f; 368 | } 369 | } 370 | 371 | FAUSTPP_VIRTUAL void init(int sample_rate) { 372 | classInit(sample_rate); 373 | instanceInit(sample_rate); 374 | } 375 | 376 | FAUSTPP_VIRTUAL void instanceInit(int sample_rate) { 377 | instanceConstants(sample_rate); 378 | instanceResetUserInterface(); 379 | instanceClear(); 380 | } 381 | 382 | FAUSTPP_VIRTUAL mydsp* clone() { 383 | return new mydsp(); 384 | } 385 | 386 | FAUSTPP_VIRTUAL int getSampleRate() { 387 | return fSampleRate; 388 | } 389 | 390 | FAUSTPP_VIRTUAL void buildUserInterface(UI* ui_interface) { 391 | ui_interface->openVerticalBox("ADT"); 392 | ui_interface->declare(&fHslider4, "1", ""); 393 | ui_interface->declare(&fHslider4, "unit", "%"); 394 | ui_interface->addHorizontalSlider("Pan Spread", &fHslider4, FAUSTFLOAT(1e+02f), FAUSTFLOAT(0.0f), FAUSTFLOAT(1e+02f), FAUSTFLOAT(1.0f)); 395 | ui_interface->declare(&fHslider3, "2", ""); 396 | ui_interface->declare(&fHslider3, "unit", "ms"); 397 | ui_interface->addHorizontalSlider("Delay Spread", &fHslider3, FAUSTFLOAT(4e+01f), FAUSTFLOAT(0.0f), FAUSTFLOAT(1e+02f), FAUSTFLOAT(1.0f)); 398 | ui_interface->declare(&fHslider2, "3", ""); 399 | ui_interface->declare(&fHslider2, "unit", "ct"); 400 | ui_interface->addHorizontalSlider("Pitch Spread", &fHslider2, FAUSTFLOAT(4e+01f), FAUSTFLOAT(0.0f), FAUSTFLOAT(1.5e+02f), FAUSTFLOAT(1.0f)); 401 | ui_interface->declare(&fHslider1, "4", ""); 402 | ui_interface->declare(&fHslider1, "scale", "log"); 403 | ui_interface->declare(&fHslider1, "unit", "Hz"); 404 | ui_interface->addHorizontalSlider("Lowpass", &fHslider1, FAUSTFLOAT(3.5e+03f), FAUSTFLOAT(2e+01f), FAUSTFLOAT(2e+04f), FAUSTFLOAT(0.1f)); 405 | ui_interface->declare(&fHslider0, "5", ""); 406 | ui_interface->declare(&fHslider0, "scale", "log"); 407 | ui_interface->declare(&fHslider0, "unit", "Hz"); 408 | ui_interface->addHorizontalSlider("Highpass", &fHslider0, FAUSTFLOAT(2e+01f), FAUSTFLOAT(2e+01f), FAUSTFLOAT(2e+04f), FAUSTFLOAT(0.1f)); 409 | ui_interface->declare(&fHslider6, "6", ""); 410 | ui_interface->declare(&fHslider6, "unit", "dB"); 411 | ui_interface->addHorizontalSlider("Dry", &fHslider6, FAUSTFLOAT(-3.0f), FAUSTFLOAT(-9e+01f), FAUSTFLOAT(1e+01f), FAUSTFLOAT(0.1f)); 412 | ui_interface->declare(&fHslider5, "7", ""); 413 | ui_interface->declare(&fHslider5, "unit", "dB"); 414 | ui_interface->addHorizontalSlider("Wet", &fHslider5, FAUSTFLOAT(-4.0f), FAUSTFLOAT(-9e+01f), FAUSTFLOAT(1e+01f), FAUSTFLOAT(0.1f)); 415 | ui_interface->closeBox(); 416 | } 417 | 418 | FAUSTPP_VIRTUAL void compute(int count, FAUSTFLOAT** RESTRICT inputs, FAUSTFLOAT** RESTRICT outputs) { 419 | FAUSTFLOAT* input0 = inputs[0]; 420 | FAUSTFLOAT* output0 = outputs[0]; 421 | FAUSTFLOAT* output1 = outputs[1]; 422 | float fSlow0 = fConst1 * float(fHslider0); 423 | float fSlow1 = fConst1 * float(fHslider1); 424 | float fSlow2 = float(fHslider2); 425 | float fSlow3 = 0.00083333335f * fSlow2; 426 | float fSlow4 = std::pow(2.0f, -fSlow3); 427 | float fSlow5 = float(fHslider3); 428 | float fSlow6 = fConst5 * fSlow5; 429 | float fSlow7 = 0.00041666668f * fSlow2; 430 | float fSlow8 = std::pow(2.0f, fSlow7); 431 | float fSlow9 = fConst6 * fSlow5; 432 | float fSlow10 = fConst7 * float(fHslider4); 433 | float fSlow11 = std::pow(2.0f, fSlow3); 434 | float fSlow12 = fConst8 * fSlow5; 435 | float fSlow13 = std::pow(2.0f, -fSlow7); 436 | float fSlow14 = fConst9 * fSlow5; 437 | float fSlow15 = std::pow(1e+01f, 0.05f * float(fHslider5)); 438 | float fSlow16 = 0.5f * std::pow(1e+01f, 0.05f * float(fHslider6)); 439 | for (int i0 = 0; i0 < count; i0 = i0 + 1) { 440 | fRec0[0] = fSlow0 + fConst2 * fRec0[1]; 441 | float fTemp0 = std::tan(fConst3 * fRec0[0]); 442 | float fTemp1 = 1.0f / fTemp0; 443 | float fTemp2 = (fTemp1 + 1.4142135f) / fTemp0 + 1.0f; 444 | float fTemp3 = mydsp_faustpower2_f(fTemp0); 445 | float fTemp4 = fTemp3 * fTemp2; 446 | float fTemp5 = 1.0f - 1.0f / fTemp3; 447 | float fTemp6 = (fTemp1 + -1.4142135f) / fTemp0 + 1.0f; 448 | fRec2[0] = fSlow1 + fConst2 * fRec2[1]; 449 | float fTemp7 = std::tan(fConst3 * fRec2[0]); 450 | float fTemp8 = 1.0f / fTemp7; 451 | float fTemp9 = (fTemp8 + 1.4142135f) / fTemp7 + 1.0f; 452 | float fTemp10 = 1.0f - 1.0f / mydsp_faustpower2_f(fTemp7); 453 | float fTemp11 = (fTemp8 + -1.4142135f) / fTemp7 + 1.0f; 454 | fRec4[0] = std::fmod(fRec4[1] + 257.0f - fSlow4, 256.0f); 455 | float fTemp12 = std::min(0.02f * fRec4[0], 1.0f); 456 | float fTemp13 = float(input0[i0]); 457 | fVec0[IOTA0 & 65535] = fTemp13; 458 | float fTemp14 = ((fRec5[1] != 0.0f) ? (((fRec6[1] > 0.0f) & (fRec6[1] < 1.0f)) ? fRec5[1] : 0.0f) : (((fRec6[1] == 0.0f) & (fSlow6 != fRec7[1])) ? 0.0009765625f : (((fRec6[1] == 1.0f) & (fSlow6 != fRec8[1])) ? -0.0009765625f : 0.0f))); 459 | fRec5[0] = fTemp14; 460 | fRec6[0] = std::max(0.0f, std::min(1.0f, fRec6[1] + fTemp14)); 461 | fRec7[0] = (((fRec6[1] >= 1.0f) & (fRec8[1] != fSlow6)) ? fSlow6 : fRec7[1]); 462 | fRec8[0] = (((fRec6[1] <= 0.0f) & (fRec7[1] != fSlow6)) ? fSlow6 : fRec8[1]); 463 | float fTemp15 = fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec7[0])))) & 65535]; 464 | float fTemp16 = fTemp15 + fRec6[0] * (fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec8[0])))) & 65535] - fTemp15); 465 | fVec1[IOTA0 & 131071] = fTemp16; 466 | float fTemp17 = fRec4[0] + 256.0f; 467 | int iTemp18 = int(fTemp17); 468 | float fTemp19 = std::floor(fTemp17); 469 | int iTemp20 = int(fRec4[0]); 470 | float fTemp21 = std::floor(fRec4[0]); 471 | fRec9[0] = std::fmod(fRec9[1] + 257.0f - fSlow8, 256.0f); 472 | float fTemp22 = std::min(0.02f * fRec9[0], 1.0f); 473 | float fTemp23 = ((fRec10[1] != 0.0f) ? (((fRec11[1] > 0.0f) & (fRec11[1] < 1.0f)) ? fRec10[1] : 0.0f) : (((fRec11[1] == 0.0f) & (fSlow9 != fRec12[1])) ? 0.0009765625f : (((fRec11[1] == 1.0f) & (fSlow9 != fRec13[1])) ? -0.0009765625f : 0.0f))); 474 | fRec10[0] = fTemp23; 475 | fRec11[0] = std::max(0.0f, std::min(1.0f, fRec11[1] + fTemp23)); 476 | fRec12[0] = (((fRec11[1] >= 1.0f) & (fRec13[1] != fSlow9)) ? fSlow9 : fRec12[1]); 477 | fRec13[0] = (((fRec11[1] <= 0.0f) & (fRec12[1] != fSlow9)) ? fSlow9 : fRec13[1]); 478 | float fTemp24 = fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec12[0])))) & 65535]; 479 | float fTemp25 = fTemp24 + fRec11[0] * (fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec13[0])))) & 65535] - fTemp24); 480 | fVec2[IOTA0 & 131071] = fTemp25; 481 | float fTemp26 = fRec9[0] + 256.0f; 482 | int iTemp27 = int(fTemp26); 483 | float fTemp28 = std::floor(fTemp26); 484 | int iTemp29 = int(fRec9[0]); 485 | float fTemp30 = std::floor(fRec9[0]); 486 | float fTemp31 = (fVec2[(IOTA0 - std::min(65537, std::max(0, iTemp29))) & 131071] * (fTemp30 + (1.0f - fRec9[0])) + (fRec9[0] - fTemp30) * fVec2[(IOTA0 - std::min(65537, std::max(0, iTemp29 + 1))) & 131071]) * fTemp22 + (fVec2[(IOTA0 - std::min(65537, std::max(0, iTemp27))) & 131071] * (fTemp28 + (-255.0f - fRec9[0])) + (fRec9[0] + (256.0f - fTemp28)) * fVec2[(IOTA0 - std::min(65537, std::max(0, iTemp27 + 1))) & 131071]) * (1.0f - fTemp22) + (fVec1[(IOTA0 - std::min(65537, std::max(0, iTemp20))) & 131071] * (fTemp21 + (1.0f - fRec4[0])) + (fRec4[0] - fTemp21) * fVec1[(IOTA0 - std::min(65537, std::max(0, iTemp20 + 1))) & 131071]) * fTemp12 + (fVec1[(IOTA0 - std::min(65537, std::max(0, iTemp18))) & 131071] * (fTemp19 + (-255.0f - fRec4[0])) + (fRec4[0] + (256.0f - fTemp19)) * fVec1[(IOTA0 - std::min(65537, std::max(0, iTemp18 + 1))) & 131071]) * (1.0f - fTemp12); 487 | fRec14[0] = fSlow10 + fConst2 * fRec14[1]; 488 | float fTemp32 = fRec14[0] + 0.5f; 489 | fRec15[0] = std::fmod(fRec15[1] + 257.0f - fSlow11, 256.0f); 490 | float fTemp33 = std::min(0.02f * fRec15[0], 1.0f); 491 | float fTemp34 = ((fRec16[1] != 0.0f) ? (((fRec17[1] > 0.0f) & (fRec17[1] < 1.0f)) ? fRec16[1] : 0.0f) : (((fRec17[1] == 0.0f) & (fSlow12 != fRec18[1])) ? 0.0009765625f : (((fRec17[1] == 1.0f) & (fSlow12 != fRec19[1])) ? -0.0009765625f : 0.0f))); 492 | fRec16[0] = fTemp34; 493 | fRec17[0] = std::max(0.0f, std::min(1.0f, fRec17[1] + fTemp34)); 494 | fRec18[0] = (((fRec17[1] >= 1.0f) & (fRec19[1] != fSlow12)) ? fSlow12 : fRec18[1]); 495 | fRec19[0] = (((fRec17[1] <= 0.0f) & (fRec18[1] != fSlow12)) ? fSlow12 : fRec19[1]); 496 | float fTemp35 = fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec18[0])))) & 65535]; 497 | float fTemp36 = fTemp35 + fRec17[0] * (fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec19[0])))) & 65535] - fTemp35); 498 | fVec3[IOTA0 & 131071] = fTemp36; 499 | float fTemp37 = fRec15[0] + 256.0f; 500 | int iTemp38 = int(fTemp37); 501 | float fTemp39 = std::floor(fTemp37); 502 | int iTemp40 = int(fRec15[0]); 503 | float fTemp41 = std::floor(fRec15[0]); 504 | fRec20[0] = std::fmod(fRec20[1] + 257.0f - fSlow13, 256.0f); 505 | float fTemp42 = std::min(0.02f * fRec20[0], 1.0f); 506 | float fTemp43 = ((fRec21[1] != 0.0f) ? (((fRec22[1] > 0.0f) & (fRec22[1] < 1.0f)) ? fRec21[1] : 0.0f) : (((fRec22[1] == 0.0f) & (fSlow14 != fRec23[1])) ? 0.0009765625f : (((fRec22[1] == 1.0f) & (fSlow14 != fRec24[1])) ? -0.0009765625f : 0.0f))); 507 | fRec21[0] = fTemp43; 508 | fRec22[0] = std::max(0.0f, std::min(1.0f, fRec22[1] + fTemp43)); 509 | fRec23[0] = (((fRec22[1] >= 1.0f) & (fRec24[1] != fSlow14)) ? fSlow14 : fRec23[1]); 510 | fRec24[0] = (((fRec22[1] <= 0.0f) & (fRec23[1] != fSlow14)) ? fSlow14 : fRec24[1]); 511 | float fTemp44 = fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec23[0])))) & 65535]; 512 | float fTemp45 = fTemp44 + fRec22[0] * (fVec0[(IOTA0 - int(std::min(fConst4, std::max(0.0f, fRec24[0])))) & 65535] - fTemp44); 513 | fVec4[IOTA0 & 131071] = fTemp45; 514 | float fTemp46 = fRec20[0] + 256.0f; 515 | int iTemp47 = int(fTemp46); 516 | float fTemp48 = std::floor(fTemp46); 517 | int iTemp49 = int(fRec20[0]); 518 | float fTemp50 = std::floor(fRec20[0]); 519 | float fTemp51 = (fVec4[(IOTA0 - std::min(65537, std::max(0, iTemp49))) & 131071] * (fTemp50 + (1.0f - fRec20[0])) + (fRec20[0] - fTemp50) * fVec4[(IOTA0 - std::min(65537, std::max(0, iTemp49 + 1))) & 131071]) * fTemp42 + (fVec4[(IOTA0 - std::min(65537, std::max(0, iTemp47))) & 131071] * (fTemp48 + (-255.0f - fRec20[0])) + (fRec20[0] + (256.0f - fTemp48)) * fVec4[(IOTA0 - std::min(65537, std::max(0, iTemp47 + 1))) & 131071]) * (1.0f - fTemp42) + (fVec3[(IOTA0 - std::min(65537, std::max(0, iTemp40))) & 131071] * (fTemp41 + (1.0f - fRec15[0])) + (fRec15[0] - fTemp41) * fVec3[(IOTA0 - std::min(65537, std::max(0, iTemp40 + 1))) & 131071]) * fTemp33 + (fVec3[(IOTA0 - std::min(65537, std::max(0, iTemp38))) & 131071] * (fTemp39 + (-255.0f - fRec15[0])) + (fRec15[0] + (256.0f - fTemp39)) * fVec3[(IOTA0 - std::min(65537, std::max(0, iTemp38 + 1))) & 131071]) * (1.0f - fTemp33); 520 | float fTemp52 = 0.5f - fRec14[0]; 521 | fRec3[0] = 0.25f * (fTemp52 * fTemp51 + fTemp32 * fTemp31) - (fRec3[2] * fTemp11 + 2.0f * fRec3[1] * fTemp10) / fTemp9; 522 | fRec1[0] = (fRec3[2] + fRec3[0] + 2.0f * fRec3[1]) / fTemp9 - (fRec1[2] * fTemp6 + 2.0f * fRec1[1] * fTemp5) / fTemp2; 523 | float fTemp53 = fSlow16 * fTemp13; 524 | output0[i0] = FAUSTFLOAT(fTemp53 + fSlow15 * ((fRec1[0] + fRec1[2] - 2.0f * fRec1[1]) / fTemp4)); 525 | fRec26[0] = 0.25f * (fTemp32 * fTemp51 + fTemp52 * fTemp31) - (fTemp11 * fRec26[2] + 2.0f * fTemp10 * fRec26[1]) / fTemp9; 526 | fRec25[0] = (fRec26[2] + fRec26[0] + 2.0f * fRec26[1]) / fTemp9 - (fTemp6 * fRec25[2] + 2.0f * fTemp5 * fRec25[1]) / fTemp2; 527 | output1[i0] = FAUSTFLOAT(fTemp53 + fSlow15 * ((fRec25[0] + fRec25[2] - 2.0f * fRec25[1]) / fTemp4)); 528 | fRec0[1] = fRec0[0]; 529 | fRec2[1] = fRec2[0]; 530 | fRec4[1] = fRec4[0]; 531 | IOTA0 = IOTA0 + 1; 532 | fRec5[1] = fRec5[0]; 533 | fRec6[1] = fRec6[0]; 534 | fRec7[1] = fRec7[0]; 535 | fRec8[1] = fRec8[0]; 536 | fRec9[1] = fRec9[0]; 537 | fRec10[1] = fRec10[0]; 538 | fRec11[1] = fRec11[0]; 539 | fRec12[1] = fRec12[0]; 540 | fRec13[1] = fRec13[0]; 541 | fRec14[1] = fRec14[0]; 542 | fRec15[1] = fRec15[0]; 543 | fRec16[1] = fRec16[0]; 544 | fRec17[1] = fRec17[0]; 545 | fRec18[1] = fRec18[0]; 546 | fRec19[1] = fRec19[0]; 547 | fRec20[1] = fRec20[0]; 548 | fRec21[1] = fRec21[0]; 549 | fRec22[1] = fRec22[0]; 550 | fRec23[1] = fRec23[0]; 551 | fRec24[1] = fRec24[0]; 552 | fRec3[2] = fRec3[1]; 553 | fRec3[1] = fRec3[0]; 554 | fRec1[2] = fRec1[1]; 555 | fRec1[1] = fRec1[0]; 556 | fRec26[2] = fRec26[1]; 557 | fRec26[1] = fRec26[0]; 558 | fRec25[2] = fRec25[1]; 559 | fRec25[1] = fRec25[0]; 560 | } 561 | } 562 | 563 | }; 564 | FAUSTPP_END_NAMESPACE 565 | 566 | 567 | #if defined(__GNUC__) 568 | # pragma GCC diagnostic pop 569 | #endif 570 | 571 | 572 | 573 | //------------------------------------------------------------------------------ 574 | // End the Faust code section 575 | 576 | 577 | 578 | 579 | ADT::ADT() 580 | { 581 | 582 | mydsp *dsp = new mydsp; 583 | fDsp.reset(dsp); 584 | dsp->instanceResetUserInterface(); 585 | 586 | } 587 | 588 | ADT::~ADT() 589 | { 590 | } 591 | 592 | void ADT::init(float sample_rate) 593 | { 594 | 595 | mydsp &dsp = static_cast(*fDsp); 596 | dsp.classInit(sample_rate); 597 | dsp.instanceConstants(sample_rate); 598 | clear(); 599 | 600 | } 601 | 602 | void ADT::clear() noexcept 603 | { 604 | 605 | mydsp &dsp = static_cast(*fDsp); 606 | dsp.instanceClear(); 607 | 608 | } 609 | 610 | void ADT::process( 611 | const float *in0, 612 | float *out0,float *out1, 613 | unsigned count) noexcept 614 | { 615 | 616 | mydsp &dsp = static_cast(*fDsp); 617 | float *inputs[] = { 618 | const_cast(in0), 619 | }; 620 | float *outputs[] = { 621 | out0,out1, 622 | }; 623 | dsp.compute(count, inputs, outputs); 624 | 625 | } 626 | 627 | const char *ADT::parameter_label(unsigned index) noexcept 628 | { 629 | switch (index) { 630 | 631 | case 0: 632 | return "Pan Spread"; 633 | 634 | case 1: 635 | return "Delay Spread"; 636 | 637 | case 2: 638 | return "Pitch Spread"; 639 | 640 | case 3: 641 | return "Lowpass"; 642 | 643 | case 4: 644 | return "Highpass"; 645 | 646 | case 5: 647 | return "Dry"; 648 | 649 | case 6: 650 | return "Wet"; 651 | 652 | default: 653 | return 0; 654 | } 655 | } 656 | 657 | const char *ADT::parameter_short_label(unsigned index) noexcept 658 | { 659 | switch (index) { 660 | 661 | case 0: 662 | return ""; 663 | 664 | case 1: 665 | return ""; 666 | 667 | case 2: 668 | return ""; 669 | 670 | case 3: 671 | return ""; 672 | 673 | case 4: 674 | return ""; 675 | 676 | case 5: 677 | return ""; 678 | 679 | case 6: 680 | return ""; 681 | 682 | default: 683 | return 0; 684 | } 685 | } 686 | 687 | const char *ADT::parameter_symbol(unsigned index) noexcept 688 | { 689 | switch (index) { 690 | 691 | case 0: 692 | return "Pan_Spread"; 693 | 694 | case 1: 695 | return "Delay_Spread"; 696 | 697 | case 2: 698 | return "Pitch_Spread"; 699 | 700 | case 3: 701 | return "Lowpass"; 702 | 703 | case 4: 704 | return "Highpass"; 705 | 706 | case 5: 707 | return "Dry"; 708 | 709 | case 6: 710 | return "Wet"; 711 | 712 | default: 713 | return 0; 714 | } 715 | } 716 | 717 | const char *ADT::parameter_unit(unsigned index) noexcept 718 | { 719 | switch (index) { 720 | 721 | case 0: 722 | return "%"; 723 | 724 | case 1: 725 | return "ms"; 726 | 727 | case 2: 728 | return "ct"; 729 | 730 | case 3: 731 | return "Hz"; 732 | 733 | case 4: 734 | return "Hz"; 735 | 736 | case 5: 737 | return "dB"; 738 | 739 | case 6: 740 | return "dB"; 741 | 742 | default: 743 | return 0; 744 | } 745 | } 746 | 747 | const ADT::ParameterRange *ADT::parameter_range(unsigned index) noexcept 748 | { 749 | switch (index) { 750 | 751 | case 0: { 752 | static const ParameterRange range = { 100.0, 0.0, 100.0 }; 753 | return ⦥ 754 | } 755 | 756 | case 1: { 757 | static const ParameterRange range = { 40.0, 0.0, 100.0 }; 758 | return ⦥ 759 | } 760 | 761 | case 2: { 762 | static const ParameterRange range = { 40.0, 0.0, 150.0 }; 763 | return ⦥ 764 | } 765 | 766 | case 3: { 767 | static const ParameterRange range = { 3500.0, 20.0, 20000.0 }; 768 | return ⦥ 769 | } 770 | 771 | case 4: { 772 | static const ParameterRange range = { 20.0, 20.0, 20000.0 }; 773 | return ⦥ 774 | } 775 | 776 | case 5: { 777 | static const ParameterRange range = { -3.0, -90.0, 10.0 }; 778 | return ⦥ 779 | } 780 | 781 | case 6: { 782 | static const ParameterRange range = { -4.0, -90.0, 10.0 }; 783 | return ⦥ 784 | } 785 | 786 | default: 787 | return 0; 788 | } 789 | } 790 | 791 | bool ADT::parameter_is_trigger(unsigned index) noexcept 792 | { 793 | switch (index) { 794 | 795 | default: 796 | return false; 797 | } 798 | } 799 | 800 | bool ADT::parameter_is_boolean(unsigned index) noexcept 801 | { 802 | switch (index) { 803 | 804 | default: 805 | return false; 806 | } 807 | } 808 | 809 | bool ADT::parameter_is_integer(unsigned index) noexcept 810 | { 811 | switch (index) { 812 | 813 | default: 814 | return false; 815 | } 816 | } 817 | 818 | bool ADT::parameter_is_logarithmic(unsigned index) noexcept 819 | { 820 | switch (index) { 821 | 822 | case 3: 823 | return true; 824 | 825 | case 4: 826 | return true; 827 | 828 | default: 829 | return false; 830 | } 831 | } 832 | 833 | float ADT::get_parameter(unsigned index) const noexcept 834 | { 835 | mydsp &dsp = static_cast(*fDsp); 836 | switch (index) { 837 | 838 | case 0: 839 | return dsp.fHslider4; 840 | 841 | case 1: 842 | return dsp.fHslider3; 843 | 844 | case 2: 845 | return dsp.fHslider2; 846 | 847 | case 3: 848 | return dsp.fHslider1; 849 | 850 | case 4: 851 | return dsp.fHslider0; 852 | 853 | case 5: 854 | return dsp.fHslider6; 855 | 856 | case 6: 857 | return dsp.fHslider5; 858 | 859 | default: 860 | (void)dsp; 861 | return 0; 862 | } 863 | } 864 | 865 | void ADT::set_parameter(unsigned index, float value) noexcept 866 | { 867 | mydsp &dsp = static_cast(*fDsp); 868 | switch (index) { 869 | 870 | case 0: 871 | dsp.fHslider4 = value; 872 | break; 873 | 874 | case 1: 875 | dsp.fHslider3 = value; 876 | break; 877 | 878 | case 2: 879 | dsp.fHslider2 = value; 880 | break; 881 | 882 | case 3: 883 | dsp.fHslider1 = value; 884 | break; 885 | 886 | case 4: 887 | dsp.fHslider0 = value; 888 | break; 889 | 890 | case 5: 891 | dsp.fHslider6 = value; 892 | break; 893 | 894 | case 6: 895 | dsp.fHslider5 = value; 896 | break; 897 | 898 | default: 899 | (void)dsp; 900 | (void)value; 901 | break; 902 | } 903 | } 904 | 905 | 906 | float ADT::get_Pan_Spread() const noexcept 907 | { 908 | mydsp &dsp = static_cast(*fDsp); 909 | return dsp.fHslider4; 910 | } 911 | 912 | float ADT::get_Delay_Spread() const noexcept 913 | { 914 | mydsp &dsp = static_cast(*fDsp); 915 | return dsp.fHslider3; 916 | } 917 | 918 | float ADT::get_Pitch_Spread() const noexcept 919 | { 920 | mydsp &dsp = static_cast(*fDsp); 921 | return dsp.fHslider2; 922 | } 923 | 924 | float ADT::get_Lowpass() const noexcept 925 | { 926 | mydsp &dsp = static_cast(*fDsp); 927 | return dsp.fHslider1; 928 | } 929 | 930 | float ADT::get_Highpass() const noexcept 931 | { 932 | mydsp &dsp = static_cast(*fDsp); 933 | return dsp.fHslider0; 934 | } 935 | 936 | float ADT::get_Dry() const noexcept 937 | { 938 | mydsp &dsp = static_cast(*fDsp); 939 | return dsp.fHslider6; 940 | } 941 | 942 | float ADT::get_Wet() const noexcept 943 | { 944 | mydsp &dsp = static_cast(*fDsp); 945 | return dsp.fHslider5; 946 | } 947 | 948 | 949 | void ADT::set_Pan_Spread(float value) noexcept 950 | { 951 | mydsp &dsp = static_cast(*fDsp); 952 | dsp.fHslider4 = value; 953 | } 954 | 955 | void ADT::set_Delay_Spread(float value) noexcept 956 | { 957 | mydsp &dsp = static_cast(*fDsp); 958 | dsp.fHslider3 = value; 959 | } 960 | 961 | void ADT::set_Pitch_Spread(float value) noexcept 962 | { 963 | mydsp &dsp = static_cast(*fDsp); 964 | dsp.fHslider2 = value; 965 | } 966 | 967 | void ADT::set_Lowpass(float value) noexcept 968 | { 969 | mydsp &dsp = static_cast(*fDsp); 970 | dsp.fHslider1 = value; 971 | } 972 | 973 | void ADT::set_Highpass(float value) noexcept 974 | { 975 | mydsp &dsp = static_cast(*fDsp); 976 | dsp.fHslider0 = value; 977 | } 978 | 979 | void ADT::set_Dry(float value) noexcept 980 | { 981 | mydsp &dsp = static_cast(*fDsp); 982 | dsp.fHslider6 = value; 983 | } 984 | 985 | void ADT::set_Wet(float value) noexcept 986 | { 987 | mydsp &dsp = static_cast(*fDsp); 988 | dsp.fHslider5 = value; 989 | } 990 | 991 | 992 | 993 | -------------------------------------------------------------------------------- /plugins/adt/ADT.hpp: -------------------------------------------------------------------------------- 1 | 2 | //------------------------------------------------------------------------------ 3 | // This file was generated using the Faust compiler (https://faust.grame.fr), 4 | // and the Faust post-processor (https://github.com/jpcima/faustpp). 5 | // 6 | // Source: adt.dsp 7 | // Name: ADT 8 | // Author: Christopher Arndt 9 | // Copyright: 10 | // License: MIT License 11 | // Version: 0.1 12 | //------------------------------------------------------------------------------ 13 | 14 | 15 | 16 | 17 | 18 | 19 | #pragma once 20 | #ifndef ADT_Faust_pp_Gen_HPP_ 21 | #define ADT_Faust_pp_Gen_HPP_ 22 | 23 | #include 24 | 25 | class ADT { 26 | public: 27 | ADT(); 28 | ~ADT(); 29 | 30 | void init(float sample_rate); 31 | void clear() noexcept; 32 | 33 | void process( 34 | const float *in0, 35 | float *out0,float *out1, 36 | unsigned count) noexcept; 37 | 38 | enum { NumInputs = 1 }; 39 | enum { NumOutputs = 2 }; 40 | enum { NumActives = 7 }; 41 | enum { NumPassives = 0 }; 42 | enum { NumParameters = 7 }; 43 | 44 | enum Parameter { 45 | p_Pan_Spread, 46 | p_Delay_Spread, 47 | p_Pitch_Spread, 48 | p_Lowpass, 49 | p_Highpass, 50 | p_Dry, 51 | p_Wet, 52 | 53 | }; 54 | 55 | struct ParameterRange { 56 | float init; 57 | float min; 58 | float max; 59 | }; 60 | 61 | static const char *parameter_label(unsigned index) noexcept; 62 | static const char *parameter_short_label(unsigned index) noexcept; 63 | static const char *parameter_symbol(unsigned index) noexcept; 64 | static const char *parameter_unit(unsigned index) noexcept; 65 | static const ParameterRange *parameter_range(unsigned index) noexcept; 66 | static bool parameter_is_trigger(unsigned index) noexcept; 67 | static bool parameter_is_boolean(unsigned index) noexcept; 68 | static bool parameter_is_integer(unsigned index) noexcept; 69 | static bool parameter_is_logarithmic(unsigned index) noexcept; 70 | 71 | float get_parameter(unsigned index) const noexcept; 72 | void set_parameter(unsigned index, float value) noexcept; 73 | 74 | 75 | float get_Pan_Spread() const noexcept; 76 | 77 | float get_Delay_Spread() const noexcept; 78 | 79 | float get_Pitch_Spread() const noexcept; 80 | 81 | float get_Lowpass() const noexcept; 82 | 83 | float get_Highpass() const noexcept; 84 | 85 | float get_Dry() const noexcept; 86 | 87 | float get_Wet() const noexcept; 88 | 89 | 90 | void set_Pan_Spread(float value) noexcept; 91 | 92 | void set_Delay_Spread(float value) noexcept; 93 | 94 | void set_Pitch_Spread(float value) noexcept; 95 | 96 | void set_Lowpass(float value) noexcept; 97 | 98 | void set_Highpass(float value) noexcept; 99 | 100 | void set_Dry(float value) noexcept; 101 | 102 | void set_Wet(float value) noexcept; 103 | 104 | 105 | public: 106 | class BasicDsp; 107 | 108 | private: 109 | std::unique_ptr fDsp; 110 | 111 | 112 | 113 | }; 114 | 115 | 116 | 117 | 118 | #endif // ADT_Faust_pp_Gen_HPP_ -------------------------------------------------------------------------------- /plugins/adt/DistrhoPluginInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Automatic Double Tracking audio effect based on DISTRHO Plugin Framework (DPF) 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Copyright (C) 2024 Christopher Arndt 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to 10 | * deal in the Software without restriction, including without limitation the 11 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 | * sell copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | * IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef DISTRHO_PLUGIN_INFO_H 28 | #define DISTRHO_PLUGIN_INFO_H 29 | 30 | // The plugin name. 31 | // This is used to identify your plugin before a Plugin instance can be created. 32 | #define DISTRHO_PLUGIN_NAME "ADT" 33 | // The plugin brand name. Used for the LV2 metadata and VST3 UI interface. 34 | // Must be a valid C++ identifier, i.e. can not contain spaces or dashes. 35 | #define DISTRHO_PLUGIN_BRAND "chrisarndt.de" 36 | // The plugin URI when exporting in LV2 format. 37 | // See https://lv2plug.in/book/#_manifest_ttl_in 38 | #define DISTRHO_PLUGIN_URI "https://chrisarndt.de/plugins/adt" 39 | // The plugin id when exporting in CLAP format, should be in reverse URI form 40 | #define DISTRHO_PLUGIN_CLAP_ID "de.chrisarndt.adt" 41 | 42 | #define DISTRHO_PLUGIN_HAS_UI 0 43 | #define DISTRHO_UI_USE_NANOVG 0 44 | 45 | #define DISTRHO_PLUGIN_IS_RT_SAFE 1 46 | #define DISTRHO_PLUGIN_NUM_INPUTS 1 47 | #define DISTRHO_PLUGIN_NUM_OUTPUTS 2 48 | #define DISTRHO_PLUGIN_WANT_TIMEPOS 0 49 | #define DISTRHO_PLUGIN_WANT_PROGRAMS 1 50 | #define DISTRHO_PLUGIN_WANT_MIDI_INPUT 0 51 | #define DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 0 52 | 53 | // See http://lv2plug.in/ns/lv2core#ref-classes 54 | #define DISTRHO_PLUGIN_LV2_CATEGORY "lv2:AmplifierPlugin" 55 | // See: https://github.com/DISTRHO/DPF/blob/f5815166356e85a5fe244f6024c2e401f04b10fa/distrho/DistrhoInfo.hpp#L740 56 | #define DISTRHO_PLUGIN_VST3_CATEGORIES "Fx|Tools|Stereo" 57 | // See: https://github.com/DISTRHO/DPF/blob/f5815166356e85a5fe244f6024c2e401f04b10fa/distrho/DistrhoInfo.hpp#L784 58 | #define DISTRHO_PLUGIN_CLAP_FEATURES "audio-effect", "utility", "stereo" 59 | 60 | #endif // DISTRHO_PLUGIN_INFO_H 61 | -------------------------------------------------------------------------------- /plugins/adt/Makefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # Makefile for DISTRHO Plugins # 3 | # ---------------------------- # 4 | # Created by falkTX, Christopher Arndt, and Patrick Desaulniers 5 | # 6 | 7 | # -------------------------------------------------------------- 8 | # Project name, used for binaries 9 | 10 | NAME = adt 11 | 12 | # -------------------------------------------------------------- 13 | # FAUST DSP source 14 | 15 | FAUST_DSP_DIR ?= ../../faust 16 | FAUST_ARCH_DIR ?= $(FAUST_DSP_DIR)/arch 17 | FAUST_DSP_SOURCE = $(FAUST_DSP_DIR)/$(NAME).dsp 18 | FAUST_IDENTIFIER := $(shell grep 'declare name' $(FAUST_DSP_SOURCE) | cut -f 2 -d '"') 19 | 20 | # -------------------------------------------------------------- 21 | # Plugin types to build 22 | 23 | BUILD_CLAP ?= true 24 | BUILD_DSSI ?= false 25 | BUILD_JACK ?= false 26 | BUILD_LADSPA ?= false 27 | BUILD_LV2 ?= true 28 | BUILD_VST2 ?= false 29 | BUILD_VST3 ?= true 30 | 31 | # -------------------------------------------------------------- 32 | # Files to build 33 | 34 | FILES_DSP = \ 35 | $(FAUST_IDENTIFIER).cpp \ 36 | PluginADT.cpp 37 | 38 | # -------------------------------------------------------------- 39 | # Do some magic 40 | include ../../dpf/Makefile.plugins.mk 41 | 42 | # -------------------------------------------------------------- 43 | # Enable all selected plugin types 44 | 45 | ifeq ($(BUILD_CLAP),true) 46 | TARGETS += clap 47 | endif 48 | 49 | ifeq ($(BUILD_DSSI),true) 50 | ifneq ($(MACOS_OR_WINDOWS),true) 51 | ifeq ($(HAVE_DGL),true) 52 | ifeq ($(HAVE_LIBLO),true) 53 | TARGETS += dssi 54 | endif 55 | endif 56 | endif 57 | endif 58 | 59 | ifeq ($(BUILD_JACK),true) 60 | ifeq ($(HAVE_JACK),true) 61 | TARGETS += jack 62 | endif 63 | endif 64 | 65 | ifeq ($(BUILD_LADSPA),true) 66 | TARGETS += ladspa 67 | endif 68 | 69 | ifeq ($(BUILD_LV2),true) 70 | TARGETS += lv2_dsp 71 | endif 72 | 73 | ifeq ($(BUILD_VST2),true) 74 | TARGETS += vst 75 | endif 76 | 77 | ifeq ($(BUILD_VST3),true) 78 | TARGETS += vst3 79 | endif 80 | 81 | 82 | # -------------------------------------------------------------- 83 | # Make targets 84 | 85 | all: $(TARGETS) 86 | 87 | # -------------------------------------------------------------- 88 | # Generate C++ source & header from FAUST DSP source 89 | 90 | $(BUILD_DIR)/$(FAUST_IDENTIFIER).cpp.o: $(FAUST_IDENTIFIER).hpp $(FAUST_IDENTIFIER).cpp 91 | 92 | $(FAUST_IDENTIFIER).cpp: $(FAUST_DSP_SOURCE) 93 | faustpp -DIdentifier=$(FAUST_IDENTIFIER) -a $(FAUST_ARCH_DIR)/generic.cpp $< > $@ 94 | 95 | $(FAUST_IDENTIFIER).hpp: $(FAUST_DSP_SOURCE) 96 | faustpp -DIdentifier=$(FAUST_IDENTIFIER) -a $(FAUST_ARCH_DIR)/generic.hpp $< > $@ 97 | 98 | # -------------------------------------------------------------- 99 | # Installation 100 | 101 | install: all 102 | ifeq ($(BUILD_CLAP),true) 103 | @mkdir -p -m755 $(DESTDIR)$(CLAP_DIR) && \ 104 | install -m755 $(TARGET_DIR)/$(NAME).clap $(DESTDIR)$(CLAP_DIR) 105 | endif 106 | ifeq ($(BUILD_DSSI),true) 107 | ifneq ($(MACOS_OR_WINDOWS),true) 108 | ifeq ($(HAVE_DGL),true) 109 | ifeq ($(HAVE_LIBLO),true) 110 | @mkdir -p -m755 $(DESTDIR)$(DSSI_DIR) && \ 111 | install -m755 $(TARGET_DIR)/$(NAME)-dssi$(LIB_EXT) $(DESTDIR)$(DSSI_DIR) 112 | endif 113 | endif 114 | endif 115 | endif 116 | ifeq ($(BUILD_LADSPA),true) 117 | @mkdir -p -m755 $(DESTDIR)$(LADSPA_DIR) && \ 118 | install -m755 $(TARGET_DIR)/$(NAME)-ladspa$(LIB_EXT) $(DESTDIR)$(LADSPA_DIR) 119 | endif 120 | ifeq ($(BUILD_LV2),true) 121 | @mkdir -p -m755 $(DESTDIR)$(LV2_DIR)/$(NAME).lv2 && \ 122 | install -m755 $(TARGET_DIR)/$(NAME).lv2/*$(LIB_EXT) $(DESTDIR)$(LV2_DIR)/$(NAME).lv2 && \ 123 | install -m644 $(TARGET_DIR)/$(NAME).lv2/*.ttl $(DESTDIR)$(LV2_DIR)/$(NAME).lv2 124 | endif 125 | ifeq ($(BUILD_JACK),true) 126 | ifeq ($(HAVE_JACK),true) 127 | @mkdir -p -m755 $(DESTDIR)$(BINDIR) && \ 128 | install -m755 $(TARGET_DIR)/$(NAME)$(APP_EXT) $(DESTDIR)$(BINDIR) 129 | endif 130 | endif 131 | ifeq ($(BUILD_VST2),true) 132 | @mkdir -p -m755 $(DESTDIR)$(VST2_DIR) && \ 133 | install -m755 $(TARGET_DIR)/$(NAME)-vst$(LIB_EXT) $(DESTDIR)$(VST2_DIR) 134 | endif 135 | ifeq ($(BUILD_VST3),true) 136 | @mkdir -p -m755 $(DESTDIR)$(VST3_DIR)/$(dir $(VST3_FILENAME)) && \ 137 | install -m755 $(TARGET_DIR)/$(VST3_FILENAME) $(DESTDIR)$(VST3_DIR)/$(VST3_FILENAME) 138 | endif 139 | 140 | 141 | install-user: all 142 | ifeq ($(BUILD_CLAP),true) 143 | @mkdir -p -m755 $(USER_CLAP_DIR) && \ 144 | install -m755 $(TARGET_DIR)/$(NAME).clap $(USER_CLAP_DIR) 145 | endif 146 | ifeq ($(BUILD_DSSI),true) 147 | ifneq ($(MACOS_OR_WINDOWS),true) 148 | ifeq ($(HAVE_DGL),true) 149 | ifeq ($(HAVE_LIBLO),true) 150 | @mkdir -p -m755 $(USER_DSSI_DIR) && \ 151 | install -m755 $(TARGET_DIR)/$(NAME)-dssi$(LIB_EXT) $(USER_DSSI_DIR) 152 | endif 153 | endif 154 | endif 155 | endif 156 | ifeq ($(BUILD_JACK),true) 157 | ifeq ($(HAVE_JACK),true) 158 | @mkdir -p -m755 $(HOME)/bin && \ 159 | install -m755 $(TARGET_DIR)/$(NAME)$(APP_EXT) $(HOME)/bin 160 | endif 161 | endif 162 | ifeq ($(BUILD_LV2),true) 163 | @mkdir -p -m755 $(USER_LV2_DIR)/$(NAME).lv2 && \ 164 | install -m755 $(TARGET_DIR)/$(NAME).lv2/*$(LIB_EXT) $(USER_LV2_DIR)/$(NAME).lv2 && \ 165 | install -m644 $(TARGET_DIR)/$(NAME).lv2/*.ttl $(USER_LV2_DIR)/$(NAME).lv2 166 | endif 167 | ifeq ($(BUILD_LADSPA),true) 168 | @mkdir -p -m755 $(USER_LADSPA_DIR) && \ 169 | install -m755 $(TARGET_DIR)/$(NAME)-ladspa$(LIB_EXT) $(USER_LADSPA_DIR) 170 | endif 171 | ifeq ($(BUILD_VST2),true) 172 | @mkdir -p -m755 $(USER_VST2_DIR) && \ 173 | install -m755 $(TARGET_DIR)/$(NAME)-vst$(LIB_EXT) $(USER_VST2_DIR) 174 | endif 175 | ifeq ($(BUILD_VST3),true) 176 | @mkdir -p -m755 $(USER_VST3_DIR)/$(dir $(VST3_FILENAME)) && \ 177 | install -m755 $(TARGET_DIR)/$(VST3_FILENAME) $(USER_VST3_DIR)/$(VST3_FILENAME) 178 | endif 179 | 180 | # -------------------------------------------------------------- 181 | 182 | .PHONY: all install install-user 183 | -------------------------------------------------------------------------------- /plugins/adt/PluginADT.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Automatic Double Tracking audio effect based on DISTRHO Plugin Framework (DPF) 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Copyright (C) 2024 Christopher Arndt 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to 10 | * deal in the Software without restriction, including without limitation the 11 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 | * sell copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | * IN THE SOFTWARE. 25 | */ 26 | 27 | #include "PluginADT.hpp" 28 | 29 | START_NAMESPACE_DISTRHO 30 | 31 | // ----------------------------------------------------------------------- 32 | 33 | PluginADT::PluginADT() 34 | : Plugin(ADT::NumParameters, presetCount, 0) // # of params, # of programs, 0 states 35 | { 36 | dsp = new ADT; 37 | fSampleRate = getSampleRate(); 38 | 39 | for (unsigned p = 0; p < ADT::NumParameters; ++p) { 40 | Parameter param; 41 | initParameter(p, param); 42 | setParameterValue(p, param.ranges.def); 43 | } 44 | } 45 | 46 | PluginADT::~PluginADT() { 47 | delete dsp; 48 | } 49 | 50 | // ----------------------------------------------------------------------- 51 | // Init 52 | 53 | void PluginADT::initParameter(uint32_t index, Parameter& parameter) { 54 | if (index >= ADT::NumParameters) 55 | return; 56 | 57 | const ADT::ParameterRange* range = dsp->parameter_range(index); 58 | parameter.name = dsp->parameter_label(index); 59 | parameter.shortName = dsp->parameter_short_label(index); 60 | parameter.symbol = dsp->parameter_symbol(index); 61 | parameter.unit = dsp->parameter_unit(index); 62 | parameter.ranges.min = range->min; 63 | parameter.ranges.max = range->max; 64 | parameter.ranges.def = range->init; 65 | parameter.hints = kParameterIsAutomatable; 66 | 67 | if (dsp->parameter_is_boolean(index)) 68 | parameter.hints |= kParameterIsBoolean; 69 | if (dsp->parameter_is_integer(index)) 70 | parameter.hints |= kParameterIsInteger; 71 | if (dsp->parameter_is_logarithmic(index)) 72 | parameter.hints |= kParameterIsLogarithmic; 73 | if (dsp->parameter_is_trigger(index)) 74 | parameter.hints |= kParameterIsTrigger; 75 | } 76 | 77 | /** 78 | Set the name of the program @a index. 79 | This function will be called once, shortly after the plugin is created. 80 | */ 81 | void PluginADT::initProgramName(uint32_t index, String& programName) { 82 | if (index < presetCount) { 83 | programName = factoryPresets[index].name; 84 | } 85 | } 86 | 87 | // ----------------------------------------------------------------------- 88 | // Internal data 89 | 90 | /** 91 | Optional callback to inform the plugin about a sample rate change. 92 | */ 93 | void PluginADT::sampleRateChanged(double newSampleRate) { 94 | fSampleRate = newSampleRate; 95 | dsp->init(newSampleRate); 96 | } 97 | 98 | /** 99 | Get the current value of a parameter. 100 | */ 101 | float PluginADT::getParameterValue(uint32_t index) const { 102 | return dsp->get_parameter(index); 103 | } 104 | 105 | /** 106 | Change a parameter value. 107 | */ 108 | void PluginADT::setParameterValue(uint32_t index, float value) { 109 | if (index >= ADT::NumParameters) 110 | return; 111 | 112 | const ADT::ParameterRange* range = dsp->parameter_range(index); 113 | dsp->set_parameter(index, CLAMP(value, range->min, range->max)); 114 | } 115 | 116 | /** 117 | Load a program. 118 | The host may call this function from any context, 119 | including realtime processing. 120 | */ 121 | void PluginADT::loadProgram(uint32_t index) { 122 | if (index < presetCount) { 123 | for (int i=0; i < ADT::NumParameters; i++) { 124 | setParameterValue(i, factoryPresets[index].params[i]); 125 | } 126 | } 127 | } 128 | 129 | // ----------------------------------------------------------------------- 130 | // Process 131 | 132 | /** 133 | Plugin is activated. 134 | */ 135 | void PluginADT::activate() { 136 | fSampleRate = getSampleRate(); 137 | dsp->init(fSampleRate); 138 | } 139 | 140 | 141 | void PluginADT::run(const float** inputs, float** outputs, 142 | uint32_t frames) { 143 | dsp->process(inputs[0], outputs[0], outputs[1], (unsigned)frames); 144 | } 145 | 146 | // ----------------------------------------------------------------------- 147 | 148 | Plugin* createPlugin() { 149 | return new PluginADT(); 150 | } 151 | 152 | // ----------------------------------------------------------------------- 153 | 154 | END_NAMESPACE_DISTRHO 155 | -------------------------------------------------------------------------------- /plugins/adt/PluginADT.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Automatic Double Tracking audio effect based on DISTRHO Plugin Framework (DPF) 3 | * 4 | * SPDX-License-Identifier: MIT 5 | * 6 | * Copyright (C) 2024 Christopher Arndt 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to 10 | * deal in the Software without restriction, including without limitation the 11 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 12 | * sell copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | * IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef PLUGIN_ADT_H 28 | #define PLUGIN_ADT_H 29 | 30 | #include "DistrhoPlugin.hpp" 31 | #include "ADT.hpp" 32 | 33 | START_NAMESPACE_DISTRHO 34 | 35 | #ifndef MIN 36 | #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) 37 | #endif 38 | 39 | #ifndef MAX 40 | #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) 41 | #endif 42 | 43 | #ifndef CLAMP 44 | #define CLAMP(v, min, max) (MIN((max), MAX((min), (v)))) 45 | #endif 46 | 47 | // ----------------------------------------------------------------------- 48 | 49 | class PluginADT : public Plugin { 50 | public: 51 | PluginADT(); 52 | 53 | ~PluginADT(); 54 | 55 | protected: 56 | // ------------------------------------------------------------------- 57 | // Information 58 | 59 | const char* getLabel() const noexcept override { 60 | return "ADT"; 61 | } 62 | 63 | const char* getDescription() const override { 64 | return "Automatic double tracking (not only) for vocals"; 65 | } 66 | 67 | const char* getMaker() const noexcept override { 68 | return "chrisarndt.de"; 69 | } 70 | 71 | const char* getHomePage() const override { 72 | return DISTRHO_PLUGIN_URI; 73 | } 74 | 75 | const char* getLicense() const noexcept override { 76 | return "https://spdx.org/licenses/MIT"; 77 | } 78 | 79 | uint32_t getVersion() const noexcept override { 80 | return d_version(0, 2, 2); 81 | } 82 | 83 | // Go to: 84 | // 85 | // http://service.steinberg.de/databases/plugin.nsf/plugIn 86 | // 87 | // Get a proper plugin UID and fill it in here! 88 | int64_t getUniqueId() const noexcept override { 89 | return d_cconst('a', 'd', 't', 'v'); 90 | } 91 | 92 | // ------------------------------------------------------------------- 93 | // Init 94 | 95 | void initParameter(uint32_t index, Parameter& parameter) override; 96 | void initProgramName(uint32_t index, String& programName) override; 97 | 98 | // ------------------------------------------------------------------- 99 | // Internal data 100 | 101 | float getParameterValue(uint32_t index) const override; 102 | void setParameterValue(uint32_t index, float value) override; 103 | void loadProgram(uint32_t index) override; 104 | 105 | // ------------------------------------------------------------------- 106 | // Optional 107 | 108 | // Optional callback to inform the plugin about a sample rate change. 109 | void sampleRateChanged(double newSampleRate) override; 110 | 111 | // ------------------------------------------------------------------- 112 | // Process 113 | 114 | void activate() override; 115 | void run(const float**, float** outputs, uint32_t frames) override; 116 | 117 | // ------------------------------------------------------------------- 118 | 119 | private: 120 | double fSampleRate; 121 | ADT* dsp; 122 | 123 | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginADT) 124 | }; 125 | 126 | struct Preset { 127 | const char* name; 128 | float params[ADT::NumParameters]; 129 | }; 130 | 131 | const Preset factoryPresets[] = { 132 | //,{ 133 | // "Preset name", // preset name 134 | // {0.0f, ...} // array of ADT::NumParameters float param values 135 | //} 136 | { 137 | "Default", 138 | { 139 | 100.0f, // p_Pan_Spread 140 | 40.0f, // p_Delay_Spread 141 | 40.f, // p_Pitch_Spread 142 | 3500.0f, // p_Lowpass 143 | 20.0f, // p_Highpass 144 | -3.0f, // p_Dry 145 | -4.0f // p_Wet 146 | } 147 | } 148 | }; 149 | 150 | const uint presetCount = sizeof(factoryPresets) / sizeof(Preset); 151 | 152 | // ----------------------------------------------------------------------- 153 | 154 | END_NAMESPACE_DISTRHO 155 | 156 | #endif // #ifndef PLUGIN_ADT_H 157 | -------------------------------------------------------------------------------- /screenshot-ardour8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpotlightKid/adt/977688c94d3f3327097e801e95a36f38a34fe61c/screenshot-ardour8.png -------------------------------------------------------------------------------- /scripts/build-win32.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Build win32 binaries of CLAP, LV2 and VST2/3 plugin format 4 | # 5 | 6 | PROJECT_VERSION="$(git describe --abbrev=0 2>/dev/null)" 7 | 8 | if [[ -z "$PROJECT_VERSION" ]]; then 9 | echo "WARNING: No git tags found. Can't create binary distribution archive" 10 | echo "Hint: Use 'git tag -a ' to create a project version." 11 | echo 12 | fi 13 | 14 | set -e 15 | 16 | # Preparation 17 | _FLAGS="-DPTW32_STATIC_LIB -Werror" 18 | _ARCH=i686-w64-mingw32 19 | _PREFIX="/usr/${_ARCH}" 20 | export PATH=${_PREFIX}/bin:$PATH 21 | export AR=${_ARCH}-ar 22 | export CC=${_ARCH}-gcc 23 | export CXX=${_ARCH}-g++ 24 | export PKG_CONFIG_PATH=${_PREFIX}/lib/pkgconfig 25 | export WIN32=true 26 | export CFLAGS="${_FLAGS}" 27 | export CXXFLAGS="${_FLAGS}" 28 | export LDFLAGS="-static" 29 | export CROSS_COMPILING=true 30 | 31 | # Start clean 32 | make clean > /dev/null 33 | make -C dpf clean > /dev/null 34 | rm -rf bin-w32 35 | 36 | # Build now 37 | make HAVE_CAIRO=false HAVE_JACK=false BUILD_VST2=true BUILD_LADSPA=false 38 | mv bin bin-w32 39 | 40 | set +e 41 | 42 | # Make Zip archive of binaries 43 | if [[ -n "$PROJECT_VERSION" ]]; then 44 | CHECKOUT="$(pwd)" 45 | REPO_URL="$(git remote get-url origin)" 46 | PROJECT_NAME="${REPO_URL##*/}" 47 | SRCDIR="$PROJECT_NAME-${PROJECT_VERSION#v}" 48 | ZIP_NAME="$SRCDIR-win32.zip" 49 | mkdir -p dist 50 | rm -f dist/$ZIP_NAME && zip -r dist/$ZIP_NAME bin-w32 51 | fi 52 | -------------------------------------------------------------------------------- /scripts/build-win64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Build win32 binaries of CLAP, LV2 and VST2/3 plugin format 4 | # 5 | 6 | PROJECT_VERSION="$(git describe --abbrev=0 2>/dev/null)" 7 | 8 | if [[ -z "$PROJECT_VERSION" ]]; then 9 | echo "WARNING: No git tags found. Can't create binary distribution archive" 10 | echo "Hint: Use 'git tag -a ' to create a project version." 11 | echo 12 | fi 13 | 14 | set -e 15 | 16 | # Preparation 17 | _FLAGS="-DPTW32_STATIC_LIB -Werror" 18 | _ARCH=x86_64-w64-mingw32 19 | _PREFIX="/usr/${_ARCH}" 20 | export PATH=${_PREFIX}/bin:$PATH 21 | export AR=${_ARCH}-ar 22 | export CC=${_ARCH}-gcc 23 | export CXX=${_ARCH}-g++ 24 | export PKG_CONFIG_PATH=${_PREFIX}/lib/pkgconfig 25 | export WIN32=true 26 | export WIN64=true 27 | export CFLAGS="${_FLAGS}" 28 | export CXXFLAGS="${_FLAGS}" 29 | export LDFLAGS="-static" 30 | export CROSS_COMPILING=true 31 | 32 | # Start clean 33 | make clean > /dev/null 34 | make -C dpf clean > /dev/null 35 | rm -rf bin-w64 36 | 37 | # Build now 38 | make HAVE_CAIRO=false HAVE_JACK=false BUILD_VST2=true BUILD_LADSPA=false 39 | mv bin bin-w64 40 | 41 | # Make Zip archive of binaries 42 | if [[ -n "$PROJECT_VERSION" ]]; then 43 | CHECKOUT="$(pwd)" 44 | REPO_URL="$(git remote get-url origin)" 45 | PROJECT_NAME="${REPO_URL##*/}" 46 | SRCDIR="$PROJECT_NAME-${PROJECT_VERSION#v}" 47 | ZIP_NAME="$SRCDIR-win64.zip" 48 | mkdir -p dist 49 | rm -f dist/$ZIP_NAME && zip -r dist/$ZIP_NAME bin-w64 50 | fi 51 | -------------------------------------------------------------------------------- /scripts/bundle-source.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Build source distribution archive with all git sub-modules included 4 | # 5 | 6 | PROJECT_VERSION="$(git describe --abbrev=0 2>/dev/null)" 7 | 8 | if [[ -z "$PROJECT_VERSION" ]]; then 9 | echo "ERROR: No git tags found. Can't create source distribution archve." 10 | echo "Hint: Use 'git tag -a ' to create a project version." 11 | exit 1 12 | fi 13 | 14 | set -e 15 | 16 | CHECKOUT="$(pwd)" 17 | REPO_URL="$(git remote get-url origin)" 18 | PROJECT_NAME="${REPO_URL##*/}" 19 | PROJECT_NAME="${PROJECT_NAME%.git}" 20 | SRCDIR="$PROJECT_NAME-${PROJECT_VERSION#v}" 21 | TARBALL_NAME="$SRCDIR-source.tar.gz" 22 | BUILDDIR="build/${PROJECT_VERSION#v}" 23 | 24 | mkdir -p "$BUILDDIR" dist 25 | cd "$BUILDDIR" 26 | rm -rf "$SRCDIR" 27 | git clone --recursive --branch "$PROJECT_VERSION" --single-branch "$CHECKOUT" "$SRCDIR" 28 | cd "$SRCDIR" 29 | for fn in .git .gitmodules .gitignore; do 30 | find . -name $fn -type f -print0 | xargs -0 rm -f 31 | done 32 | rm -rf .git 33 | cd .. 34 | tar -zcvf "$CHECKOUT/dist/$TARBALL_NAME" "$SRCDIR" 35 | 36 | gpg --armor --detach-sign --yes "$CHECKOUT/dist/$TARBALL_NAME" 37 | cd "$CHECKOUT" 38 | rm -rf "$BUILDDIR" 39 | ls -l dist 40 | --------------------------------------------------------------------------------