Analog Keys: patterns, sounds, NRPN and parameter locks
Mapping versioned binary objects while preserving unknown bytes and separating live observations from firmware correlations.
Technical research Β· edition 2 Β· reviewed 2026-10-24

Prismal Labs native editor research fixture, 10 October 2026. This is an application test image, not a photograph of the hardware. View full-size image
What we found
The important Analog Keys finding is that there are several independent numbering systems. MIDI channels select a configured destination; an NRPN namespace and parameter select a control; a pattern lock stores a physical parameter ID; a sound or kit stores bytes at version-specific offsets. Some numbers coincide, but they are not interchangeable.
We consolidated 298 named manual assignments (227 NRPN and 71 CC rows), a separate 227-entry firmware physical-ID map, and calibrated sound/FX/CV fields. The downloadable tables retain every row. The examples below show how to use them without losing fine precision, editing the wrong track, or corrupting a lock pool.
Channels, NRPN addresses and precision
Use configured track channels for synth 1β4, FX and CV. AUTO addresses the currently selected track, so it is unsuitable for unattended fixed-track control. Performance has its own channel; program receive/send have dedicated channel settings or AUTO. Display channels 1β16 correspond to status-byte low nibble 0β15. OFF channels should not be treated as channels 1 or 16.
USB input/output routing, note receive, CC/NRPN receive, encoder destination, keyboard destination, mute destination, clock receive/send, transport receive/send and program receive/send settings affect what is accepted or emitted. Encoder parameter-output mode selects CC versus NRPN; knob movement is not guaranteed to produce both. Keyboard external/multimap/polyphony settings also affect notes. The research left these settings unchanged.
Program changes select project patterns, not arbitrary +Drive sounds/projects. Map program 0β127 to A01βH16 using bank=program//16, pattern=program%16+1. Change timing depends on the sequencer/pattern-change mode; a sent program number does not by itself prove the new pattern is active. The retained app uses enabled outgoing program notifications and working-pattern readback to establish active state. Exact immediate/queued-change edge cases were not swept here.
The NRPN address is (namespace << 7) | parameter. Send the following CC sequence on the same channel and serialize it against other NRPN senders:
The 63, 62 and 26 above are hexadecimal controller bytes (99,98,38 decimal). No request ID or explicit ACK exists. Parameter output/readback or a working-kit dump provides confirmation. The existing sender emits all four controls; behavior of running status, partial address selection, relative data increment/decrement, RPN null selection and interleaved multiple writers was not verified.
| Namespace / parameter | Destination | Data significance |
|---|---|---|
0 / 0β9 | Performance AβJ | MSB value 0β127; LSB unused in manual |
1 / synth table | Synth track | MSB plus LSB for fine-capable fields; many coarse/enum fields use only MSB |
1 / 100 | Track level | LSB value 0β127, MSB unused in manual |
1 / 101 | Track mute | LSB value 0β127, MSB unused in manual |
2 / FX table | FX track | Namespace 2, not the synth parameter of the same number |
3 / CV table | CV track | Namespace 3, output configuration determines useful units |
For normal fine-capable parameters, MIDI's logical value is 128*value_msb+value_lsb; the existing working-sound BE word measurement maps it to 256*value_msb + 2*value_lsb. Thus one NRPN fine step is 1/128 in coarse units, while the stored Q8.8 word can preserve 1/256. Depth fields have a different scale/bias, and enum controls may clamp or normalize values. Do not apply one linear display range to every field.
Read/edit ranges and value kinds are in sound_fields.json, fx_fields.json and cv_fields.json. Existing NRPN calibration includes accepted/normalized enum behavior; a successful write is not evidence that an out-of-domain number is a new enum.
Evidence: Elektron/KeysSequencer/research/usb-api/midi-control.md.
Address coverage and the complete maps
The consolidated 298-row CSV and JSON (data/midi_parameters.json, retained research) include every named CC/NRPN row in the local manual appendix, including address bytes and MSB/LSB data ranges. They are authoritative over compact range summaries below. Blank encoder rows were not turned into named parameters. Two named PWM-speed rows whose local PDF text lost digit 8 were restored from the OSC page grid to NRPN 8 and 28 and explicitly flagged extracted_digit_repaired; the existing firmware map independently includes those NRPNs.
| Scope | NRPN named rows | CC named rows |
|---|---|---|
| Synth pages | 91 | 57 |
| FX | 56 | 0 in this appendix |
| CV | 68 | 0 in this appendix |
| Performance | 10 | 10 |
| Track level/mute | 2 | 2 |
| Modwheel/breath | β | 2 |
| Total | 227 | 71 |
The older manual omits some firmware-defined controls, including synth Noise Colour. The separate firmware map records NRPN associations where established. Absence from a manual table is not proof of unsupported behavior, and a blank numerical position is not permission to assign an invented control.
nrpn_address_coverage.json accounts for all 128 numerical addresses in each of namespaces 0β3, labelling named manual, additional firmware-mapped and unassigned positions without inventing reserved-command semantics.
Synth namespace 1:
| Page | NRPN LSBs | Named controls / unused positions |
|---|---|---|
| OSC1 | 0,2β9 | Tune; detune, keytrack, level, waveform, sub oscillator, pulse width, PWM speed/depth; 1 blank in manual |
| Noise | 10,12,14 | Sample/hold, fade, level; colour 13 is established in firmware map rather than this manual table |
| OSC2 | 20,22β29 | OSC1 counterparts; 21 blank in manual |
| Oscillator common | 30β39 | AM1, sync mode/amount, bend, slide, AM2, note sync, vibrato fade/speed/depth |
| Filters | 40β49 | Filter1 frequency/resonance, overdrive, keytrack/envelope, filter2 frequency/resonance/type/keytrack/envelope |
| Amp | 50β59 | Attack/decay/sustain/release/shape, chorus/delay/reverb sends, pan, volume |
| Filter envelope | 60β69 | ADSR/shape/gate, destination A/depth A, destination B/depth B |
| Envelope 2 | 70β79 | Corresponding envelope controls |
| LFO1 / LFO2 | 80β89 / 90β99 | Speed/multiplier/fade/phase/mode/waveform, destinations and depths A/B |
FX namespace 2: external inputs 0β9; chorus 40β49; delay 50,51,53β59; reverb 60β63,65,66,69; LFO1 80β89; LFO2 90β99. Blank delay 52 and reverb 64,67,68 are not named controls in this appendix.
CV namespace 3: CV A 0β6, CV B 20β26, CV C 40β46, CV D 50β56; envelope1 60β69; envelope2 70β79; LFO1 80β89; LFO2 90β99. Each output page covers coarse/fine tuning, value, clock, source, bend and slide. Sending a voltage-related parameter is not equivalent to selecting/calibrating CV output type.
Common CCs:
| Function | CC MSB / LSB, decimal |
|---|---|
| Modwheel / breath | 1/33; 2/34 |
| Performance AβJ | 3,4,8,9,11,64,65,66,67,68; no paired LSB |
| OSC1/OSC2 tune | 16/48; 17/49 |
| Filter1/Filter2 frequency | 18/50; 19/51 |
| EnvelopeF depth A/B | 20/52; 21/53 |
| Envelope2 depth A/B | 22/54; 23/55 |
| LFO1 depth A/B | 24/56; 25/57 |
| LFO2 depth A/B | 26/58; 27/59 |
| Pan / volume / slide | 10; 7; 5 |
| Track mute / level | 94; 95 |
| Synth coarse parameters | Full named assignments in the CSV, including 69β93 and 102β119 |
CCs 64β68 are performance controls on the configured performance channel. Do not assume every use of CC64 is a global sustain command independent of routing. Note hold/pedal behavior and receive thresholds were not measured here.
Evidence: Elektron/KeysSequencer/research/usb-api/midi-control.md.
Physical IDs are not NRPN numbers
physical_parameter_ids.csv contains all 227 discovered synth/FX/CV IDs, pages, labels, NRPN associations where known, lockability and firmware descriptor offsets. This count includes modulation-only and None destinations; it does not equal 227 writable parameter-lock controls.
| Namespace selected by pattern track | Defined IDs/entries | Selectable lock controls |
|---|---|---|
| Synth tracks 0β3 | 101, IDs 00β64 | 93 |
| FX track 4 | 57 entries, including None at 49 | 56 |
| CV track 5 | 69 entries, including None at 44 | 68 |
Synth IDs 12β14 are combined/modulation pitch targets, 2C combined filter frequency, 60 None, 61β63 frequency modulation targets; these are excluded from creating locks. 64 is Noise Colour. IDs 65β7F have no synth descriptor in the inspected OS 1.52/1.56 images. Preserve unexpected incoming IDs without treating them as additional unnamed controls.
For example synth tune's physical ID 0 corresponds to NRPN 0, while synth keytrack has physical ID 4 and NRPN 3. CV coarse tuning uses separate output IDs (00 A, 01 B), while CV A fine tuning is ID 04, value 08, clock 0C, source 10. These examples show why equality cannot be assumed even when some controls happen to match.
Matching OS 1.52 has a 56-byte descriptor array at file offset 0x1568DC. Record fields are kind +0, physical ID +4, long-name pointer +40, group +44, short-name +48, page +52. ROM base is 0x40000400; helper 0x70E2 reads the physical-ID field and lock setter 0x97234 uses that conversion. Prior static analysis compared OS 1.56 and found the same 227 names/pages. That agreement supports these facts, not wholesale compatibility of all dump fields. Existing firmware-map evidence (../../Ableton_Core/Keys_Manager/Reference/firmware-lock-map.txt, retained research), official matching firmware.
Evidence: Elektron/KeysSequencer/research/usb-api/midi-control.md.
Sound values and the depth-step correction
Offsets here refer to a decoded 350-byte sound, never the packed .syx file.
| Offset | Bytes | Meaning |
|---|---|---|
| 0 | 4 | Magic BE EF BA BA |
| 4 | 4 | BE version 5 or 6 |
| 8 | 4 | Tags/flags; retain unless separately decoded |
| 12 | 16 | Name, NUL padded |
| Parameter offsets | 1 or 2 | 96 field records with page, kind, range and center |
| Other bytes | β | Preserve; no exhaustive current-version field assignment |
The historical community sound table uses absolute packed-frame addresses. Convert a non-flag byte address a using r=a-10, then decoded_offset=(r//8)*7 + (r%8)-1; reject r%8==0 because that addresses the MSB flag byte. This distinction explains why a packed address cannot be used directly as a sound or kit offset. Original sound-map primary source, labelled OS 1.40A.
Existing decoded representations include byte values, BE Q8.8 words and depth words. For word, value=u16/256-center; for depth, value=(u16-16384)/128; bytes use value=u8-center. Limits and enum domains differ from the seven-bit MIDI envelope range. The word/depth fields contain precision that raw seven-bit data-entry values alone cannot express.
The existing sound UI schema advertises 1/256 for depth fields, while its actual codec accepts increments of 1/128. The research table corrects the representable depth step to 1/128 and retains the original as source_ui_step; product code was not changed. FX/CV word fields instead use unbiased BE Q8.8 (u16/256); do not apply the synth depth bias to their stored words.
sound_enums.json preserves factual enum tables for waveform, sub oscillator, filter/envelope/LFO shapes, LFO multipliers/modes, destinations, tags and characters from that historical source. It is not a promise that every enum or sound-menu field stayed unchanged through OS 1.52. New enum assignments require firmware or calibration confirmation.
Evidence: Elektron/KeysSequencer/research/usb-api/sysex-and-payloads.md.
The versioned pattern and lock pool
All three local pattern layouts begin with BE version, then six tracks in order synth 1β4, FX, CV. Track base is 4 + track_index Γ stride; use 743/native-v6, 745/SysEx-v8 or 751/SysEx-v9. A track has 64 step slots regardless of active sequence length.
| Offset relative to track | Structure / interpretation |
|---|---|
| 0β127 | 64 BE u16 trig flags; low-byte bit 0 note, bit 1 trigless; bit 4 note slide, bit 5 parameter slide; other bits retained |
| 128 | 64 note bytes; FF uses default note |
| 192 | 64 velocity bytes; FF uses default velocity |
| 256 | 64 encoded note-length bytes; preserve nonlinear/enum meaning |
| 320 | 64 signed microtiming bytes; local edit range β23β¦23 |
| 384 | 64 trig-condition bytes; preserve unmapped condition codes |
| 448,449,450 | Default note, velocity, length |
| 454 | Per-track length in the confirmed advanced-mode path |
| 532,596,660 | Three 64-byte note/chord/arp offset lanes; FF absent, otherwise value minus 64 |
| Other track bytes | Arp, sound locks, note setup, flags and version-specific tail data not fully decoded by this reference |
Version 9 differs in track tail/flag semantics as well as stride. Preserve both bytes of every trig word and never recreate a trig word from only the recognized bits. Pattern scale/mode layouts also have version-specific confirmation limits.
Lock pool starts at 4 + 6 Γ stride, has 128 lanes Γ 66 bytes. Each lane: u8 physical_parameter_id, u8 track, then 64 coarse values. FF FF marks an unused lane; value FF means no lock at that step. A following 80 80 lane supplies 64 fine values in 128ths. Orphan fine lanes or duplicate (parameter, track) bases are ambiguous and should refuse edits. A fine lane consumes one of the same 128 physical lanes.
Physical IDs are selected from the synth/FX/CV firmware tables according to track. They are not NRPN LSB numbers, kit byte offsets or display ordinals. See midi-control.md (midi-control.md#physical-parameter-ids-and-locks, retained research) and the full 227-row map. Unknown incoming lanes should survive reads/exports without invented labels.
Footer begins at 4 + 6 Γ stride + 128 Γ 66: local parser reads BE master length at +0, mode at +6, scale at +7. Normal timing is confirmed for SysEx v8/v9 with mode 0, master 1β64 and scale 0β6. Advanced timing is confirmed for v8/mode 1, master 1β1024; per-track scale is at stride-2. Other cases remain unknown. Kit link, pattern slot metadata and unassigned footer bytes must be retained.
Evidence: Elektron/KeysSequencer/research/usb-api/sysex-and-payloads.md.
A worked control example
For synth filter-1 frequency, namespace 1 and parameter 40 give NRPN address 1*128+40 = 168. If the configured synth track is display channel 3, its CC status is B2 (hex). A coarse value 64 with fine value 32 is sent as:
All bytes above are hexadecimal. The logical MIDI word is 128*64+32 = 8224; the measured normal working-sound word correspondence is 256*64+2*32 = 16448, or 64.25 before any field-specific center offset. This example assumes the destination channel has been configured accordingly; it is not a factory channel assignment. Track level/mute use the exceptional LSB rule, and depth fields use their own scale/bias.
For locks, allocate the physical ID from the appropriate track namespace. Synth keytrack illustrates the trap: its physical ID is 4, while its NRPN parameter is 3. Copying the NRPN LSB into the lock lane would address a different parameter.
Prior calibration and downloadable evidence
The existing NRPN report (../../Ableton_Core/Keys_Manager/NRPN_TEST_REPORT.json, retained research), FX report (../../Ableton_Core/Keys_Manager/FX_TEST_REPORT.json, retained research) and CV report (../../Ableton_Core/Keys_Manager/CV_TEST_REPORT.json, retained research) remain the record for prior parameter transactions. They report 99,56,68 passing parameter checks respectively; each also contains a working_kit_restored: true metadata record. This session consolidated those maps without replaying parameter writes. Source file hashes are in local_source_hashes.json (data/local_source_hashes.json, retained research).
Unverified control behavior includes all-notes-off/reset handling, poly pressure, full parameter enum edge cases, program-change scheduling under every mode, MIDI receive/output filters under other globals, multimap binary encoding, CV calibration fields and every front-panel action over private Overbridge messages. Those are recorded in coverage.md (coverage.md, retained research), not silently assigned a standard MIDI interpretation.
Additional complete maps: sound fields, FX fields, CV fields, sound enums, synth lock fields, FX lock fields, and CV lock fields.
Evidence: Elektron/KeysSequencer/research/usb-api/midi-control.md.
Applying the findings
Build a librarian around typed fields: address namespace, physical ID, stored offset, codec, representable step, enum domain and evidence version. Preserve unknown bytes. Reject ambiguous duplicate/orphan lock lanes instead of guessing. A coarse-plus-fine lock consumes two of the same 128 physical lanes, so capacity must be counted in lanes, not user-visible controls.
Confirm edits by parameter output or a working-buffer readback; NRPN itself has no explicit acknowledgement. Serialize four-CC sequences against other writers on the same channel. Keep a display value separate from its stored integer so round trips do not discard precision.
Limits and open questions
The prior reports record 99 synth, 56 FX and 68 CV passing checks with working-kit restoration; this publication did not rerun hardware writes. Some manual rows required documented extraction repair, and older manuals omit firmware-mapped Noise Colour. Unknown numerical positions remain unassigned. Version/length/stride gates are required before applying any binary offset.
Research illustrations

Prismal Labs hardware capture, 8 October 2026: decoded 122 by 32 monochrome LCD, enlarged in the retained research preview. View full-size image
Primary references
Research provenance
The methods and results above are drawn from these retained research records. Dates and product versions inside the article identify the scope of each experiment; publication review does not mean the hardware or numerical tests were rerun.
Elektron/KeysSequencer/research/usb-api/midi-control.mdβ SHA-256a84f079df6e1a2400d7be4ab47b111d5e7d69d3ea8e1764e4e14cacaec546a6dElektron/KeysSequencer/research/usb-api/sysex-and-payloads.mdβ SHA-256f1ff6b7704bbfddd2e5ca20d0ce1fc77c782d13067c2db913f5667e95f5e6204Elektron/KeysSequencer/research/usb-api/data/midi_parameters.csvβ SHA-256e483027f18facd64162a57035aa2285a63665afe454717958f1bf476851539ecElektron/KeysSequencer/research/usb-api/data/physical_parameter_ids.csvβ SHA-25694d253f8806ff8640e53e35bd676ce7b48c12d93ab87b9c6d04acaf8638c9c2cElektron/KeysSequencer/research/usb-api/data/nrpn_address_coverage.jsonβ SHA-256d2c9dc97d1d63b41c078162c2bc4957ce53777a7c2d7973db98cfd733bb2456fElektron/KeysSequencer/research/usb-api/data/sound_fields.jsonβ SHA-256fe3c965d573d18a8d0485837fc6a6b0a50ab7bcaed363adc1e9b298084bca3d6Elektron/KeysSequencer/research/usb-api/data/fx_fields.jsonβ SHA-256b1e6c2799c5b22ff92f0a2495aec0597f600ed38e0fee52ac5b892d2abc89088Elektron/KeysSequencer/research/usb-api/data/cv_fields.jsonβ SHA-256ad5c7170adea6bd5554fe4c80808cb6c25459d588764708b4a1bb12deb3f7889Elektron/KeysSequencer/research/usb-api/data/sound_enums.jsonβ SHA-256be5228fc9810828cba33910550cc425c073bb0f17e75895ff7366a21a99aba78Elektron/KeysSequencer/research/usb-api/data/lock_fields.jsonβ SHA-256214df0bc5a0a9ff05ee75406cb8a0c091999ba62f75ff233a29d0c37fe887446Elektron/KeysSequencer/research/usb-api/data/fx_lock_fields.jsonβ SHA-256e4b154cf21380386c0caf18d66dc6a11911c581c069cd6ff34209bcf98ecf471Elektron/KeysSequencer/research/usb-api/data/cv_lock_fields.jsonβ SHA-256d40a14e9cd5b8b537d1c51e3b814643356c0961b9d0b9c440c4a41c59c1ab48d
