Maschine MK2
maschine-synth-editor
Mod

maschine-synth-editor

Rising67/100

ESP32-S3 firmware that turns a Native Instruments Maschine Mk2 into a MIDI editor/librarian for hardware synths

maschine-synth-editor is a mod for the Native Instruments Maschine MK2, by @elmokki. Open source under MIT, 1 star on GitHub.

forNative Instruments Maschine MK2·by@elmokki

Unclaimed. Is this yours? Sign in with GitHub as @elmokki to claim it.

Downloads
0
Star
1
Forks
0
Commits
72
Last commit
Get the source

No release files yet. Build from source.

MIT· elmokki/maschine-synth-editor·downloads come from the creator’s GitHub releases

72
Commits
0
Releases
72 commits and 0 releases in the last year
Activity · last 12 months

Maschine Mk2 → ESP32-S3 synth editor controller

Goal: drive a full-size Native Instruments Maschine Mk2 (the hardware controller) from an ESP32-S3 over USB host, to use as a programmer/editor controller for hardware synths: the Maschine's knobs, buttons and displays edit the synth over its DIN MIDI port (through the Maschine's own USB-MIDI interface), and the ESP32 keeps a patch library on its flash. The pads are a bonus (scales, chords).

Status

Protocol fully reverse-engineered and confirmed on real hardware, directly over raw hidraw (no USB packet capture needed at any point). See docs/PROTOCOL.md for the complete writeup: HID report layouts, the display/pad/button/encoder byte-level details, every quirk and gotcha hit along the way (and why), and what's still unverified.

Critical path for the synth-editor use case:

  • ✅ Encoders (main + 8 touch-encoders above the displays)
  • ✅ Buttons (all 56 bits mapped; 48 confirmed by name)
  • ✅ Displays (pixel-level control + text rendering via Pillow; one hardware display quirk and one unfixable ghosting limitation documented)
  • ✅ 5-pin DIN MIDI — works directly via the device's standard USB-MIDI class interface, no custom protocol needed at all for this part (big simplification: no DIN jacks needed on the ESP32 board)
  • ✅ Pads + pad LEDs (secondary priority, but needed first anyway to find/fix a few protocol- level bugs that also affected other things)

ESP32-S3 firmware (src/, PlatformIO + ESP-IDF USB host library): Maschine enumerates and is powered from the board's OTG port; pads + pad LEDs, all buttons and encoders, both displays (bitmap fonts) and DIN MIDI in/out all work on real hardware. A few full-speed-only quirks had to be worked around — see docs/ESP32_NOTES.md.

Synths

Group buttons A-H pick a section (functions of the synth), the main encoder pages through it, the eight encoders and display buttons above the displays edit the values. Every editor has a patch library on LittleFS (browse, store, categories), a patch overview (Grid button), envelope/vector pictures, and a tutorial for the synth's special controls (Shift + Control). Reading back from the unit needs its MIDI OUT on the Maschine's MIDI IN (see below for what needs it); editing and playing never do.

Name lists (Note Repeat): fills both displays with names in small text, 24 a page. With Browse off and a wave knob on the page (Wavestation PATCH and SEQ) it lists the waves; otherwise, or with Browse on, the library's patches. The main encoder moves the cursor (Shift: a page), Enter picks (loads the patch / sets the wave) and closes the list, Browse off closes the patch list, a Group button goes back to the editor. In a name list the knob of the value itself (WAVE, TONE, ...) moves the cursor too. Lists exist for: Wavestation PATCH / SEQ waves, Wavestation PERF patches, JV-880 waves (PATCH, RHYTHM) and performance-part patches, D-110 PCM waves (TONE), tones (PATCH, RHYTHM key) and U-110 tones.

Setup (Control): the synth's own settings (four a page; with more, the main encoder turns the page, e.g. the Wavestation PATCH's IMPORT is on page 2) and the global ones (MIDI thru, LED brightness, NOTES IN, HANG NOTES). The IMPORT button sits above the IMPORT setting and is pressed twice. The header shows only the patch's name (its place in the instrument, e.g. R3:31, while browsing).

SynthEditorState
Plugiator MiniMax, B4000 (organ)all parameters, factory presetsdone
Volca FM2DX7 voices (all operators, algorithm picture), .syx importdone
Roland D-110TONE, PATCH, RHYTHM; read from the unit, write to the unitdone
Roland JV-880PATCH (4 tones), RHYTHM (61 keys), PERF (8 parts); expansion boards, read, IMPORT, store to the unitdone
Roland U-110one patch = 6 parts, read, IMPORT, store to the unitdone
Korg Wavestation SRPATCH (4 waves, vector mix, SysEx parameters); IMPORT of RAM/ROM/card banks and store into RAM banks (bank dumps)done
Korg Wavestation SRPERF (8 parts: patch, level, bus, ranges, tuning, play settings; effects: routing, mixes, both effect units with all 55 types); IMPORT, read, storedone
Korg Wavestation SRSEQ (wave sequences: up to 255 steps with wave, level, duration, crossfade, tuning; start, loop; copy / paste of steps, length, reverse and whole-sequence changes in group C); IMPORT of the banks' sequences, read, Grid overview, listeningdone: REC > TO SR writes into any RAM 1-3 sequence (see the warning below)

