Conversation
MA-7 stores operators in the chip's native 10-byte layout rather than the packed 7-byte VM35 one: MULTI/DT moves to byte 9, WS/FB to byte 6, and bytes 5/7/8 are reserved. Undoing that shuffle reuses the existing VM35 decoder, so MA-7 files now play on the FM engine instead of falling back to the GM wavetable.
|
@CodeRabbit summary |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds MA-7 SEQU score-track decoding, MA-7 FM voice-exclusive decoding, format documentation, regression tests, and bank-0 fallback lookup for missing non-zero-bank patches. ChangesMA-7 SMAF support
Bank fallback lookup
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant MMF
participant _WM_smaf2midi
participant decode_mobile
participant MIDI
MMF->>_WM_smaf2midi: MA-7 format_type 0x03 track
_WM_smaf2mid->>decode_mobile: Pass SEQU decoding flag
decode_mobile->>MIDI: Emit repacked MIDI events
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Action performedSummary regeneration triggered. |
p[10] selects the MA-7 voice body layout; only form 0x00 (3 global + 10 bytes/operator) is established, so require it and an exact body length instead of assuming every 7F 21 record uses that shape. Also drop the bogus voice-type reading of p[9], which holds split points.
sezero
left a comment
There was a problem hiding this comment.
Built and played cleanly. My valgrind was silent.
Awesome, I just found a stash of 1000+ MMF files; I'm now iterating over all of them to make sure they play and nothing blows up (smoke test). Might be some more missing features. The cool news is that no other FOSS player on the planet supports MA-7 based files. :) |
p[10] is effectively the voice type: forms 0x00 and 0x02 are FM and share the 3-global + 10-byte-operator layout (0x02 adds a 16-byte trailer), while 0x01/0x03/0x07 are sampled voices whose bodies start with a PCM sample rate. Decoding 0x02 covers every FM voice in every known MA-7 file. Also document the MA-1..MA-6 gaps in SMAF_TODO.md.
Add MA-7 SMAF support (score + FM voices)
MA-7
.mmffiles previously failed to play. This decodes both halves of the format and fixes the bank lookup that kept them silent.SEQU score (
format_type 0x03)Not a compressed format as previously assumed — it's Mobile Standard with the status byte repacked for 32 channels:
0x8+n), bits 3-0 = channel low nibble0xF0/0xFFliteral; no running status (status bytes are< 0x80)sequflagExplains the old "mystery
0x61record": pitch bend on ch1 + the next duration byte.MA-7 FM voices (
43 79 08 7F 21)Operators are stored in the chip's native 10-byte layout, not packed 7-byte VM35:
MULTI/DT→ byte 9,WS/FB→ byte 6, bytes 5/7/8 reserved. Undoing the shuffle reuses the existing VM35 decoder.Bank fallback (
src/patches.c)0x7c) that no GUS/SF2 set defines;_WM_get_patch_datahad no fallback → silenceVerification
Both decodes checked against Yamaha's MCP-MA7 middleware (Ghidra + Unicorn, clean-room; the DLL is 32-bit x86 so it emulates directly, no Wine).
smaf_sequ,ma7_voice), 3/3 passLimitations
0x00is decoded — 10 of the 58 voicerecords across the 5 known MA-7 files.
p[10]selects the form;0x01(plain VM35),
0x02,0x03and0x07are declined rather than guessed,and those voices fall back to GM. Form
0x00is not the common case —form
0x03is (36/58). Per file:AB00221GM7/AB03957GM7get all theirvoices,
Blossomgets 2 of 25,AccidentCafe7none,First Lovehas novoice records (streaming
Mtsp).equivalent; they're ignored, so those voices lose whatever those fields do.
unchanged.
format_type 0x01) isnot decompressed, and MA-3/MA-5 PCM (sampled) voices are parsed but not
played.
smaf825 both route it to their HandyPhone decoder), so there was nothing to
cross-check against.
docs/formats/SmafFileFormat.txtrecords thederivation, the corpus sources, and what was ruled out.
From AB00221GM7.MMF and AB03957GM7.MMF
AB00221GM7.mp3
AB03957GM7.mp3