Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Freakout

Open, lossless JSON patch tools and direct transport discovery for the Arturia MiniFreak and MicroFreak. The installed command is freakout; the historical freak-patch and minifreak-patch command names remain as compatible aliases.

The project keeps device support honest and explicit:

  • MiniFreak: mature .mnfx parsing and writing plus independent Collage USB reads of the active patch and any of the 512 saved slots. One hundred fifty-eight named parameters have verified, read-back writes from JSON.
  • MicroFreak: USB discovery, firmware identification, preset and wavetable reads, guarded saved-preset writes, and arbitrary user-wavetable uploads are available. Preset and wavetable read/write plus the 128-slot sample-directory inventory and lossless sample-body download have an independent CoreMIDI backend. A firmware-5 bank scan found 107 self-named fields without brittle absolute offsets; 101 have bounded metadata-scaled, normalized, bipolar, signed-offset, or live-destination JSON values, while six internal/action fields remain explicitly raw-only. The firmware-owned full Init template is also readable directly as editable JSON.
  • Writes: MiniFreak active-buffer and occupied-slot edits are enabled only for verified fields. MicroFreak lossless JSON and wavetable writes require an explicit acknowledgement and use backup, stable preflight, exact readback, and automatic rollback on failure. Empty MicroFreak Init preset slots are refused because the upload protocol cannot recreate their empty representation.

This is an independent open-source project and is not affiliated with Arturia. See NOTICE.md for the clean-room provenance and redistribution boundary.

Install for development

python3 -m venv .venv
.venv/bin/pip install -e .

Independent MicroFreak preset and wavetable transport uses CoreMIDI through mido. The separately installed elektroid-cli remains an optional, proven compatibility backend. Elektroid is GPL-3.0; this MIT package invokes its command-line interface and does not incorporate its source code.

Discover connected devices

freak-patch devices
freak-patch capabilities
freak-patch json-schema > patch.schema.json

Example discovery output:

coremidi:Arturia MicroFreak: microfreak backend=direct connector=arturia-microfreak-sysex firmware=not probed
usb:1c75:0602:1: minifreak backend=direct connector=arturia-minifreak-collage-usb firmware=not probed

Direct discovery is bounded and read-only. It reports the actual patch bus: paired MIDI SysEx for MicroFreak and vendor-specific Collage USB for MiniFreak. Use freak-patch devices --backend elektroid for the optional compatibility inventory and its firmware identification.

Shared patch JSON

Every document declares its target and contains only that device's block:

{
  "schema_version": "arturia-freak-patch/1",
  "device": "microfreak",
  "metadata": {
    "name": "NervousKeys",
    "category": "Keys",
    "source_slot": 1
  },
  "shared": {},
  "microfreak": {
    "archive": {
      "version_tag": "174",
      "category_id": 2,
      "init": 0,
      "p1": 16
    },
    "decoded_parameters": {
      "filter.cutoff": 0.402417065950499
    },
    "parameter_evidence": {
      "filter.cutoff": {
        "status": "hardware_raw_rw_fw5_semantics_unconfirmed",
        "raw_value": 13186,
        "byte_offsets": [88, 93, 94],
        "flag_mask": 16,
        "encoding": "unsigned_15bit_normalized"
      }
    },
    "raw_payload_base64": "...",
    "decoded_parameter_support": "partial"
  }
}

MiniFreak documents use a minifreak block containing the complete normalized parameter dictionary and, optionally, a compact recipe. MicroFreak documents retain the complete raw payload and keep verified named parameters separate.

Convert files losslessly:

freak-patch to-json MyPatch.mnfx MyPatch.json
freak-patch to-json MyPatch.mfp MyPatch.json
freak-patch from-json MyPatch.json rebuilt.mfp
freak-patch from-json MyPatch.json rebuilt.mfpz

Plain .mfp/project-bank .mbp preset objects and official one-entry .mfpz containers share the same lossless core. .mfpz output uses the expected 0_preset archive member and can be converted back to JSON directly.

MIDI Control Center's observed MicroFreak project directory can also be round-tripped as one lossless, explicitly slotted JSON document:

freak-patch microfreak-bank-to-json /path/to/project bank.json
freak-patch microfreak-bank-from-json bank.json /path/to/restored-project
freak-patch microfreak-bank-to-json Factory6.mfprojz factory6.json
freak-patch microfreak-bank-from-json factory6.json Rebuilt.mfprojz

