feat: add MIDI harmonizer for chord-aware melody processing#4313
Draft
ogabrielluiz wants to merge 8 commits intoSynthstromAudible:mainfrom
Draft
feat: add MIDI harmonizer for chord-aware melody processing#4313ogabrielluiz wants to merge 8 commits intoSynthstromAudible:mainfrom
ogabrielluiz wants to merge 8 commits intoSynthstromAudible:mainfrom
Conversation
Contributor
Collaborator
|
Hey just fyi this PR will need to be rebased to the main branch as the community branch is now obsolete. Thanks! |
Add standalone harmonizer library that maps incoming MIDI melody notes to chord tones using configurable snap modes (Nearest, RoundDown, RoundUp, Root, Root5th), target tightness levels (ChordTones, Scale, Extensions, Loose), optional voice leading, diatonic intervals, and per-note probability. The engine is self-contained with no firmware dependencies beyond standard C++.
Wire the harmonizer engine into the Deluge firmware: - MidiInstrument processes melody notes through the harmonizer, applying chord-based harmonization with configurable probability, interval offsets, retrigger, and latch behavior - InstrumentClip stores per-clip HarmonizerSettings with XML serialization (read/write) and transpose clamping to [-24, 24] - PlaybackHandler resets harmonizer state on playback stop - Register MidiHarmonizer as a runtime feature setting
Add 10 menu item classes for the harmonizer submenu accessible from MIDI/CV clips: mode, tightness, interval, transpose, chord channel, probability, voice leading, retrigger, interval velocity, and latch. Each item includes null-guard safety checks and runtime feature gating. Register all harmonizer menu items in the sound editor, add l10n strings for both OLED and 7-segment displays, and wire up the submenu navigation.
Comprehensive CppUTest suite covering: - ChordState and ChannelState data structures - All 5 snap modes (Nearest, RoundDown, RoundUp, Root, Root5th) - All 4 target tightness levels (ChordTones, Scale, Extensions, Loose) - Voice leading behavior and diatonic interval computation - Multi-clip isolation, chord channel changes, mapping lifecycle - Boundary conditions (MIDI notes 0/127, empty chords, overflow) 86 tests, 254 checks, all passing.
Add comprehensive documentation for the MIDI harmonizer feature covering setup, snap modes, target tightness, voice leading, diatonic intervals, chord channel configuration, and all harmonizer parameters.
The ARM cross-compiler deduces conflicting types (long vs int) for std::clamp when mixing int32_t with integer literals. Use explicit std::clamp<int32_t> to resolve the ambiguity.
The generated g_english.cpp and g_seven_segment.cpp had 14 harmonizer strings that were missing from the source JSON files, causing the CI build to fail when the generator reproduced shorter files. Add the missing entries to both english.json and seven_segment.json and regenerate the cpp files.
08c33f4 to
97f3b45
Compare
97f3b45 to
a73bef3
Compare
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.
Adds a MIDI harmonizer that snaps melody notes to chord tones in real-time,
enabling chord-aware harmonization across MIDI/CV clips. A dedicated chord
channel feeds chord data while melody channels are harmonized according to
configurable rules — all per-clip with XML persistence.
Key Features
Usage
Architecture
The harmonizer engine (
midi_harmonizer.cpp/h) is a standalone library withno firmware dependencies beyond standard C++, making it independently testable.
mappings, and voice leading state
harmonizer_settings.h): lightweight POD configstored per-clip with XML serialization
MidiInstrumentintercepts note-on/off and routes throughthe harmonizer;
InstrumentCliphandles persistence;PlaybackHandlerresets state on stop
Functional Areas Affected
io/midi/midi_harmonizer.cpp/h,harmonizer_settings.hgui/menu_item/harmonizer/*.h(10 files)gui/ui/sound_editor.cpp/h,menus.cpp/hl10n/english.json,seven_segment.json,strings.h, generated filesmodel/instrument/midi_instrument.cppmodel/clip/instrument_clip.cpp/hplayback/playback_handler.cppmodel/settings/runtime_feature_settings.cpp/hTesting
leading, diatonic intervals, multi-clip isolation, chord channel switching,
mapping lifecycle, and MIDI boundary conditions
Test Plan