Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OPM (YM2151) support #87

Open
bryc opened this issue Mar 5, 2019 · 11 comments
Open

OPM (YM2151) support #87

bryc opened this issue Mar 5, 2019 · 11 comments
Assignees

Comments

@bryc
Copy link

bryc commented Mar 5, 2019

OK hopefully here is better place to discuss (coming from jpcima/ADLplug#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 ;)

@Wohlstand
Copy link
Owner

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.

@jpcima
Copy link
Collaborator

jpcima commented Mar 5, 2019

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
Copy link
Collaborator

jpcima commented Mar 5, 2019

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
Copy link
Collaborator

jpcima commented Mar 6, 2019

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
Copy link
Collaborator

jpcima commented Mar 6, 2019

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.

@freq-mod
Copy link
Contributor

freq-mod commented Mar 6, 2019

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

@jpcima
Copy link
Collaborator

jpcima commented Mar 6, 2019

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. ❗

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.

@bryc
Copy link
Author

bryc commented Mar 7, 2019

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.

@mmontag
Copy link

mmontag commented Nov 29, 2021

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

@Wohlstand
Copy link
Owner

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.

@mmontag
Copy link

mmontag commented Dec 6, 2021

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)

@Wohlstand Wohlstand moved this to Backlog in @Wohlstand's works Nov 25, 2023
@Wohlstand Wohlstand moved this from Backlog to Maybe later in @Wohlstand's works Nov 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Maybe later
Development

No branches or pull requests

5 participants