Changelog

Every version, newest first, and everything that changed in it.

Unreleased in development

Changed

Fixed

1.0.0RC 17 September 2026

The first release candidate, 153 entries since 0.4.0. Not a download: these binaries are for the owner's own testing in Ableton, FL Studio, Reaper and Freally Oscillate, and no link appears on the site until that has happened.

It runs in four places now — this plugin, a standalone, a browser tab running the same generator compiled to wasm, and MixSir on a phone. New: collaboration rooms, four Factory Expansion packs (1,400 instruments, 5,085 loops, 189 more artists), clip fades, an audio clip view that is the actual audio, per-note chance and velocity, a session that travels inside the exported file, and a green product.

Known: no Linux editor yet, so Linux is not built here; binaries are unsigned by policy, with checksums beside them; and eleven review findings are recorded and not fixed in docs/product-roadmap.md, none of them a crash or data loss.

Fixed - the e2e gate was timing out on a cold dev server, 2026-09-17

Four accessibility specs failed on page.goto with nothing wrong with the page: a cold vite compiles the module graph on the first browser request (19.5 s measured), and at four workers four specs paid it at once. e2e/warm.setup.ts now compiles the app once before the suite — a11y went 4-failed/3-flaky to 9/9, and the whole run got faster, 4.7 min against 7.1.

⚠ The first attempt put the exclusion on the wrong config layer and silently reduced the gallery to 0 tests collected, which a gate reports as a pass.

Changed - the product is green now, and it is the icon's green, 2026-09-16

Every purple in the app, the plugin and the docs site is gone. #79D920 is sampled from images/freally-icon.png — the weighted centre of its bright-green pixels — so the UI and the taskbar icon are the same green rather than nearly the same.

⛔ The light theme takes the icon's shadow green, #1A6B02, because #79D920 is 1.79:1 on white. The same arithmetic caught a real bug: a brand button with a hard-coded white label, illegible on the new green, now uses --color-on-primary.

⚠ The neutrals moved by hue and not luminance, so none of the 112 contrast assertions shifted. The cyan playhead colour is untouched by design.

Added - the name turns at the top of the window, 2026-09-16

"FREALLY MIDI MASTER v1.0.0RC", carved and rotating on its Y axis at the top centre of the app. It is an extrusion rather than a flip — ten copies stacked along Z, because a single rotateY vanishes to a hairline at 90° and reads as the name blinking out. It stops dead under prefers-reduced-motion, held at an angle so the depth survives.

Added - clips fade in and out, with a curve you can bend, 2026-09-16

Every clip in the Song Arrangement has a fade in and a fade out, each with a handle for its length and a dot for its shape — so an artist's arrangement can be bent into your own.

⛔ The two paths can never cross: a crossed pair describes no envelope at all, so when they would overlap they scale down in proportion rather than one silently deleting the other. The page's fadeGain mirrors the engine's Fade::gain_at exactly, so the drawing and the audio are one formula.

Added - the audio view of a clip is now the actual audio, 2026-09-16

Switch the arrangement to audio clips and you see each clip rendered through its own instrument, so you know what it sounds like before dragging it into your DAW.

⛔ The editor thread never renders — 320 clips at half a second each would freeze the host. The plugin answers from a cache or queues the work, and the timeline keeps its note sketch until the picture arrives. "Real time" falls out of the cache key being the clip and its sound, so a turned knob is a fresh render and nothing polls.

⚠ A browser tab keeps the note sketch for ever: no audio is staged there.

Added - per-note chance and velocity range, 2026-09-16

Any note in the piano roll can be given a chance of playing and a velocity that wanders. Mike: "B5-2 — Per-note chance/probability", "B5-3 — Per-note velocity deviation/range". A chance is drawn as how much of the note is filled; a range is a band around its cap on the velocity lane.

⛔⛔ THE EXPORT BAKES, AND IT BAKES THE SAME WAY EVERY TIME

Either the .mid bakes one roll and two exports differ — breaking the golden snapshots and the byte-identical web_parity gate — or the feature is preview-only and lies about what you will get.

▶ Both horns assume the bake is random. It is not. The roll is a hash of the clip's seed, the pass and the note's index, and every export pins the pass, so the file bakes and two exports are identical. Ableton bakes non-deterministically; this is strictly better and costs nothing. An untouched note skips the roll entirely rather than always winning, which keeps every snapshot byte-identical.

Fixed - the standalone's icon came from a file that never existed, 2026-09-16

plugin/build.rs told every reader to regenerate icon.ico from images/freally_app_icon.png, which has never been in this repo. It names images/freally-icon.png now — the real product icon.

⚠ The .ico entries are DIB and verified one by one: PNG-compressed entries make the resource compiler fall back to the stock Rust icon silently.

Added - your session travels inside the file, 2026-09-16

An exported .mid or .wav now carries the whole session that made it. In a DAW it is an ordinary file; opened here, the artist, seeds, pins, mood, locks, mutes and pad assignments all come back — so a file reopens as yours rather than as somebody's notes. MIDI uses FF 7F, which readers must skip; audio uses a RIFF chunk beside the acid chunk that already carries the tempo. Drop back a .wav this product bounced and the session returns instantly instead of a minute of analysis approximating it.

⛔ A file somebody sent you is untrusted: the blob is versioned and length-capped, and a document with one wrong field is refused whole, because a half-applied session is your artist name over somebody else's pins. midly parses a truncated file without complaining — 200 bytes still yields a plausible document — so the blob declares its own length.

Fixed - the browser's Export button could not write a file, 2026-09-16

Pressing Export on the Song tab in a browser said "there is nothing generated to write", every time: one store serves the plugin and the tab and sends { song }, while the tab's file layer read a files list nothing sends. It renders through the command the drag already used, so the file you download and the file you drag are the same bytes.

Fixed - dropping a .mid on the browser's Song tab stored the wrong thing, 2026-09-16

explorer_song, explorer_midi_split and explorer_midi_audition were all answered with the split, so the Song tab got a list of parts where an arrangement goes.

⚠ Both shipped because the specs covering those buttons run against the mock, which answers correctly. The tab's file layer had no test at all; it now asserts the shape rather than the name, since the name gate was green for both bugs.

Fixed - the owner's force-mute worked on nobody, 2026-09-15

Force-mute, force-camera-off and remove-from-room were three buttons that did nothing and reported nothing: the page had asked for collab_force and collab_remove since they were written, and the plugin answered neither. The page reads any rejection as "there is no sidecar", which is why nobody ever saw an error — including an owner trying to close a stuck open mic. Both are answered now, and a malformed argument is refused rather than defaulted, because every default here is a decision about somebody else's camera.

Fixed - a legal notice nobody could read in the dark theme, 2026-09-15

The name-framing notice under the roster combobox is ~10.9px and was painted in the muted tier, which the palette reserves for large text. It measured 4.33:1, under the 4.5:1 small text needs. It uses the body tier now.