This models both the synchronized .mbp directory and the confirmed .mfprojz ZIP topology (project directory, bank directory, numbered preset objects). It preserves the opaque archive tag—observed values include 134, 174, numeric project identifiers, and DEVBUILD—plus the 18-bit characteristics field and raw 8-bit category field.

An extracted project generated by this tool was also accepted by MIDI Control Center 1.23.0's official library scanner: the project appeared as Codex Preset Probe, and its two generated slots were decoded as Carrytron and Comb-Me. The app's archive-picker path remains a separate pending UI check because its custom canvas does not expose automatable controls on macOS.

The characteristics are decoded by name in JSON (Acid, Aggressive, Ambient, …, Soundtrack) while the exact bit string remains alongside them. They can be updated without hand-editing the bitset:

freak-patch set-microfreak-characteristics patch.json tagged.json Ambient Soft

MicroFreak wavetables can be prepared as either plain .mfw or the official one-entry .mfwz container; both are accepted by guarded upload commands:

freak-patch wavetable prepare microfreak table.wav table.mfwz --name MyTable

Complete 16-slot Control Center wavetable directories also round-trip through lossless JSON. .mfwbz project/bank ZIP output is available for testing, but remains explicitly marked research until a generated archive is imported back into Control Center:

freak-patch microfreak-wavetable-bank-to-json /path/to/wave-bank waves.json
freak-patch microfreak-wavetable-bank-from-json waves.json Waves.mfwbz

Read a saved MicroFreak patch directly from the connected device:

freak-patch pull 1 42 patch-42.json
freak-patch push-microfreak 1 42 edited.json backups/slot-42.mfp \
  --i-understand-this-writes
freak-patch pull-microfreak-direct 42 patch-42-direct.json
freak-patch pull-microfreak-init-direct microfreak-init-template.json
freak-patch set-microfreak-json patch-42-direct.json filter.cutoff 0.5 edited.json
# Cross-engine edits must start from a preset whose VCO.Type layout supports
# the requested engine. Firmware-5 presets support all 22 engines.
freak-patch set-microfreak-json firmware-5-preset.json osc.type 20 scan-grains.json
freak-patch push-microfreak-direct 42 edited.json backups/slot-42-direct.mfp \
  --select-after-write --i-understand-this-writes
freak-patch select-microfreak-direct 42 \
  --i-understand-this-changes-live-buffer
freak-patch microfreak-globals-direct
freak-patch microfreak-globals-json-direct > microfreak-globals.json
freak-patch microfreak-global-codes-direct 2 19 20
freak-patch microfreak-global-write-probe keyboard.root_note 1 \
  --recovery-slot 320 --i-understand-this-changes-device-setting
freak-patch set-microfreak-global-direct keyboard.root_note 1 \
  backups/root-before.json --i-understand-this-changes-device-setting
freak-patch microfreak-samples-direct --occupied-only
freak-patch microfreak-sample-storage-direct
freak-patch microfreak-live-word-direct 0
freak-patch microfreak-live-table-direct > microfreak-live-table.json
freak-patch microfreak-live-structured-direct > microfreak-current-fields.json
freak-patch microfreak-current-overlay-json-direct 320 current-over-slot320.json
freak-patch microfreak-sequence-playback-direct sequence-playback.json \
  --source-slot 5 --recovery-slot 320 \
  --i-understand-this-temporarily-changes-clock-source
freak-patch microfreak-live-cc-probe filter.cutoff 49 0 \
  --recovery-slot 320 --i-understand-this-changes-live-buffer
freak-patch microfreak-live-word-write-probe 257 9546 \
  --recovery-slot 320 --i-understand-this-changes-live-buffer
freak-patch microfreak-live-record-write-probe 257 9546 \
  --recovery-slot 320 --i-understand-this-changes-live-buffer
freak-patch collect-microfreak-saved-live-direct saved-live.json \
  --recovery-slot 320 --i-understand-this-changes-live-buffer
python3 tools/analyze_microfreak_saved_live_corpus.py saved-live.json --json
freak-patch collect-microfreak-oscillator-types-direct oscillator-types.json \
  --recovery-slot 320 --i-understand-this-changes-live-buffer
python3 tools/analyze_microfreak_oscillator_type_corpus.py \
  oscillator-types.json --json