What needs the MIDI IN cable

The unit's MIDI OUT goes to the Maschine's MIDI IN only for reading back:

EditorNeeds the cable forWorks without it
Plugiator MiniMax, B4000; Volca FM2nothingeverything
Roland D-110, JV-880, U-110 (all entries)Auto (read the sound from the unit), IMPORTediting, playing, storing into the unit (direct writes); the remembered patch is loaded when the unit does not answer
Korg Wavestation SR PATCH, PERF, SEQAuto, IMPORT, and storing into the SR's memory (REC > TO SR, on all three entries): the SR only takes whole banks, so the bank is read first, one item replaced and the bank sent backediting and sending to the edit buffer (PATCH, PERF), playing, listening to a SEQ sequence, saving to the library
Sequencer (Scene), arpeggiatornote entry from a keyboard on the MIDI IN; the arpeggiator playing notes from the MIDI INeverything else

In short: without the cable the Roland editors (and the Plugiator and Volca ones) only lose the knowledge of what is in the unit; storing into it still works. The Wavestation PATCH and PERF entries are live editors (the sound goes to the SR's edit buffer), but cannot store into the SR or read from it; SEQ then only edits the library, because a sequence has no edit buffer to hear or keep an edit in.

Also in: the SR's Auto buttons (PATCH, PERF, SEQ) show a loading screen while they wait for the unit; pad scales and chords, optional pad aftertouch (Pad Mode: OFF, channel or polyphonic; only a hard press, raw 3000-4000, counts), pad pressure settings (Pad Mode page 2 - my values: min 700, max 2600, linear, aftertouch 3000-3600, the main encoder turns the page: MIN PRESS = where a pad counts as hit, MAX PRESS = where velocity is 127, CURVE linear / soft / hard, AT START / AT END = where aftertouch starts and is 127, and a column with the last pad's measurements: HIT, VEL, NOW, AT), MIDI thru, LED brightness, a Volume button for the synths that have one.

Sequencer