⚠ The accessibility suite drives the light theme, where the same declaration measured 5.78:1 and passed, so a unit assertion now checks all three themes.

Fixed - the gate that watches for dead controls could not see collaboration, 2026-09-15

bridge_names.rs scraped every invoke('name') in the frontend — but every collaboration module passes a constant through a helper, precisely so one spelling cannot drift from three call sites. The convention that made those names safe is the one that hid them, and seven commands were invoked by shipped controls and answered by nothing. The gate resolves constants now; two are fixed above and the other five are listed in the test with the reason each is unbuilt, so the gap is named in executable form rather than forgotten.

Changed - an exported pattern's track name says "the style", 2026-09-12

The track name written inside a .mid read trap — Drums; it now reads trap style — Drums, the distinction the interface and filenames already make. A performer's name describes a style, never a badge of origin on a file that leaves this app.

⚠ Not one note moved: the four golden snapshots differ by six bytes of text each.

Added - the File Explorer opens on Categories, with the numbers, 2026-09-11

It used to open on instrument families in whatever order the engine held them, with no counts — and the library shelves, loop packs and drum kits were a folder tree drawn inside the instrument browser, so Factory Packs could not be reached from the top at all.

It now opens on Categories, one row per place, each saying how much is in it: Instruments and four Factory Expansions (248 and 350 each), Drum Packs (eleven kits, 407 one-shots, auditionable for the first time), and Factory Packs (5,085 MIDI loops). Rows sort alphabetically in whichever of the eighteen languages you use, and an unplugged drive keeps its place and is marked Unavailable in words rather than only in colour.

The count comes from the engine unfiltered — what is on the shelf, not what survived the chips — so it does not move when you press Bassline.

⛔ Fixed by the same change: the shelves leaked into each other. Factory Expansion 2 → Keys listed every Keys instrument on all five shelves, because the shelf was a folder on screen and nothing at all in the query.

Changed - the interface says "the style", not "the artist", 2026-09-11

Nine remaining labels said artist where they meant the style — "Using the artist's tempo", "Whatever the artist writes". Eight made a claim about a real person. All nine now name the style, in all eighteen languages, using each language's own word.

Added - the documentation site in eighteen languages, 2026-09-11

A language picker on every page, offering the same eighteen languages the plugin does, each by its own name.

Fixed - naming your exports no longer breaks Settings in a browser tab, 2026-09-11

The export-naming panel asked the tab for a naming template and got back a different shape than it reads, taking the whole Settings panel down with it. A tab has no naming template — its downloads are named in the engine — so it says so and leaves the section out.

Fixed - bells ring like bells instead of being cut short, 2026-09-10

A church bell rang 3.2 seconds when its own partials are tuned to ring for nine: letting go of the key engaged a damper, and a tower bell has none. Same for a gong, orchestra bells, a steel pan and a handpan. A church bell now rings 6.6 seconds, and genuinely damped instruments are untouched, because shortening the sound is the point of those.

Two faults that fix uncovered: stopping everything stopped working on those instruments, so a panic left a gong ringing at full level — a panic and a key release are now different things — and bending a struck instrument was changing its loudness by up to 7 dB, because retuning a ringing resonator moves its level too.

⚠ Known and not fixed: 107 of the 118 library instruments named Bell or Chime are built from harmonic oscillators rather than a bell's inharmonic partials. The generators only reach for the modelled ones.

Fixed - the pitch bend knob now bends, and stays where you put it, 2026-09-10

Twelve of the thirteen instrument engines ignored the pitch wheel entirely — every bell, guitar, bowed string, horn, piano, organ, voice, drum machine and character instrument, from the drawn knob and from a hardware controller. A modelled instrument is told its pitch once, and nothing carried the wheel to it afterwards. Now a bell's partials, a guitar's string length and a singer's voice all move, while the parts that do not follow the note stay put — a violin's body, a vocal's formants, a kalimba's box.

And the knob no longer undoes you. It sprang back to centre on release, which is what a hidden sprung wheel does and not what a drawn knob with a readout does. It holds its position now; double-click re-centres it, as every other knob does.

⚠ That made a second fault reachable, fixed here too: on the resonant-chord-bank instruments, the second note of a phrase played with the wheel held came out a fifth sharp. Nothing could have found it before, because a wheel could not still be held when the next key went down.

Fixed - the virtual keyboard fills the space it is given, 2026-09-10

The piano stopped part way across and hugged the right edge: its row sizes children to their own content, so the keyboard was as wide as the small octave controls above it rather than as wide as the app. It fills its container at every size now.

Added - drag a Factory Pack loop straight into your patterns, 2026-09-10

The pack browser ships 5,085 MIDI loops and could play every one and drag one out to your DAW — but there was no way to bring one in, so you heard the beat you wanted and rebuilt it by hand. Every loop row is a drag source now: drop it on a generator and it lands split onto the right parts, exactly as a .mid from the File Explorer does.

⚠ The Song tab refuses a loop and says so with the cursor: Song builds an arrangement out of a file's sections, and four bars have none.

Fixed - a peer's shared folders can be opened, and the badge tells the truth, 2026-09-09

The shared explorer got its client last release and could not have worked. Three faults, all invisible because the mock browser was hand-fed rows in the page's shape and nothing compared it to what the plugin sent.

No folder could be opened. The plugin answered kind: "folder" | "sound" with no isDir, which is what the pane reads to draw a twisty — so every share root rendered as a file, and "do you have this?" was being asked about directories.

Every file claimed to be a fraction of a second long. The row's duration field is not a duration: it is length folded logarithmically onto 0-to-1 so a one-shot and a four-bar loop compare. It was drawn as "0.35s". It is named for what it is now and shown without a unit.

"You have something close" could never appear. That needs the four numbers describing a sound and only the fingerprint was sent, so a producer with a FLAC of a pack they own in WAV was told they did not own it.

⚠ The owner's rule is unchanged: no sample byte crosses between two peers — sixteen bytes of fingerprint and four numbers.

Fixed - a Wi-Fi blip no longer ends your collaboration session, 2026-09-09

A dropped packet or a laptop waking from sleep was treated as the other person leaving. The connection reports "disconnected" while it is still trying — an explicitly transient state that usually resolves itself — and the sidecar tore the link down on the first one. It now re-checks the address it has for eight seconds, which makes a brief outage invisible. Anything longer is still a real departure: the seat, handle and colour are held for two minutes as before.

Fixed - loading an instrument brings up the keyboard and its knobs, 2026-09-09

Dropping a sample onto a generator, or routing one in with Ctrl+Arrow, gave the part a voice — and the knob row that shapes it did not appear until you switched tabs and came back, because the reverb, delay, drive and pitch controls were reading a stale answer to "does this part make a sound yet?". Loading an instrument now also opens the on-screen keyboard, so there is something to play it with.

Changed - two drum behaviours reach the artists they were built for, 2026-09-09