freak-patch collect-microfreak-oscillator-cc-direct oscillator-cc.json \
  --recovery-slot 320 --i-understand-this-changes-live-buffer
freak-patch microfreak-sample-download-direct 1 sample-1.raw
freak-patch push-microfreak-sample-direct 2 sample-1.raw \
  backups/sample-2-before.mfsample --name MySample \
  --i-understand-this-writes
freak-patch clear-microfreak-sample-direct 2 \
  backups/sample-2-before-clear.mfsample --i-understand-this-writes

The live-table command performs one read-only session across the complete firmware-bounded active synth object: 24 groups with 16 raw 16-bit words each. The JSON preserves every wire address, unsigned and signed interpretations, and the exact reply payload. Hardware has answered all 384 addresses. The 20 documented CC controls are semantically labeled; non-CC words remain open.

The structured live command adds the bulk saved/live correlation layer. A diversity optimizer selected 40 of the 320 saved presets to maximize variation across all 107 firmware-tagged fields; every preset was paired with all 384 live words and slot 320 restored exactly. Ninety-five varying tags matched live word vectors byte-for-byte. Ninety-two were initially unambiguous, while the three chord-offset tags covaried. One saved-preset sentinel mapped Kbd.Hold, Kbd.Root, Arp.Dice, and Seq.XiceRst to nine exact live aliases; a second raw sentinel separated all three chord offsets across six aliases. Independent operation-49 writes confirmed each newly mapped field and restored the complete table. Oscillator type is the separately proven normalized word 0000. One read now returns 100 named current fields (99 structured plus oscillator type), with no varying structured tag left ambiguous. Seven constant tags remain without live addresses. JSON classifies six as tentative UI-action placeholders and Gen.Panel as tentative legacy panel state, based on their names, groups, all-zero values across 320 saved presets, and absence from the live table. The normal interpreted editor refuses them; the explicit raw research editor still preserves access without claiming they are sound parameters. The non-word sequence body also remains explicitly unresolved rather than guessed.

The generic live-CC probe reads all 384 words, sends one documented CC, reads the complete table again, sends an explicit inverse CC, and requires an exact final comparison; it recalls the named recovery preset if the inverse is not exact. On firmware 5.0.0.36, cutoff CC 23 changed only its three known aliases (0101, 0F0E, 1008) and slot 320 restored every word. Hold CC 64 changed no operation-41 word and Hold-off reproduced the baseline directly. That negative result is retained: the documented performance CC is not assumed to be the saved tag Kbd.Hold; the latter was subsequently mapped through saved-preset activation and operation 49 at 010D/020A/0303.

For qualified current-state capture, microfreak-current-overlay-json-direct combines all 100 mapped operation-41 fields with a complete caller-selected saved-slot base. It explicitly distinguishes fields applied to that engine's tagged layout, live fields absent from the layout, and sequence/header bytes preserved from the saved base. It is intentionally labelled partial-current, not a lossless unsaved-current dump. A hardware cutoff-CC test changed only VCF.Cutoff; the overlay changed exactly its two unpacked saved-value bytes, then slot-320 recall restored all 384 live words exactly.

Global settings are a separate transport surface. The guarded operation-42 probe reads the original value with operation 43, writes the target, reads it back, compares the complete patch live table, writes the original value, and verifies both final states. Keyboard Root Note code 46 was proven 0 -> 1 -> 0; each operation-43 readback matched and no operation-41 word changed. The live JSON therefore records keyboard.root_note as a global counterpart to constant tag Kbd.Root, not as a fabricated live-word address.

The labeled global JSON combines Arturia's installed device description with firmware-5 setter bounds, without requiring either artifact at runtime. All 43 named global settings now have explicit allowed wire values. Thirty-four use device-description labels; nine hidden settings use the firmware's clamp domains and retain raw labels where units are unknown. The durable setter writes a JSON before-state backup and requires exact operation-43 target readback. A failed readback triggers an inverse write and independently verifies recovery. A second hardware probe proved hidden Automation Out code 23 from On -> Off -> On, with exact readback and no patch-table changes.

