Browser app to design, edit, and export Yamaha arranger styles (.sty) from Live Audio
Styles (.aus) and MIDI.
Files never leave your device — all parse / compile runs client-side.
npm install
npm run dev- Drop a
.aus(Audio Phraser) or open an existing.sty - Optionally drop
.midfiles onto timeline lanes (Bass / Chord / Pad / Phrase) - Preview, set name / tempo, pick your target keyboard
- Compile .sty → Download → USB → Style → User
| Model | SFF | Live Audio (.aus) |
|---|---|---|
| Genos2, Genos | SFF2 | yes |
| PSR-SX920 / SX720 | SFF2 | yes |
| PSR-SX900 / SX700 | SFF2 | yes |
| PSR-S975 / S970 | SFF2 | yes |
| Tyros5 | SFF2 | yes |
| PSR-SX600 | SFF2 | no |
The target model is picked in the export panel and drives validation. PSR-SX600 does not
play Audio Styles — compiling an .aus-derived style for it is refused up front rather
than letting you discover it from “Data not loaded properly” on the instrument. The model
list lives in src/lib/models/models.ts; add a model there and the picker, the gate and
the size advisory all follow.
Both dialects below were dumped byte-for-byte from real files. fixtures/knjraus.aus
(an Audio Phraser export) and working demo sty.sty (a loadable Live Audio style) are the
project's ground truth and are asserted against in npm run test:binary.
knjraus.aus working demo sty.sty
MThd (fmt 0, div 960) MThd (fmt 0, div 1920)
MTrk (126 B) MTrk
CASM 204 CASM 2122
CSEG CSEG ×3 (sections are grouped!)
Sdec 15 sections Sdec + N × Ctab(27) + N × Cntt(2)
Ctb2 47 B (rhythm only) OTSc 8580
AASM 159 FNRc 141
ASEG ▸ Adec + Atab + AMix AASM 318
AFil 508459 AFil 1016974
ADSg ▸ AWav ▸ WAVE ▸ Afmt/Adat
AInf ▸ BPnt (beat grid)
Notes that matter when you touch the writers:
Ctb2is 47 bytes,Ctabis 27. Both appear inside files markedSFF2. Audio Phraser writes a singleCtb2(the rhythm channel); a real loadable style usesCtab. We generateCtabby default because that layout is verified field-by-field against 14 varied real tables — see the header ofsff2Writer.tsfor the byte map.Cntt(2 B per channel) carries the bass-on flag, notCtabbyte 21.- Sections are split across several
CSEGgroups. Reading only the first one loses most of the section list. - Section content starts at measure 2. Measure 1 is the SFF setup block (
SFF2/SIntmarkers, System On sysex, initial CCs). Both reference files put their first section marker exactly one bar in. - A real style's declared
MTrklength can overrun the start ofCASM— in the reference style by 67 bytes.findEffectiveSmfEnd()prefers the CASM offset. This is not corruption; do not "fix" it. AInf▸BPntis a table of (sample-frame, beat) pairs — the exact loop grid. We read it in preference to guessing tempo from the loop duration.
SMF Format 0 (SFF2 + SInt [+ optional timeline MIDI only])
→ CASM (from your .aus only)
→ OTSc (One Touch Setting — required for Style Editor)
→ FNRc (preserved when the source has one)
→ AASM / AFil (Live Audio from your .aus only)
Style Editor crash (Unexpected error / SRJRRR L11): caused by Live Audio .sty files
missing OTSc after CASM. The exporter always injects one.
| Source | Used? |
|---|---|
Your .aus CASM |
Yes |
Your .aus AASM / AFil / AWav |
Yes |
Your .aus FNRc |
Yes, when present |
| Timeline MIDI you assigned | Only if present |
| Demo / template MIDI channels | Never |
The psrtutorial recipe (convert .aus → .sty, then splice AASM + AFil from your
.aus into a donor style's MThd…SInt header) was a genuinely useful discovery — it
identified AASM + AFil as the chunks that carry the audio. As a procedure it has three
problems this app avoids:
- The donor's CASM comes with it. You inherit another style's channel tables, note limits, chord rules and section list. Nothing describes your audio.
- The chunk order in that post is wrong. It lists
OTSclast; real loadable styles put it betweenCASMandAASM, and the Style Editor crashes when it is missing there. - “Copy MThd until SInt” drops the section markers, because
SIntsits at tick 0 and every marker comes after it. You get a style with no section map.
This app takes CASM, AASM/AFil and FNRc from your .aus only, rebuilds the conductor
around them, and injects the OTSc the .aus lacks.
Export validates structure before download, then checks the result against your target model. Prefer Require source CASM (on by default).
If the keyboard says “Data not loaded properly”:
- Re-export a complete
.ausfrom Audio Phraser (CASM + AASM/AFil) - Confirm the build log: CASM from AUS + AASM/AFil audio
- Confirm the target model in the export panel actually supports Audio Styles
- Copy the full file to a FAT32 USB stick; load from User memory
| Command | Purpose |
|---|---|
npm run dev |
Vite dev server |
npm run build |
Typecheck + production build |
npm run typecheck |
tsc -b |
npm test |
Both suites below |
npm run test:binary |
Golden-byte tests against the real .aus / .sty fixtures |
npm run test:export |
Structure + round-trip tests |
The test scripts import the app's real .ts modules through a small loader
(scripts/ts-loader.mjs) built on Node's own type-stripping — no toolchain download, and
they run offline. Requires Node 22.18+.
- The exported
OTScis still a borrowed template when your.aushas none — it carries another style's voices. Generating OTS from your chosen sounds is not done yet. - One MIDI part per channel, not per (channel × section): you cannot yet give Bass one pattern in Main A and a different one in Main B.
- No CASM editor — note transposition rules, note limits and retrigger behaviour can only be copied from the source, not edited.
- Voice names in
gmPrograms.tsare GM-accurate but the “XG” bank numbers are not real PSR-SX/Genos voice addresses. No MegaVoice / Super Articulation handling.
- Preview uses GM SoundFonts (
smplr); needs network once to fetch fonts - Sections: timeline section pills; CASM Sdec aligned when lifted from AUS
See LICENSE.