A comping snare and a backbeat played on a clap were both built and neither was reachable — no artist asked for either. Art Blakey now comps, which his research entry describes; Trina and Trick Daddy put the backbeat on the clap, which is what their entries say Miami bass does.

Fixed - the same preset now sounds the same twice, 2026-09-06

Auditioning a preset gave a slightly different sound every click — for wide detuned texture pads, up to four times the level. Starting a fresh sound reset the delay and reverb and left every voice's randomness running, and that randomness is both where an oscillator starts in its cycle and the noise a drum is made of, so a pad's voices cancelled by a different amount each play. They are seeded from the preset now: the same sound twice is the same sound, and notes still vary between themselves.

⚠ Two presets were genuinely too quiet to preview once the measurement could be trusted — Pluck Coin and Frozen Cloud — and both are nudged up.

Fixed - no instrument sits off centre any more, 2026-09-05

Some sounds baked with a DC offset — the waveform shifted off the centre line rather than swinging around it. It reads as loudness on a meter and as nothing to an ear, eats headroom, and makes a mix behave oddly for reasons nothing on screen explains. Current Pad was worst at −0.26 of full scale, with forty rows across the Expansions sharing the shape. Every synth removes this at the output; Freally now does too.

⚠ A handful of pads are quieter, and that is the fix working — part of their level was the offset pushing the saturator harder. None was re-voiced: they tripped a level check that measured them a fifth of the way up a swell it gave 1.25 seconds to finish. It listens for four seconds now, as the preview player does.

Fixed - knobs, keys and every other drag control, 2026-09-05

Turning a knob on the Synth page could do nothing at all: it lit up, took focus, showed a number, and the sound never changed.

Every drag control asks the OS to hold the pointer for the length of the gesture, so a drag survives the cursor wandering off the knob — and that request was made before the control armed itself. On any machine where it was refused, the control never started listening and the gesture was thrown away. Twelve controls shared the fault: the knobs, keyboard keys, drum grid, piano roll, velocity lane, ruler, envelope editor, pad editor, kit rows, preview strip, rail resizer and song timeline. They arm first and ask second now.

Fixed - the pianos sound like pianos, 2026-09-05

Every piano had a buzz at the start instead of a key strike. Two faults, both measured rather than guessed:

The hammer is louder and brighter now, brighter on the grand than the upright, which is the difference between the two actions. The unison strings are tuned closer together — the old spread wandered enough between notes to be heard as a wobble.

Fixed - the Play button under the file browser, 2026-09-05

The Play button below the browser and the one inside it did different things, and the outer one was wrong: on a MIDI file it played whatever .wav you auditioned last, under the MIDI file's name. Both go through the same door now.

Fixed - Reverse shows you the clip backwards, 2026-09-05

Switching Reverse on changed the sound and left the picture alone, so the one control whose job is to be obvious showed nothing. The waveform is drawn end-first while reverse is on, the playhead still travels left to right, and clicking a peak plays the peak you clicked.

Added - voice chat can find your microphone and speakers, 2026-09-05

Collaboration's voice half had everything except the hardware: echo canceller, noise gate, codec and jitter buffer were all built and driven by nothing. The session helper now lists the microphones and outputs your machine reports, opens the pair you chose, and closes them the moment you switch Voice off — so the light on your interface goes out when you say it should. Your output is a separate choice from your microphone, because monitors and headphones are different things.

⚠ Voice chat needs the device at 48 000 Hz. If yours is not, Freally names the device and the rate rather than failing quietly.

Fixed - the playhead marker no longer freezes when the window is busy, 2026-09-05

Dragging the standalone's title bar froze the playhead until you let go, then it jumped forward — which looked exactly like playback stopping and restarting. It had not; the sound played the whole time. The marker was asking the plugin where it was thirty times a second and waiting, and moving a window on Windows blocks the app's window loop, so answers stopped arriving while the audio thread never missed a beat. It now keeps moving from the tempo between answers and corrects itself when one lands.

⚠ The same freeze could happen any time a DAW's window was busy, so this is not only about dragging.

Added - your own samples, on your own shelf, 2026-09-05

Point Freally MIDI Master at the folders you keep one-shots in and it works out which can be played as instruments. Press Find instruments in my folders in Categories; it reports progress and you can stop it at any time. A second pass over unchanged folders is instant. What it finds goes on a shelf of your own, below the four Factory Expansions, named after you.

⚠ A quiet sample is kept — quiet is your choice, and only a file with no sound at all is refused. Anything over ten seconds is left off: playing a sample lower stretches it, so an eight-second pad an octave down is sixteen seconds held per note.

⚠ Scanning needs the plugin or the standalone. A browser tab can open one folder at a time and forgets it on reload, so there is no library for it to walk.

Added - the app asks what to call your shelf, 2026-09-05

The first time you open Freally MIDI Master, right after the licence, it asks what your shelf should be called and will not generate until you answer. Everything you save lives under that name, and changing it renames the shelf — nothing moves and nothing is lost.

⚠ If your machine will not let the app save the name, it keeps it for the session, says so, and lets you carry on. Nothing is ever blocked by a file it could not write.

Added - the KIT panel tells you when a sample slides, 2026-09-05

Drop a riser or a sliding 808 onto a melodic pad and the app used to find a note in it, confidently, then play that slide at every key — each a different interval. It now measures whether the sample holds its pitch and says so under the pad: "This sample does not hold one pitch, so every key will play its slide." It tells you rather than refusing the file: a slide is still worth playing, it is just not an instrument.

Added - the numbers behind a human drummer, 2026-09-05

data/humanize/groove.json holds what 1,150 real drum performances actually do — per style a swing ratio, and per drum how far it sits from the rest of the kit, how much it wanders, and what a ghost, a main hit and an accent measure. Nothing you have made changes: no shipped artist uses the new numbers, so every seed rebuilds the beat it rebuilt before.

⚠ One finding is audible: a drummer's hi-hat pedal lands 7–20 ms ahead of the rest of the kit in every style measured. And one thing is deliberately absent — how much a drummer wanders is ~15 ms whether jazz or punk, so there is no per-genre looseness table, because there is no per-genre looseness.

Added - hear a style as you build it, 2026-09-05

With the transport running, the style editor plays what you are building as you build it — move the swing slider or change the snare placement and the next loop is the style you just described. Nothing is saved while you do it, and your own take comes back the moment you close the editor, whether you saved the style or not. Auditioning is a sound, not a change.

Added - the phone can ask the desk for an MP3, 2026-09-04

MixSir could always record its own playback into a WebM, which works anywhere and has one flaw nothing could fix: it records in real time, so a three-minute song took three minutes. On the same network as your desk you can now just download an MP3, encoded offline on the machine that has the audio. Every stem has its own button, so sending somebody a bassline is one tap instead of a 40 MB WAV.

⛔ Three files, three meanings, named under the buttons: Save your mix renders the balance you just set, on the phone; Save small is that balance as a WebM in real time; Desk mix — MP3 is the take as generated, every fader at unity. Confusing them would quietly throw away the mix you spent ten minutes on. A stem is the exception, and that is why it is the best of them: a stem at unity is the stem.

