From 5797f8b8b7fcaa95d754cc5651b4cb54ffa631ca Mon Sep 17 00:00:00 2001 From: Armin Date: Tue, 28 Jul 2026 16:27:38 +0200 Subject: [PATCH] add modules to gitignore, remove tracked modules --- .gitignore | 6 +- AGENTS.md | 174 ++++++++++++++++++++ Installer/build.sh | 44 ++--- Installer/win/Wavetable.iss | 2 +- README.md | 292 ++++++++++++++++++++++++++++++++- modules/MTS-ESP | 1 - modules/clap-juce-extensions | 1 - modules/gin | 1 - modules/juce | 1 - modules/melatonin_inspector | 1 - modules/plugin_sdk | 1 - plugin/Source/PluginEditor.cpp | 2 +- 12 files changed, 488 insertions(+), 38 deletions(-) create mode 100644 AGENTS.md delete mode 160000 modules/MTS-ESP delete mode 160000 modules/clap-juce-extensions delete mode 160000 modules/gin delete mode 160000 modules/juce delete mode 160000 modules/melatonin_inspector delete mode 160000 modules/plugin_sdk diff --git a/.gitignore b/.gitignore index 9d078de..792c923 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,8 @@ Installer/macOS/bin Installer/win/bin Installer/_flat_presets .DS_Store -.claude \ No newline at end of file +.claude + +# modules +modules + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..6814a83 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,174 @@ +# AGENTS.md — Wavetable Synth Project Context + +## Project Overview + +Wavetable is a polyphonic wavetable synthesizer audio plugin (VST3, AU, CLAP, LV2, Standalone) built with **JUCE** and the **Gin** framework. It's developed by SocaLabs (Roland Rabien). + +- **Version**: 1.0.34 (tracked in `VERSION` file) +- **Language**: C++20 +- **Build system**: CMake (minimum 3.24) +- **Bundle ID**: `com.socalabs.wavetable` + +## Repository Structure + +``` +Wavetable/ +├── CMakeLists.txt # Main build config +├── CMakePresets.json # Presets: xcode (macOS), vs (Windows), ninja-gcc (Linux) +├── VERSION # Current version string +├── Changelist.txt # Version history (used by release.sh) +├── release.sh # GitHub release script +├── tag.sh # Tags current VERSION and pushes +├── plugin/ +│ ├── Source/ +│ │ ├── PluginProcessor.h/cpp # Main processor (WavetableAudioProcessor) +│ │ ├── PluginEditor.h/cpp # Editor (WavetableAudioProcessorEditor) +│ │ ├── Editor.h/cpp # Main UI layout component +│ │ ├── Panels.h # All section UI boxes (OscillatorBox, FilterBox, etc.) +│ │ ├── WavetableVoice.h/cpp # Synth voice +│ │ ├── Cfg.h # Compile-time constants +│ │ └── FX/ # Custom FX (DeRez2, FireAmp, GrindAmp) +│ └── Resources/ +│ ├── layout.json # UI layout +│ ├── Presets/ # Factory presets (XML, per-category subdirs) +│ ├── Wavetables/ # Factory wavetables +│ └── WavetablesFLAC/ # FLAC-compressed wavetables +├── modules/ # Git submodules +│ ├── gin/ # Gin framework (core dependency) +│ ├── juce/ # JUCE framework +│ ├── clap-juce-extensions/ # CLAP format support +│ ├── MTS-ESP/ # Microtuning support +│ ├── plugin_sdk/ # VST2 SDK (optional) +│ └── melatonin_inspector/ # Debug UI inspector +├── installer/ +│ ├── build.sh # Full installer build script (macOS/Linux/Windows) +│ ├── macOS/ # macOS pkg installer resources +│ └── win/ # Windows Inno Setup installer +└── .github/workflows/ + ├── build.yaml # CI build on push + └── release.yaml # Release build on tag push +``` + +## Key Architecture + +### Plugin Core +- **`WavetableAudioProcessor`** (`plugin/Source/PluginProcessor.h`) — inherits `gin::Processor` + `gin::Synthesiser` +- **`WavetableAudioProcessorEditor`** (`plugin/Source/PluginEditor.h`) — inherits `gin::ProcessorEditor` +- **`Editor`** (`plugin/Source/Editor.h`) — the main content component with all section boxes + +### UI Panels (Panels.h) +All section UIs are `gin::ParamBox` subclasses: +- `OscillatorBox` — wavetable osc with navigation buttons in header +- `SubBox`, `NoiseBox` — simple boxes +- `FilterBox` — complex with ADSR, routing buttons +- `ADSRBox` — envelope display + knobs +- `LFOBox`, `ENVBox` — tabbed (addHeader with HeaderButton) +- `StepBox` — step sequencer +- `ModBox`, `MatrixBox` — modulation source/matrix tabs +- `GlobalBox` — global controls +- FX boxes: `GateBox`, `ChorusBox`, `DistortBox`, `DelayBox`, `ReverbBox` + +### Gin Framework (submodule) +- **`gin::ParamBox`** (`modules/gin/.../gin_parambox.h`) — base for all section boxes +- **`gin::ParamHeader`** — header bar with gradient background + label text +- **`gin::CopperLookAndFeel`** (`modules/gin/.../gin_copperlookandfeel.cpp`) — default LookAndFeel +- **Colors**: title1/title2 (header gradient), matte1/matte2 (body gradient), accent (copper) +- **`gradientRect()`** helper — vertical linear gradient fill + +### Custom LookAndFeel +The project uses `gin::CopperLookAndFeel` by default (set in `gin_processor.cpp`). Colors can be overridden per-component via `findColour()`. + +**Important**: `ParamHeader::paint()` is **private** and has hardcoded font size and gradient colors. To customize header appearance, you must edit `gin_parambox.h` directly in the submodule. This is a local modification that will be overwritten on `git submodule update`. + +## Build Instructions + +### Quick Build (macOS) +```bash +git clone --recursive https://github.com/FigBug/Wavetable.git +cd Wavetable +cmake --preset xcode +cmake --build --preset xcode --config Release +# Output: Builds/xcode/Wavetable_artefacts/Release/ +``` + +### CMake Presets +- **macOS**: `xcode` — generates Xcode project, builds universal (arm64 + x86_64) +- **Windows**: `vs` — generates Visual Studio solution +- **Linux**: `ninja-gcc` — generates Ninja build files with GCC + +### Build Outputs (macOS) +``` +Builds/xcode/Wavetable_artefacts/Release/ +├── Standalone/Wavetable.app +├── VST/Wavetable.vst +├── VST3/Wavetable.vst3 +├── AU/Wavetable.component +└── CLAP/Wavetable.clap +``` + +### Installer (macOS) +```bash +./installer/build.sh +# Output: installer/macOS/bin/Wavetable.pkg +# Requires Xcode CLI tools; signing/notarization optional (needs secrets) +``` + +The installer pkg installs: +- VST → `/Library/Audio/Plug-Ins/VST/` +- VST3 → `/Library/Audio/Plug-Ins/VST3/` +- AU → `/Library/Audio/Plug-Ins/Components/` +- CLAP → `/Library/Audio/Plug-Ins/CLAP/` +- Factory wavetables + presets → `/Library/Audio/Presets/SocaLabs/Wavetable/` + +### Manual Plugin Install (macOS, no installer) +Copy built bundles manually: +```bash +cp -R Builds/xcode/Wavetable_artefacts/Release/AU/Wavetable.component ~/Library/Audio/Plug-Ins/Components/ +cp -R Builds/xcode/Wavetable_artefacts/Release/VST3/Wavetable.vst3 ~/Library/Audio/Plug-Ins/VST3/ +cp -R Builds/xcode/Wavetable_artefacts/Release/CLAP/Wavetable.clap ~/Library/Audio/Plug-Ins/CLAP/ +``` +Factory resources: +```bash +mkdir -p ~/Library/Audio/Presets/SocaLabs/Wavetable +cp -R plugin/Resources/WavetablesFLAC ~/Library/Audio/Presets/SocaLabs/Wavetable/Wavetables +# Presets (flatten subdirs): +find plugin/Resources/Presets -name "*.xml" -exec cp {} ~/Library/Audio/Presets/SocaLabs/Wavetable/ \; +``` + +## Release Process + +1. Update `VERSION` file +2. Add changelog entry in `Changelist.txt` under the version +3. Commit and push +4. Run `./tag.sh` — tags `v{VERSION}` and pushes the tag +5. GitHub Actions (`release.yaml`) builds installers for all platforms +6. `release.sh` creates a GitHub release and uploads to socalabs.com + +## Submodule Notes + +The Gin submodule is pinned at commit `414fecf`. Local modifications to Gin files (e.g., `gin_parambox.h`, `gin_copperlookandfeel.cpp`) are intentional and should not be committed to the submodule. Be aware that `git submodule update` will overwrite these changes. + +## Coding Conventions + +- Standard JUCE/Gin code style (camelCase methods, PascalCase classes) +- `gin::Parameter::Ptr` for all synth parameters +- `gin::ParamBox` subclassed for each UI section +- Parameters defined as nested structs in `WavetableAudioProcessor` (e.g., `OSCParams`, `FilterParams`) +- No comments unless explicitly requested +- Build with `-ffast-math -fno-finite-math-only` on macOS/Release + +## Common Tasks + +### Changing header label appearance +Edit `modules/gin/modules/gin_plugin/components/gin_parambox.h` → `ParamHeader::paint()`. The font and gradient are hardcoded there. + +### Changing header gradient colors +Edit `modules/gin/modules/gin_plugin/lookandfeel/gin_copperlookandfeel.cpp` → `title1ColourId` / `title2ColourId` in constructor. + +### Adding new parameters +1. Add to the relevant Params struct in `PluginProcessor.h` +2. Initialize in `PluginProcessor.cpp` (`setup()` method) +3. Add UI control in the appropriate Box class in `Panels.h` + +### Changing UI layout +Edit `plugin/Resources/layout.json` — positions are grid-based (56px columns, 70px rows, 23px header height). diff --git a/Installer/build.sh b/Installer/build.sh index 3aa595b..43dca8b 100755 --- a/Installer/build.sh +++ b/Installer/build.sh @@ -48,8 +48,8 @@ fetch_reporter () { # $1 platform, $2 output file # # Reset staging # -rm -Rf "$PROJECT_ROOT/Installer/$PLATFORM/bin" -mkdir -p "$PROJECT_ROOT/Installer/$PLATFORM/bin" +rm -Rf "$PROJECT_ROOT/installer/$PLATFORM/bin" +mkdir -p "$PROJECT_ROOT/installer/$PLATFORM/bin" rm -Rf "$PROJECT_ROOT/bin" mkdir -p "$PROJECT_ROOT/bin" @@ -58,7 +58,7 @@ mkdir -p "$PROJECT_ROOT/bin" # gin's loadDirectory() doesn't recurse, and the legacy BinaryData flow stored # presets flat in the user directory — keeping flat matches what users see. # -FLAT_PRESETS="$PROJECT_ROOT/Installer/_flat_presets" +FLAT_PRESETS="$PROJECT_ROOT/installer/_flat_presets" rm -Rf "$FLAT_PRESETS" mkdir -p "$FLAT_PRESETS" find "$PROJECT_ROOT/plugin/Resources/Presets" -name "*.xml" -type f -exec cp {} "$FLAT_PRESETS/" \; @@ -101,8 +101,8 @@ if [ "$PLATFORM" = "macOS" ]; then cmake --preset xcode cmake --build --preset xcode --config Release - STAGE="$PROJECT_ROOT/Installer/macOS/bin/stage" - PKG_DIR="$PROJECT_ROOT/Installer/macOS/bin/pkgs" + STAGE="$PROJECT_ROOT/installer/macOS/bin/stage" + PKG_DIR="$PROJECT_ROOT/installer/macOS/bin/pkgs" rm -Rf "$STAGE" "$PKG_DIR" mkdir -p "$STAGE/vst" "$STAGE/vst3" "$STAGE/au" "$STAGE/clap" mkdir -p "$STAGE/resources/Library/Audio/Presets/$VENDOR/$PLUGIN" @@ -166,13 +166,13 @@ if [ "$PLATFORM" = "macOS" ]; then --install-location "/" \ --identifier "${BUNDLE_BASE}.resources.pkg" \ --version "$VERSION" \ - --scripts "$PROJECT_ROOT/Installer/macOS/scripts" \ + --scripts "$PROJECT_ROOT/installer/macOS/scripts" \ "$PKG_DIR/resources.pkg" # CrashReporter component: latest signed CrashReporter.app + this plugin's # registration JSON. Staged under .incoming and promoted by the postinstall # only if strictly newer (shared component, never downgraded). - REP_STAGE="$PROJECT_ROOT/Installer/macOS/bin/reporter" + REP_STAGE="$PROJECT_ROOT/installer/macOS/bin/reporter" REP_ROOT="$REP_STAGE/Library/Application Support/Rabien Software/Crash Reporter" rm -Rf "$REP_STAGE" mkdir -p "$REP_ROOT/Plugins" "$REP_ROOT/.incoming" @@ -180,34 +180,34 @@ if [ "$PLATFORM" = "macOS" ]; then ( cd "$REP_STAGE" && unzip -qo CrashReporter_Mac.zip && rm CrashReporter_Mac.zip ) mv "$REP_STAGE/CrashReporter.app" "$REP_ROOT/.incoming/" fi - cp "$PROJECT_ROOT/Installer/crashreporter.json" "$REP_ROOT/Plugins/wavetable.json" + cp "$PROJECT_ROOT/installer/crashreporter.json" "$REP_ROOT/Plugins/wavetable.json" find "$REP_STAGE" -name ".DS_Store" -delete if [ -n "${APPLICATION:-}" ] && [ -d "$REP_ROOT/.incoming/CrashReporter.app" ]; then codesign -s "$DEV_APP_ID" --options=runtime --timestamp --force -v "$REP_ROOT/.incoming/CrashReporter.app" fi - chmod +x "$PROJECT_ROOT/Installer/macOS/reporter-scripts/postinstall" + chmod +x "$PROJECT_ROOT/installer/macOS/reporter-scripts/postinstall" # Disable bundle relocation so the installer installs to our staged path # instead of redirecting to a CrashReporter.app found elsewhere via Spotlight. - COMP_PLIST="$PROJECT_ROOT/Installer/macOS/bin/reporter-component.plist" + COMP_PLIST="$PROJECT_ROOT/installer/macOS/bin/reporter-component.plist" pkgbuild --analyze --root "$REP_STAGE" "$COMP_PLIST" /usr/libexec/PlistBuddy -c "Set :0:BundleIsRelocatable false" "$COMP_PLIST" 2>/dev/null || true pkgbuild --root "$REP_STAGE" --install-location "/" \ --identifier "${BUNDLE_BASE}.crashreporter.pkg" --version "$VERSION" \ --component-plist "$COMP_PLIST" \ - --scripts "$PROJECT_ROOT/Installer/macOS/reporter-scripts" \ + --scripts "$PROJECT_ROOT/installer/macOS/reporter-scripts" \ "$PKG_DIR/reporter.pkg" # productbuild — combine into one signed installer - cp "$PROJECT_ROOT/Installer/EULA.rtf" "$PKG_DIR/EULA.rtf" - cp "$PROJECT_ROOT/Installer/macOS/welcome.txt" "$PKG_DIR/welcome.txt" + cp "$PROJECT_ROOT/installer/EULA.rtf" "$PKG_DIR/EULA.rtf" + cp "$PROJECT_ROOT/installer/macOS/welcome.txt" "$PKG_DIR/welcome.txt" - PKG_OUT="$PROJECT_ROOT/Installer/macOS/bin/${PLUGIN}.pkg" + PKG_OUT="$PROJECT_ROOT/installer/macOS/bin/${PLUGIN}.pkg" - productbuild --distribution "$PROJECT_ROOT/Installer/macOS/distribution.xml" \ + productbuild --distribution "$PROJECT_ROOT/installer/macOS/distribution.xml" \ --package-path "$PKG_DIR" \ --resources "$PKG_DIR" \ --version "$VERSION" \ @@ -278,7 +278,7 @@ else cmake --build --preset vs --config Release ART_DIR="$PROJECT_ROOT/Builds/vs/${PLUGIN}_artefacts/Release" - STAGE="$PROJECT_ROOT/Installer/win/bin" + STAGE="$PROJECT_ROOT/installer/win/bin" rm -Rf "$STAGE" mkdir -p "$STAGE/VST" "$STAGE/VST3" "$STAGE/CLAP" @@ -292,12 +292,12 @@ else if fetch_reporter win "$REP_DIR/CrashReporter_Win.zip"; then ( cd "$REP_DIR" && 7z x -y CrashReporter_Win.zip >/dev/null && rm CrashReporter_Win.zip ) fi - cp "$PROJECT_ROOT/Installer/crashreporter.json" "$REP_DIR/wavetable.json" + cp "$PROJECT_ROOT/installer/crashreporter.json" "$REP_DIR/wavetable.json" # # Sign binaries via Microsoft Trusted Signing. # Required env: AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET. - # Cert is referenced via Installer/win/metadata.json. + # Cert is referenced via installer/win/metadata.json. # uuid_re='^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$' WIN_SIGN=0 @@ -325,7 +325,7 @@ else nuget install Microsoft.Trusted.Signing.Client -Version 1.0.86 \ -OutputDirectory "$TOOLS_DIR" -ExcludeVersion -NonInteractive DLIB="$TOOLS_DIR/Microsoft.Trusted.Signing.Client/bin/x64/Azure.CodeSigning.Dlib.dll" - METADATA="$PROJECT_ROOT/Installer/win/metadata.json" + METADATA="$PROJECT_ROOT/installer/win/metadata.json" sign_file () { "$SIGNTOOL" sign -v -fd SHA256 \ @@ -341,14 +341,14 @@ else fi # Build installer .exe - cd "$PROJECT_ROOT/Installer/win" + cd "$PROJECT_ROOT/installer/win" ISCC="/c/Program Files (x86)/Inno Setup 6/ISCC.exe" if [ ! -f "$ISCC" ]; then ISCC="/c/Program Files/Inno Setup 6/ISCC.exe" fi - "$ISCC" "$PROJECT_ROOT/Installer/win/${PLUGIN}.iss" + "$ISCC" "$PROJECT_ROOT/installer/win/${PLUGIN}.iss" - EXE_OUT="$PROJECT_ROOT/Installer/win/bin/${PLUGIN}.exe" + EXE_OUT="$PROJECT_ROOT/installer/win/bin/${PLUGIN}.exe" # Sign installer if [ "$WIN_SIGN" = "1" ]; then diff --git a/Installer/win/Wavetable.iss b/Installer/win/Wavetable.iss index 133a24a..1aa5ae1 100644 --- a/Installer/win/Wavetable.iss +++ b/Installer/win/Wavetable.iss @@ -72,7 +72,7 @@ Source: "bin\VST3\Wavetable.vst3\*"; DestDir: "{commoncf64}\VST3\Wavetable.vst3\ Source: "bin\CLAP\Wavetable.clap"; DestDir: "{commoncf64}\CLAP"; Flags: ignoreversion overwritereadonly; Components: clap ; Factory content (Wavetables, Presets) → C:\ProgramData\SocaLabs\Wavetable\ -; Presets are flattened by Installer/build.sh into Installer/_flat_presets/. +; Presets are flattened by installer/build.sh into installer/_flat_presets/. Source: "..\_flat_presets\*.xml"; DestDir: "{commonappdata}\SocaLabs\Wavetable\Presets\"; Flags: ignoreversion; Components: resources Source: "..\..\plugin\Resources\WavetablesFLAC\*.wt2048"; DestDir: "{commonappdata}\SocaLabs\Wavetable\Wavetables\"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: resources diff --git a/README.md b/README.md index 1a3feb1..7c380c5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A 2 oscillator wavetable synthesizer with flexible modulation options. -![Screenshot](Screenshots/Screenshot1.png) +![Screenshot](screenshots/Screenshot1.png) [Download](https://github.com/FigBug/Wavetable/releases) | [Product Page](https://socalabs.com/synths/Wavetable/) @@ -48,22 +48,300 @@ A 2 oscillator wavetable synthesizer with flexible modulation options. - VST3 - VST2 (requires VST2 SDK) - AU (macOS) +- CLAP - LV2 - Standalone -## Building +## System Requirements -Requirements: -- CMake 3.16+ -- C++20 compatible compiler +- macOS 10.13 or later +- Windows 10 or later +- Linux (Ubuntu 20.04 or compatible) + +--- + +## Building on macOS (ARM64 / Apple Silicon) + +### Prerequisites + +- Xcode (with Command Line Tools) +- CMake 3.24+ (`brew install cmake`) +- Git + +### Clone & Build ```bash git clone --recursive https://github.com/FigBug/Wavetable.git cd Wavetable -cmake -B build -cmake --build build --config Release + +# Configure (generates Xcode project, universal arm64 + x86_64) +cmake --preset xcode + +# Build Release +cmake --build --preset xcode --config Release ``` +Build products are in `Builds/xcode/Wavetable_artefacts/Release/`: + +| Format | Path | +|--------|------| +| Standalone | `Standalone/Wavetable.app` | +| VST | `VST/Wavetable.vst` | +| VST3 | `VST3/Wavetable.vst3` | +| AU | `AU/Wavetable.component` | +| CLAP | `CLAP/Wavetable.clap` | + +### Install via Installer (.pkg) + +Build the signed/notarized installer (or unsigned for local use): + +```bash +./installer/build.sh +# Output: installer/macOS/bin/Wavetable.pkg +``` + +Open `Wavetable.pkg` and follow the installer. It installs: + +| Component | Install Location | +|-----------|-----------------| +| VST | `/Library/Audio/Plug-Ins/VST/` | +| VST3 | `/Library/Audio/Plug-Ins/VST3/` | +| AU | `/Library/Audio/Plug-Ins/Components/` | +| CLAP | `/Library/Audio/Plug-Ins/CLAP/` | +| Factory wavetables & presets | `/Library/Audio/Presets/SocaLabs/Wavetable/` | + +### Install Manually (no installer) + +Copy the built bundles to the system plugin directories: + +```bash +# AU (Logic Pro, GarageBand) +cp -R Builds/xcode/Wavetable_artefacts/Release/AU/Wavetable.component \ + ~/Library/Audio/Plug-Ins/Components/ + +# VST3 (Ableton Live, Reaper, Bitwig, etc.) +cp -R Builds/xcode/Wavetable_artefacts/Release/VST3/Wavetable.vst3 \ + ~/Library/Audio/Plug-Ins/VST3/ + +# CLAP (Ableton Live 12+, Bitwig, Reaper) +cp -R Builds/xcode/Wavetable_artefacts/Release/CLAP/Wavetable.clap \ + ~/Library/Audio/Plug-Ins/CLAP/ + +# VST (legacy) +cp -R Builds/xcode/Wavetable_artefacts/Release/VST/Wavetable.vst \ + ~/Library/Audio/Plug-Ins/VST/ +``` + +Install factory wavetables and presets: + +```bash +mkdir -p ~/Library/Audio/Presets/SocaLabs/Wavetable +cp -R plugin/Resources/WavetablesFLAC \ + ~/Library/Audio/Presets/SocaLabs/Wavetable/Wavetables + +# Presets must be flattened (subdirectories are not scanned by the plugin) +find plugin/Resources/Presets -name "*.xml" -exec \ + cp {} ~/Library/Audio/Presets/SocaLabs/Wavetable/ \; +``` + +After copying, rescan plugins in your DAW. For AU, you may need to log out and back in, or run: + +```bash +killall -9 AudioComponentRegistrar +``` + +--- + +## Parameter Reference + +### Oscillators + +Two identical wavetable oscillators provide the main sound source. + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Enable | On/Off | Enable or disable the oscillator | +| Wavetable | - | Select from built-in wavetables or load custom WAV files | +| Tune | -36 to +36 semitones | Coarse pitch adjustment | +| Fine | -100 to +100 cents | Fine pitch adjustment | +| Level | -100 to 0 dB | Oscillator volume | +| Pos | 0-100% | Wavetable position - morphs through the wavetable frames | +| Pan | -100% to +100% | Stereo panning | +| Formant | -1.0 to +1.0 | Formant shifting for tonal variation | +| Bend | -1.0 to +1.0 | Pitch bend modulation amount | +| Voices | 1-8 | Number of unison voices | +| Detune | 0-0.5 | Pitch spread between unison voices (enabled when Voices > 1) | +| Spread | -100% to +100% | Stereo spread of unison voices (enabled when Voices > 1) | +| Retrig | On/Off | Retrigger oscillator phase on each new note | + +**Tip:** Drag on the wavetable display to adjust the position in real-time. + +### Sub-Oscillator + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Enable | On/Off | Enable or disable the sub-oscillator | +| Wave | Sine, Triangle, Saw Up, Pulse 50%, Pulse 25%, Pulse 12% | Waveform selection | +| Tune | -36 to +36 semitones | Pitch adjustment | +| Level | -100 to 0 dB | Volume | +| Pan | -100% to +100% | Stereo panning | +| Retrig | On/Off | Retrigger phase on new notes | + +### Noise Generator + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Enable | On/Off | Enable or disable noise | +| Type | White, Pink | Noise color | +| Level | -100 to 0 dB | Volume | +| Pan | -100% to +100% | Stereo panning | + +### Filter + +Multi-mode filter with envelope control and key/velocity tracking. + +**Filter Types:** LP 12, LP 24, HP 12, HP 24, BP 12, BP 24, NT 12, NT 24 + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Enable | On/Off | Enable or disable the filter | +| Type | See above | Filter type selection | +| Frequency | 20 Hz - 20 kHz | Cutoff frequency | +| Resonance | 0-100% | Filter resonance/Q | +| Key | 0-100% | Keyboard tracking amount | +| Velocity | 0-100% | Velocity to filter frequency modulation | +| Amount | -1.0 to +1.0 | Filter envelope modulation depth | + +**Filter Envelope:** + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Attack | 0-60 seconds | Attack time | +| Decay | 0-60 seconds | Decay time | +| Sustain | 0-100% | Sustain level | +| Release | 0-60 seconds | Release time | +| Retrig | On/Off | Retrigger envelope on new notes | + +**Filter Routing:** Use the routing buttons (WT1, WT2, Sub, Noise) to select which sound sources are processed by the filter. + +### Amplitude Envelope + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Attack | 0-60 seconds | Attack time | +| Decay | 0-60 seconds | Decay time | +| Sustain | 0-100% | Sustain level | +| Release | 0-60 seconds | Release time | +| Velocity | 0-100% | Velocity sensitivity | +| Retrig | On/Off | Retrigger on new notes (mono mode with glide only) | + +### LFOs + +Three independent LFOs with multiple waveforms. + +**Waveforms:** None, Sine, Triangle, Saw Up, Saw Down, Square, Square+, Sample & Hold, Noise, Step Up (3/4/8 steps), Step Down (3/4/8 steps), Pyramid (3/5/9 steps) + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Enable | On/Off | Enable or disable the LFO | +| Wave | See above | Waveform selection | +| Sync | On/Off | Sync to host tempo | +| Rate | 0-50 Hz | LFO speed (when Sync is off) | +| Beat | Note values | LFO speed (when Sync is on) | +| Depth | -1.0 to +1.0 | Modulation amount | +| Phase | -1.0 to +1.0 | Starting phase offset | +| Offset | -1.0 to +1.0 | DC offset/center bias | +| Fade | -60 to +60 seconds | Fade in (positive) or fade out (negative) time | +| Delay | 0-60 seconds | Delay before LFO starts | +| Retrig | On/Off | Retrigger phase on new notes | + +### Modulation Envelopes + +Three independent ADSR envelopes for modulation. + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Enable | On/Off | Enable or disable the envelope | +| Attack | 0-60 seconds | Attack time | +| Decay | 0-60 seconds | Decay time | +| Sustain | 0-100% | Sustain level | +| Release | 0-60 seconds | Release time | +| Retrig | On/Off | Retrigger on new notes | + +### Step LFO + +A 32-step sequencer for rhythmic modulation. + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Enable | On/Off | Enable or disable | +| Beat | Note values | Step clock speed (tempo-synced) | +| Length | 2-32 steps | Number of active steps | +| Retrig | On/Off | Retrigger sequence on new notes | +| Steps 1-32 | -1.0 to +1.0 | Individual step values | + +### Modulation Matrix + +The mod matrix routes any modulation source to any parameter with flexible depth, curve shaping, and polarity controls. + +**Source types:** Single ring = mono (global), double ring = poly (per-voice). + +**MIDI sources:** Pitch Bend (mono), Note Number (poly), Velocity (poly), CC 1-120 (mono) + +**MPE sources (when enabled):** Pressure (poly), Timbre (poly), Pitch Bend (poly) + +**Internal sources:** LFO 1-3 poly/mono, Step LFO poly/mono, Filter Envelope, Mod Envelopes 1-3 + +**Assigning modulation:** +1. **Drag and Drop** - Drag a source icon from the mod source list onto any knob +2. **Learn Mode** - Click a source icon, then click a knob to assign + +**Matrix panel controls:** Enable toggle, depth slider, bipolar button, curve button, delete button. + +**Polarity:** Unipolar (0 to 1) or Bipolar (-1 to +1). + +**Curves:** Linear, Quadratic (In/Out/In-Out), Sine (In/Out/In-Out), Exponential (In/Out/In-Out), plus inverted versions of all. + +### Effects + +Effects can be reordered by dragging. + +**Gate:** Beat, Length (2-16 steps), Attack, Release, L/R step pattern + +**Chorus:** Delay (0.1-30 ms), Rate (0.1-10 Hz), Depth (0.1-20 ms), Width, Mix + +**Distortion:** Simple (Amount), Bitcrusher (Rate/Rez/Hard/Mix), Fire Amp (Gain/Tone/Output/Mix), Grind Amp (Gain/Tone/Output/Mix) + +**Delay:** Sync, Time/Beat, Feedback, Crossfeed, Mix + +**Reverb:** Size, Decay, Lowpass, Damping, Predelay, Mix + +### Global Settings + +| Parameter | Range | Description | +|-----------|-------|-------------| +| Level | -100 to 0 dB | Master output volume | +| Voices | 2-40 | Maximum polyphony | +| Mono | On/Off | Monophonic mode | +| Glide | Off, Glissando, Portamento | Pitch glide mode | +| Glide Time | 0.001-20 seconds | Glide duration | +| Legato | On/Off | Legato mode (mono only) | +| Pitch Bend | 0-48 semitones | MIDI pitch bend range | +| MPE | On/Off | Enable MPE support | + +--- + +## Tips & Tricks + +1. **Rich Pads:** Use both oscillators with different wavetables, slight detune, and long filter envelope +2. **Punchy Basses:** Enable the sub-oscillator, use LP24 filter with short decay envelope +3. **Movement:** Modulate wavetable position with an LFO for evolving textures +4. **Rhythmic Effects:** Use the Step LFO or Gate effect for pulsing sounds +5. **Expression:** Enable MPE and map pressure/timbre to filter cutoff and wavetable position +6. **Layering:** Route oscillators differently through the filter for complex timbres + +--- + ## License The synth is BSD licensed. However, it depends on JUCE. To use in a commercial application, you must have a JUCE license. Wavetables have their own license. diff --git a/modules/MTS-ESP b/modules/MTS-ESP deleted file mode 160000 index 2d7c013..0000000 --- a/modules/MTS-ESP +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2d7c013ebf4a076c35811e62293e8f819d053a91 diff --git a/modules/clap-juce-extensions b/modules/clap-juce-extensions deleted file mode 160000 index 26bab6b..0000000 --- a/modules/clap-juce-extensions +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 26bab6be8c428ba9537fdd2fd80d2dbb07dd9164 diff --git a/modules/gin b/modules/gin deleted file mode 160000 index 414fecf..0000000 --- a/modules/gin +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 414fecf9c28e72a9a5a4ac188f0fc6ef2e83eb2a diff --git a/modules/juce b/modules/juce deleted file mode 160000 index f8f8864..0000000 --- a/modules/juce +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f8f8864172464b9adf9eba6101e1f784838d1597 diff --git a/modules/melatonin_inspector b/modules/melatonin_inspector deleted file mode 160000 index d0e42b8..0000000 --- a/modules/melatonin_inspector +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d0e42b81bb7b747b0b7b51a993366a1f46ea3a55 diff --git a/modules/plugin_sdk b/modules/plugin_sdk deleted file mode 160000 index bcbef19..0000000 --- a/modules/plugin_sdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bcbef199f4dd78b883aebd6477cc104dad850e1b diff --git a/plugin/Source/PluginEditor.cpp b/plugin/Source/PluginEditor.cpp index 565ac4c..aa3f50e 100644 --- a/plugin/Source/PluginEditor.cpp +++ b/plugin/Source/PluginEditor.cpp @@ -102,5 +102,5 @@ void WavetableAudioProcessorEditor::addMenuItems (juce::PopupMenu& m) m.addSeparator(); - m.addItem ("Manual", [] { juce::URL ("https://github.com/FigBug/Wavetable/blob/master/Manual.md").launchInDefaultBrowser(); }); + m.addItem ("Manual", [] { juce::URL ("https://github.com/FigBug/Wavetable/blob/master/README.md").launchInDefaultBrowser(); }); }