The Scene button opens a step sequencer that runs on top of every synth (it keeps playing when you leave the screen; Play starts and stops it from anywhere, and Scene pulses while it plays).

  • 8 tracks (Group A-H, each its own colour), up to 128 steps each, 16th notes; every track has its own length, MIDI channel, transpose and mute. A step has a note, velocity, gate, ratchet (1-8 hits) and a tie (continues the previous note; a different note is played legato).
  • The 16 pads are the shown page's steps; Step arrows turn the page. Rec switches between WRITE (pads switch steps on and off) and SELECT (pads only pick the step to edit). The NOTE knob moves along the scale chosen on the Pad Mode screen, and a new step starts from the previous step's note or the scale's root.
  • Control inside Scene opens the sequencer's settings: a MIDI IN channel on which incoming notes fill the picked step (pitch, velocity, and how long the key is held becomes the gate or a chain of ties).
  • Pattern opens 16 pattern slots on the pads, stored on LittleFS and saved automatically; a playing sequencer switches at the end of the longest track. Erase + a pad clears a slot, Erase + a Group button clears a track.
  • Shift + Rec is live recording: the pads play notes (on the Pad Mode scale, on the picked track's channel) and, while the sequencer plays, are written into the nearest 16th. How long a pad is held becomes the gate or a chain of ties, a new note replaces the step, and Erase held clears the steps the playhead passes. Rec leaves it, leaving Scene turns it off. One note a step, so a chord keeps its last note.
  • Pattern then Erase + a pad clears a pattern slot (or the whole pattern in use) and says so on the display.
  • Control also has CLOCK OUT (off by default): MIDI clock, Start and Stop to the DIN OUT while the sequencer plays, so the Volcas and drum machines follow its tempo (Restart sends Start again).
  • The engine runs in its own task on core 1, clocked by a hardware timer.
  • Shift + Control in Scene opens the sequencer's own tutorial.

Not yet: chords (polyphony), chaining patterns into scenes, MIDI clock in.

Arpeggiator

Solo switches the arpeggiator on and off on every screen (the LED is lit when it is on); Shift + Solo opens its settings. The notes of the held pads - and, with it on, notes arriving on the MIDI IN on the pad channel - are played one after another on the pad channel instead of together. It starts on the grid of the chosen rate: in time with the sequencer while that plays, otherwise on a clock of its own at the same tempo (the main encoder sets it on the settings screen).

  • Knobs: MODE (UP, DOWN, UP-DOWN, DOWN-UP, ORDER = the order the pads were pressed, RANDOM, CHORD = all held notes at once), RATE (1/4 to 1/32, with triplets), GATE, OCTAVES (1-4), SWING, VELOCITY (HELD = the pad's own, or a fixed one), LATCH (the notes stay after the pads are released until a new group is played), RETRIG (a new pad starts the pattern over).
  • A picture above the knobs shows one pass of the pattern as bars (a bar's height is its pitch), the note playing now filled; the held notes are listed beside it. Chord pads arpeggiate as chords; Mute (panic) clears everything.
  • Shift + Control on the settings screen opens its tutorial. The settings are saved; the arpeggiator itself starts off.
  • Tested on the unit except the MIDI IN notes.

Warning, Wavestation SR SEQ: the SR has no edit buffer for wave sequences, so REC > TO SR replaces the chosen sequence in the unit for good. Any sequence of RAM 1-3 can be chosen (encoder 8 on the Store screen, which starts at RAM 3, sequence 31, the last one; the slot's name as of the last IMPORT is shown). The whole bank is kept as it was in /lfs/ws/backup/seq00 - seq02 first (one file a bank, overwritten by the next write to that bank). The Store screen opens at the slot the sequence came from, and AUTO reads that slot back (READ BANK / READ SEQ are used only for a sequence that is not in the SR yet). The modulation amount is written too (the unit's own rule, see docs/WAVESTATION.md).

Planned

  • Sequencer: chords (polyphony), pattern chaining, MIDI clock in.
  • Arpeggiator: test with a keyboard on the MIDI IN.
  • Korg NS5R (documents are in the local reference/).
  • Volca Drum.
  • Overviews for the RHYTHM entries (JV-880, D-110).
  • Scene: saved multi-synth scenes (patterns of the sequencer plus each synth's patch).
  • A MIDI joystick of the author's own (vector control for the Wavestation, CC 16/17 through a splitter).

Layout

  • docs/PROTOCOL.md — the protocol reference. Read this first.
  • docs/ESP32_NOTES.md — firmware notes, step by step, incl. the full-speed workarounds.
  • src/ — ESP32-S3 firmware (main.c HID side, display.c, midi.c, generated fonts.c, editor.c the generic editor, synth_*.c one driver per synth entry, sequencer.c / seq_ui.c the step sequencer, arp.c / arp_ui.c the arpeggiator; CLAUDE.md has the code map).
  • docs/WAVESTATION.md — notes on the Wavestation SR's SysEx and data.
  • tools/ws_fx_gen.py — generates src/ws_fx_data.c (the Wavestation effect tables) from the local Edisyn clone.
  • tools/gen_font.py — regenerates src/fonts.c/fonts.h from a TTF.
  • tools/*_import.py, tools/*_names.py — build the patch libraries and name lists in data/ for each synth.
  • tools/plugiator_import.py — Plugiator parameter tables + factory presets from the Plug-in Manager's files (see docs/ESP32_NOTES.md, Step 5).
  • reference/, data/ — local only (gitignored): third-party manuals and factory presets.
  • pc_reference/ — small self-contained Python scripts (not copied from any third-party project) used to find and verify the protocol, and to keep verifying it quickly without needing to flash firmware. Point them at your Maschine Mk2's /dev/hidrawN node.

Why PC-first

Everything was prototyped and verified on a PC first (pc_reference/) because iteration there is seconds, not a flash-and-reboot cycle. The plan is to port the now-confirmed protocol knowledge in docs/PROTOCOL.md directly to ESP32-S3 firmware (ESP-IDF's native USB host library: a separate, simple USB-MIDI code path for the DIN MIDI side, and a HID code path for everything else), rather than re-discovering any of this on-device.

Credit / prior art

No third-party code is vendored in this repo. While reverse-engineering, these existing open-source projects were read (not copied) for cross-reference, and are credited in detail in docs/PROTOCOL.md along with exactly which of their assumptions turned out to be wrong for this unit and had to be re-verified:

Third-party material (not in this repository)

reference/ (manuals, factory banks, notes) and data/ (the LittleFS image: patch libraries, name lists) are local only. The tools/*_import.py and *_names.py scripts build data/ from them; they expect reference/edisyn/ (a clone of eclab/edisyn, Apache 2.0, whose parameter tables and SysEx layouts several drivers follow) and the synths' own manuals and patch lists, which you have to supply yourself. Fonts in tools/fonts/ are Spleen (BSD-2, see tools/fonts/LICENSE.spleen).

Licence: MIT (see LICENSE).