Platform index / Digital mixing console
Yamaha QL1
A nine-processor console whose mixing DSPs have no instruction memory at all — the audio path is fixed-function silicon configured through a register file.
The load-bearing finding. The five YSS919C "DSP7" mixing chips expose a 512-word register file and no program port. This was proven not just from the pin tables but from absence: every region of the 64 MB flash is accounted for and there is no DSP7 program image anywhere in it.
Verdict. The mixing engine is closed by construction rather than by policy — there is no software on it to replace. The programmable surface is real but sits alongside the mix engine, not inside it.
Method
Three bases, deliberately kept apart. The silicon and firmware findings are static analysis of the V5.91 USB firmware update package, cross-referenced against the published service manual's LSI pin descriptions — no console was opened and none of it has been checked against a machine. The second basis arrived on 2026-08-01: a QL1 and a Rio3224-D2 on our own lab network, captured from a mirrored port, from which the head-amp control path between console and stagebox was decoded — and then confirmed by transmitting a message built from that decoding, which the stagebox accepted and acted on. Nothing measured on the network says anything about the silicon, and the bases are not mixed. The third is the console file: .CLF files written by QL Editor V5.8.1 running offline with no console attached, with the patch table and the name layout located by controlled diffs — change exactly one thing, save again, compare.
Artifacts examined
MQLP5_91.PGM— 27.5 MB main-CPU image (console application + GUI resource pack)QL-MD103.BIN— 110 KB channel-name display sub-MCU imageFWUpdate_QL1_v4020401_sw310.dnt— 4.7 MB Audinate Brooklyn II package- Service manual, LSI PIN DESCRIPTION section
QL Editor.app— Premium Rack plugins shipped as unstripped x86_64 dylibs- A port-mirrored capture of a QL1 paired to a Rio3224-D2 — pairing, patching, gain sweeps and phantom power on inputs 1–4, with 3,907 control messages in the 0.1 % of frames that are not Dante audio
- A second capture of the write test: twelve hand-built gain messages transmitted from a laptop on the same network, and the stagebox's own status broadcasts echoing the new values back
.CLFconsole files saved from QL Editor V5.8.1 offline — a baseline, two saves differing by a single patch point, and one differing by a single channel rename
No manufacturer firmware, binaries or documentation are redistributed here. Artifacts are referenced by name and version only. See the method and legal statement for the basis on which this analysis was performed and the boundaries it observes.
Hardware architecture
| Item | Finding | Confidence |
|---|---|---|
| Main CPU | Renesas R8A77240D500BG — an SH7724 (SH-4A, SH-Mobile R2R) at IC101 | Verified |
| Mixing DSP | 5 × Yamaha YSS919C-FZ "DSP7" (IC251/252/255/256/257). QL5 fits 7 | Verified |
| Effects DSP | 4 × Yamaha YSS910C-VZ "DSP6" (IC201–204) | Verified |
| Premium Rack DSP | Analog Devices ADSP-21369KBPZ-3A SHARC — JTAG header fitted on the board | Verified |
| Codec DSP | TI TMS320DA150PGE16D (C54x-class) at IC552 | Verified |
| FPGA | Altera Cyclone IV E EP4CE15F23C8N (IC152) — audio crossbar and master clock system | Verified |
| DSP7 interconnect | SIO00–SIO63 — 64 bidirectional serial lines, MCKS at 128 × Fs, own SDRAM per chip | Verified |
| Network | Marvell 88E6350R L2 switch, DM9000AEP MAC, KSZ8051RNL PHY | Verified |
| Converters | AK5385B ADC / AK4396 DAC / AK4125 SRC; CS8406 AES/EBU transmitter | Verified |
| Storage | NOR flash (AMD/Spansion command set, 16- and 32-bit bus variants), battery-backed SRAM for scenes, SDRAM | Verified |
| Panel MCUs | LPC1763 Cortex-M3, M38039-family 8-bit MCUs, HD6433683E H8/300H | Verified |
| Audio networking | Audinate Brooklyn II module over MSIOF | Verified |
Software architecture
| Item | Finding | Confidence |
|---|---|---|
| Operating system | Renesas HI7000/4-family µITRON 4.0 kernel. No Linux anywhere | Verified |
| Image load base | 0x8803BF80 — P1 space, so physical 0x0803BF80 = SDRAM + 0x3BF80. The image is placed in RAM by a bootloader not present in the .PGM | Verified |
| Code volume | ≈7 MB of SH-4A little-endian machine code; the remainder is GUI resources | Verified |
| Task model | ~130 named µITRON objects across kernel, panel bus, display, mix engine, Premium Rack, MIDI, Dante, network, L2 switch and remote control | Verified |
| Debug facilities | Live serial debug monitor (task/sema/flag/mbox/mpl/mbf commands) plus Hitachi DT10 trace instrumentation still present in shipping firmware | Verified |
| Plugin ABI | Premium Rack plugins export createPerseusPlugin_203 — the identical symbol appears in the console firmware (-sh4a-per) and in the macOS editor's dylibs (-mac-per) | Verified |
| Console plugin linkage | Statically linked into the main firmware image, not shipped as separate files | Verified |
| Head-amp control does not ride Dante's own control protocol | Gain, phantom power and metering between the console and its stagebox travel as a Yamaha-proprietary block tunnelled inside Audinate ConMon packets, identified by three ASCII bytes at the head of the block. Dante carries it the way it would carry any other vendor's ConMon payload; Audinate's own control protocol on UDP 4440 is used only for patching. An adapter that speaks nothing but Audinate's documented protocols will never see a gain change | Measured |
| Addressed by the wrong MAC | The block addresses devices by their Yamaha MAC, not their Dante MAC and not their IP — the console appears as 00:a0:de:e0:ce:f6 where its Dante interface is 00:1d:c1:17:ea:2c. Two NICs on the same console, and only one of them is the one the control path names. Broadcast-style messages use an all-ones destination | Measured |
| What the arrays carry | Head-amp gain is 32 × int16 big-endian centi-dB, confirmed by sweeping inputs 1, 2, 3 and 4 in isolation and watching exactly one array slot move each time; the sweep clamped at −6.00 dB, which is the Rio3224-D2's documented minimum. Phantom power is 32 × uint8 booleans, confirmed the same way, one slot per press. Input metering is 32 × uint8 broadcast by the stagebox at 31 Hz — 3,461 messages in 110 s — and its scale is not calibrated: no known signal was ever injected, so the mapping to dBFS is unknown and it must not be presented as a meter | Measured |
| On pairing, the console's state wins | At pairing the stagebox announced all 32 inputs at +36.00 dB; 60 ms later the console overwrote every channel with its own stored −6.00 dB, and the stagebox did not push back. Anything mirroring console state has to expect a full-array overwrite the moment a console connects, and must not read it as 32 individual user edits | Measured |
| Eight more arrays with known shape and unknown meaning | The same opcode carries further per-channel arrays whose element count, addressing and width are now evidence-backed — 32 × uint8 and 32 × int16 among them, answered in full during pairing. What is not known is what they mean, because no such parameter was touched while recording: every value observed is a resting default. Two of them rest at values that make a second gain array and an 80 Hz high-pass tempting. Neither was ever seen to move | Measured |
| Discovery is asymmetric | The console answers read-only Audinate queries from an arbitrary host, returning its Dante name, its Brooklyn II module and the Audinate control application it runs. The stagebox answers nothing on any of those ports — and accepts and acts on Yamaha control from the same host. Audinate-level queries are therefore not a reliable way to enumerate Yamaha stageboxes; mDNS finds both, under their Dante names | Measured |
| The console file is not the modern Yamaha container | CL and QL Editor ship no parameter descriptors at all, and a .CLF is not the #YAMAHA MBDF container the DM3, DM7 and TF share: it is flat binary, no compression and no archive, 117,508 bytes for a QL5 default state, and its header names the product and the editor build in the clear (QL [OSX, 5.8.1.27]). The file formats split exactly where the firmware does — this generation is a different architecture, and it writes a different kind of file | Verified |
| The input patch is one byte per channel, contiguous | Located by two controlled diffs in the offline editor: moving one channel to a Dante source changed two bytes in a 117 KB file, and moving a second channel eight further along changed a byte eight positions further on. One byte per channel, no stride, no indirection — the whole patch table is a flat run | Verified |
| Source encoding, exactly as the bytes have it | 0x01–0x40 are Dante 1–64; 0x41–0x48 are local inputs 1–8; 0xc1–0xd8 are local inputs 9–32. The split between 0x41–0x48 and 0xc1 upward, for what the console presents as one continuous range of 32 inputs, is not explained — it is recorded because it is what the file says, not because a formula was found. "Simplifying" it to a single base plus channel number is right for eight channels and wrong for twenty-four. The picker's other sources — slots, effects returns, playback and none — are unmapped | Verified |
| Channel names are stored four characters at a time | A name is not contiguous: the first four characters sit in one block and the next four 384 bytes further on, at 96 channels per block, across two blocks — so eight characters maximum, and the third block is different data entirely. Every default name on this console is exactly four characters (ch 1 … ch96), which means a contiguous four-byte read decodes every default file perfectly and truncates every name anyone would actually type | Verified |
Update path & security model
| Item | Finding | Confidence |
|---|---|---|
| Image signing | None found | Inferred |
| Encryption | None — the package is plainly structured and its components are directly readable | Verified |
| The head-amp control path has no authentication | It is multicast on the control network, carries no credential and no session, and is protected only by an additive checksum over the block — integrity with no authenticity in it, the same shape as this manufacturer's unsigned firmware packages. A message built to that rule and transmitted from an ordinary laptop on the same network was accepted and applied by the stagebox, which echoed the new gain back on its own status broadcast. The device never NAKs, so a refusal and a framing error look identical from outside. How such a message is constructed is deliberately not recorded here | Measured |
| The console file carries a checksum | Every edit moved one or two bytes near 0x010039 and moved them differently each time, with nothing else in a 117 KB file changing. That is a checksum: harmless for reading, and a hard blocker for ever writing a console file, since an assembled file with a stale value may simply be refused and there is no way to find out without a console. It has not been solved and nothing here attempts it. It sits a few bytes before an MMS marker — the namespace of the other Yamaha format — which is an observation and not a link | Verified |
These rows describe how a platform validates a firmware image, because that is a structural fact about its architecture. They are not a vulnerability disclosure and no exploit, bypass or circumvention technique is published here. Licensing and entitlement mechanisms are out of scope throughout — seescope boundaries.
What is programmable
- 1Mini-YGDAI slot card
The cheapest route to putting custom DSP in the audio path with no console modification at all. Host aperture 0xBA002000 + (slot << 11), 16-bit port on A10..A1.
- 2EP4CE15 patch FPGA (IC451)
The audio crossbar between Dante, every DSP7, the SHARC, the DSP6 bank and both slots. JTAG header present, and it is configurable from the CPU. Highest leverage, least investigated.
- 3ADSP-21369 SHARC (FX IC101)
The Premium Rack engine. A documented part, SPI-slave boot, JTAG header already fitted. Eight stereo slots means up to 16 mono inserts, patchable from the console's own UI. The one place third-party code could plausibly run.
- 4Head-amp control over Dante — a different axis entirely
Everything above is about getting custom DSP into the audio path, and each route needs the console opened or a card fitted. This one needs neither: gain, phantom and metering for a whole stagebox ride the control network in the clear, and a message built from the observed rule was accepted by a real Rio3224-D2. It controls the machine rather than changing what it is — and it is the only route on this page that has been exercised on hardware.
Traps
Mistakes this analysis actually made, or came close to making. They are recorded because each one produces a plausible-looking wrong answer rather than an obvious failure.
- The image load base is 0x8803BF80, not 0x88000000. The wrong value looks entirely plausible and silently yields almost no valid cross-references.
- Never attribute an MMIO constant from string-pool proximity. Doing so produced a claim that 0xBA002000 was the DSP7 window when it is the slot aperture — published, then retracted.
- Trusting the control block's own length field. An earlier pass took it as authoritative and recorded several arrays as never populated — they had in fact been answered in full. A device answering a read request echoes the query's length unchanged and appends the data past the boundary that length implies, so a parser that trusts it sees an empty reply and silently discards the payload. The checksum is what settles the real end of a block: across 3,907 captured messages, none validated under the wrong boundary.
- Reading a resting default as a meaning. One unmapped array sits at exactly the value the gain array holds at rest, which makes "second gain array" irresistible; another sits where an 80 Hz high-pass would. Neither was ever observed to move, and a value that never changes proves nothing about what it is.
- Trusting the strip label after a patch change. QL Editor raises a confirmation dialog whose default is No, and the strip label updates before it is answered — so the first attempt looked exactly like a successful edit and the two saved files came out byte-identical. If a diff shows nothing, check the change actually stuck before concluding the format does not store it.
- Deriving the name field from a default file. Every default name is exactly four characters, so a four-byte contiguous read is correct on every file anyone has lying around and wrong on every file anyone would save. Only a rename exposed the 384-byte split; no amount of staring at a default file would have.
Open questions
- The patch FPGA's configuration path from the CPU has not been traced.
- The DSP7 register-file semantics are undocumented; only the bus interface is known.
- The firmware teardown is still unchecked against a physical console. A QL1 and its stagebox were captured on our own network, but on their control network — nothing in the V5.91 image analysis above was confirmed on the machine, no console was opened, and the two bases on this page should not be read as one.
- What the remaining head-amp arrays mean. Their element counts, addressing and widths are evidence-backed and every observed value is a resting default. Mapping them is a ten-minute job with the hardware in front of you — change one parameter at a time on one input, with a pause between each, and each will light up exactly one array — and it has not been done.
- Whether one 32-slot array covers every input, or the arrays are banked. Repeating a single-parameter change on input 9 answers it in a minute; the capture predates the question.
- The metering scale. The meter array's floor and peak were observed, but no calibrated signal was ever injected, so it has a range and no unit.
- The rest of the patch source table. Slots, effect returns, playback and the null source are all offered by the editor and none is mapped; one more controlled diff per source class would extend the table, and a diff on a channel above 32 would establish its length.
- Whether a CL-written file really is the same format. QL Editor writes
.CLF, the same extension CL Editor's save panel offers, so one adapter should cover both — an expectation from a file extension, not a finding, and no CL-written file has been examined.
Status of this entry. A written teardown exists and its claims carry evidence citations. Rows labelled Measured were read off a running unit; everything else on this page is derived from files and has not been checked against hardware.