⚠ Nothing was added to the plugin — the encoder lives in the companion program behind its own feature flag, and a check fails if that stops being true.

Changed - the novelty guard screens against 47 melodies instead of 7, 2026-09-04

Every melody the generator writes is fingerprinted by its shape — the run of intervals and gaps between onsets — and checked against a bundled table before you hear it; a match is thrown away and drawn again. That shipped with seven public-domain melodies and 104 fingerprints, which is a working switch with almost nothing behind it. It now holds 47 melodies and 834 fingerprints, still under the five milliseconds it promises.

⛔ What this is not. Every melody in the table is public domain, permanently: screening against a commercial hook would mean deriving that hook's contour, and a contour listing is note data — the one thing this product must never carry. The guard catches an accidental quotation of a well-known melody. It is not why the output is original; that is the engine being rule-based with no recording anywhere in the chain.

Added - four Factory Expansion packs, 1,400 new pitchable instruments, 2026-09-04

The library goes from 248 to 1,648 instruments, and from 410,688 presets to 2,729,088 — still not one file on disk, because every preset is computed from its address. They arrive as four new shelves rather than being poured into the folders you know: subtractive analog; FM and early digital; texture, tape and dust; and voice and world bodies plus the two registers nothing else uses.

They sound like machines, not presets, and the first draft had none of the four things that do it: the oscillators run free, so no two notes begin identically; the filter tracks the keyboard; velocity opens the filter rather than only raising level, which is the commonest tell of a synthesised instrument; and a second LFO puts a cent or two of drift on the pitch — not vibrato, just the patch being alive.

Nothing sounds like anything else, and it is measured: the existing gate renders every instrument at every variation in all 69 genres and fails if any two land on the same fingerprint.

Added — Freally MIDI Master runs in a browser, 2026-09-03

The whole app, in a tab, with nothing to install — not a demo and not cut down. The browser runs the same crate the plugin does, compiled to WebAssembly, so a beat generated in a tab and one generated in your DAW are the same bytes. That is a gate rather than a promise: web_parity generates on both sides and compares the .mid byte for byte, refusals included.

⛔ Two things a browser cannot do, said before you find out the hard way: there is no Follow DAW, because a tab has no host transport, and a clip cannot be dropped straight onto a DAW track. Both limits appear in the app and in Settings → About.

The library reaches the tab whole — 410,688 presets — and costs nothing to deliver, because every one is computed rather than stored. After one visit it generates with the network off, and it installs to its own window. The offline charter is amended in the same change: the page is delivered over the network, generation happens on your machine, and nothing you make is ever uploaded.

Changed

Added — the instruments now sound like records, 2026-09-02

The factory instruments were retuned against what a professional sample measures — how long a hat rings, where a kick's weight sits, how a mallet decays. Producers had been reaching past several of them, and the numbers say why: the drum-machine hi-hats were three to five times shorter than a real one, so they read as clicks instead of hats.

A bug underneath four engines was the bigger story. decay on the modal, percussion and world-percussion engines, and length on impact, are each documented as a multiplier whose neutral is 1.0 — and every one was clamped to a ceiling of 1.0. No sound in the library could ring longer than the real instrument. The marimba measured 250 ms against a 510 ms reference and would not move however hard the model pushed. All four are fixed, with a gate that fails if the ceiling returns.

248 instruments now, up from 225, for 410,688 presets. Pitch modulation is findable: 91 respond to it and 157 do not, the library filters by it, and every row that has it carries a mark.

Added — 5,085 MIDI loops in the Factory Packs, 2026-09-02

Browse and hear drum, percussion, bass, chord, melody and countermelody loops instead of generating, listening and generating again. Every one was written by this app's own generators from its own style models — nine megabytes of notes, not a gigabyte of somebody else's recordings. Picking a loop plays it and the list stays on screen, so a folder can be walked straight through.

Two things had to be fixed first. The browser drew the folders and clicking a row did nothing — the renderer and the file reader were both finished and neither was connected. And once connected, every loop was read as a drum loop regardless of folder, which is worse than it sounds: a bassline sits exactly where the kick, snare, clap and hats live on the standard map, so it played back as a completely convincing beat that was not the file.

Added — 189 more artists and producers, 2026-09-02

Dancehall riddim builders, amapiano, Jersey club, drum & bass, house, reggaeton and the Detroit and Michigan lanes. 2,413 style models ship now.

Fixed — a held key never stopped, 2026-09-02

Pressing a key beside a generator's piano roll sounded a note that never ended. Releasing the mouse now stops it, as does dragging away, the window losing focus or the panel closing. The keys are also labelled properly: black keys take white text, white keys black, on both keyboards.

Fixed — the loop browser could have shipped empty, 2026-09-02

A change that stopped the loop pack being compiled into the app twice — nine megabytes, in every build — also stopped it being found at all. The browser would have drawn an empty tree. Caught by the test that counts the files rather than trusting the code.

Changed — the test suite runs in a fraction of the time, 2026-09-02

Nothing a producer sees, but it is the difference between catching a mistake in minutes and in an hour. One gate regenerated every model's bar once for every other model it was compared against — 435 seconds down to 1. The variety suites now use every core: melody 576s → 60s, countermelody 800s → 66s. The local CI runner also puts its cheap checks first, so a formatting slip is reported in seconds rather than after the whole Rust suite.

Fixed — the variety gate covered one genre of sixty-nine, 2026-08-31

The gate ran House alone; Trap had sub basses that sounded identical and it found nothing because it looked nowhere near them. There is now one #[test] per genre — 69 of them, sweeping 372,600 presets. Getting them green took four rounds:

⚠ The gate resolves finely enough to catch what was reported — Sub808's twenty-four correlated at 1.0000 — and does not adjudicate whether two audibly different marimbas differ enough.

Fixed — an instrument sounded the same in all 69 genres, 2026-08-31

Measured, and stark: Sub808's signature preset correlated 0.9938 between Trap and House, and an acoustic piano ran 0.974–0.997 across the entire roster. apply_genre's modelled branch could only reach filter.cutoff, filter.drive and the FX chain — a filter a physical model barely uses and a chain that sits after it — so nothing it did changed how an instrument was struck, bowed or blown.

colour_modelled maps the genre onto each engine's own parameters. The 808 is decay and glide: a trap 808 rings a bar or more and slides into the note, a house kick is tight and does not, and the profiles already carried it as weight — Trap 0.88 against House 0.60. Hammer hardness is the piano, which is what voicing literature talks about: Jazz sits at drive 0.10 against Metal's 0.70. A brighter genre pulls a Hammond's upper drawbars up; a harder one picks a string nearer the bridge.

⚠ Each push is built from more than one profile dimension: a single dimension at ±0.30 is below what a listener or a fingerprint can tell apart.