Oscillator type is decoded and edited through firmware 5's self-describing VCO.Type field, not the older fixed byte. A 320-preset hardware sweep proved that its metadata-scaled integer matches live word 0000 for every preset and restored slot 320 with no live-table differences. The sweep observed engine indices 1 through 17 in the connected saved bank. A separate complete CC 9 sweep then activated all 22 firmware engines, read the expected normalized engine value back from live word 0000, and restored all 384 live words exactly. This hardware-proves WaveUser, Sample, Scan Grains, Cloud Grains, and Hit Grains at runtime indices 18 through 22 even though they were absent from that saved bank.

Firmware-generation layout is an explicit boundary. Historical presets have a VCO.Type.metadata maximum below 22 and cannot safely be migrated merely by changing that byte: a guarded attempt produced a different engine and was restored. Start an edit targeting engines 18 through 22 from a genuine firmware-5 preset. Arturia's installed New Presets 5.0 library supplies such payloads with a 22-engine, 110-field layout. A guarded edit of one of those payloads from Sample to Scan Grains was written to slot 320, read back exactly over the wire, selected with live word 0000 = 29788, and then restored to the original preset with zero differences across the live table. The .mfp archive wrapper version is local file metadata and is normalized on device; wire-state verification therefore compares the transmitted header fields and all 4,672 payload bytes rather than that non-transmitted wrapper byte.

The write probe temporarily changes one hardware-correlated live word, reads all aliases back, and restores the complete table. Operation-40 request bytes must each be 7-bit clean; when the original value is not representable, the required recovery slot is recalled and all 384 words must match the baseline. No preset save/store command is sent.

The sample inventory is a read-only, lossless view of all 128 directory headers. It reports the name, byte length, memory address, checksum, device ID, and exact raw header. The download command uses the firmware's sequential 4 KiB read stream and writes the exact device bytes; a 384,000-byte hardware sample matched across complete reads before and after the upload experiment. The guarded uploader accepts raw mono 32 kHz PCM16LE, performs the allocation and header/body transactions, downloads the complete stored body independently, and compares its name, length, checksum, and every audio byte. A 384,000-byte copy of Ney was uploaded to empty slot 2 as CodexProbe, matched exactly, and was cleared back to empty; the neighboring slot-1 body retained its original SHA-256. Sample backups are lossless .mfsample recovery artifacts: the exact 28-byte directory header followed by the exact PCM body.

Direct selection sends bank-select plus program-change, so a guarded JSON write can be made active without pressing the preset encoder. MIDI does not acknowledge program changes; the command reports that distinction explicitly.

Firmware 5.0.0.36 also responds at reserved bank 4, program 0, beyond the four saved-preset banks. It returns a stable Init header plus a complete 4,672-byte body. A bounded test selected slot 320, read the pseudo-slot, changed the live cutoff through documented CC 23, read it again, and reselected slot 320; the header and every body byte remained identical. The Init command therefore labels this as a firmware template, not as the unsaved current patch.

The earlier live-buffer CC correlation experiment is still available for protocol research:

freak-patch live microfreak-sentinel work/cc-plan.json \
  --i-understand-this-changes-live-buffer
# This legacy experiment requires physically saving the selected test preset.
freak-patch pull-microfreak-direct 320 work/cc-after.json
freak-patch live analyze-microfreak-sentinel \
  work/cc-before.json work/cc-after.json work/cc-plan.json work/cc-analysis.json

This is no longer the primary MicroFreak mapping path. Firmware-5 preset bodies are self-describing after MIDI unpacking, so normal research can read all saved slots and edit tagged parameters without requiring a device-button press:

freak-patch set-microfreak-structured-value \
  patch-42-direct.json VCF.Cutoff 0.5 edited.json
freak-patch set-microfreak-sequence-note \
  patch-42-direct.json A 1 1 60 sequence-edited.json
freak-patch set-microfreak-sequence-velocity \
  patch-42-direct.json A 1 1 100 sequence-velocity-edited.json
freak-patch set-microfreak-sequence-status \
  patch-42-direct.json A 1 tie sequence-tie-edited.json
freak-patch set-microfreak-sequence-automation \
  patch-42-direct.json A 1 1 64 sequence-automation-edited.json
freak-patch set-microfreak-sequence-destination \
  patch-42-direct.json A 1 filter.cutoff sequence-destination-edited.json

Both 64-step Sequence A/B blocks are retained in JSON. The four note slots are editable; source-specific high-byte non-note tokens are shown separately as note_bytes and round-trip exactly. Four raw 0..127 velocities are editable. The four 8-bit automation values and their presence mask are also explicit and editable. Each pattern's following 18-byte trailer is retained losslessly. Its first four little-endian words are now exposed as the automation lanes' operation-41 destination addresses, with mapped parameter names and FFFF as unused. All 17 nonempty destination addresses in the connected 320-preset bank were already mapped live words. Hardware playback of MotivSeq then matched lanes 1..3 at 0101, 0102, and 0602 to outgoing cutoff CC 23, resonance CC 83, and envelope-decay CC 106 respectively. Sequence byte 12 is exposed as note_status: 0 = rest, 1 = trigger, and 2 = tie. The mapping was verified by MIDI-clock playback and the MicroFreak's own outgoing Note On/Off boundaries; note_event_code retains the exact raw byte. Trailer byte 8 is the per-pattern gate percentage: a guarded 50 to 10 sentinel moved Note Off from clock 4 to the Note On clock. Trailer byte 9 mirrors the Seq.Length value but is not authoritative; changing only it did not shorten playback, while changing the tagged field to its minimum produced an exact four-step loop. JSON now exposes the UI domains as Seq.GateLen = 10..90 and Seq.Length = 4..64, and the normal editor keeps both trailer mirrors synchronized. The final two bytes in each step and trailer bytes 10..17 remain raw-only.

Normal MIDI Control Center startup is not a current-patch reader. Two passive firmware-5 traces each fetched 512 preset headers plus the complete sample/wavetable inventory, but zero preset bodies or active edit buffers. The saved-slot backend is therefore the proven MicroFreak patch path today; the separate current-buffer command remains protocol research.

microfreak-sequence-playback-direct provides a behavioral partial-current fallback for the selected active pattern. It temporarily selects USB clock, sends Start/Clock plus a held transposition note, and records the MicroFreak's own outgoing notes, velocities, automation CCs, and clock-relative boundaries as JSON. With --source-slot, --recovery-slot is mandatory; the command recalls that recovery slot and requires all 384 live words to match the preflight baseline. Clock Source is backed up, restored, and read back in all successful captures. This is not labelled a lossless Sequence A/B object dump: inactive/raw bytes and selecting both patterns remain open.

The remaining firmware-backed SysEx work is tracked explicitly in docs/microfreak-firmware-notes.md and docs/transport-roadmap.md. All seven read-only operation-49/6 kind-0x13 status selectors now have raw hardware captures and a decoded JSON command:

freak-patch microfreak-status-records-direct status-records.json

The leading remaining avenues are caller analysis for kinds 0x1E and 0x18 and resolution of computed indirect dispatches that might reach the active Sequence A/B object. Operation 4C remains disabled pending readback/rollback proof, and operation 53 remains an unsafe static-only surface that must not be hardware-probed yet.

Adding --live-snapshot-every N samples operation 41 at exact external-clock boundaries. By default it reads all 384 words; repeated --live-field options restrict the trace to named fields and all their aliases for finer timing. A 96-clock hardware trace of MotivSeq captured 102 automation CCs while the targeted live words tracked three saved automation destinations. The aliases can differ slightly while smoothed motion is advancing because they are read serially; stable preset and recovery reads still agree exactly.

The direct MiniFreak Collage read transport is available with:

freak-patch pull-current active.json
freak-patch pull-minifreak 1 slot-1.json

The first command reads the active edit buffer. The second reads durable slot

  1. Those can differ even when they have the same preset name. MiniFreak V must be installed because its binary currently supplies the Collage protobuf schema, but MiniFreak V is not launched and does not perform the transfer.

One hundred fifty-eight exact corpus-mapped fields can be edited offline in a direct-read JSON document and written to the active buffer. Forty use compact session deltas; the other 118 use the activating whole-resource transaction. The command updates the signed 16-bit value and regenerates the payload checksum:

freak-patch set-minifreak-json active.json filter.cutoff 0.5 edited.json
freak-patch push-current edited.json backups/active-before.bin \
  --i-understand-this-writes
freak-patch push-slot edited-slot.json 256 backups/slot-256-before.bin \
  --i-understand-this-writes

