This page is read from MIDI Instrument Definitions, a Python library used in the author's other projects, in which every number is traced to a document its maker published. Its source is on GitHub.
Teenage engineering OP-1 field MIDI implementation
The MIDI implementation of the teenage engineering OP-1 field: what it answers to, and the 52 controls it offers, on firmware 1.7.0.
At a glance
- Firmware
- This page describes firmware 1.7.0.
- MIDI channel
- Any one of 1 to 16.
- Parts
- Tape track, 4 of them: on MIDI channels 1 to 4, taking controls.
Sound slot, 8 of them: on MIDI channels 1 to 8, taking controls. - Voices
- Not recorded.
- Note range
- Not recorded.
- Velocity
- Received.
- Aftertouch
- Not recorded.
- Pitch bend
- Not recorded.
- Program change
- Received, with 16 presets.
- MIDI clock
- Received.
- Start and stop
- Received.
- Control change
- 52 controls, in the tables below.
- NRPN
- Not recorded.
- System exclusive
- Not recorded.
Controls
In the order the definition gives them, by part and group. Under each control is the name a program calls it by, once pymidiinstrumentdefs.load("teenage_engineering/op_1_field") has loaded them.
On the base MIDI channel
MIDI LFO
| Control | CC | Values |
|---|---|---|
MIDI LFO input 1midi_lfo_input_1 |
1 | 0-127 Received, never sent; The player chooses what it controls |
MIDI LFO input 2midi_lfo_input_2 |
2 | 0-127 Received, never sent; The player chooses what it controls |
MIDI LFO input 3midi_lfo_input_3 |
3 | 0-127 Received, never sent; The player chooses what it controls |
MIDI LFO input 4midi_lfo_input_4 |
4 | 0-127 Received, never sent; The player chooses what it controls |
Patch
| Control | CC | Values |
|---|---|---|
synth: parameter 1 / drum: active key pitchsynth_parameter_1 |
46 | 0-127 Received, never sent |
synth: parameter 2 / drum: active key loop insynth_parameter_2 |
47 | 0-127 Received, never sent |
synth: parameter 3 / drum: active key loop outsynth_parameter_3 |
48 | 0-127 Received, never sent |
synth: parameter 4 / drum: active key play modesynth_parameter_4 |
49 | 0-127 Received, never sent |
synth envelope: attack / drum envelope: attacksynth_envelope_attack |
50 | 0-127 Received, never sent |
synth envelope: decay / drum envelope: gainsynth_envelope_decay |
51 | 0-127 Received, never sent |
synth envelope: sustain / drum envelope: releasesynth_envelope_sustain |
52 | 0-127 Received, never sent |
synth envelope: release / drum envelope: smoothsynth_envelope_release |
53 | 0-127 Received, never sent |
randomize active patchrandomize_active_patch |
62 | 64-127 triggeredReceived, never sent |
reset active patchreset_active_patch |
63 | 64-127 triggeredReceived, never sent |
Patch FX
| Control | CC | Values |
|---|---|---|
patch fx parameter 1patch_fx_parameter_1 |
54 | 0-127 Received, never sent |
patch fx parameter 2patch_fx_parameter_2 |
55 | 0-127 Received, never sent |
patch fx parameter 3patch_fx_parameter_3 |
56 | 0-127 Received, never sent |
patch fx parameter 4patch_fx_parameter_4 |
57 | 0-127 Received, never sent |
Patch LFO
| Control | CC | Values |
|---|---|---|
patch lfo parameter 1patch_lfo_parameter_1 |
58 | 0-127 Received, never sent |
patch lfo parameter 2patch_lfo_parameter_2 |
59 | 0-127 Received, never sent |
patch lfo parameter 3patch_lfo_parameter_3 |
60 | 0-127 Received, never sent |
patch lfo parameter 4patch_lfo_parameter_4 |
61 | 0-127 Received, never sent |
Master FX
| Control | CC | Values |
|---|---|---|
master fx parameter 1master_fx_parameter_1 |
70 | 0-127 Received, never sent |
master fx parameter 2master_fx_parameter_2 |
71 | 0-127 Received, never sent |
master fx parameter 3master_fx_parameter_3 |
72 | 0-127 Received, never sent |
master fx parameter 4master_fx_parameter_4 |
73 | 0-127 Received, never sent |
Master compressor
| Control | CC | Values |
|---|---|---|
master compressor parameter 1master_compressor_parameter_1 |
74 | 0-127 Received, never sent |
master compressor parameter 2master_compressor_parameter_2 |
75 | 0-127 Received, never sent |
master compressor parameter 3master_compressor_parameter_3 |
76 | 0-127 Received, never sent |
master compressor parameter 4master_compressor_parameter_4 |
77 | 0-127 Received, never sent |
Master EQ
| Control | CC | Values |
|---|---|---|
master eq lowmaster_eq_low |
90 | 0-127 Received, never sent |
master eq midmaster_eq_mid |
91 | 0-127 Received, never sent |
master eq highmaster_eq_high |
92 | 0-127 Received, never sent |
Tape
| Control | CC | Values |
|---|---|---|
tape record leveltape_record_level |
78 | 0-127 Received, never sent |
tape: previous bartape_previous_bar |
82 | 64-127 triggeredReceived, never sent |
tape: next bartape_next_bar |
83 | 64-127 triggeredReceived, never sent |
tape: jump to starttape_jump_to_start |
84 | 64-127 triggeredReceived, never sent |
tape: jump to endtape_jump_to_end |
85 | 64-127 triggeredReceived, never sent |
tape: set loop intape_set_loop_in |
86 | 64-127 triggeredReceived, never sent |
tape: set loop outtape_set_loop_out |
87 | 64-127 triggeredReceived, never sent |
tape: toggle looptape_toggle_loop |
88 | 64-127 triggeredReceived, never sent |
tape: stoptape_stop |
104 | 64-127 triggeredReceived, never sent |
tape: playtape_play |
105 | 64-127 triggeredReceived, never sent |
Tempo
| Control | CC | Values |
|---|---|---|
tempotempo |
80 | 0-5 bpm_40_to_50, 6-120 bpm_52_to_166, 121-127 bpm_168_to_180Received, never sent |
metronome levelmetronome_level |
81 | 0-127 Received, never sent |
Performance
| Control | CC | Values |
|---|---|---|
sustain pedalsustain_pedal |
64 | 64-127 downReceived, never sent |
octaveoctave |
79 | 0-63 down, 64-127 upReceived, never sent |
Sound selection
| Control | CC | Values |
|---|---|---|
mode selectmode_select |
93 | 0-63 synth, 64-127 drumReceived, never sent |
Tape track
Mixer
| Control | CC | Values |
|---|---|---|
mixer volumemixer_volume |
7 | 0-127 Received, never sent |
mixer mutemixer_mute |
9 | 64-127 mutedReceived, never sent |
mixer panmixer_pan |
10 | 0-127 Received, never sent |
Sound slot
Sound selection
| Control | CC | Values |
|---|---|---|
sound slot selectsound_slot_select |
102 | 64-127 triggeredReceived, never sent |
Where these facts come from
Source documents
- OP–1 field guide - teenage engineering, v.1.7.0, its user manual, read on 5 October 2026 (the file read).
- OP-1 field user guide, firmware 1.7.0 (REV 10), dated 29 April 2026, its user manual, read on 5 October 2026 (the file read).
- OP-1 field user guide, firmware 1.6.0 (REV 9), dated 15 December 2025, its user manual, read on 5 October 2026 (the file read).
How they were read
The OP-1 field guide, in the two forms teenage engineering publishes it: a web page at teenage.engineering/guides/op-1, whose version is v.1.7.0, and a PDF whose metadata titles it OP-1 field user guide firmware 1.7.0 (REV 10), 78 pages, created 2026-04-29. Neither is complete and the page offers the PDF as though it were the same document.
THE MIDI REFERENCE IS THE PAGE'S AND THE PDF HAS NOTHING LIKE IT. Two tables - nine incoming message rows and 38 control change rows giving 49 controller numbers - and the word "incoming" appears nowhere in either PDF edition. The four controllers the midi LFO answers to run the other way: they are in the PDF's prose and in no table. So both documents are cited, and 52 controls come out of them.
THE TABLE IS READ STRUCTURALLY, NOT OFF THE RENDERED TEXT. Each row of the page is a div carrying four cell divs, one per column, so the page states where its columns are - the same principle as a drawn rule in a PDF. The rendered text flattens that to one value a line, where a function cell wrapping onto two lines and a value cell split around a ≥ glyph are indistinguishable from a new column. Notes/4602_extract_op_1_field.py reads the grid.
THE PAGE CARRIES TWO download as PDF LINKS AND ONE OF THEM IS INVISIBLE. The 1.7.0 guide is behind those words; the 1.6.0 guide is behind a bare line break in the next span, so a reader sees one link and anything reading the markup finds two, with nothing in the link text to tell them apart. Choosing the PDF on the page is therefore a coin toss between two firmwares, and both are saved beside this definition so that which was read is not a guess.
WHAT THE PREVIOUS EDITION IS FOR. It is cited for one fact and quoted for one sentence. Its MIDI settings page is fuller than the current edition's: "set the incoming and outgoing midi channel" (previous p. 61) against the 1.7.0 guide's one-line summary, which names only the outgoing one. So the newer document is the less precise about which directions that setting reaches, and the older one is what says there is an incoming channel at all. It also names "such as modwheel and other midi cc data" (previous p. 61) where the newer says only "other messages" (pdf p. 60), which is the only place either document connects a controller number to the setting that filters it.
CLOCK IS RECORDED AS RECEIVED AND THE PROSE ALMOST SAYS MORE. The incoming table lists clock as a sync input, and the tempo chapter describes four sync modes of which "midi sync - external clock sync" (pdf p. 52) is the one that reads a MIDI clock: "external clock is detected and sync is received" (pdf p. 53). What it does not quite say is that a MIDI clock is sent. "ochre means master clock is sent, orange means midi sync is received" (pdf p. 52) is about the tape-speed link display, "beat match - internal master clock" (pdf p. 52) names a mode without naming a port, and free tempo is where "internal clock is used, no sync is sent or received" (pdf p. 53) - which implies sending happens elsewhere without saying over what. The one sync output the document describes plainly is PO sync, an audio pulse on the headphone jack rather than a MIDI message. So receives is as far as the documents go.
TRANSPORT IS RECEIVED IN FULL - start, continue, stop and song position, each with a row of its own, the last one to "set sequencer position" (guide). The settings page mentions an "origin for song position pointer" (pdf p. 60), which reads like a transmitting side; it is one phrase against a table headed incoming, so it is recorded here and not in the field.
PROGRAM CHANGE REACHES SIXTEEN SLOTS THROUGH ONE RANGE OF NUMBERS: "load synth/drum slot" (guide), where "0–7 = synth slots 1–8" (guide) and 8 to 15 are the drum slots. So the sixteen are eight synth and eight drum, which is why presets is 16 and not 8.
ONE CONTROLLER IS LEFT OUT AND THE REASON IS THE STANDARD RATHER THAN THE DOCUMENT. The table's last row is CC 123, all notes off, which is a channel mode message: it means the same on every instrument that has one, so PyMidiDefs says it and a definition does not.
AND THE MAKER'S OWN APPARATUS HAS THREE SMALL FAULTS, recorded and not tidied. Two different footnotes are both printed as a single asterisk - one about channels 1 to 4 being tape tracks, one about what synth and drum mode do to eight of the rows - so the mark cannot tell a reader which it means. One row reads 1 -4 where its three siblings read 1 - 4. And two numbers are skipped between neighbours that are both used: CC 89 sits between 88 and 90, and CC 103 between 102 and 104, with nothing anywhere saying whether they do nothing or were missed. The table's other gaps are wide ones and need no explaining.
THE SIBLING IS ALREADY HERE AND IS A DIFFERENT INSTRUMENT. teenage_engineering/op_1 is the original OP-1, whose guide is at the /original path because this maker reused the older instrument's address for the newer one: teenage.engineering/guides/op-1 serves this instrument. That definition carries no controls at all - its guide publishes no controller list - so the successor publishes a full MIDI reference where the original published none. Which is which was established from the page titles rather than from the addresses.
AND THE FOUR MIDI LFO INPUTS ARE THE ONE THING BOTH INSTRUMENTS HAVE, RECORDED TWO WAYS. The original's four incoming control changes are routed to a destination the player picks, and its maker publishes no number for any of them. That definition records control_change: learned and no controls. This instrument has the same four inputs and a factory map of 48 besides, and the PDF of its guide gives the four their numbers, 1 to 4 (pdf p. 31). learned says there are controller numbers that are the owner's and that no file can list, and it may stand beside the numbers a maker fixes. This instrument has no such number: every number below is the maker's, and what the player chooses for four of them is the destination. So the four are carried as controls, which is true of their numbers - the maker fixes 1 to 4 and the player fixes only what they reach - each says assignment: slot, and control_change is left unset. Whether the original's learned holds by that reading is an open question: its four may be fixed numbers that nobody printed. Until 2026-10-13 the reason given here was that one word could not say both of a whole instrument, which the format has since settled the other way. This was the first definition here to carry both a factory map and numbers whose destination the player picks.