Added — a gate on the genre axis, and why it counts rather than bans

an_instrument_sounds_different_in_every_genre renders every instrument's signature preset in all 69 genres — 15,525 renders — and requires each to sound distinct in at least 62 of them.

⛔ A count, not a pairwise ban. Requiring all 2,346 genre pairs to differ failed on Jungle == Breakbeat and Cinematic == Downtempo, genres that really do share a character — and authoring a difference between them to make a test green is exactly the mistake behind 396 reverted artist models. What was asked for is that an instrument is not one sound wearing 69 labels, and a floor on the distinct count says that without inventing anything.

Fixed — an audition rendered from scratch every time, 2026-08-31

⛔ This library cannot be pre-baked, and the number is why. 225 instruments × 69 genres × 24 variations is 372,600 presets; at four seconds of 22 kHz mono that is 61 GB, and at the 48 kHz float the player reads, 266 GB. So a clip is rendered once and then behaves like a baked one: 23.79 ms mean, 42.5 ms worst to render against ~0.1 ms to hand back a held copy. Thirty-two clips, about 24 MB — arrowing up and down a list revisits the same handful of rows, so a small cache catches nearly every repeat.

Added — ↑/↓ walk the library and play what they land on, 2026-08-31

The same gesture the file tree has had since August, and the library was the one list in the panel where every row had to be clicked. ⚠ Bound to the listbox rather than the window, so it never fires while the piano roll is using the same keys to nudge notes.

Fixed — half the preset library was one sound repeated, 2026-08-31

⛔⛔ modelled_defaults promised "a touch of per-preset humanisation" over let _ = rng; — a comment describing behaviour nobody had written. The re-roll it called only knows how to vary a wavetable, none of which a physical model reads. Measured, Sub808 variations 0–5 were byte-identical, correlation 1.0000, while the patch's wavetable dutifully changed. Roughly half the library is modelled, so half of the 24 variations per combo were one sound twenty-four times. randomize_modelled moves each engine's own parameters, jittered around the kind's defaults rather than re-rolled, because a variation is a different take on an instrument, not a different instrument.

⛔ A sub is a sine, and swapping it is not a variation. The pack re-roll replaced it with a saw and stacked nine detuned voices; at 32 Hz that is edges, beating and aliasing — exactly the static reported.

⛔ Slap Bass and Pluck Bass shared an arm and were the same patch under two names. Both are an electric bass string now, separated where a player separates them.

Added — a gate that listens to all 5,400 presets in a genre, 2026-08-31

no_two_presets_in_a_genre_render_the_same_sound renders every instrument × variation in House — 225 × 24 — fingerprints each by length, level, attack slew and eight harmonic ratios, and asserts no two collide. 24 seconds.

⛔ It has to listen, not read the patch: the 808 Sub's variations differed on paper, so a fingerprint taken from Patch would have passed all twenty-four. It was checked against the bug — with randomize_modelled disabled it fails immediately and names the colliding pairs.

Fixed — the preview did not promise what the generator played, 2026-08-31

The patch was never the problem: the audition and the generator build the same preset. What diverged was everything stacked on top — PartSound carries reverb, delay, drive, pitch modulation, gain, pan and an ADSR, the generator applied all seven and the audition none, so a part still wearing the last instrument's reverb played the new one through it. Choosing an instrument now resets the shaping, through a single door both the Use in … button and Ctrl+→ go through.

⚠ Deliberately not the rule above it in the browser, which reads a part's stored sound first so merely touching a part cannot wipe your edits. Choosing a new instrument is a different act.

Changed — the library opens on Trap, and its genres read alphabetically, 2026-08-31

⚠ genre is an index into a list that does not exist yet when the store's default is written, so 0 never meant a genre — it meant whichever the taxonomy listed first. It moves to Trap when the taxonomy arrives, and only from an untouched 0. The sort is on what is drawn, never on what is stored: the library slices on the taxonomy index, so sorting the list itself would silently repoint every address.

⚠ The mock answered Genre 1 … Genre 69 — already alphabetical and containing no Trap, so it could not have tested either rule. It answers real names now.

Fixed — every instrument auditioned as the same sub-second blip, 2026-08-31

The symptom was real and it was not the synthesis: measured through the real render path an acoustic piano's spectral centroid sits at 1.32 against a clavinet's 2.87, and the routing is right.

⛔⛔ What they shared was the shape. The audition borrowed a renderer that sizes a one-shot for a sampler — a 0.6 s gate and a 1.4 s tail. Half a second is long enough to hear a marimba and nowhere near long enough to hear an organ, a violin or a pad, the families whose character is what happens after the attack — so all 225 came back as sub-second blips at the same pitch and roughly the same peak.

The audition holds its own note now, 1.5 s + 2.5 s: durations that were all 0.6–1.0 s are 0.64 s for a clavinet and 1.84–1.91 s for an organ. ⚠ A struck instrument pays nothing, being cut at the silence floor.

Fixed — the preview player never showed an instrument playing, 2026-08-31

The playhead poll asked selected === null — but selected names a file, and auditioning an instrument clears it on purpose so the MIDI panel stops describing a .mid you can no longer hear. So an auditioned instrument read as "nothing playing": no playhead, no elapsed time, no seek, for the whole clip. It asks whether a waveform is loaded now, which is true of both paths.

Fixed — every generation in the standalone came out at 120 BPM, 2026-08-31

⛔ nih-plug's standalone reports a tempo, and it is its --tempo default of 120. The file's own header says there is nothing to sync to, and the transport said 120 every block anyway — so auto-sync with no pin became a 120 override that beat every artist in the roster: suicideboys authors 125–160 and generated at 120, Drake 130–150 and generated at 120.

One line fixes it: the host tempo is authoritative by default, because a DAW's tempo must never be second-guessed, and cleared by the standalone unless the user named a tempo themselves with --tempo, in which case it is exactly what they asked for.

Changed — the style inspector left the left rail, 2026-08-31

The bottom-left panel now shows the style's name, genre, scales and tempos and nothing else — which is what ArtistPane already drew. The parameter dump under it is gone; prettifying its labels twice did not answer the complaint, because the parameters themselves were not wanted.

⚠ StyleInspector is kept, unmounted, so it is one line to restore — and with it go the per-parameter overrides and its own "Save as my style". The Style Editor dialog still saves a style of your own.

Fixed — clicking an instrument to hear it also built its patch, 2026-08-31

A library row called select, which builds the patch in Rust and reloads the synth page — two round trips per row, paid by someone who was only listening through a list. The audition never needed either. A row now auditions and highlights, nothing more, so an instrument reaches a generator by exactly one gesture: the Use in … button or Ctrl+→.

⛔ And that button now lands where the rows say it will. It read activeTab while the rows read targetPart, which differ on the SYNTH page — so the button named one generator and the list beside it another. It also loads the patch now; without that you heard the old instrument until you generated again.

Fixed — a generation could use a scale the artist never writes in, 2026-08-30

