AI Engineering
A complete web application from AI: the self-experiment
An AI environment builds a browser groovebox with its own drum model - and a logbook records what it did well and where it failed.
1. The find
The domain mybytes.com is considerably older than today's myBytes GmbH. Historical sources show that a browser-based music application used to be reachable at /mixer.html: the Internet Archive lists snapshots of this URL from February 2008 to March 2015, and contemporary reports attribute the page to a Microsoft campaign on copyright education for teenagers, implemented by an external agency in the technology of its day.
For the record, because it matters to us: today's myBytes GmbH has no organisational or commercial connection to that earlier offering. We are neither its legal successor nor its continuation; the domain was acquired only later. Nothing in the new application reuses code, graphics or sounds of the former product.
What interested us was something else: a URL that carried a browser mixer more than fifteen years ago is lying fallow. How would you build such an application today? And how much of it can modern generative AI actually take on?
2. The question
We deliberately defined the experiment narrowly. An AI-supported engineering environment (Claude in Claude Code) was given the task of building a real groovebox at /mixer.html: step sequencer, synthesis, mixer and, at its core, a machine learning model that generates and varies drum patterns while running entirely in the user's browser.
The division of labour was fixed in advance. The AI designs, implements and documents; the human decides at defined gates: architecture approvals, listening tests, design judgments, licensing questions. Every session was recorded in a development logbook; every claim in this article comes from those records or from measurement data of a documented run.
3. From brief to requirements
The idea first became a requirements catalogue: eight tracks (twelve in the end, including three toms and a cymbal track), a 32-step grid across two bars, transport with BPM and swing, per track volume, panning, mute and solo, plus demo content that carries the page when it is first opened. One hard rule applied to the AI component: the model does not generate audio waveforms but musical events - which instrument hits on which step, and how hard. Sound generation stays entirely with the Web Audio API.
Two constraints shaped everything that followed. First: every sound in the application is synthesised; there are no third-party samples and therefore no unresolved rights. Second: inference runs locally; no audio data and no musical content leave the browser. A network trace of a complete session (loading, playback, generating, varying) proves it: the only transfers are page assets and model files via GET; the only outgoing data trail is the click events of the site's own website statistics, which run on every page and contain no musical content whatsoever.
4. The architecture
The application consists of four layers. A central store holds the pattern (steps, notes, settings) as the single source of truth. A scheduler plans audio events; a web worker ticks every 25 milliseconds, whereupon the main thread schedules all events of the next 120 milliseconds sample-accurately against the AudioContext clock. The audio engine holds a chain of gain and stereo panner per track and renders the drum sounds into buffers from synthesis parameters at startup. The AI layer, finally, loads two small TensorFlow.js models and writes its results into the store, never directly into the audio engine.
The scheduler part is the classic of browser audio development: trigger notes with setInterval and you will hear timing fluctuations as soon as the browser throttles the tab. The lookahead pattern (planning ahead on the audio clock, tick in the worker) has been the established approach for years, and the AI implemented it correctly on the first attempt.
5. The model: a small VAE for drum patterns
The centrepiece is a variational autoencoder over symbolic drum patterns - a model that condenses patterns into a compact numerical representation and generates from it again. A pattern is a matrix of 32 steps and five classes (kick, snare, closed and open hi-hat, percussion); values are hit velocities between 0 and 1. The encoder maps these 160 numbers onto a 32-dimensional latent vector; the decoder reconstructs the pattern from it with two heads: one says whether a hit occurs, the other how hard.
Why a VAE and not an autoregressive model? Because of the core function. Varying an existing pattern is precisely definable in latent space: encode the pattern, shift the vector by a controlled radius, decode. The application's variation control maps exactly this radius. The measurement confirms the concept: the mean change of the pattern grows monotonically with the radius, from 0.016 at r = 0.1 to 0.192 at r = 1.7, without saturation in the measured range.
Training used the Groove MIDI Dataset (Google, CC BY 4.0), real e-drum recordings of human drummers: 20,474 two-bar windows from 1,150 files, split by drummer (70.4 / 14.8 / 14.8 percent) so that no player appears in both training and test. The chosen model has 201,856 parameters and trained for 70 epochs in 12.3 seconds on a CPU - not a typo: at this scale, training is not an infrastructure problem. An ablation over the size of the latent space (8, 16, 24, 32 dimensions) yielded onset F1 scores of 0.638, 0.710, 0.737 and 0.749; 32 was chosen.
The exported models total 397.4 kilobytes (fp16). A parity test recomputed the forward pass in numpy directly from the shipped weights; the maximum deviation from the training environment was 0.0009.
The model grew with the product once during the project: when the application gained tom tracks, a second model version followed with eight classes (the previous five plus three toms), its own seed, its own run. Before it stood a gate: the occupancy measurement. All three tom classes lie below the level of the already sparse open hi-hats in the dataset (34.0, 17.4 and 28.9 percent of the windows versus 38.1) - the decision to train anyway and to carry the sparseness as a documented finding was made by the human.
The overall F1 dropped, as expected, from 0.749 to 0.697 (the target has three more sparse classes), the models grew to 542 kilobytes combined, and the parity test passed with a maximum deviation of 0.0012.
The application's styles are anchors in latent space - four from the start, a fifth added as the consequence of a finding (section 9). Of the original four, two (Lo-Fi, Experimental) come from genre subsets of the dataset, two (House, Electronic) from curated reference patterns. The difference is a story of its own: the dataset's "dance" subset sounded like a lot but consisted of only seven recordings by two drummers - an anchor built from it would have encoded those two people, not the genre. The decision to discard this subset was made at that recount - before any listening test and without any model metric forcing it.
6. Web Audio: sound without samples
Every sound in the application originates from code. The kick is a sine with falling pitch plus a short click, the snare a triangle body with a noise component, hi-hats and cymbals are filtered noise, and the melodic voices come from a small subtractive synth engine of our own with oscillators, filter and envelopes. This is not frugality but a legal position: not a single third-party sample exists in the project, and the parameters of every sound are in the source code.
7. Inference in the browser
The runtime is TensorFlow.js 4.22.0, fully self-hosted - no CDN dependency, which also matches the privacy architecture. The backend chain tries WASM, then WebGL, then CPU. This article deliberately gives no latency figures: we did not run a systematic measurement campaign across devices and browsers, and single values from the development machine would be anecdotes. If you want your own numbers, you get them first-hand: a built-in benchmark mode (open the page with ?bench=1) runs 100 generate and 100 variation inferences with a fixed seed and exposes backend, load time and p50/p95 as JSON - measured on your own device, not on ours.
What is interesting is what is NOT the problem at this model size: inference time and memory play practically no role. The real engineering work is in the surroundings: in loading paths, backend fallbacks and the decision to ship the runtime with the model artefacts instead of pulling it from a package manager.
8. What the AI did well
The first runnable version of the application - sequencer, synthesis, mixer, demo patterns, a page with basic search engine equipment - was built in a single working day, the TF.js integration layer the same evening. The lookahead scheduling was correct on the first attempt. The synth engine's parameter registry generates controls, value ranges, normalisation and documentation from a single source; the click-free envelopes work around a known browser incompatibility (Firefox does not support cancelAndHoldAtTime) by computing the curve value at the transition point analytically - a solution we have not found in any tutorial.
And: the AI consistently wrote tests for its own logic (47 in the end), which caught real bugs several times before a human could hear them.
9. Where the AI failed
The logbook is, at this point, the most honest source of the project.
The blank screen: the first delivered version of the listening test tool showed nothing but a heading. The cause was a classic JavaScript error (access to a constant before its initialisation) that none of the 27 unit tests of the time could see, because none of them loaded the entry point as a whole. The human found it on the running system; the consequence was a new class of tests.
Musical taste: the "Experimental" demo pattern took two attempts. The first was theoretically interesting (polyrhythms, quartal harmony) and, in the human's judgment, sounded simply terrible. The second attempt became a dark halftime groove and passed. There was no metric for that.
Usability: the marker for open hi-hats was a small "o" and was read as the digit zero. The melody tracks were deliberately not editable at first, but felt like a defect. And the layout of the track headers took five attempts because the AI misinterpreted two instructions in a row - in the end it turned out that the original arrangement was the best, which only the comparison made visible.
Honesty of the model: the VAE systematically generates too few open hi-hats (they occur in only 38.1 percent of the windows in the dataset), and quantisation to a 16th grid costs 7.84 percent of the original hits (still 7.08 with the second version's extended tom mapping), because human playing sits off the grid (mean deviation: 0.176 steps). Both facts are also stated on the product page, not only here.
Genre fidelity: the second model version delivered perhaps the most instructive finding of the project. The model CAN do toms - reconstruction of held-out patterns reaches F1 scores of 0.30 to 0.55 depending on the tom class, in the same range as the open hi-hats. But in the generated patterns of the four app styles, toms almost never appear: per tom class in 6.3, 1.3 and 7.5 percent of cases. The reason is not a training error but the anchor choice: House, Electronic and Lo-Fi are precisely the genres in which drummers hardly play toms - the style anchors lie in tom-poor regions of the latent space. The model reproduces the truth of its genres, not the wish of its developers.
The proof of the pudding followed one day later and confirmed the diagnosis. A fifth style anchor, "Fills", computed as the mean of the 6,682 tom-heavy windows of the dataset (around a third of the data, all ten drummers, at least three tom hits per two bars) - without a single model weight being touched: at this anchor, toms appear in 58, 20 and 61 percent of the generated patterns instead of 6.3, 1.3 and 7.5, with the core kit intact (kick 92, snare 95, closed hi-hat 87 percent). The price is the same mechanism in the opposite direction: open hi-hats drop to 5 percent at this anchor, because in real playing, fills replace exactly the hi-hat work. The solution was not to change the model, but to show it a different region of its own map.
10. The role of the human
According to the logbook, the work is distributed like this: the AI wrote practically all of the code and the documentation. The human made the fundamental architecture decisions (a model of our own instead of pre-trained checkpoints, after the Magenta project turned out to be archived), all judgments of taste and quality (listening tests, layout, demo patterns), the licensing and data strategy, and he found the bugs that only become visible on the running system. Without these gates the application would have been finished sooner - and worse.
One detail deserves mention: during the integration, the human once made a commit in the middle of an ongoing rebuild; two new files were missing from the commit, and the build would have failed. The AI recognised the pattern (a documented trap of the deploy process) and reported it before the pipeline went red. Collaboration here means: each side catches the other's mistakes.
11. The result
The application is freely usable at mybytes.com/mixer.html, no account, no upload. It has kept growing since the experiment: a pattern bank with song mode, a subtractive synth engine with 15 presets and its own sound editor per track, shapeable drum synthesis, an arpeggiator and send effects were added in the same ways of working - AI builds, human decides.
12. Conclusion
Can AI develop a complete web application today? It can do an astonishing amount of it: in this project, architecture implementation, code, tests and documentation come almost entirely from an AI environment, and the speed fundamentally changes the economics of such experiments - a training run of seconds on a CPU, one working day to a playable application.
What it has not replaced: judgment. Every point at which the product became good rather than merely functional was a human decision - from the discarded style anchor via two attempts at a demo pattern to the realisation that the first layout was the right one. Generative AI shifts speed and the division of labour considerably; architectural responsibility, quality control and taste remain work.
Transparency: The drum model was trained on the Groove MIDI Dataset (Google LLC, CC BY 4.0; Gillick, Roberts, Engel, Eck, Bamman: "Learning to Groove with Inverse Sequence Transformations", ICML 2019). All figures in this article come from two documented training runs (version 1: seed 20260809, version 2 with toms: seed 20260810; identical dataset split) or from the measurements named in the text; single values are single values, not means over several runs. Both runs took place before the first commit of the training repository; the metric files therefore carry no commit reference. The Fills anchor is a subsequent anchor addition without retraining; its presence figures come from a measurement over 100 generated patterns (seed 20260811). The training code is published as a repository: github.com/myBytesResearch/drum-vae-mixer.
Sources
- Internet Archive, Wayback Machine, snapshots of mybytes.com/mixer.html - earliest: 16 Feb 2008, latest: 16 Mar 2015; accessed 2026-08-11.
- Microsoft press release, 13 Feb 2008: "Teens Less Likely to Download Illegally When They Know the Laws, Microsoft Survey Finds" (accessed 2026-08-09).
- YALSA blog (American Library Association), 26 Feb 2008: "MyBytes Teaches Teens a Little Something about Copyright" (accessed 2026-08-09).
- Glen Rhodes, portfolio entry MyBytes - glenrhodes.com/portfolio/portfolio/mybytes (accessed 2026-08-09).
- Groove MIDI Dataset (Google LLC, CC BY 4.0; recorded on a Roland TD-11 e-drum kit) - magenta.tensorflow.org/datasets/groove (accessed 2026-08-11). Paper: Gillick, Roberts, Engel, Eck, Bamman: "Learning to Groove with Inverse Sequence Transformations", ICML 2019.
- Magenta project, archived January 2026 - github.com/magenta/magenta (accessed 2026-08-09).
- Chris Wilson: "A Tale of Two Clocks" (lookahead scheduling for Web Audio) - web.dev/articles/audio-scheduling (accessed 2026-08-11).
- Browser support for AudioParam.cancelAndHoldAtTime - caniuse.com/mdn-api_audioparam_cancelandholdattime (Firefox without support; as of 2026-08-11).
- Training repository with all measurement data, seeds and the results notebook - github.com/myBytesResearch/drum-vae-mixer.