Safety fixes, random voice generator, resizable UI, 4-op sysex import#517
Open
wellsst wants to merge 9 commits intoasb2m10:masterfrom
Open
Safety fixes, random voice generator, resizable UI, 4-op sysex import#517wellsst wants to merge 9 commits intoasb2m10:masterfrom
wellsst wants to merge 9 commits intoasb2m10:masterfrom
Conversation
- Add missing return after null file error in sendSysexCartridge (crash) - Mask algorithm index to 0-31 range in dx7note init/update (OOB crash) - Change sysex offset from uint8 to int to prevent truncation (wrong memory write) - Guard PluginFx::process against zero-length buffers (crash in some DAWs) - Add default case to filter switch to prevent uninitialized variable - Clamp shift amounts in Exp2::lookup and Freqlut::lookup (undefined behavior) - Null-terminate opSwitch after strncpy (buffer overread) - Add null check for InputStream in setupStartupCart (null deref) - Remove memcpy that overwrote normalized sysex data (dead code / data corruption) - Clamp portamento_cc loaded from XML to 0-127 (OOB array access) - Guard pitchStep division against zero and out-of-range values (division by zero) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add RND button to GlobalEditor between STORE and the program selector - Implement randomizeVoice() that generates musically-biased random DX7 patches - Operator frequencies use harmonically useful ratios (0,1,2,3,4,5,6,7,8,10,12,16) - Envelope shapes favor pad-like characteristics: slower decay, high sustain levels - Pitch EG held flat to prevent unwanted pitch shifts - LFO kept subtle: low pitch/amp depth, slow speed, favors sine/triangle waveforms - Feedback capped at 0-4 to avoid harsh distortion - Random voice names generated as "RND-" + 6 random alphanumeric chars Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add ResizableCornerComponent for drag-to-resize - Scale UI proportionally using existing AffineTransform zoom mechanism - Maintain aspect ratio via ComponentBoundsConstrainer - Limit max size to fit screen height (prevents overflow on ultrawide monitors) - Minimum size is 50% of base, maximum fits available screen - Configure standalone window to respect constrainer - Zoom factor persists via existing preference system Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tion CI/Build fixes: - Fix script injection: quote github.ref in CI pipeline - Fix codesign typo: --stric -> --strict in macOS installer - Fix Windows CI: COPY_PLUGIN_AFTER_BUILD -> JUCE_COPY_PLUGIN_AFTER_BUILD - Remove obsolete MSVC int32_t/uint32_t typedefs (unnecessary since VS 2010+) - Remove deprecated OSMemoryBarrier() on macOS (unused with GCC fence fallback) - Remove #define snprintf _snprintf (unnecessary since VS 2015+) Header safety: - Add #pragma once to lfo.h, freqlut.h, sin.h, exp2.h Audio quality fix: - Fix EngineMkI compute_fb2/compute_fb3 gain interpolation: dgain for non-feedback operators was always zero (gain - gain = 0), causing zipper noise and clicks on fast envelopes with algorithms 4 and 6 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Automatically detects 4-op bulk sysex files (format number 0x04) and converts them to DX7-compatible 6-operator patches on load. Conversion details: - Maps 4-op algorithms 1-8 to DX7 algorithms 1,14,8,7,5,22,31,32 - Scales envelope rates from 4-op range (0-31) to DX7 range (0-99) - Converts DX100 frequency ratio indices (64-entry lookup table) to DX7 coarse + fine frequency parameters - Maps detune from 4-op range (0-6, center=3) to DX7 (0-14, center=7) - Sets DX7 operators 5 and 6 to silent (output level 0) - Preserves LFO, feedback, transpose, and voice names directly - Works with any .syx file containing the standard 4104-byte bulk format Tested with DX100 factory patches - loads and plays correctly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Thread safety: - Make vuSignal, forceRefreshUI, refreshVoice std::atomic to prevent data races between audio and UI threads (critical on ARM/Apple Silicon) - Move lastCCUsed.setValue() off audio thread: store to atomic pendingCCValue on audio thread, poll and forward to Value on UI timer (prevents deadlocks from JUCE Value listener callbacks on audio thread) - Use local float for VU meter loop, store once at end (avoids atomic operations per sample) Drag-and-drop: - Accept .syx files dropped onto main window (not just cart manager) - Works with both DX7 and 4-op sysex files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Persist zoom factor immediately when corner-drag resizing (savePreference) - Remove constrainer from standalone DocumentWindow — keep only on editor to prevent feedback loop where window title bar height caused progressive shrinking on each move Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Random patch history: - RND button now saves each generated patch to a 32-slot ring buffer - PREV button steps back through random patch history - Allows recalling previously generated sounds without losing them Async dialogs: - Convert all synchronous AlertWindow::showMessageBox calls to showMessageBoxAsync in PluginProcessor.cpp and PluginEditor.cpp - Prevents potential UI freezing and DAW deadlocks from blocking modal dialogs on the message thread (deprecated in JUCE 6+) - Two remaining synchronous dialogs (showOkCancelBox, showYesNoCancelBox) left for now as they require callback refactoring Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Keyboard shortcuts: - Ctrl+R: randomize voice (same as RND button) - Ctrl+Z: undo randomize (same as PREV button) Null safety fixes: - AlgoDisplay: initialize opStatus and algo to nullptr, guard access - ProgramListBox: initialize listener to nullptr - VUMeter: guard against null image pointer in paint() - OperatorEditor: null-check getParentComponent() before chaining - Env: initialize all members in constructor (staticcount_, level_, targetlevel_, rising_, ix_, inc_, down_) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
compute_fb2/compute_fb3was always zero, causing zipper noise on algorithms 4 and 6Details
Safety-Critical Fixes
returnafter null file errorPluginData.cppdx7note.ccuint8tointPluginProcessor.cppPluginFx::processagainst zero-length buffersPluginFx.cppdefaultcase to filter switchPluginFx.cppExp2::lookupandFreqlut::lookupexp2.h,freqlut.ccopSwitchafterstrncpyPluginData.cppsetupStartupCartPluginData.cppmemcpyoverwriting normalized sysex dataPluginData.cppportamento_ccfrom XML to 0-127PluginData.cpppitchStepdivision against zerodx7note.cc4-Op Import
Converts 4-op patches by mapping algorithms (1-8 → DX7 equivalents), scaling envelope rates (0-31 → 0-99), converting DX100 frequency ratio indices to DX7 coarse+fine, and silencing unused operators 5-6. Tested with DX100 factory patches.
Test plan
🤖 Generated with Claude Code