The engine already samples an unpinned scale from the model's own list, so the hole was the pin: it survives an artist switch by design and nothing asked whether the new artist writes in it. Picking minor pentatonic on trap and moving to UK Drill generated drill in a mode drill does not use — and the chip made it easy, offering all 41 modes the engine knows, of which trap authors four. The chip now offers the artist's own scales, and an artist switch drops a pin the new artist does not write.

⚠ Dropped rather than substituted, where the tempo beside it is clamped: a range has a nearest legal value, a set does not. There is no "nearest" mode to phrygian, and inventing one would be the app choosing an artist's sound. The key chip is untouched — a key is transposition, where a mode is the character itself.

Changed — "Does not write" is back in the artist pane, 2026-08-30

It is the half that prevents silence: the bass, chord, melody and counter generators each return an empty track when the model authored no block, so an artist who writes no bassline answers Generate on that tab with nothing at all.

⚠ Only the negative half. "Writes …" is a list you can infer from the tabs; "does not write …" is the one that changes what you do next, and it renders only when something is missing.

Fixed — the seed sat on top of the STYLE panel, 2026-08-30

.stage__controls is 740px intrinsic and was nowrap with flex-shrink: 0 on every child — an immovable object in a 1fr track between two rails you can drag to 560px each. An oversized item in a column flex container overflows towards the start, so it painted leftwards across the rail.

⛔ SeedChip.css had already solved half of this and was being overruled: the seed input is flex: 1 1 20ch with min-width: 0 precisely so it can hand a character back, and the blanket flex-shrink: 0 one level up meant it was never asked. The seed asks for 10ch and grows now, because flexbox picks line breaks from the basis before any shrinking happens. The row wraps as a last resort, which it never did before.

Changed — the artist pane says three things, 2026-08-30

Genres, scales and tempo range — and every scale, where it showed the first. An artist who only writes natural minor and one who moves between minor, dorian and minor pentatonic are different to write with, and one entry cannot tell them apart.

⛔ What came out, named so it is not restored by accident: the era, the first key, the half-time note, the moods, and Writes / Does not write. It also retires a contradiction this pane carried — it claimed Bass for the 360 models whose 808 is the bassline, while the Bass tab refused them.

Fixed — Drake generated at 73 BPM, 2026-08-30

Drake authors 130–150. A tempo pin survives an artist switch by design and was held only to Ableton's 20–999, so a 73 carried in from another artist stayed 73. The bound now lives in the control you are looking at, and an artist switch pulls a carried pin into the new artist's range — clamped, not cleared, because someone who asked for the fast end of one artist means the fast end of the next.

⛔ It was tried two layers deeper first and tests rejected both. In the store setter, the tempo box sets a pin on every keystroke and clamps only on blur — or typing "5" on the way to "50" would be corrected under the cursor. In the engine, reroll_section passes the record's tempo through the same function, so the clamp pulled a song at 155 down to 145 one section at a time.

Fixed — the instruments, for every model rather than a few, 2026-08-30

2,224 models, and only the melody had ever been asked what it was. The other three parts came from a genre shortlist that had read nothing about the model. Each part answers from its own block now:

⚠ The counter got its own shelf because it shared the melody's, and not one lead list held a pad, a string section or a choir — so 655 models saying "my counter is sustained" were answered with a Saw Lead.

Fixed — 120 BPM and 73 BPM sounded exactly the same, 2026-08-30

Schedule::arm places every note from the tempo the take was generated at, and nothing re-armed when the number changed: the chip moved, the next Generate used it, and whatever was already loaded went on playing at the old tempo.

⛔ A tempo is a clock, not a generation setting. The notes do not move; the clock does, which is what a DAW does when you drag its tempo. The same re-arm answers the other direction — with auto-sync on, dragging the project tempo used to leave the plugin playing at whatever it was made at.

Fixed — three readouts and a title bar, 2026-08-30

Fixed — the instruments an artist actually loads, 2026-08-30

⛔⛔ Drake's melody was a Hand Bell and his counter-melody was a Recorder. Three defects, measured:

▶ Measured after: Drake's melody is a soft Electric Piano, Future's a bright Bell, Adele's a warm Grand Piano. The engines were never the problem — 179 of the 225 instruments already route to a physical model.

Added — the night's instructions, 2026-08-30

Fixed — three readouts that were lying, 2026-08-30

Added — the v1.0.0 Must-Haves, 2026-08-29

Verified as already built

FMM-S01 (in-plugin sampler), FMM-S02 (MIDI-only bypass and per-lane audio mute with the MIDI still flowing) and FMM-S03 (native drag-out of MIDI and rendered audio) were all shipped under earlier task numbers.

Added — a record button, a metronome, and one key playing a chord, 2026-08-26

Security — three ways into a room that should not have existed, 2026-08-27

⚠ None is reachable in a shipped build yet, but each was a real hole in otherwise finished code, and each is fixed with a test that reproduces it.

Fixed — the recorder, on the second look, 2026-08-27

Every one was in code that had just shipped, and every fix has a test that fails against the old behaviour.

Fixed — the browser build, and a fixture that lied, 2026-08-27

Changed — the privacy page says what actually leaves the machine, 2026-08-27

⛔⛔ It said "no STUN server is configured and there is no default compiled in". That was not true. The build ships two — Cloudflare and Google — and contacts one when you open or join a room, so it can learn that some address is using a WebRTC application. Not who you are talking to, and not what you send. Both are named on the page now in all eighteen languages, with when they are contacted and what they learn.

⚠ A test had been asserting the untrue sentence, which is how it survived. What is still owed, and now says so, is a setting to change them or switch them off.

Added — the instrument grew a keyboard, a library you can save into, and a sample rack, 2026-08-23

Fixed — four defects nobody was looking for, 2026-08-23

Changed

Fixed — an inherited secondaryAnchor ate a child's whole kick budget, 2026-08-22

⛔⛔ 129 shipped models now generate a different kick. drums.kick.anchors is an array, so a child authoring its own replaces the parent's — but secondaryAnchor is a separate scalar beside it, so it survived that replacement and was unioned back in. A model saying "my anchors are 1 and 3" was given 1, 2& and 3, and where that filled the density budget every kick hit became guaranteed and the lane stopped varying. Measured on darius-rucker: 92 distinct kick shapes in 200 seeds over his own base, 4 over one whose secondary is "2&".

A child that authors anchors and not secondaryAnchor no longer inherits one. 34 genres author the field and 282 models author their own anchors with a budget an added secondary would fill, so this was never one model's problem.

Fixed — the About screen credited a dataset the product does not use, 2026-08-22

In all eighteen languages it said "Timing and velocity statistics derived from the Magenta Groove MIDI Dataset". That is not true: the humanizer is hand-authored from published technique research, and the tool that would have read GMD has never been written. Removed from the About pane and from docs/credits.md. Attribution is owed when you use a work; attributing one you do not use is a false statement about where the product's numbers came from.

