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 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 di localStorage (aunuac_base_url, aunuac_api_key, aunuac_model_id) dan dikirim ke backend lewat header x-base-url + x-api-key. Tidak ada fallback ke .env, tidak ada penyimpanan di server.
  • Fetch Models (GET /api/models) mem-proxy GET {Base URL}/models dan 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.
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 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:

  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/
├─ 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 sebagai web/_worker.js/index.js; route lain diteruskan ke binding ASSETS.
# 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/midi hanya 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

GejalaPenyebab & solusi
400 Base URL tidak validIsi Base URL root OpenAI-compatible (biasanya berakhiran /v1).
401 saat Fetch ModelsKey kosong/salah untuk endpoint tersebut.
404 dari endpointPath salah, Model ID tidak ada, atau key ditolak tanpa petunjuk (beberapa gateway membalas 404 untuk key invalid).
429Rate limit endpoint. Tunggu atau ganti key/model.
Output AI bukan JSON validRespons terpotong batas token / model lemah. Kurangi bar atau track, atau pakai model lebih kuat.
Semua nada terbuang oleh Boundary SanitizerAI memberi startTime di luar totalBars*4. Generate ulang; bila konsisten, kecilkan durasi bar.
Model tidak munculKlik Fetch Models; Model ID juga bisa diketik manual (field teks + datalist).
Audio tidak berbunyiBrowser 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 EdgePastikan deploy dari folder deploy/ hasil npm run wasmer:build (bukan root repo).

AunuAC (AunuAudioCreator) — AI MIDI Studio

aunuhost/aunuac: AunuAC (AunuAudioCreator) — AI MIDI Studio