AunuAC — AunuAudioCreator
AI MIDI Studio · Extended Multi-Track Edition
Ubah satu paragraf deskripsi musik menjadi aransemen 16 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, @google/genai (Structured JSON Output), Tone.js, @tonejs/midi, dan disiapkan untuk Wasmer Edge (WinterJS / WASIX).
1. Fitur
Branding & BYOK
- Identitas AunuAC di header, metadata
title: "AunuAC - AunuAudioCreator", favicon SVG. - Input Gemini API Key bertipe password; disimpan hanya di
localStorage(aunuac_gemini_api_key) dan dikirim ke backend lewat headerx-api-key. Tidak ada fallback ke.env, tidak ada penyimpanan di server. - Model selector hybrid: tombol Fetch Models (
GET /api/models) mengisi dropdown dengan model yang mendukunggenerateContent, plus toggle Custom Model ID untuk mengetik ID manual (model eksperimental, dsb).
Song brief & 16 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). - 16 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 memakai response schema Gemini sehingga output selalu 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/
├─ 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 16 track + preset cepat
│ ├─ 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 # 16 track, kategori, channel, preset
└─ audioEngine.ts # Tone.js engine + export @tonejs/midi
3. Menjalankan (dokumentasi perintah)
Perintah di bawah dijalankan di lingkungan build Anda (mesin Wasmer / CI), bukan dijalankan otomatis oleh asisten.
Toolchain minimal di mesin lokal (opsional)
Kalau mesin Anda hanya dipakai untuk menyiapkan toolchain — bukan build — cukup pasang tiga paket ini di folder terpisah (tidak menyentuh dependency aplikasi):
npm install --prefix .wasmer-toolchain --legacy-peer-deps `
@cloudflare/next-on-pages@1.13.16 vercel@47.0.4 wrangler@4.159.0
.wasmer-toolchain\node_modules\.bin\next-on-pages.cmd --version
.wasmer-toolchain\node_modules\.bin\vercel.cmd --version
.wasmer-toolchain\node_modules\.bin\wrangler.cmd --version
next-on-pagestetap membutuhkannext+ dependency aplikasi pada saat benar-benar build. Karena itu build penuh dijalankan di mesin build (Wasmer/CI), bukan di mesin yang hanya berisi toolchain.
Instalasi penuh (mesin build)
npm ci
Catatan dependency:
.npmrcmemakailegacy-peer-deps=true:next-on-pages@1.13.16mensyaratkan peer@cloudflare/workers-types ^4, sedangkanwrangler@4.159+mensyaratkan^5. Keduanya peer opsional yang hanya berisi deklarasi tipe, jadi resolusi peer dilewati.nextdipin ke 15.5.29.next-on-pagessecara resmi mendukung<=15.5.2, tetapi 15.5.7+ wajib untuk menambal CVE-2025-66478 (RCE via RSC, CVSS 10.0); 15.5.29 adalah backport terbaru pada jalur 15.5 yang sama.- Jika npm memblokir postinstall (
install-scripts), build tetap jalan:esbuildmemakai paket@esbuild/<platform>dansharptidak dipakai (images.unoptimized: true).
Development lokal (Node)
npm run dev
# http://localhost:3000
Build produksi Node (opsional, untuk sanity check)
npm run build
npm run start
4. Build & deploy ke Wasmer Edge
Wasmer Edge menjalankan JavaScript worker di atas WinterJS/WASIX, sehingga Next.js
harus diubah lebih dulu menjadi output Workers-style dengan @cloudflare/next-on-pages.
# 1. Build edge bundle -> .vercel/output/static (berisi _worker.js)
npm run edge:build
# 2. Jalankan paket Wasmer secara lokal (butuh Wasmer CLI)
wasmer run .
# 3. Login & deploy ke Wasmer Edge
wasmer login
wasmer deploy
Setelah wasmer deploy:
- CLI akan mempublikasikan paket sesuai
wasmer.tomllalu membacaapp.yaml(package: .) dan menanyakan nama/namespace bila belum ada. - Ganti
name: aunuacpadaapp.yamlbila nama aplikasi sudah dipakai akun lain. - Untuk namespace eksplisit, aktifkan blok
[package]diwasmer.tomldan isinamespace-anda/aunuac. - Preview cepat hasil build edge tanpa Wasmer (opsional):
npm run edge:preview.
Catatan kompatibilitas WASIX
- Kedua API route memakai
export const runtime = "edge"dan Web Standard Fetch API — tidak adafs,net,child_process, atau binary native. @google/genaidiimpor dari entry@google/genai/web(build browser) agar bundler tidak menarikgoogle-auth-library/wsyang khusus Node.next.config.tsmenetapkanimages.unoptimized: truekarena optimizer gambar Next membutuhkansharp(native).- Tidak ada
output: "export"— API routes harus tetap dinamis. - Tone.js dan
@tonejs/midihanya diimpor dinamis di client (await import(...)), sehingga tidak ikut ke bundle server/WASIX.
5. Kontrak API
GET /api/models
Header: x-api-key: <GEMINI_API_KEY>
{
"models": [{ "id": "gemini-2.5-flash", "name": "Gemini 2.5 Flash" }],
"count": 1,
"fetchedAt": "2026-01-01T00:00:00.000Z"
}
Server memanggil https://generativelanguage.googleapis.com/v1beta/models lalu menyaring
supportedGenerationMethods yang memuat generateContent.
POST /api/generate
Header: 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": "gemini-2.5-flash"
}
Respons: { song, tracks, report, model, generatedAt } — lihat src/lib/types.ts.
Kode error: 400 input tidak valid, 401 key kosong, 502 kegagalan Gemini/JSON,
dengan body { error, detail, status }.
6. Troubleshooting
| Gejala | Penyebab & solusi |
|---|---|
401 saat Fetch Models | Key kosong/salah. Pastikan dari Google AI Studio dan punya akses Gemini API. |
429 | Kuota gratis habis. Tunggu atau ganti key/model. |
Output AI bukan JSON valid | Respons terpotong batas token. Kurangi bar (mis. 64 → 32) atau track aktif. |
Semua nada terbuang oleh Boundary Sanitizer | AI memberi startTime di luar totalBars*4. Generate ulang; bila konsisten, kecilkan durasi bar. |
| Model tidak muncul di dropdown | Klik Fetch Models; atau aktifkan Custom Model ID dan ketik ID manual. |
| Audio tidak berbunyi | Browser butuh gesture pengguna: klik Play sekali; cek volume tab, lalu M/S pada mixer. |
wasmer deploy gagal: package/name | Ubah name: di app.yaml, atau aktifkan [package] di wasmer.toml dengan namespace Anda. |
| Halaman 500 di Edge | Pastikan npm run edge:build dijalankan sebelum deploy dan tidak ada import Node-only di route. |
7. Lisensi
Kode aplikasi ini disediakan apa adanya untuk pengembangan pribadi/commercial Anda. Ketentuan penggunaan Gemini API mengikuti Google AI Studio; penggunaan Wasmer Edge mengikuti ketentuan akun Wasmer Anda.