Added — tags in the File Explorer, and the crash folder is finally offered

Added — three gates that close holes nothing was watching

Added — thirteen more parameters the dataset authored and no code read, 2026-08-18

Thirteen keys came off the debt register, across roughly 1,600 authored settings doing nothing.

Fixed — what the review pass found, 2026-08-18

Changed — the debt register says what is actually owed, 2026-08-18

Four entries were stale or wrong: timbreHint claimed 21 models and is 1,234 authorings, the largest authored-but-unread key in the dataset; monoCutSelf's true half already works and what is unread is the four models authoring false; minimalism and chordFrequency were filed at the wrong level, and the latter is inherited by all 590. Three are now marked a question for Mike rather than a to-do, because each either overrules a key the same model authors or is inert.

Added — sixteen parameters the dataset authored and no code read, 2026-08-18

⛔ Every one draws from its own seeded stream. Breaking that rule was caught two lanes away: the sub layer's velocity advanced the kick's stream, the kick moved, the bassline follows the kick, and a model fell to 946/1000 distinct basslines against a floor of 950 — a bassline gate failing because of a drum velocity.

Fixed — two panics reachable from a hand-edited model, 2026-08-18

Fixed — a style with nothing in it no longer saves, 2026-08-18

A draft that says nothing its base does not already say, opened with no beat on screen, is refused with a reason rather than written. ⛔ Ticking a scale is deliberately not content: the scale list the editor offers is narrowed to the base's own, so every scale you can tick is one your base already uses.

⛔ Measured against the draft the dialog opened with, not against a blank form — the first cut got that wrong in a way that made the rule almost never fire, because the draft seeds its swing from the selected model's defaults and six models out of 1,303 happened to match.

Changed — two dataset-load costs measured and removed, 2026-08-18

The lint no longer allocates a JSON pointer per key per model — it built a full pointer whether or not a finding fired, plus a lowercased copy of every key. And resolve_all merges each ancestor chain once: 534 of the 590 models are artists over a few dozen genre archetypes, and every one redid the same merge.

Fixed — a sustained countermelody stopped entering in the same place every time, 2026-08-17

A sustain_pad countermelody now chooses where in the phrase it comes in. The entry was the first tick the lead left free — the same answer for every seed that drew the same phrase length — so over a vamp, where all four bars are one chord, a third of seeds got one held note in one place. Twenty-seven models sat just under the counter-variety floor on that alone; twenty-three clear it now with no change to their data.

⚠ The entry is chosen from the phrase's first half: a pad that comes in during the last bar of its phrase is not a pad, and length is the whole claim sustain_pad makes. The old answer stays as the fallback for a lead so legato that the first half offers nothing, so no model's pad goes silent.

Added — the parts a generator answers, and four archetypes the research was owed, 2026-08-15

Changed — the roster sounds like its research again, 2026-08-15

396 artist and producer models restored to the values their research entries state, on the owner's instruction: "i don't care that they overlap, just ensure that it doesn't use copyrighted material." Two batch passes had moved them, both to beat pairwise distinctness gates. ⚠ Six keep their later state because that change fixed something musical and said what.

The two pairwise gates no longer fail on overlap. Two artists in one lane, on one kit, at one tempo should land on the same bar sometimes — that is what makes each sound like themselves rather than a deliberately-detuned neighbour. Both still print their ceilings, and both still fail on a pair identical at every seed.

The novelty guard now screens the bassline, which is what makes that safe. ⛔ It had excluded every bassline on an argument true of one rhythm in five — "a bassline is locked to the kick" — while 194 shipped models author independent_riff. ⚠ The table still ships hashes only: a fingerprint is a contour, and there is no way back from one to a note.

Fixed — what the review pass found in the four days above, 2026-08-16

Six reviewers over one branch. Three found the same defect independently.

Fixed — 2026-08-15

Added — browse by era, and a switch-off that survives the project, 2026-08-15

Fixed — 2026-08-15

Added — a sample becomes notes, 2026-08-14

Fixed — a project file could take the DAW down with it, 2026-08-14

⛔ A time signature carried in a shared project could abort the host. The meter arrives from the page and from persisted pins and neither was range-checked: 25/1 made one ninety-sixth of a bar longer than a quarter note, and the clamp bounding a drum note's length panics when its floor exceeds its ceiling. panic = "abort" is release-only, so in a shipped build that is the whole DAW and every unsaved project in it. The meter is narrowed where it enters and bounded where it is used, because either alone leaves the other door open. ⚠ Found by reading, not by a failing test — the suite was green.

The browser preview would decode a file that is not audio: it checked that a path was local, inside the library and a file, and never checked the extension.

Fixed — the tempo chip catches up with the mood, 2026-08-14

Pinning a mood updates the chips at once rather than on the next artist change — trap is 140 and its dark mode 136, so the readout named a tempo the engine was never going to use. ⛔ The base pin had the same gap in a way that looked fixed: it did re-read the chips, but before the pin had reached the plugin, so it filled them in with the value you had just moved away from.

Added — an artist generates in every genre they work in, 2026-08-14

"Drake, but in R&B". The roster has always listed an artist under every genre they work in — 529 of the 534 artist and producer models name a genre they do not inherit — and Generate has always answered the one they do. A Generate in chip picks which: the artist's own blocks over a different genre's foundation, so 2Pac under boom-bap is 2Pac over boom-bap rather than either alone.

⚠ Saved with the project, like the mood — reopening on the artist's own genre would silently produce a different record from the same seed. ⛔ Not a blend of two genres: merging two bases gives mud rather than two modes.

Added — the sound gets its own editor, 2026-08-14

Changed

The longest test binary in the project runs in 1.70 seconds instead of 1,300.91. It re-read 609 JSON files and re-resolved all 590 models on every call, once per generation across seven tests. The same helper existed in fifteen engine binaries.

Fixed

Added — the browser at library scale, and a history that outlives the session, 2026-08-13

Changed

Fixed

Added — every drum lane expands into a pitch lane, 2026-08-13

Fixed

Added — the drum grid becomes an editor, 2026-08-11

Added — the keyboard shortcuts panel, 2026-08-11

It has a button now, next to Settings and About. It was reachable only by pressing ? or F1 — a panel whose entire job is telling you what the keys do, findable only if you already knew a key. It also fits on one screen, and the drum grid's own gestures are documented for the first time, in all eighteen languages.

Fixed — 2026-08-11

Added — 32 new genres, 2026-08-10

The genre list goes from 20 to 52 — dark plugg, Detroit bounce, Jersey club, ATL swag rap, UK underground, EDM rage, digicore, jump-up DnB, neurofunk, jungle, pop DnB, UK garage, house, dance pop, pop 2020s, country pop, country shuffle, neo-soul, funk, future bass, afrobeats, amapiano, dancehall, reggaeton, baile funk, afroswing, Memphis rap, G-funk, lo-fi hip hop, sexy drill, hyphy and crunk.