The session-delta keys cover oscillator tuning/shape/volume, glide and bend range, the filter, envelopes, LFOs, macros, and voice controls. Mapped FX, keyboard, sequencer, and arpeggiator fields automatically use whole-resource activation. freak-patch capabilities minifreak reports the current boundary, while pull-current includes every key, byte offset, .mnfx name, encoding, session ID candidate, and live_session_write status in JSON. push-current refuses every byte difference outside the 158 mapped fields, backs up the current 3,328-byte buffer, selects session delta or resource store, and requires exact full-buffer readback. It automatically restores the backup on failure. A successful edit remains active-buffer-only; save it on the hardware if it should survive preset recall or power cycling.

Persistent writes to occupied MiniFreak slots are supported with a fresh raw backup, exact readback, and automatic restore on failure. Empty-slot creation is disabled: firmware 4.0.1 accepts an Init payload but its resource-remove operation returns an I/O error, so the original empty state cannot yet be restored programmatically.

Hardware JSON keeps each mapped normalized value beside its signed 16-bit raw value, byte offset, and encoding. The 3,328-byte payload is retained losslessly; checksum byte 4 is regenerated so the XOR of the complete payload is 0xff.

Bulk reverse-engineering tools avoid serial knob-by-knob work:

freak-patch sentinel generate presets/minifreak-default-base.mnfx work/sentinel
freak-patch sentinel collect-corpus /path/to/mnfx-exports work/corpus
freak-patch sentinel analyze-corpus work/corpus/corpus.json -o work/corpus/map.json
freak-patch sentinel verify-session-map work/corpus/session-backup.bin \
  --i-understand-this-writes

The corpus analyzer pairs uniquely named .mnfx exports with rearranged device slots, tests multiple numeric encodings, and ranks binary offsets. The session probe assigns unique sentinels to all mapped IDs in one shot, locates their actual offsets independently, and requires exact baseline restoration.

Change a live parameter using Arturia's documented CC surface:

freak-patch live controls minifreak
freak-patch live controls microfreak
freak-patch live set minifreak filter.cutoff 42

Live CC is explicitly separate from patch storage: it changes the active sound, does not save a slot, and provides no readback.

Wavetables

List and read MicroFreak tables without changing the device:

freak-patch wavetable list 1
freak-patch wavetable pull 1 1 ney.json

Prepare a MicroFreak upload artifact offline from an exact-format WAV:

freak-patch wavetable prepare microfreak table.wav table.mfw --name "My Table"

The WAV must be mono PCM16, 32 kHz, and exactly 8,192 samples: 32 cycles of 256 samples. Upload either the prepared .mfw or a lossless JSON pull:

freak-patch wavetable push 1 2 table.mfw backups/slot-2.mfw \
  --i-understand-this-writes
freak-patch push-microfreak-wavetable-direct 2 table.mfw backups/slot-2-direct.mfw \
  --i-understand-this-writes

Arbitrary upload to a previously empty slot is hardware-verified through both the compatibility and independent backends. A failed or mismatched write restores an occupied backup or clears a previously empty slot. The lower-level same-content transport probe remains available for diagnostics.

MiniFreak raw wavetable validation currently accepts the format observed by the open-source MiniFreak converter: 189 frames of 512 signed 24-bit samples. The Collage schema exposes wavetable resources and the device reports 32 fwt entries, but MiniFreak firmware 4.0.1 does not expose user wavetable import. No MiniFreak wavetable write command is enabled.

Existing MiniFreak recipe workflow

The original commands remain available:

freak-patch build recipe.json --base exported-init.mnfx -o patch.mnfx
freak-patch show patch.mnfx
freak-patch dump patch.mnfx
freak-patch diff a.mnfx b.mnfx

Use an Init preset exported from your own MiniFreak V installation as the base. Local .mnfx, .mfp, and wavetable exports are ignored by Git so vendor and personal preset data are not accidentally published.

Tests

PYTHONPATH=src python3 -m unittest discover -s tests -v

See Open-source landscape, Transport roadmap, and the evidence-ranked MicroFreak firmware notes. The separate firmware-to-SysEx analysis playbook records the reusable method and MiniFreak handoff breadcrumbs. The separate MIDI Control Center analysis records host-side framing, wavetable, and subcommand-dictionary findings. A parallel MiniFreak firmware research TODO tracks both analysis passes while keeping desktop and hardware claims apart.

About

Open lossless JSON patch tools and direct USB/MIDI transport for Arturia MiniFreak and MicroFreak

Resources

Contributing

Stars

15 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages