Builder, upcoming page, mods page for the current mods

- builder.html: build C900NXS.UPD in the browser (official 1.31 update in,
  mods ticked with their dependencies, no-liability and Claude Code
  confirmations, download). Ports of upd.py, the LZSS packer and the mods'
  application; the result is checked against the SHA-256 the Python
  patcher gives and is byte for byte the patcher's file.
- builder/data.js from tools/make_builder_data.py: the mods' bytes per
  combination; firmware parts (UTILITY table, HOT KEYS box, the asset
  blob's resource table) are made from the user's own update.
- index.html: rgb_waveform, extended_bpm, phasemeter, cuecolours,
  hotcuekeys (experimental), ledsaver, credit; stable/experimental and a
  green "ran on a player" dot.
- upcoming.html: beat jump, stems, uniform Camelot / Open Key, 3-band
  waveform.
- docs.html: the builder, the new mod names, hot cue loading and locks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Thiemo TizianiandClaude Opus 5.5 committed 2026-10-19 00:21:47 +02:00
1 parent f931ca0423
commit e4728b16ea
12 files changed
+1347 -145

No files matched your search

+94 -73
View File
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CDJ-900NXS Mods</title>
<meta name="description" content="Firmware mods for the Pioneer CDJ-900NXS (firmware 1.31): RGB waveform, cue colours, hot cues on the beat divide keys and more — compared with stock.">
<meta name="description" content="Firmware mods for the Pioneer CDJ-900NXS (firmware 1.31): RGB waveform, extended BPM, phase meter, cue colours, hot cues on the beat divide keys and more — compared with stock, built in your browser.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
@@ -18,6 +18,8 @@
<a class="brand" href="index.html"><span class="disc" aria-hidden="true"></span><span>CDJ-900NXS Mods</span></a>
<nav class="tabs" aria-label="Sections">
<a href="index.html" aria-current="page">Mods</a>
<a href="builder.html">Builder</a>
<a href="upcoming.html">Upcoming</a>
<a href="docs.html">Docs</a>
</nav>
<button class="theme-btn" type="button" aria-label="Switch light / dark">☀</button>
@@ -31,13 +33,13 @@
<h1>New tricks for an <span class="grad">old favourite</span>.</h1>
<p class="lead">
A set of firmware mods that bring features of newer players to the CDJ-900NXS:
an RGB waveform, rekordbox cue colours, visible hot cues and
<strong>hot cues you can play from the deck itself</strong>. Built into the player's own
update file by a patcher that leaves the boot loader untouched.
an RGB waveform, a BPM to two decimals, a phase meter, rekordbox cue colours and
<strong>hot cues you can play from the deck itself</strong>. Build your own update file
right here in the browser — the boot loader stays untouched.
</p>
<div class="cta">
<a class="btn primary" href="#mods">See the mods</a>
<a class="btn" href="docs.html#install">How to install</a>
<a class="btn primary" href="builder.html">Build your update</a>
<a class="btn" href="#mods">See the mods</a>
<a class="btn" href="docs.html#hotcuekeys">Hot cue guide</a>
</div>
@@ -56,10 +58,10 @@
<section>
<div class="wrap">
<div class="strip">
<div class="tile"><div class="n">6</div><div class="t">mods, pick the ones you want</div></div>
<div class="tile"><div class="n">A–C</div><div class="t">hot cues on the BEAT DIVIDE keys, at once</div></div>
<div class="tile"><div class="n">7</div><div class="t">mods, pick the ones you want</div></div>
<div class="tile"><div class="n">A–C</div><div class="t">hot cues on the BEAT DIVIDE keys, loaded in the background</div></div>
<div class="tile"><div class="n">0 bytes</div><div class="t">changed in the boot loader and recovery</div></div>
<div class="tile"><div class="n">1 file</div><div class="t">a normal <code>C900NXS.UPD</code> for the player's USB update</div></div>
<div class="tile"><div class="n">1 file</div><div class="t">a normal <code>C900NXS.UPD</code>, built in your browser</div></div>
</div>
</div>
</section>
@@ -67,83 +69,82 @@
<section id="mods">
<div class="wrap">
<h2 class="section-title">The mods</h2>
<p class="section-sub">Each one compared with stock. Three are by <a href="https://github.com/arnoldasr/cdj900nxs">arnoldasr</a>, three are ours. Choose any combination in the patcher.</p>
<p class="section-sub">Each one compared with stock. Three are by <a href="https://github.com/arnoldasr/cdj900nxs">arnoldasr</a>, four are ours. Choose any combination in the <a href="builder.html">builder</a>.</p>
<div class="legend">
<span class="badge ok">ran on a player</span>
<span class="badge emu">emulator only</span>
<span class="badge warn">partly tested</span>
<span class="badge bad">known faults</span>
<span class="state stable">stable</span>
<span class="state experimental">experimental</span>
<span class="player">ran on a player</span>
</div>
<div class="grid">
<!-- code -->
<!-- rgb_waveform -->
<article class="card">
<div class="card-head">
<div class="icon" aria-hidden="true">🌈</div>
<div>
<h3>RGB waveform, BPM &amp; phase meter <code>code</code></h3>
<h3>RGB waveform <code>rgb_waveform</code></h3>
<div class="by">by arnoldasr</div>
</div>
<div class="badges"><span class="badge ok">ran on a player</span></div>
<div class="meta"><span class="player">ran on a player</span><span class="state stable">stable</span></div>
</div>
<p>The detail waveform in RGB colours, as on newer Pioneer players, instead of plain blue. Plus the BPM with two decimals and a two-line phase meter.</p>
<p>The big waveform in RGB colours, as on newer Pioneer players, instead of plain blue — and the whole-track overview at the bottom as a warm red-to-white gradient, so drops and breaks stand out.</p>
<div class="vs">
<figure><img src="assets/detail-stock.png" alt="Stock blue detail waveform"><figcaption>Stock</figcaption></figure>
<figure class="mod"><img src="assets/detail-mods.png" alt="RGB detail waveform"><figcaption>Modded</figcaption></figure>
<figure class="mod"><img src="assets/detail-mods.png" alt="RGB detail waveform"><figcaption>RGB</figcaption></figure>
</div>
<div class="vs">
<figure><img src="assets/bpm-stock.png" alt="Stock BPM 145.0"><figcaption>BPM · stock</figcaption></figure>
<figure class="mod"><img src="assets/bpm-mods.png" alt="BPM with two decimals"><figcaption>BPM · two decimals</figcaption></figure>
<div class="vs stack">
<figure><img src="assets/overview-stock.png" alt="Stock blue overview waveform"><figcaption>Overview · stock</figcaption></figure>
<figure class="mod"><img src="assets/overview-mods.png" alt="Gradient overview waveform"><figcaption>Overview · gradient (with cue colours and hot cues)</figcaption></figure>
</div>
<ul class="diff">
<li><span class="k">Stock</span><span>Blue waveform, BPM to one decimal, phase meter as four boxes.</span></li>
<li><span class="k new">Modded</span><span>RGB waveform, BPM to two decimals (stacked), phase meter on two lines.</span></li>
<li><span class="k">Stock</span><span>Blue waveform, flat blue overview.</span></li>
<li><span class="k new">Modded</span><span>RGB waveform, red-to-white overview.</span></li>
</ul>
</article>
<!-- utility -->
<!-- extended_bpm -->
<article class="card">
<div class="card-head">
<div class="icon" aria-hidden="true">🔢</div>
<div>
<h3>Extended BPM <code>extended_bpm</code></h3>
<div class="by">by arnoldasr</div>
</div>
<div class="meta"><span class="player">ran on a player</span><span class="state stable">stable</span></div>
</div>
<p>The BPM to two decimals: the tenths move into a small digit above, the hundredths take the place below — handy for matching tempos by ear and by eye.</p>
<div class="vs">
<figure><img src="assets/bpm-stock.png" alt="Stock BPM 145.0"><figcaption>Stock</figcaption></figure>
<figure class="mod"><img src="assets/bpm-mods.png" alt="BPM with two decimals"><figcaption>Two decimals</figcaption></figure>
</div>
<ul class="diff">
<li><span class="k">Stock</span><span>BPM to one decimal.</span></li>
<li><span class="k new">Modded</span><span>BPM to two decimals, stacked.</span></li>
</ul>
</article>
<!-- phasemeter -->
<article class="card">
<div class="card-head">
<div class="icon" aria-hidden="true">🎚️</div>
<div>
<h3>Phase meter switch <code>utility</code></h3>
<div class="by">by arnoldasr · needs <code>code</code></div>
<h3>Phase meter <code>phasemeter</code></h3>
<div class="by">by arnoldasr</div>
</div>
<div class="badges"><span class="badge ok">ran on a player</span></div>
<div class="meta"><span class="player">ran on a player</span><span class="state stable">stable</span></div>
</div>
<p>Choose the phase meter in UTILITY. The rarely used SLIP FLASHING item becomes PHASE METER.</p>
<p>A two-line phase meter instead of the four boxes: orange for the master, blue for this deck, each with a marker that sweeps along the bar. Switched in UTILITY, where the rarely used SLIP FLASHING item becomes PHASE METER.</p>
<div class="vs">
<figure><img src="assets/phase-stock.png" alt="Stock phase meter: four boxes"><figcaption>Phase meter · stock</figcaption></figure>
<figure class="mod"><img src="assets/phase-mods.png" alt="Two-line phase meter"><figcaption>Phase meter · two lines</figcaption></figure>
<figure><img src="assets/phase-stock.png" alt="Stock phase meter: four boxes"><figcaption>Stock</figcaption></figure>
<figure class="mod"><img src="assets/phase-mods.png" alt="Two-line phase meter"><figcaption>Two lines</figcaption></figure>
</div>
<div class="vs stack">
<figure class="mod"><img src="assets/utility-phase.png" alt="UTILITY menu with PHASE METER item"><figcaption>UTILITY › PHASE METER</figcaption></figure>
</div>
<ul class="diff">
<li><span class="k">Stock</span><span>UTILITY › SLIP FLASHING.</span></li>
<li><span class="k new">Modded</span><span>UTILITY › PHASE METER picks the meter.</span></li>
</ul>
</article>
<!-- overview -->
<article class="card">
<div class="card-head">
<div class="icon" aria-hidden="true">🔥</div>
<div>
<h3>Overview colour gradient <code>overview</code></h3>
<div class="by">by arnoldasr</div>
</div>
<div class="badges"><span class="badge ok">ran on a player</span></div>
</div>
<p>The whole-track overview at the bottom of the screen gets a warm red-to-white colour gradient instead of flat blue, so drops and breaks stand out.</p>
<div class="vs stack">
<figure><img src="assets/overview-stock.png" alt="Stock blue overview waveform"><figcaption>Stock</figcaption></figure>
<figure class="mod"><img src="assets/overview-mods.png" alt="Gradient overview waveform with coloured cues and hot cues"><figcaption>Modded (with cue colours and hot cues)</figcaption></figure>
</div>
<ul class="diff">
<li><span class="k">Stock</span><span>Flat blue overview.</span></li>
<li><span class="k new">Modded</span><span>Red-to-white gradient.</span></li>
<li><span class="k">Stock</span><span>Four boxes; UTILITY › SLIP FLASHING.</span></li>
<li><span class="k new">Modded</span><span>Two lines with markers; UTILITY › PHASE METER picks the meter.</span></li>
</ul>
</article>
@@ -155,9 +156,9 @@
<h3>Cue colours &amp; hot cues shown <code>cuecolours</code></h3>
<div class="by">ours · made with Claude Code</div>
</div>
<div class="badges"><span class="badge ok">ran on a player</span></div>
<div class="meta"><span class="player">ran on a player</span><span class="state stable">stable</span></div>
</div>
<p>Memory cues take the colour you gave them in rekordbox. The hot cues stored on the USB (A–H) appear as lettered boxes in their rekordbox colour on the overview and the detail waveform — the stock 900NXS ignores them completely.</p>
<p>Memory cues take the colour you gave them in rekordbox. The hot cues stored on the USB (A–H) appear as lettered boxes in their rekordbox colour on the overview and the big waveform — the stock 900NXS ignores them completely.</p>
<div class="vs">
<figure><img src="assets/detail-stock.png" alt="Stock: red memory triangles only"><figcaption>Stock</figcaption></figure>
<figure class="mod"><img src="assets/hotcue-detail.png" alt="Hot cue A box on the detail waveform"><figcaption>Hot cue A on the waveform</figcaption></figure>
@@ -177,15 +178,15 @@
<h3>Hot cue keys <code>hotcuekeys</code></h3>
<div class="by">ours · made with Claude Code · needs <code>cuecolours</code></div>
</div>
<div class="badges"><span class="badge warn">partly tested</span></div>
<div class="meta"><span class="player">ran on a player</span><span class="state experimental">experimental</span></div>
</div>
<p>Play your rekordbox hot cues on the deck. A short press of QUANTIZE switches the hot key mode; the top three BEAT DIVIDE keys become hot cues A–C, ready to start at once. Press to jump and play, hold for a gate, set new ones while paused and delete them with DELETE. The key LEDs show which hot cues exist.</p>
<p>Play your rekordbox hot cues on the deck. A short press of QUANTIZE switches the hot key mode; the top three BEAT DIVIDE keys become hot cues A–C. After a track loads they are buffered in the background, so each starts at once — also from a pause, in CDJ and VINYL mode. Hold for a gate, set new ones while paused, delete them with DELETE; changes are saved on the USB with colours (A green, B orange, C blue).</p>
<div class="vs">
<figure><img src="assets/display-stock.png" alt="Stock: QUANTIZE label only"><figcaption>Stock</figcaption></figure>
<figure class="mod"><img src="assets/display-mods.png" alt="HOT KEYS box beside QUANTIZE"><figcaption>HOT KEYS mode on</figcaption></figure>
</div>
<div class="vs stack">
<figure class="mod"><img src="assets/utility-hotcue.png" alt="UTILITY menu with BEAT JUMP and HOT CUE KEYS items"><figcaption>UTILITY › HOT CUE KEYS</figcaption></figure>
<figure class="mod"><img src="assets/utility-hotcue.png" alt="UTILITY menu with the HOT CUE KEYS item"><figcaption>UTILITY › HOT CUE KEYS</figcaption></figure>
</div>
<ul class="diff">
<li><span class="k">Stock</span><span>No hot cues on the 900NXS; BEAT DIVIDE keys only for loops.</span></li>
@@ -194,41 +195,61 @@
<a class="more" href="docs.html#hotcuekeys">Hot cue guide →</a>
</article>
<!-- beatjump -->
<!-- ledsaver -->
<article class="card">
<div class="card-head">
<div class="icon" aria-hidden="true">⏭️</div>
<div class="icon" aria-hidden="true">✨</div>
<div>
<h3>Beat jump <code>beatjump</code></h3>
<h3>LED animation <code>ledsaver</code></h3>
<div class="by">ours · made with Claude Code</div>
</div>
<div class="badges"><span class="badge emu">emulator only</span></div>
<div class="meta"><span class="player">ran on a player</span><span class="state stable">stable</span></div>
</div>
<p>TRACK SEARCH jumps 1, 2, 4 or 8 beats along the beat grid instead of changing the track, set in UTILITY › BEAT JUMP (which replaces SCREEN SAVER).</p>
<p>When the screen saver dims the display, the deck comes alive: the BEAT DIVIDE keys fade in a wave, SYNC and MASTER pulse against each other, the transport keys light one after another and the jog's three rings run inner, middle, outer and back — a loop of about four and a half seconds. Any key ends it. UTILITY › LED ANIMATION, on from the first start.</p>
<ul class="diff">
<li><span class="k">Stock</span><span>TRACK SEARCH changes the track; UTILITY › SCREEN SAVER.</span></li>
<li><span class="k new">Modded</span><span>TRACK SEARCH jumps beats; UTILITY › BEAT JUMP OFF / 1 / 2 / 4 / 8.</span></li>
<li><span class="k">Stock</span><span>The screen saver only dims the display.</span></li>
<li><span class="k new">Modded</span><span>Button LEDs and jog rings animate while it is dimmed.</span></li>
</ul>
<div class="callout" style="margin:0"><strong>Rebuilt.</strong> Jumps while playing go through a buffer of their own and come back in phase; the CUE point and hot cues A–C stay. Needs <code>hotcuekeys</code>. Tested in the emulator only.</div>
<a class="more" href="docs.html#ledsaver">Read more →</a>
</article>
<!-- credit -->
<article class="card">
<div class="card-head">
<div class="icon" aria-hidden="true">☠️</div>
<div>
<h3>Boot text <code>credit</code></h3>
<div class="by">ours · made with Claude Code</div>
</div>
<div class="meta"><span class="player">ran on a player</span><span class="state stable">stable</span></div>
</div>
<p>The boot screen tells you what you are running: <em>Pionaarr Mods 1.0</em> instead of <em>Ver 1.31</em>. Leave it out to keep the stock text.</p>
<div class="vs">
<figure><img src="assets/boot-stock.png" alt="Stock boot screen: Ver 1.31"><figcaption>Stock</figcaption></figure>
<figure class="mod"><img src="assets/boot-mods.png" alt="Boot screen: Pionaarr Mods 1.0"><figcaption>Pionaarr Mods 1.0</figcaption></figure>
</div>
</article>
</div>
<p class="caption">More in the works — beat jump, stems, a uniform key notation and a 3-band waveform: see <a href="upcoming.html">Upcoming</a>.</p>
</div>
</section>
<section id="patcher">
<section id="build">
<div class="wrap">
<h2 class="section-title">One patcher, your choice</h2>
<p class="section-sub">The patcher takes the official 1.31 update, adds the mods you tick and writes a new <code>C900NXS.UPD</code>. Only the main application changes; the boot loader, the recovery loader and the other sections are copied byte for byte and checked again before the file is written.</p>
<h2 class="section-title">Build it in your browser</h2>
<p class="section-sub">The <a href="builder.html">builder</a> takes the official 1.31 update, adds the mods you tick and gives you a new <code>C900NXS.UPD</code> — all on your computer, nothing is uploaded. Only the main application changes; the boot loader, the recovery loader and the other sections are copied byte for byte and checked again before you can download the file.</p>
<div class="cta"><a class="btn primary" href="builder.html">Open the builder</a></div>
<p class="section-sub" style="margin-top:28px">Prefer the command line? The Python patcher builds the same file, byte for byte:</p>
<div class="term"><span class="c"># pick the mods in a list</span>
<span class="p">$</span> python cdj900nxs_patcher.py C900NXS.UPD
<span class="c"># or name them</span>
<span class="p">$</span> python cdj900nxs_patcher.py C900NXS.UPD --mods code,utility,overview,cuecolours,hotcuekeys
<span class="p">$</span> python cdj900nxs_patcher.py C900NXS.UPD --mods rgb_waveform,extended_bpm,phasemeter,cuecolours,hotcuekeys
<span class="c"># back to stock</span>
<span class="p">$</span> python cdj900nxs_patcher.py C900NXS.UPD --stock</div>
<p class="caption">Before it builds, the patcher shows a disclaimer that you must accept. <a href="docs.html#install">Full install guide →</a></p>
<p class="caption">Both ask you to accept a disclaimer first. <a href="docs.html#install">Full install guide →</a></p>
</div>
</section>
</main>
@@ -237,7 +258,7 @@
<div class="wrap cols">
<div>
<div class="ai"><span class="dot"></span>Made with Claude Code · Claude Opus 5.5</div>
<p>This website, the mods <code>beatjump</code>, <code>cuecolours</code> and <code>hotcuekeys</code>, and the patcher were developed with Claude Code (Anthropic's AI coding assistant, model Claude Opus 5.5), by reverse engineering the firmware in an emulator. The mods <code>code</code>, <code>utility</code> and <code>overview</code> are by <a href="https://github.com/arnoldasr/cdj900nxs">arnoldasr</a>.</p>
<p>This website, the builder, the mods <code>cuecolours</code>, <code>hotcuekeys</code>, <code>ledsaver</code> and <code>credit</code>, and the patcher were developed with Claude Code (Anthropic's AI coding assistant, model Claude Opus 5.5), by reverse engineering the firmware in an emulator. The mods <code>rgb_waveform</code>, <code>extended_bpm</code> and <code>phasemeter</code> are by <a href="https://github.com/arnoldasr/cdj900nxs">arnoldasr</a>.</p>
</div>
<div>
<h4>Disclaimer</h4>