Each writes its own drums, chords, melody, countermelody and bassline — none inherits a part wholesale — and each arrives with three moods, so picking a genre gives three different records rather than one. Every one is measured against the rest of the roster.

Fixed — a note could sustain past the end of the pattern, 2026-08-10

A ghost snare nudged late, or a tambourine on the final subdivision, could carry its length beyond the pattern — so the clip you dragged out held a note the bar had no room for. The other four generators had always trimmed; the kit never did.

Fixed — basslines could wander out of key, 2026-08-10

A chromatic bass note now lands somewhere. Passing tones are written as an interval off the chord, and over an ordinary chord that interval can leave the key — so the bass played a note reached from nowhere that led nowhere. It now approaches the note it precedes, the way a bass player walks into a change. Walked flat sevenths and blue notes are kept: those are the idiom, not the bug.

A bass no longer plays above the chords it is holding up, and four models whose bass doubled their own 808 note-for-note now play a real second part.

Fixed — the plugin could ship a stale genre list, 2026-08-10

The dataset is compiled into the binary and nothing told the build system to watch it, so a plugin built after a model changed could keep serving the roster it was compiled with, with nothing anywhere saying so.

Fixed — the File Explorer could not open a subfolder, and it was breaking four other things too, 2026-08-10

You can browse into subfolders again, at any depth. Opening a library folder worked; opening anything inside it was refused, because Windows' canonicalize returns paths beginning \\?\ and the check that refuses network paths treated that leading \\ as one. The same refusal was silently breaking the preview player, the waveform, .mid reading and dropping a sample onto a drum pad — all of which go through the same guard. Genuine UNC paths are still refused.

The browser can use the whole rail, where it was capped at roughly half the height however deep your folders ran.

Security — a page-supplied path could make the plugin authenticate to a stranger, 2026-08-10

Fixed — three ways your work could go missing, 2026-08-10

Added — a real file tree, folder tabs, starred favourites, and MIDI that knows what it is, 2026-08-10

Added — drop a MIDI file in and it works out what is in it, 2026-08-10

Drag a .mid onto a generator and its notes land there, or drop it on the Song tab and take the parts you want — the whole file arrives as an arrangement and nothing overwrites what you have until you choose it. A layered file is separated into Bass, Melody, Counter, Chords and Drums, and every part says why it was routed where it was — "on the GM drum channel", "lowest voice", "from the file name" — so a wrong guess is one click to redirect.

It was taught by real files, not by assumptions. Four sample-pack exports broke the first version three times out of three: packs put drums on channel 0, not the GM drum channel, so drums are recognised by their shape — a handful of pitches, struck many times, short. Held melodic notes overlap constantly, so chords are notes struck together rather than merely overlapping. And an 808's MIDI note says which key fires the sample, not how low it sounds, so a bassline routinely sits in melody register — which is why the file's own name is trusted above any measurement.

Added — drum pads on the stage, one box to find any artist, and a window that finally behaves, 2026-08-09

Fixed — 2026-08-09

Added — every artist gets moods, you can build and train a style of your own, and nothing copies your samples without asking, 2026-08-09

Fixed — 2026-08-09

Added — the melody stops quoting other people, every genre gets its own voice, and the hats talk, 2026-08-08

Changed

Four golden snapshots moved, each diff read before regenerating: trap and UK drill now author a hi-hat fill; ny-drill, liquid-dnb, country-train and boom-bap play their own basslines instead of inheriting one; and one closed hat that sat on top of an open hat is gone, which changes every later hat's velocity because humanize walks a lane in note order.

Fixed — what the review found, 2026-08-09

Fifteen findings survived independent verification. Worst first:

⚠ Two gates were reporting success over less than they claimed: the lane list had drifted to 21 of the engine's 37, and the solo test required the melodic parts to go silent — which is how that behaviour survived review.

Added — the sample browser you can actually use, and clips that look like clips, 2026-08-07

Fixed — what three reviews found, 2026-08-07

Fixed — the audition player, 2026-08-07

Fixed — 2026-08-07

Added — a real drum kit, a sample browser, and a kit per genre, 2026-08-07

Fixed — 2026-08-07

Added — play the generators together, and the 808s slide, 2026-08-06

Fixed — the drum lanes, the KIT panel, and a short right rail, 2026-08-06

Fixed — the editor window sizes itself correctly, 2026-08-06

Fixed — six defects found running the plugin in Ableton, 2026-08-06

Added

Changed

Fixed — an xhigh code review of the above, 2026-08-06

Fifteen verified defects, four of which would have shipped something broken.

Verified

Fixed

Added

Fixed

Song Mode went through four reviews before it shipped, every finding with a test watched failing first: undo now reaches the project file; undo across an artist change no longer resurrects the previous artist's record; locks and the loop follow their section when you clone, where a padlock used to draw on the wrong section and a re-roll regenerated the very clips it said were pinned; and re-rolling honours the record it belongs to.

Changed

Fixed

A machine without WebView2 no longer takes the DAW down with it. Opening the editor with no WebView2 runtime — or a read-only temp directory, or the plugin's browser profile already held by another WebView2 environment, which is what the standalone opened alongside a DAW does — panicked inside the host's own editor-open callback. Release builds abort on panic, so the host could not catch it and the session went with it. The editor now opens blank and says why. Two related panics went the same way: the custom-protocol handler, which ran from a frame a panic cannot even unwind out of, now answers 500.

0.4.0 29 July 2026

Added — unlimited undo/redo, and the licence gate

Fixed

Changed

0.3.0 29 July 2026

Added — melodic generation, and moods that multiply it

Fixed

Changed — Freally MIDI Master is becoming a plugin

Decided 2026-07-28. Not for the format's sake: a plugin is handed the host's tempo, time signature and playhead, so a generated pattern lands in the song you are actually writing rather than at whatever tempo the artist is authored at. docs/product-roadmap.md carries the decision, what survived and what did not.

Removed — the desktop app is retired

Freally MIDI Master ships as a plugin now. Releases from here on carry the CLAP and the VST3 and nothing else; the Windows, macOS and Linux installers are no longer built.

If you are on v0.2.0: nothing you have installed stops working, and nothing is uninstalled. Your copy will simply stop finding updates, because there will not be any — the update channel goes quiet rather than breaking. To carry on, install the plugin from this release and load it in your DAW, which is where the tempo sync, the host key and the notes-on-the-track live. That is the whole reason for the move: the desktop app could not know what song you were writing.

Known issue

Added

Fixed

0.2.0 25 July 2026

Phase 1: the app makes beats. Search an artist, press Generate, hear it, and drag it into a DAW.

Added

Changed

0.1.0 22 July 2026

First tagged build: the Phase 0 foundation. The Studio shell, the pure generation engine, the style-model dataset and the full CI spine are in place; the generators themselves arrive in Phase 1, so the transport and Generate are deliberately disabled rather than pretending to work.

Added

Known limitations