{"id":47827850,"url":"https://github.com/fabriziosalmi/mixi","last_synced_at":"2026-05-23T07:11:01.679Z","repository":{"id":349003755,"uuid":"1200255164","full_name":"fabriziosalmi/mixi","owner":"fabriziosalmi","description":"Deterministic audio workstation. Browser-native. Zero install. Dual decks, Rust/Wasm DSP, WebGPU visuals, 19 instruments, automixer, beatmatching, 17 skins, MIDI, headphone cue.","archived":false,"fork":false,"pushed_at":"2026-05-16T21:07:52.000Z","size":39872,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-16T22:35:38.349Z","etag":null,"topics":["audio-workstation","beatmatching","daw","dj","dsp","electron","midi","mixer","music","rust","synth","vitepress","wasm","web-audio","webgpu"],"latest_commit_sha":null,"homepage":"https://www.mixidaw.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fabriziosalmi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":"CLA.md"},"funding":{"github":["fabriziosalmi"]}},"created_at":"2026-04-03T07:46:32.000Z","updated_at":"2026-05-16T21:07:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fabriziosalmi/mixi","commit_stats":null,"previous_names":["fabriziosalmi/mixi"],"tags_count":49,"template":false,"template_full_name":null,"purl":"pkg:github/fabriziosalmi/mixi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabriziosalmi%2Fmixi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabriziosalmi%2Fmixi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabriziosalmi%2Fmixi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabriziosalmi%2Fmixi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fabriziosalmi","download_url":"https://codeload.github.com/fabriziosalmi/mixi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabriziosalmi%2Fmixi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33386151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T04:15:53.637Z","status":"ssl_error","status_checked_at":"2026-05-23T04:15:53.242Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-workstation","beatmatching","daw","dj","dsp","electron","midi","mixer","music","rust","synth","vitepress","wasm","web-audio","webgpu"],"created_at":"2026-04-03T20:01:56.728Z","updated_at":"2026-05-23T07:11:01.673Z","avatar_url":"https://github.com/fabriziosalmi.png","language":"TypeScript","funding_links":["https://github.com/sponsors/fabriziosalmi"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"screenshot.png\" alt=\"MIXI — Browser-native DJ workstation\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003e\u003ca href=\"https://www.mixidaw.com/app/\"\u003eMIXI\u003c/a\u003e\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  Deterministic audio workstation. Browser-native. Zero install.\u003cbr\u003e\n  Dual decks, Rust/Wasm DSP, WebGPU visuals, 19 instruments, automixer, beatmatching, 17 skins, MIDI, headphone cue.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.mixidaw.com/app/\"\u003e\u003cstrong\u003eLaunch in Browser\u003c/strong\u003e\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://github.com/fabriziosalmi/mixi/releases/latest\"\u003eDownload Desktop\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://www.mixidaw.com/\"\u003eWebsite\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://github.com/fabriziosalmi/mixi/discussions\"\u003eDiscussions\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/fabriziosalmi/mixi/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/fabriziosalmi/mixi?label=latest\u0026color=00d4ff\" alt=\"Latest Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/fabriziosalmi/mixi/actions/workflows/test.yml\"\u003e\u003cimg src=\"https://github.com/fabriziosalmi/mixi/actions/workflows/test.yml/badge.svg\" alt=\"Test Gate\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/fabriziosalmi/mixi/actions/workflows/docs.yml\"\u003e\u003cimg src=\"https://github.com/fabriziosalmi/mixi/actions/workflows/docs.yml/badge.svg\" alt=\"Docs\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-PolyForm%20NC%201.0.0-blue\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003ctable align=\"center\"\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/fabriziosalmi/mixi/releases/latest\"\u003e\u003cstrong\u003emacOS (ARM64)\u003c/strong\u003e\u003cbr\u003e\u003ccode\u003e.dmg\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/fabriziosalmi/mixi/releases/latest\"\u003e\u003cstrong\u003emacOS (Intel)\u003c/strong\u003e\u003cbr\u003e\u003ccode\u003e.dmg\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/fabriziosalmi/mixi/releases/latest\"\u003e\u003cstrong\u003eWindows\u003c/strong\u003e\u003cbr\u003e\u003ccode\u003e.exe\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/fabriziosalmi/mixi/releases/latest\"\u003e\u003cstrong\u003eLinux\u003c/strong\u003e\u003cbr\u003e\u003ccode\u003e.AppImage\u003c/code\u003e\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://www.mixidaw.com/app/\"\u003e\u003cstrong\u003eBrowser\u003c/strong\u003e\u003cbr\u003eZero install\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## What This Is\n\nMIXI is a dual-deck DJ engine and step sequencer that runs entirely inside a web browser. The DSP pipeline runs in Rust/Wasm (AudioWorklet) or falls back to hand-wired Web Audio API nodes. No Tone.js. No third-party audio wrappers. No server required.\n\nLoad two tracks. Mix them. The groovebox runs in parallel on its own bus. The automixer watches phase, spectrum, and headroom on a 50ms tick and applies corrections as visible, non-destructive mutations. Plug in a MIDI controller and it maps to anything. Pick one of 17 skins or write your own in pure CSS.\n\nIt ships as a static site. It also packages as an Electron desktop app for macOS, Windows, and Linux. An optional Python sidecar handles heavier analysis offline.\n\n---\n\n## Signal Chain\n\n```\nDeck A/B (Track mode):\n  BufferSource → Trim → 3-Band Parallel Isolator EQ (LR4 24dB/oct)\n    → ColorFX → DeckFX [FLT|DLY|REV|PHA|FLG|GATE]\n      ├── Fader → Crossfader → MasterBus\n      └── CueGain → HeadphoneBus\n\nDeck A/B (TurboKick mode):\n  KickSynth (pitch/decay/click/drive) → ValveA (tube) → ValveB (punch)\n    → Filter+LFO → Delay → Rumble (dark reverb + sidechain pump)\n      → DeckChannel.input → EQ → Fader → MasterBus\n\nDeck A/B (TurboBass mode):\n  MainOsc (saw/pulse) + SubOsc (sine, -1oct) → PreFilterHP (44Hz)\n    → Drive (tanh) → DiodeLadder (4-pole AudioWorklet, tanh saturation)\n      ↑ FilterLFO (BPM-synced) ↑ FilterEnv (bipolar, accent-modulated)\n    → VCA (2ms attack) → Dry + Distortion (Rat asymmetric)\n    → Delay (BPM-synced, HP feedback) → Bus (reverb, chorus, limiter)\n      → DeckChannel.input → EQ → Fader → MasterBus\n\n  EQ Crossover (Linkwitz-Riley):\n    Trim → LP₁→LP₂(250Hz) → lowGain  → merge\n    Trim → HP₁→HP₂(250Hz) → LP₃→LP₄(4kHz) → midGain → merge\n    Trim → HP₃→HP₄(4kHz)  → highGain → merge\n    Kill = gain 0. Other bands 100% unaffected.\n\nMasterBus:\n  Gain → MasterFilter → BandSplit (300Hz crossover)\n    ├── Sub (\u003c300Hz) → Mono Sum (phase-safe for PA)\n    └── High (\u003e300Hz) → Oversampled tanh Waveshaper\n  → Parallel Compressor (gain-compensated) → DC Blocker (10Hz)\n  → Headroom Pad (-0.3dB) → Brickwall Limiter → destination\n\nHeadphoneBus:\n  CueSum + MasterTap → Mix knob → Level → destination\n  Split mode: Master → R ear | Cue → L ear\n\nWasm DSP Path (optional, toggle in Settings):\n  Source A → Trim → AudioWorklet input[0] ─┐\n  Source B → Trim → AudioWorklet input[1] ──┤→ Rust DSP Engine\n    DspEngine: Deck EQ → ColorFX → FX → Fader → Crossfader\n    → Master: Filter → Distortion → Punch → Predictive Limiter → DC Blocker\n    ← 128 samples @ 44.1kHz, ~10µs per block (99.6% headroom)\n```\n\nEQ is a **parallel 3-band isolator** with Linkwitz-Riley 24dB/oct crossovers (two cascaded Butterworth per crossover point). Flat magnitude sum at crossover, zero phase difference between bands. Kill on any band silences only that band — other bands completely unaffected.\n\nThe Rust DSP engine (`mixi-core`) runs the full signal chain in an AudioWorklet when enabled: per-deck EQ, color filter, 5 effects, fader, crossfader mixing, master filter, distortion, parallel compression, predictive limiter (0.2ms lookahead), and DC blocker. Parameters flow via a 512-byte SharedArrayBuffer with layout versioning.\n\nThe brickwall limiter (threshold -0.5dB, ratio 20:1, attack 1ms) guarantees the output never exceeds 0dBFS regardless of how the faders are handled.\n\n---\n\n## Quick Start\n\nThe fastest way to install the desktop app on macOS or Linux is via our terminal installer:\n\n```bash\ncurl -sL https://raw.githubusercontent.com/fabriziosalmi/mixi/main/install.sh | bash\n```\n\nAlternatively, to build and run it locally:\n\n```bash\ngit clone https://github.com/fabriziosalmi/mixi.git\ncd mixi\nnpm install\nnpm run dev\n```\n\nOpen `http://localhost:5173`. Load audio files. Mix.\n\n### Production Build\n\n```bash\nnpm run build\nnpm run preview\n```\n\n### Electron Desktop App\n\n```bash\nnpm run build:all\nnpm run dist            # current OS\nnpm run dist:mac        # macOS\nnpm run dist:win        # Windows\nnpm run dist:linux      # Linux\n```\n\n### Python Sidecar (optional)\n\nExtended analysis, file management, and MCP bridge for external agents.\n\n```bash\ncd api\npip install -r requirements.txt\npython main.py --port 7779\n```\n\n---\n\n## Core Modules\n\n| Module | What It Does |\n|--------|-------------|\n| **Dual Decks** | Independent transport, pitch/tempo, hot cues, loops, scratch emulation. 19 pluggable deck modes: Track, Groovebox, TurboKick, TurboBass + 16 community instruments (TurboFM, TurboSynth, TurboVox, and more via [mixi-decks](https://github.com/fabriziosalmi/mixi-decks)). |\n| **TurboKick Deck** | Kick drum synthesizer + 16-step sequencer. THUMP macro, dual valves (tube + punch), filter + LFO, Berghain-style RUMBLE. |\n| **TurboBass Deck** | Acid synth with 4-pole diode ladder filter (AudioWorklet, mismatched first pole, per-sample tanh saturation, 2x oversampling). Mathematically derived DSP: VT from pole signal geometry, k_max from Barkhausen criterion, resonance compensation, quadratic curve. Saw + variable duty-cycle pulse wave, sub-oscillator, analog drift, pre-filter drive/HP. Bipolar filter envelope, octave-based env mod, accent with resonance-controlled depth. TIE (legato), gate length, slide time, filter tracking (Devil Fish mod). Rat-style distortion, ducking spring reverb, chorus, BPM-synced delay. ACID macro, copy/paste, pattern mutate/shift, 32 factory patterns (4 banks), 16/32-step sequencer. Two-row knob UI. |\n| **3-Band Isolator EQ** | Parallel Linkwitz-Riley 24dB/oct crossover. Kill = gain 0, other bands unaffected. |\n| **Deck Effects** | 10 built-in (7 in FX strip + 3 system): Filter (inline bipolar LP/HP), Delay (BPM-synced), Reverb (synthetic IR), Phaser (4-stage allpass), Flanger, Gate (beat-locked chop), Bitcrusher, Echo (dub delay with LP feedback), Tape Stop (LP darkening), Noise (white noise sweep). Parallel sends, gain-compensated. |\n| **Master DSP** | Band-split distortion, gain-compensated parallel compression, DC blocker, brickwall limiter. Sub-bass mono sum. |\n| **Rust DSP Engine** | Full signal chain in Wasm AudioWorklet. Per-deck EQ/FX/Fader + spectral sidechain compression + master chain. 10µs/block, 99.6% headroom. Zero-alloc hot path. Toggle in Settings. |\n| **AutoMixer** | Stateless 20Hz-tick arbiter. Reads a Blackboard of deck states. Applies Ghost Mutations — visible, auditable corrections for phase drift, spectral clash, headroom recovery. 20 intents across 5 domains (safety, spectral, dynamics, rhythm, structure). |\n| **Groovebox Deck** | 4-voice step sequencer (kick/snare/hat/perc) with drum synthesis on a decoupled bus. Own panning, mute, solo. Synced to master BPM. |\n| **BPM/Key Detection** | Powered by [open-bpm](https://github.com/fabriziosalmi/open-bpm): 7-estimator architecture (IOI + Comb + AC + Spectral FFT + Hopf + Tempogram + Low-band AC), SuperFlux onset detection, metrical fusion for octave resolution. 68.8% Acc1 on GiantSteps, 8.5:1 vs librosa. Two-speed API (fast + full). Goertzel chromagram for key (Camelot). Pure Rust/Wasm — no browser pre-processing. |\n| **MIDI** | WebMIDI API. Map any CC/note to any parameter. MIDI Clock Out/In (24 ppqn) for external gear sync. |\n| **MIXI Sync** | Binary sync protocol (64-byte UDP packets, port 4303). PID phase lock, auto-discovery, master election, predictive VJ triggers. BroadcastChannel fallback for browser. |\n| **Beatmatching** | Aerospace-grade PLL phase correction, harmonic sync, predictive phase, differential phase overlay, variable beatgrid, onset correlation, groove offset, drift compensation, audio clock reconciliation. |\n| **Waveform** | Min-max decimation, drag-to-scrub, beatgrid editing (Shift+Click), BPM confidence display, overview viewport drag, energy shadow, zoom sync. Direct DOM writes, no React reconciliation. |\n| **Headphone Cue** | Split-stereo or dual-output routing. Mix knob blends cue and master. |\n| **Recording** | Crash-proof WAV recording (SPSC ring buffer → disk, 1MB fixed RAM). WebM fallback in browser. Orphan recovery on crash. |\n| **WebGPU VFX** | 14-effect GPU shader: spectrum border, beat shockwave, particles, plasma, CRT, Tron floor, feedback loops. Ring texture spectrogram (64-frame history, 30 KB/s GPU upload). Canvas 2D fallback. ESC kill-switch. |\n| **Native Audio** | Optional cpal output via N-API addon (Electron). CoreAudio/WASAPI/ALSA bypass. Zero-copy SharedArrayBuffer ring. |\n| **17 Skins** | Runtime-switchable. Pure CSS custom properties — zero JavaScript per skin. |\n\n### Available Skins\n\nAcid, Aqua, Arcade Invaders, Blackfluo, Bloodmoon, Casino, Dune, E-Ink, Freetekno, Gold, Hologram, Industrial, Matrix, Nordic, Synthwave, Vaporwave, White.\n\nEach skin is a directory containing `skin.json` (metadata) and `skin.css` (CSS custom properties). To create a new skin, copy any existing one and modify the variables. No TypeScript changes required.\n\n### Mobile\n\nDedicated touch-optimized UI, code-split so desktop never downloads mobile code. Detects phones (`minDim \u003c 500 + touch`) and loads a purpose-built layout.\n\n- **Portrait** — Single-deck focus: hero BPM display, tall waveform, inline EQ/FX/PADS toolbar. Tap A/B to switch focus. Mini-strip shows the other deck's state. Crossfader pinned at bottom for thumb access.\n- **Landscape** — Dual-deck mixing: both decks side-by-side with waveforms, pitch faders, nudge buttons, and a horizontal crossfader.\n- **Overlays** — Slide-up glassmorphism panels (spring animation) for EQ, FX grid, performance pads, and headphone routing. Swipe down to dismiss.\n- **Haptics** — Vibration feedback: tick on pad tap, snap on crossfader center detent, confirm on cue save, panic on shake reset.\n- **Shake-to-panic** — Shake the phone to reset all EQ, FX, loops, and crossfader to defaults.\n- **Beat pulse** — Deck card borders flash in sync with the BPM for visual rhythm feedback.\n- **PWA** — Installable as a standalone app on iOS and Android. Safe area inset handling for notches.\n\n---\n\n## Architecture\n\n```\nsrc/\n  audio/          Core engine, DSP nodes, sample manager, BPM/key detection\n    dsp/          Wasm DSP bridge, SharedArrayBuffer param bus, worklet lifecycle\n    nodes/        DeckChannel (LR4 EQ), MasterBus, HeadphoneBus, DeckFx\n    recording/    Crash-proof WAV recording bridge\n    native/       Native audio output bridge (cpal/N-API)\n  gpu/            WebGPU VFX renderer, WGSL shaders, GPU detection\n  ai/             AutoMixEngine, Blackboard, Ghost Mutations, intents\n  decks/          Pluggable deck modes (TurboKick, TurboBass + 16 community decks)\n  sync/           MIXI Sync protocol (packet codec, PID phase lock, bridge)\n  groovebox/      Step sequencer engine, drum synthesis, UI\n  automixer/      AutoMixer panel, beat utilities\n  midi/           WebMIDI manager, controller mapping\n  components/     React UI — decks, mixer, browser, HUD, settings\n    mobile/       Touch-optimized mobile UI — portrait, landscape, overlays\n  store/          Zustand stores — mixer state, settings, MIDI, samples\n  hooks/          React hooks — sync bridge, keyboard shortcuts, drag, beatmatching\n  bridge/         MCP bridge for external agents\n  utils/          Logger, skin loader, watermark\n  types/          Shared TypeScript interfaces\nmixi-core/        Rust DSP engine (Wasm) — EQ, FX, limiter, analysis\nmixi-native/      Rust N-API addon — cpal audio output (Electron)\nelectron/         Electron main/preload, WAV header, native audio IPC\ntests/            Unit tests (vitest) + E2E (Playwright)\n```\n\n**Design constraints:**\n\n- React never touches AudioContext directly. A one-way bridge (`useMixiSync`) subscribes to Zustand state changes and pushes them to the audio engine via `setTargetAtTime`.\n- High-frequency visuals (VU meters, vectorscopes, waveforms) write to Canvas or DOM refs, bypassing React reconciliation entirely.\n- The automixer is stateless by design. It reads a Blackboard snapshot every 50ms and emits deterministic corrections. No FSM, no accumulated state, no drift.\n\n---\n\n## Tech Stack\n\n| Layer | Technology |\n|-------|-----------|\n| UI | React 19, TypeScript (strict), vanilla CSS + CSS custom properties |\n| State | Zustand 5 with transient selectors |\n| Audio | Web Audio API — hand-wired graph, no wrappers |\n| DSP | Rust/Wasm (mixi-core) — AudioWorklet, SharedArrayBuffer, zero-alloc |\n| GPU | WebGPU (WGSL shaders), Canvas 2D fallback |\n| Native I/O | cpal via N-API addon (Electron), CoreAudio/WASAPI/ALSA |\n| Bundler | Vite 6 |\n| Desktop | Electron 41 |\n| Backend | FastAPI + MCP server (Python, optional) |\n| Tests | Vitest (568), Playwright E2E (106), cargo test (198 Rust), BPM bench (164) — 1036 total |\n| Docs | VitePress, 24 languages |\n\n---\n\n## Scripts Reference\n\n| Command | Purpose |\n|---------|---------|\n| `npm run dev` | Vite dev server + API sidecar + MCP server |\n| `npm run dev:ui` | Vite dev server only |\n| `npm run build` | TypeScript check + Vite production build |\n| `npm run preview` | Serve production build locally |\n| `npm run dev:api` | FastAPI sidecar on port 8000 |\n| `npm run dev:mcp` | MCP bridge server |\n| `npm run dev:electron` | Electron + Vite in dev mode |\n| `npm run dist` | Package desktop app for current OS |\n| `npm run docs:dev` | VitePress dev server |\n| `npm run docs:build` | Build documentation site |\n| `npm test` | Run unit tests (Vitest, 568 tests) |\n| `npm run bench` | BPM detection + sync bench (164 tests) |\n| `npm run test:e2e` | Playwright E2E tests (106 tests: smoke + mixer validation) |\n| `npm run test:watch` | Watch mode for unit tests |\n| `npm run test:coverage` | Test coverage report |\n| `cd mixi-core \u0026\u0026 cargo test` | Rust DSP tests (198 tests) |\n\n---\n\n## Contributing\n\nContributions are welcome. Please sign the [CLA](CLA.md) on your first pull request — enforced automatically via GitHub Actions.\n\n---\n\n## License\n\n[PolyForm Noncommercial License 1.0.0](LICENSE)\n\nFree for personal use, education, research, hobby projects, and non-commercial performance. The license explicitly permits underground gigs, academic work, and private experimentation.\n\nCommercial use requires a separate license. Contact: fabrizio.salmi@gmail.com\n\n---\n\n## Acknowledgements\n\n- **[js303](https://github.com/thedjinn/js303)** by thedjinn — the original Web Audio TB-303 emulation that inspired the TurboBass deck. Awesome bass.\n\n---\n\nBuilt by [Fabrizio Salmi](https://github.com/fabriziosalmi)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabriziosalmi%2Fmixi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffabriziosalmi%2Fmixi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabriziosalmi%2Fmixi/lists"}