aunuac package icon
aunuhost/aunuac
Public
wasmer run aunuhost/aunuac

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 header x-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 mendukung generateContent, 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.
KategoriTrack
Drums & PercussionKick, 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 & ChordsMain Chords/Piano, Atmospheric Pad, Rhythm Stab/Brass
Lead & MelodicMain 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:

  1. Scale Lock & Auto-Pitch Correction — nada di track bass/chords/melody yang keluar dari key & scale digeser ke nada terdekat yang valid.
  2. Anti-Clash Sidechain Simulation — bila Sub-Bass bertumpuk tepat dengan Kick, velocity-nya diturunkan 35% dan startTime digeser 0.125 beat.
  3. Boundary & Duration Sanitizer — nada melewati totalBars * 4 dibuang, durasi yang melewati akhir lagu dipotong, durasi <= 0 dihapus.

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-pages tetap membutuhkan next + 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:

  • .npmrc memakai legacy-peer-deps=true: next-on-pages@1.13.16 mensyaratkan peer @cloudflare/workers-types ^4, sedangkan wrangler@4.159+ mensyaratkan ^5. Keduanya peer opsional yang hanya berisi deklarasi tipe, jadi resolusi peer dilewati.
  • next dipin ke 15.5.29. next-on-pages secara 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: esbuild memakai paket @esbuild/<platform> dan sharp tidak 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.toml lalu membaca app.yaml (package: .) dan menanyakan nama/namespace bila belum ada.
  • Ganti name: aunuac pada app.yaml bila nama aplikasi sudah dipakai akun lain.
  • Untuk namespace eksplisit, aktifkan blok [package] di wasmer.toml dan isi namespace-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 ada fs, net, child_process, atau binary native.
  • @google/genai diimpor dari entry @google/genai/web (build browser) agar bundler tidak menarik google-auth-library/ws yang khusus Node.
  • next.config.ts menetapkan images.unoptimized: true karena optimizer gambar Next membutuhkan sharp (native).
  • Tidak ada output: "export" — API routes harus tetap dinamis.
  • Tone.js dan @tonejs/midi hanya 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

GejalaPenyebab & solusi
401 saat Fetch ModelsKey kosong/salah. Pastikan dari Google AI Studio dan punya akses Gemini API.
429Kuota gratis habis. Tunggu atau ganti key/model.
Output AI bukan JSON validRespons terpotong batas token. Kurangi bar (mis. 64 → 32) atau track aktif.
Semua nada terbuang oleh Boundary SanitizerAI memberi startTime di luar totalBars*4. Generate ulang; bila konsisten, kecilkan durasi bar.
Model tidak muncul di dropdownKlik Fetch Models; atau aktifkan Custom Model ID dan ketik ID manual.
Audio tidak berbunyiBrowser butuh gesture pengguna: klik Play sekali; cek volume tab, lalu M/S pada mixer.
wasmer deploy gagal: package/nameUbah name: di app.yaml, atau aktifkan [package] di wasmer.toml dengan namespace Anda.
Halaman 500 di EdgePastikan 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.

AunuAC (AunuAudioCreator) — AI MIDI Studio