fmtoy
fmtoy copied to clipboard
Problems with OPL playback
While I can get the OPN/OPM chips to work correctly, switching to MIDI channel 6/7 for the OPL chips causes just a horrible noise to play on note on. What is the preferred/tested format for loading sounds for OPL? I tried SBI, BNK and OP3, but same results. The same files play fine in my own OPL library. I'll try to investigate further what could be the issue, just wanted to ask if maybe that is a known current problem.
One issue I already found in fmtoy_ymf262.c in function fmtoy_ymf262_init():
DEVFUNC_WRITE_VOLUME volfn;
SndEmu_GetDeviceFunc(devinf->devDef, RWF_VOLUME_LR | RWF_WRITE, DEVRW_VALUE, 0, (void**)&volfn);
volfn(devinf->dataPtr, 0x8000);
The RWF_VOLUME_LR function needs two parameters for left and right channel volume, but the function call using volfn only gives the volume of the left channel, resulting in a random value for the right channel value. Simples fix is calling RWF_VOLUME instead:
DEVFUNC_WRITE_VOLUME volfn;
SndEmu_GetDeviceFunc(devinf->devDef, RWF_VOLUME | RWF_WRITE, DEVRW_VALUE, 0, (void**)&volfn);
volfn(devinf->dataPtr, 0x8000);
Another big bug found in fmtoy_ymf262.c, this time in function fmtoy_ymf262_set_pitch():
fmwrite(writefn, devinf->dataPtr, 0xb0 + chip_channel, (channel->chip->channels[chip_channel].on ? 0x20 : 0x00) | block_fnum >> 8);
This won't work for note off events (e.g. when the "on" variable is false), as in that case only 0 needs to be written to the 0xB0 register to trigger the note release/envelope state change from sustain to release. Since we or in the frequency as well, the note will never release and the channel will never be free to play another note. The solution is simple, only or in the frequency when a note is playing:
fmwrite(writefn, devinf->dataPtr, 0xb0 + chip_channel, (channel->chip->channels[chip_channel].on ? (0x20 | block_fnum >> 8) : 0x00));
ok can u make a pr please?
Will do that once I fix some more issues. Seems the envelope timers don't work properly yet or their increments are wrong, for example.
What do you mean by envelope timers?
Presets with a long release setting do not properly fade off. On a note off event they immediately get cut off, as the release timer overflow immediately happens, so the envelope state gets switched instantly from "release" to "off".
I recall there was also a bug where, depending on the clock, the notes don't always have the same pitch across all 3 chip types, even though they're supposed to.
Yes, this is another common issue with the clock rates, although with the OPL chips that should be fine. There is a strange thing going on with the pitch calculation for ymf262 though in fmtoys, I have to multiply the pitch in Hz by 4 (i.e. 2 octaves) to get the right pitch. Replacing that section with a line from my own OPL3 emulator gives the correct result, so probably there is a bit error in the calculation somwhere. Will look at that later too.
Currently the clock is specified to fmtoy as a single int value, so fmtoy has the duty to premultiply the clock value when initializing the chip core, depending on what it needs, and also use that clock value when computing the pitch register values. But the point of this value is that for the same value passed to all the chip glue code, we'll get a good chance that when converting the voices between them, they'll sound exactly the same.