Skip to content

elhigu/funklang

Repository files navigation

funklang

A browser reimplementation of AmigaKlang — design Commodore Amiga synth instruments in the browser and export the real, byte-identical Amiga code.

🎛️ Live: https://funklang.mkael.net

AmigaKlang (by Jochen "Virgill" Feldkötter) is a demoscene tool that renders instrument samples with code instead of storing them — saving precious memory in Amiga demos and intros. funklang is a from-scratch, fully client-side reimplementation of its editor and code generator: everything (audio preview, m68k assembly, the final .bin) runs in the browser, no server and no toolchain.

It is faithful where it counts: the audio engine matches the original sample-for-sample, and the exported .bin matches the original generator byte-for-byte.

What it does

  • Edit instruments — up to 31 instruments, each a chain of phases (operators: oscillators, envelopes, filters, FX, cross-instrument clone/chordgen…). Live knobs, drag-to-reorder, per-note audition, undo/redo, autosave, .akp/.aki load & save.
  • Hear it instantly — a bit-exact reimplementation of the AmigaKlang rendering core plays your instrument as you tweak it.
  • Export real Amiga code — the CODE button generates, entirely in-browser:
    • the m68k .asm (AK_Generate routine),
    • the C generators (to reuse in your own demo engine), and
    • the exact Amiga .bin, with its exact byte size.
  • Know the size exactly — the footer shows the patch's real assembled .bin byte count (not an estimate); click it for a per-phase breakdown of what each phase costs.

The .bin format (and how to use it)

The exported .bin is a single position-independent m68k routine, AK_Generate, followed by its data tables — raw bytes, no header, no relocation. Drop it into your demo with incbin and call it. Set these registers and jsr to offset 0:

Reg Meaning
a0 sample buffer start (output)
a1 36864-byte temporary work buffer (freeable after rendering)
a2 external samples address (used when the patch has imported samples)
a3 rendering-progress address

It's the same blob the original tool's Export ASM route produces (the author's Aklang2Asm), assembled with vasm — typically ~half the size of the gcc-compiled C build ("Export Amiga Binary"). Full details, including the progress modes and the asm-vs-gcc distinction, are in docs/bin-format.md.

Limitations

  • No sample-import UI yet. funklang's focus so far is synthetic, code-generated instruments. Samples that are already in a loaded .akp are fully supported — read, played (the imported_sample op), kept on save, and emitted in the exported asm/C/.bin. What isn't built yet is importing a new sample in the editor (wav / raw / mic); that's an early-scope choice, not a fundamental one, and it may well be added later.
  • The Amiga .exe (Shrinkler-packed executable music) and Atari .prg export routes of the original tool are out of scope; funklang focuses on the demo .bin.

Bugs & feedback

funklang is a young reimplementation, so bug reports and feature requests are very welcome — please open an issue: https://github.com/elhigu/funklang/issues

Especially valuable are cases where funklang doesn't match the original AmigaKlang — a patch that sounds different, or an exported .asm / .bin that differs from what the real tool produces. The audio engine aims to be sample-for-sample and the assembly byte-for-byte against Aklang2Asm, so any such mismatch is a bug worth reporting — ideally with the .akp attached so it can be reproduced.

It's also very likely there are browser incompatibilities and rough edges in responsiveness and mobile / touch-screen support that still need fine-tuning. Reports here help a lot — please include your browser, OS, and (for touch issues) the device.

Development

npm install
npm run dev          # Vite dev server
npm test             # Vitest: unit + bit-exact DSP + byte-exact asm
npm run typecheck    # tsc --noEmit (strict)
npm run build        # production build (bundles the vasm-WASM size worker)
./deploy.sh "msg"    # build + publish to funklang.mkael.net

Architecture and module map: docs/architecture.md. Contributor/agent conventions (incl. the release process): AGENTS.md. Version history: CHANGELOG.md.

Credits

funklang stands entirely on the shoulders of the AmigaKlang ecosystem and its authors. All synthesis design, the .bin format, and the code-generation approach are theirs; funklang is a reimplementation, not original synth research. Full attribution and third-party terms (incl. the bundled vasm/Emscripten) are in THIRD-PARTY-NOTICES.md.

  • AmigaKlang & AmigaKlang GUI — Jochen "Virgill" Feldkötter (Alcatraz / Haujobb / Maniacs of Noise). The synth, the editor, the rendering core.
  • 4KlangGopher / Alcatraz — the "big brother" modular-synth lineage AmigaKlang follows.
  • Aklang2AsmDan / Lemon — the patch→m68k-asm generator that src/asm/akgen/ reproduces byte-for-byte.
  • ShrinklerBlueberry — the executable cruncher used by the original tool.
  • LSP & STrinkler (Atari playback)Leonard / Oxygene.
  • Thanks credited by the original tool: Hellfire, Bartman, Antiriad, Leonard, and the tips crew (Soundy, H0ffman, Bifat, Stingray, Aceman, Juice, Tecon).
  • vasm (m68k assembler, compiled here to WebAssembly without any modifications) — Volker Barthelmann & Frank Wille.

Links

funklang reimplementation by Mikael Lepistö (elhigu / funktion). AmigaKlang © Jochen "Virgill" Feldkötter.

About

Web port of AmigaKlang software synth app

Resources

License

Stars

1 star

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors