Engine
This is the main DJ application that the user interacts with. This does all the mixing, cloud file loading, and almost everything else the user sees.
Application Data
Path: /usr/Engine/Engine
Available in firmware for
Hardware | Hardware ID | Available |
|---|---|---|
| ✅ | |
| ✅ | |
| ✅ | |
| ✅ | |
| ✅ | |
| ✅ | |
| ✅ | |
| ✅ | |
| ✅ | |
SC5000M (No Product Page) |
| ✅ |
| ✅ | |
| ✅ | |
| ✅ | |
| ✅ |
Binary Overview
Measured against /usr/Engine/Engine from the SC6000 5.0.4 firmware:
Property | Value |
|---|---|
Format | ELF 32-bit, |
Size | ~44 MB ( |
Image base |
|
|
|
Real functions | ~46,500 (per |
Stripped | Yes, but RTTI, |
Hardening | Stack canaries, |
Debug link |
|
Internal codename: planck
Assertion strings retain full build paths, which exposes the source tree layout and confirms the air.planck.* logging categories seen in the runtime output below:
The two top-level trees are App/src/ (Planck, PlanckEngine) and Libraries/ (split into private/, shared/ and Streaming/).
Third-party libraries
All dynamically linked, so versions can be read from the runtime's LD_LIBRARY_PATH:
Library | Use |
|---|---|
Qt (QtQuick/QML, Qt Network) | Entire UI and event system |
gRPC ( | Device-to-device and cloud RPC |
Protocol Buffers | Wire format for all RPC |
OpenSSL | Digests, RSA, EVP |
CryptoPP | Additional hashing, bundled with Widevine |
Widevine CDM | Streaming DRM ( |
TagLib | Audio file metadata parsing |
zplane Elastique | Time-stretch / pitch-shift |
Boost | Assorted utilities, incl. the UUID SHA-1 in Engine Library |
libudev | Hotplug detection for USB media |
spdlog | Logging |
Crashpad | Crash reporting ( |
Embedded QML
The Qt resource system stores QML as plaintext in .rodata: component source, property bindings, and JavaScript are all directly readable with strings. These call into a Planck bridge object exposed to the QML engine, for example:
The /Some/Slash/Path strings are keys into a global state map (StateMap), which is also how remote devices' properties are addressed: /RemoteState/%1/RemoteProperties/....
Network services
Engine runs gRPC servers as well as clients, exposing enginelibrary.v1, enginesync.v1, networktrust.v1 and remotehostscreen.v1. Discovery is a custom UDP scheme (airNetworkDiscoverer/airNetworkExchange) rather than mDNS. See Engine Networking for the full method inventory.
Reverse engineering notes
Ghidra's stock auto-analysis finds only about half the functions in this binary. Engine Ghidra Analysis documents how to recover the rest from .ARM.exidx and how to name them from RTTI vtables and assertion strings.
Command-line arguments
Engine parses its arguments with QCommandLineParser, and calls setSingleDashWordOptionMode(ParseAsLongOptions), so long names take a single dash — -skipFirmwareUpdate, not just --skipFirmwareUpdate. Both forms work. This is why the launch script in /usr/Engine/Scripts/engine can write -d0 -loggerOptions "...".
The table below is the complete set for 5.0.4, recovered from the registration function at 00bb746c, which constructs QCommandLineOption and calls addOption exactly 44 times. All 44 names were recovered, and there is no second registration site, so nothing is missing. --version also works, via addVersionOption().
Being registered does not mean being implemented. The Read column records whether the name is referenced anywhere other than its own addOption call — i.e. whether setting it could do anything at all. Eleven of the 44 are never read, so they are inert; see Options that are never read. no in that column is not a claim about what an option would do, only that nothing looks at it.
Options with an empty Value column are flags. Value names and descriptions are the binary's own.
Option | Value | Type | Read | Description |
|---|---|---|---|---|
| flag | C++, QML | Enables the Access All Areas mode. | |
| flag | no | Shows the item with active focus. | |
| flag | argv | Sends debug output to the console, instead of a log file. | |
| flag | argv | Output console only debug with ANSI color. | |
| flag | argv | Output console only debug with ANSI colour. | |
|
| path | C++ | Adds a directory as a demo drive |
| flag | C++ | Prints a message if frame to frame time exceeds a 30 milliseconds threshold | |
|
| int (ms) | C++ | Overrides the default threshold in milliseconds for detectUILags |
| flag | argv | Enables gdpr filtering for log files, and sentry. | |
| flag | no | Shows the width and height of the application. | |
| flag | C++ | Disables elastique for track decks. | |
|
| int | C++, argv | Sets the network discovery port. |
| flag | argv | Shows noise normally filtered out from debug output. | |
| flag | C++ | Writes a one off 16 MB of log file data. | |
| flag | C++ | Locks the UI update rate to 30 fps. | |
| flag | no | If only one device is connected it will be selected. | |
|
| path[,bool] | C++ | Adds a directory as a source drive. The optional parameter ejectable can be set to true but else would default to false. |
| flag | C++ | Enables shortcuts via QWERTY keyboard on embedded. | |
| flag | QML | Shows a frame timer. | |
| flag | C++ | Checks whether the asynchronous librarian runner or main thread pool are frozen. | |
| flag | no | Shows the gig timer | |
| flag | C++ | Disables the Database schema hash check. | |
| flag | no | Just try that yourself. | |
|
| CSV list | C++, argv | Comma separated list of options to modify the content and the layout of the logging output. Possible values are: %1. |
| flag | C++ | (no description: the binary literally stores | |
| flag | C++ | Do not show the new feature update pop-up message. | |
| flag | C++ | Hides the on-boarding screen. | |
| flag | C++ | Dismiss user prompts during database migration | |
| flag | C++, QML | Hides the splash screen. | |
| flag | no | Disable Sync Manager popup message boxes. | |
| flag | C++ | Will spawn only a single offline analyzer. | |
| flag | C++ | Packs files even if the audio file is missing. | |
|
| int | C++ | Sets the page cache size. |
|
| path list | C++ | Paths to JSON files with custom analytics report tags |
|
| path | C++ | Adds a directory as a sampler demo drive |
| flag | no | Shows the System Monitor | |
| flag | no | Show left and right side screens. | |
|
| int | C++ | Simulates a network mixer. |
| flag | C++, QML | Enables option for simulating a power failure. | |
| flag | C++ | Skip firmware updates. See MIDI Devices. | |
| flag | C++ | Uses fake sensors instead. | |
|
| URL | no | Overwrites the URL for the default update server ( |
|
| path | no | A directory to put dynamically created virtual drives. |
| flag | no | (no description: the binary literally stores |
How options are consumed
Three separate mechanisms read arguments, which matters because checking only the first produces false negatives — d0 looks unused until the second is taken into account:
Mechanism | What it looks like in the binary | Used by |
|---|---|---|
| a standalone name literal | most options |
a raw |
| the logger, which initialises before Qt's parser exists |
the QML bridge | the name inside a QML blob, not a standalone literal |
|
The QML channel is easy to miss: Engine's QML is stored as plaintext, so those names appear only as substrings of a much larger string and never as their own literal.
Options that are never read
activeFocusItem, dimensionInfo, enableAutoSelectSingleSource, gigTimer, laser, nosmpopup, showSystemMonitor, sideDisplays, updateServerUrl, virtualDrivesDir, watchdog.
For each of these the name occurs exactly once in the binary and the only reference to it is the addOption call, so no code path can observe it. They parse without error and then do nothing. laser is the clearest case — its description, "Just try that yourself.", is the whole joke.
Additional checks behind that claim:
Engine's embedded QML contains none of them, in either ASCII or UTF-16.
No other
/usr/Enginebinary or data file mentions them.Only
isSet(const QString&)is linked;isSet(const QCommandLineOption&)is not, so an option can only ever be queried through its name string.The same holds in
5.1.0-beta8: all eleven still occur once and none appear in ahasCommandLineArgumentcall.laserspecifically has been registered-but-unread in every release checked —1.6.2,2.4.0,3.4.0,4.3.4,5.0.4and5.1.0-beta8.
Names that are queried but never registered
Six names are read by code yet never passed to addOption, so QCommandLineParser does not know them: runTests, repeatTests, repeatTestsFor, validateAMCResultsPath, renderInfo and wifiPassword. Qt's own QCommandLineParser: option not defined: warning string is present in the binary. An unregistered name makes parse() record an unknown-option error and makes isSet() warn and return false, so these read as leftover scaffolding rather than usable switches.
runTests is the interesting one, because MidiDeviceControl::quitAndStartFirmwareUpdate (00595758) tests it first and returns immediately when set — which would make the whole firmware-update exit a no-op. See MIDI Devices.
Version coverage
skipFirmwareUpdate was added in 2.0.0; it is absent from every 1.x build. The Read column was determined against 5.0.4 and spot-checked against 5.1.0-beta8; the rest of the table has not been diffed across versions.
Runtime Console Output
LD_LIBRARY_PATH=/usr/qt/lib:${LD_LIBRARY_PATH} /usr/Engine/Engine -d0
-d0flag is the debug logging flag; see Command-line arguments for the rest
Related Files
Controller Assignments covers how the hardware controls different functions of this application.
MIDI Devices covers how this application finds its control surface, wheel displays and mixer over MIDI, and where their MCU firmware and versions live.
Engine Ghidra Analysis covers getting this binary into a navigable state in Ghidra.
Engine Networking covers the gRPC services, discovery, and cloud endpoints.