AunuAC — AunuAudioCreator
AI MIDI Studio · Extended Multi-Track Edition
Ubah satu paragraf deskripsi musik menjadi aransemen 26 track yang sudah dirapikan
(scale lock, sidechain sub-bass, boundary sanitizer), dengarkan langsung di browser lewat
Tone.js 16-channel engine, lalu unduh sebagai satu file .mid multi-track yang siap
di-drag-and-drop ke FL Studio, Ableton Live, atau Logic Pro.
Dibangun dengan Next.js 15 (App Router) + TypeScript + Tailwind CSS, endpoint OpenAI-compatible custom (Base URL + API key + Model ID dari user — tanpa provider bawaan), Tone.js, @tonejs/midi, dan berjalan di Wasmer Edge (WinterJS / WASIX).
1. Fitur
Endpoint custom & BYOK
- Identitas AunuAC di header, metadata
title: "AunuAC - AunuAudioCreator", favicon SVG. - Tidak ada provider bawaan. User mengisi Base URL endpoint OpenAI-compatible
(mis. AunuCore AI Gateway
https://ai.aunuhost.bond/v1, 9router, OpenRouter, server lokal), API Key (password field), dan Model ID. Ketiganya disimpan hanya dilocalStorage(aunuac_base_url,aunuac_api_key,aunuac_model_id) dan dikirim ke backend lewat headerx-base-url+x-api-key. Tidak ada fallback ke.env, tidak ada penyimpanan di server. - Fetch Models (
GET /api/models) mem-proxyGET {Base URL}/modelsdan mengisi saran Model ID (datalist); Model ID tetap bisa diketik manual sepenuhnya.
Song brief & 26 track
- Prompt textarea (genre, mood, gaya, referensi instrumen).
- BPM 60–200, Key 12 root × 5 skala (Major, Minor, Harmonic Minor, Dorian, Phrygian).
- Durasi extended: preset 16/32/64/128 bar atau input detik dengan konversi
Total Bars = Math.round((Seconds * BPM) / 60 / 4). - 26 track dalam 4 kategori + preset cepat: Select All, Club/EDM Full, Trap/Hip-Hop, Minimal, Clear.
| Kategori | Track |
|---|---|
| Drums & Percussion | Kick, Snare/Clap, Closed Hi-Hat, Open Hi-Hat, Percussion/Toms, Crash/Cymbal FX |
| Low-End (Bass) | Deep Sub-Bass, Mid-Bass/Reese, Acid/Pluck Bass |
| Harmonic & Chords | Main Chords/Piano, Atmospheric Pad, Rhythm Stab/Brass |
| Lead & Melodic | Main Lead Melody, Counter Melody, Fast Arpeggio (Arp), Bell/Pluck Accent |
AI Agent + Auto-Fix di server
POST /api/generate memanggil {Base URL}/chat/completions dengan JSON mode
(response_format: json_object, dengan retry tanpa JSON mode bila endpoint menolak)
sehingga output JSON murni (song + tracks[].notes[] dengan pitch, startTime,
duration, velocity).
Setelah AI merespons, server menjalankan tiga lapis perbaikan sebelum data dikirim ke UI:
- Scale Lock & Auto-Pitch Correction — nada di track bass/chords/melody yang keluar dari key & scale digeser ke nada terdekat yang valid.
- Anti-Clash Sidechain Simulation — bila Sub-Bass bertumpuk tepat dengan Kick,
velocity-nya diturunkan 35% dan startTime digeser
0.125beat. - Boundary & Duration Sanitizer — nada melewati
totalBars * 4dibuang, durasi yang melewati akhir lagu dipotong, durasi<= 0dihapus.
Statistik perbaikan dikembalikan sebagai report dan ditampilkan di UI
("AunuAC Auto-Fix applied: …"), plus header x-aunuac-autofix.
Preview & export
- Tone.js 16-track engine:
MembraneSynth(kick/toms),NoiseSynth(snare),MetalSynth(hat/crash),MonoSynth+ low-pass (sub/mid/acid bass),PolySynth(chords/pad/stab),FMSynth(lead/bell). - Mini mixer 16 kanal: volume, M (mute), S (solo) — solo mengalahkan mute track lain.
- Piano roll canvas multi-warna (merah drums, biru bass, hijau chords, kuning/ungu melody), grid bar/beat, playhead bergerak, klik untuk seek.
- Transport Play/Pause/Stop + indikator posisi
bar:beat:sixteenth. - Download Multi-Track .MIDI →
AunuAC_[Genre]_[BPM]bpm.mid, metadata BPM, nama track, dan MIDI channel 1–16 terpisah.
2. Struktur proyek
AunuAC/
├─ worker/index.js # worker WinterJS tulisan tangan (API di Wasmer)
├─ scripts/build-wasmer.mjs # rakit folder deploy/ (static export + worker)
├─ app.yaml # konfigurasi Wasmer Edge (kind, name, package)
├─ wasmer.toml # manifest paket: WinterJS + mount .vercel/output/static
├─ next.config.ts # konfigurasi Next.js kompatibel WASIX
├─ package.json
├─ postcss.config.mjs
├─ tailwind.config.ts
├─ tsconfig.json
├─ next-env.d.ts
├─ .env.example # hanya nilai non-rahasia (BYOK tidak lewat env)
├─ .gitignore
├─ README.md
└─ src/
├─ app/
│ ├─ layout.tsx # metadata "AunuAC - AunuAudioCreator"
│ ├─ page.tsx # UI utama Dark Studio DAW
│ ├─ globals.css # tema, komponen, slider mixer
│ ├─ icon.svg # favicon
│ └─ api/
│ ├─ models/route.ts # GET /api/models (edge runtime)
│ └─ generate/route.ts # POST /api/generate (edge runtime + auto-fix)
├─ components/
│ ├─ ModelPanel.tsx # BYOK key + Fetch Models + Custom Model ID
│ ├─ SongPanel.tsx # prompt, BPM, key/scale, durasi, tombol generate
│ ├─ TrackSelector.tsx # checklist 26 track + preset cepat + input kode
│ ├─ TransportBar.tsx # play/pause/stop, posisi, export MIDI
│ ├─ PianoRoll.tsx # canvas piano roll + playhead
│ └─ TrackMixer.tsx # 16 strip: volume, M, S
└─ lib/
├─ types.ts # tipe bersama server & client
├─ musicTheory.ts # skala, konversi MIDI, 3 lapis Auto-Fix
├─ trackProfiles.ts # 26 track, kategori, channel, kode, preset
└─ audioEngine.ts # Tone.js engine + export @tonejs/midi
3. Menjalankan
Development lokal (Node)
npm ci
npm run dev
# http://localhost:3000
API route di src/app/api/* adalah implementasi referensi (TypeScript, edge runtime)
untuk platform Node/workerd. Di Wasmer, API dilayani worker terpisah (lihat §4).
Build produksi Node (opsional, sanity check)
npm run build
npm run start
4. Build & deploy ke Wasmer Edge
Wasmer menjalankan WinterJS (SpiderMonkey/WASIX). Runtime worker hasil
next-on-pages tidak kompatibel dengan WinterJS (memakai async_hooks dan
Headers.forEach(cb) satu argumen — keduanya gagal di WinterJS, API route selalu 500).
Karena itu arsitektur deploy Wasmer adalah:
- UI = static export Next.js (
output: "export", di-patch saat build) — halaman AunuAC sepenuhnya client-side, jadi tidak butuh SSR. - API = worker tulisan tangan
worker/index.js(Web API paling dasar saja: fetch, URL, Headers.get/set, Response, JSON) yang dipasang sebagaiweb/_worker.js/index.js; route lain diteruskan ke bindingASSETS.
# 1. Rakit folder deploy/ (staging build + worker)
npm run wasmer:build
# 2. Deploy (butuh Wasmer CLI + WASMER_TOKEN)
npm run wasmer:deploy
# setara: wasmer deploy --non-interactive --owner aunuhost --dir deploy
scripts/build-wasmer.mjs menyalin source ke staging (tanpa src/app/api),
menambah output: "export", menjalankan next build, lalu merakit deploy/
berisi wasmer.toml (paket aunuhost/aunuac), app.yaml, dan web/.
Live: https://aunuac.wasmer.app
Catatan kompatibilitas WinterJS
- Worker tidak memakai
async_hooks,Headers.forEach, atau API Node apa pun. - Logika Auto-Fix di worker adalah port 1:1 dari
src/lib/musicTheory.ts; bila mengubah teori musik, ubah keduanya. - Tone.js dan
@tonejs/midihanya diimpor dinamis di client, tidak masuk server.
5. Kontrak API
Kedua route membaca header x-base-url (root OpenAI-compatible, mis.
https://ai.aunuhost.bond/v1) dan x-api-key.
GET /api/models
Server mem-proxy GET {Base URL}/models dengan Authorization: Bearer <key>:
{
"models": [{ "id": "mold", "name": "mold" }],
"count": 1,
"fetchedAt": "2026-01-01T00:00:00.000Z"
}
POST /api/generate
Header: x-base-url, x-api-key, content-type: application/json
{
"prompt": "Melodic techno gelap, pad hangat, bass Reese syncopated…",
"bpm": 124,
"keyRoot": "F",
"scale": "Minor",
"totalBars": 32,
"trackIds": ["kick", "snare", "closedHat", "subBass", "chords", "lead", "arp"],
"modelId": "mold"
}
Server memanggil POST {Base URL}/chat/completions (system instruction komposer +
JSON mode), lalu menormalisasi output dan menjalankan Auto-Fix.
Respons: { song, tracks, report, model, generatedAt } — lihat src/lib/types.ts.
Kode error: 400 input/Base URL tidak valid, 401 key kosong, 404/429 diteruskan
dari endpoint, 502 kegagalan jaringan/JSON, dengan body { error, detail, status }.
6. Troubleshooting
| Gejala | Penyebab & solusi |
|---|---|
400 Base URL tidak valid | Isi Base URL root OpenAI-compatible (biasanya berakhiran /v1). |
401 saat Fetch Models | Key kosong/salah untuk endpoint tersebut. |
404 dari endpoint | Path salah, Model ID tidak ada, atau key ditolak tanpa petunjuk (beberapa gateway membalas 404 untuk key invalid). |
429 | Rate limit endpoint. Tunggu atau ganti key/model. |
Output AI bukan JSON valid | Respons terpotong batas token / model lemah. Kurangi bar atau track, atau pakai model lebih kuat. |
Semua nada terbuang oleh Boundary Sanitizer | AI memberi startTime di luar totalBars*4. Generate ulang; bila konsisten, kecilkan durasi bar. |
| Model tidak muncul | Klik Fetch Models; Model ID juga bisa diketik manual (field teks + datalist). |
| Audio tidak berbunyi | Browser butuh gesture pengguna: klik Play sekali; cek volume tab, lalu M/S pada mixer. |
wasmer deploy error "could not connect / InvalidContentType" | Glitch egress intermiten CLI dari VM ini — jalankan ulang perintah yang sama; publikasi paket bisa sudah terjadi walau CLI error, jadi naikkan versi paket bila "already exists". |
| Halaman/API 500 di Edge | Pastikan deploy dari folder deploy/ hasil npm run wasmer:build (bukan root repo). |