libOPNMIDI icon indicating copy to clipboard operation
libOPNMIDI copied to clipboard

OPM (YM2151) support

Open bryc opened this issue 5 years ago • 11 comments

OK hopefully here is better place to discuss (coming from https://github.com/jpcima/ADLplug/issues/47), Re:

It's also dependent how big difference between OPN and OPM, so, bank editor can be based on OPN2-BE and can be used for both OPN and OPM (for case of OPM, show extra controls are absence on OPN2 or opposite). For case of playback, looks like OPN2-BE will need to have second chipset and second generator (or same, but with subclassing) which will pass instrument data to the necessary chip emulator. What about playback, maybe same. Anyway, for a first thing I will need the complete OPM specification to be able tweak around the chip and features.

The differences between OPN2/OPM is not major. OPN2 is just a cost-reduced version of OPM.

OPN2 core:

  • LFO Frequency values range (0-7)
  • SSG-EG allowed only
  • LFO Enable allowed only
  • CH3 mode allowed only
  • DAC mode allowed only

OPM core:

  • LFO Frequency values range (0-255)
  • Detune 2 (0-3) allowed only
  • LFO AMD/PMD control allowed only (0x80=AMD/PMD mode, 0x7F=depth value (0-127) )
  • LFO Waveform Select (0-3) allowed only
  • LFO Sync (0-1)
  • Noise enable (0-1) and Noise Frequency (0-31) allowed only

For LFO frequency , just change AND mask depending on chip mode?

Anyway, I have this: ym2151datasheet.pdf

MAME source code of ym2151.cpp driver is accurate and readable :). Here is a comparison of the register map of OPN and OPM from my notes:

outfm

You can see OPN series is more compact in memory (it is a cheaper version of OPM after all). OPM is actually the basis of OPP/OPZ chips in DX21/DX11 keyboards. The rows labeled 4x4 and 8x4 are the FM operator data.

So all that is needed is to implement YM2151 emulator core, with support of new OPM parameters.. and a way to select OPN2/OPM mode. I would do it myself and PR.. but my C++ skills very bad. It would be hard enough to figure out how to compile this ;)

bryc avatar Mar 05 '19 07:03 bryc

After some work on this branch: https://github.com/Wohlstand/OPN2BankEditor/tree/sketch-psg-and-wt, I'll be able to easier support more chips and things. At first I'll support OPN2+SN and OPNA, and then OPM too. I have to re-create OPN2:: thign into the side of Chipset to easier manage different chips and voice types.

Wohlstand avatar Mar 05 '19 08:03 Wohlstand

Can we have a flag returned from the chip core, indicating which of OPN/OPM register language is spoken by this instance ? And then, make the driver act on this flag to adapt what is written and where. It's a possibility also to express it as decorator pattern.

jpcima avatar Mar 05 '19 16:03 jpcima

More notes as I interpret the OPM emulator code.

  • At address $08 is the note trigger. The low bits "CH no" designate the channel number 0-7; the four bits designate Key-On/Off for individual operators.
  • FB/Alg is identical, but pay attention to "L/R enable" in upper bits
  • Envelope block also identical, except adding "Detune 2" bits
  • KC/KF is the tuning, which uses a different system than usual

So it does not seem af first too difficult to implement this in substitution of OPN2 without extra functionality yet, just 2 things to manage: (1) how to tune it, and (2) allow ADLMIDI usage of 2 extra FM channels (6 OPN vs 8 OPM)

jpcima avatar Mar 05 '19 18:03 jpcima

libOPNMIDI can now speak to OPM, in the work branch opm The emulator is NP2kai because it's the simplest to add, it's 2 files dropped into existing fmgen.

Notes

  • last 2 channels are recognized in the synth class, but I'm not sure midiplay has everything needed to drive them
  • LFO does not seem functional
  • tuning was made completely by trial and I don't know a precise formula for it

jpcima avatar Mar 06 '19 11:03 jpcima

Some observations about the tuning

As seen from datasheet and most MAME machines using OPM, we have an indication of recommended clock rating as 3.579545 MHz. Also from MAME, it's indicated that it has a fixed sample clock division of 64, from which is deduced a sample rate 55.930 kHz.

src/devices/bus/msx_cart/yamaha.cpp: YM2151(config, m_ym2151, XTAL(3'579'545)); // The SFG01 uses a YM2151,

The datasheet indicates a 440 Hz note is produced from a (Oct=4 Note=10) KC register, under the condition of 3.579545 MHz clock. This is not the reality of what happens with neko. To obtain 440 Hz in this condition, I found OPM has to lower sample rate to Clock/144 instead of Clock/64; where 144 is the natural divider value of OPN family chips. (but the solution is not practical, because sample rate will drop too low)

This leads me to why it worked to apply an exact factor 2.25 to frequency for tuning in OPNMIDI: that is the ratio of the OPM vs OPN dividers (144/64).

Please note: datasheet seem to only explain the tuning at that fixed clock frequency, and does not have a generic formula that I can find. So other scale factors are based on a guess because I haven't found the relation.

jpcima avatar Mar 06 '19 20:03 jpcima

from which is deduced a sample rate 55.930 kHz

Interesting, I thought YM2151 has a sample rate of 62400 Hz, as provided here: http://snesmusic.org/hoot/v2/faq.php

freq-mod avatar Mar 06 '19 21:03 freq-mod

Just tried this rate and.. guess what: This tunes the chip, but to the MIDI note numbers; such that the note can be written to the register without applying the 13 semitone offset. Is this a coincidence? I think not. :exclamation:

On this clock, the drums will sound more off on OPN instruments than will the previous rate.

So this gives a clock at 3993600 Hz (as samplerate*64). It's very near the max chip rating 4 MHz. Curiously, the only occurrence seen in MAME for this clock is found in PC88 and YM2203. pc88va.cpp: MCFG_DEVICE_ADD("ym", YM2203, 3993600) //unknown clock / divider

The clock 3.579545 MHz seems what's found about with most machines in MAME. Some exact 4 MHz and 3.58 MHz are also seen.

jpcima avatar Mar 06 '19 22:03 jpcima

X68Sound (the emu that VOPM uses) uses a value of 4000000.

Regarding the LFO, I think both PMS and PMD must be a non-zero value to take effect.

Edit: It seems that LFO Sync is a chip feature of OPM that should be looked into. The Yamaha keyboards (DX21, DX27, DX100) have a "LFO Key Sync" parameter in SysEx which might control LFO Sync. It is just a single bit (0-1). OPN series seems to lack this LFO Sync bit.

bryc avatar Mar 07 '19 02:03 bryc

Just wondering, what are the chances of OPM support getting into master? Or maybe it is already?

mmontag avatar Nov 29 '21 06:11 mmontag

Just wondering, what are the chances of OPM support getting into master? Or maybe it is already?

Didn't complete yet. As explained above, the work on OPN2BE is needed, the WOPNv3 is needed (to get a set of extra fields required for OPM support), and, finally, the internal refactoring to properly process commands for different chips without the pain.

Wohlstand avatar Nov 29 '21 07:11 Wohlstand

That's cool, was just curious. For the application I have in mind, I probably need a direct interface to chip registers anyway. (web-based Portasound patch editor)

mmontag avatar Dec 06 '21 17:12 mmontag