A JUCE audio plugin that turns a mono source (typically a guitar or vocal) into a wide stereo image while staying perfectly mono-compatible. Two micro pitch-shifters detune the input by ±Pitch cents; their decorrelated difference forms a pure side signal, while the dry input stays as the mid. The output is constructed as L = dry + width·side, R = dry − width·side, so summing (L+R)/2 collapses back to the dry signal exactly: no comb filtering, no level drop, no chorusing on mono. An optional Haas-style precedence delay on one of the wet branches broadens the image further without breaking mono compatibility.
Parameters: Pitch (0–40 cents, default 7), Mix (0–1, default 1.0; scales the side gain up to 4× internally), Haas (0–30 ms, default 0), Mono Listen (sums output to mono in-plugin, useful for verifying mono compatibility).
Built on the Starty template, which itself derives from Pamplejuce.
brew install cmake ninja clang-format # Homebrew: https://brew.shsudo apt update
sudo apt install -y \
cmake ninja-build clang clang-format lld \
libasound2-dev libx11-dev libxinerama-dev libxext-dev \
libfreetype6-dev libwebkit2gtk-4.1-dev libglu1-mesa-devOne-time, per clone. Refuses commits whose staged C/C++ files aren't clang-format clean (see .githooks/pre-commit):
git config core.hooksPath .githookscmake -B Builds -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build Builds
ctest --test-dir Builds --output-on-failureFor a universal macOS binary, add -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" to the configure step.
CI runs RealtimeSanitizer on Linux. To check locally on macOS, install Homebrew LLVM, since Apple Clang doesn't ship the RTSan runtime:
brew install llvmConfigure a separate build dir using brew's clang and the realtime flags:
CC=/opt/homebrew/opt/llvm/bin/clang \
CXX=/opt/homebrew/opt/llvm/bin/clang++ \
cmake -B Builds-rtsan -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-fsanitize=realtime" \
-DCMAKE_CXX_FLAGS="-fsanitize=realtime" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=realtime"Build and run:
cmake --build Builds-rtsan --target Tests
ctest --test-dir Builds-rtsan --output-on-failure --verbose -E NOT_BUILTEvery push and PR triggers:
build_and_test: Linux/macOS/Windows,pluginvalvalidation, artifact uploadinstrumented_tests: ASan / UBSan / TSan / RTSan (clang-20 for the latter), plus a Coverage report (gcovr → HTML artifact + step-summary numbers)clang-tidy: posts review comments on PRs
nightly.yml is wired up but its schedule: block is currently commented out, since push-driven CI is enough while development is active. Re-enable the cron in that file once the project is in maintenance mode and external drift (JUCE on develop, apt packages, runner images) becomes the main breakage risk.
Releases are tag-driven. The release job in build_and_test.yml is gated on contains(github.ref, 'tags/v') and uses softprops/action-gh-release to publish build artifacts (.exe, .zip, .pkg) as a GitHub prerelease.
To cut a release:
- On a release branch, update the
VERSIONfile in the repo root (e.g.0.1.0). - Open a PR against
mainand get it merged. - Pull the merged commit locally, then tag it with a
v-prefixed tag matching the version and push the tag:git checkout main git pull git tag v0.1.0 git push origin v0.1.0
- CI runs the full matrix on the tag, then the
releasejob picks up the artifacts and publishes a draft prerelease on GitHub. Open the Releases page, fill in the description, flip the prerelease flag off if it's a real release, and publish.
The v prefix is required; a bare 0.1.0 tag won't trigger the release job.
Dupe is released under the GNU Affero General Public License, version 3 (AGPLv3). Copyright (C) 2026 Vincent Berthiaume.
This project links against JUCE, used under the AGPLv3 free-use option of JUCE Ltd's dual-license terms.
The "One Does Not Simply" meme variant at the top of this README is from URM Academy.
Portions of the build system and project scaffolding derive from the Pamplejuce template, which is distributed under the MIT License:
MIT License
Copyright (c) 2022 Sudara Williams
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
