This helps indeed, I just translated the code into C and whoosh... It works pretty good! No more dissonant notes! :D […]
I've disassembled all of the drivers (dune/kgb/megarace) and have the bend code working in my (almost perfect?) converter.
Hope this helps!
This helps indeed, I just translated the code into C and whoosh... It works pretty good! No more dissonant notes! 😁
https://github.com/adplug/adplug/commit/284af … 876082ba62c8756
However this introduced some regressions (tested with Winamp plugin via Nuked OPL3):
1. Strange hiss sound at the beginning of "NewSan"
I isolated the weird intro sound at the beginning of NewSan. The instrument is located at 0x955E in the SDB file (MIDI instrument number 46). The transpose byte was set to F4, but when I changed it to 00, the intro sounds a lot better. Another instrument that was weird in NewSan is the chorus drums on track 8 (MIDI Instrument 44 / SDB offset 0x950E) The transpose byte is DC but while changing it to zero made it sound better, it's still not accurate.
So first, I started looking at the HERAD internals in MegaRace. It looks like this drum should be playing at MIDI note 3, which is weird because that note is technically not playable in HERAD. HERAD uses MIDI Notes C1 to B8 (0x18 to 0x77). If any MIDI notes are out of range, the sequencer will play note C1. I made a test HA2 file where I made MegaRace play all possible MIDI pitches and then compared it with AdPlug. Sure enough, AdPlug doesn't limit the pitch range (at least the lower notes anyway). Here's how that work:
HERAD pulls up the MIDI pitch. Let's say in this case it's 0x17. In between grabbing the MIDI pitch from the song data and writing the OPL FNUM, HERAD is also transposing the pitch, checking if there's a drum map involved, as well as grabbing and resetting values for the pitch slides. When it's done doing that, it'll take the transposed pitch (if there is transposing), and subtract it by 48.
17 - 48 = FFCF
Then HERAD takes that value and adds 30 to it.
FFCF + 30 = FFFF
HERAD then compares that value with 60. If the value is greater than or equals to 60, it is zeroed out. HERAD then grabs the FNUM from it's frequency table and adds it to the MIDI pitch. Since the MIDI pitch is now zero, it grabs the first value from the FNUM table, which is 0x157, aka FNUM 343, aka a C note.
Now let's do this with a valid note, like the drum from NewSan.
44 - 48 = FFFC
FFFC + 30 = 2C
2C < 60
Since 2C is less than 60, it's a valid note, so HERAD proceeds to grab the FNUM. It starts this by taking our modified MIDI pitch and dividing it by C.
2C / 0C = 0803
Then HERAD takes the high byte and adds it with itself.
08 + 08 = 10
HERAD then uses this value to look up the frequency table and grab the corresponding value.
0x10 bytes into frequency table = 0x222
0x222 equates to FNUM 546, which is the note G#.
Now, we take the low byte from our divided value (0803) and shift bits to the left twice.
03 -> 0C
Take C and perform an OR with the high byte of the FNUM value, 222.
C OR 2 = E22
Finally, perform an OR on the high byte with 20 (the 20 turns on the Key On Bit for the OPL register) and this is now the new register FNUM to be written to the OPL chip.
20 OR E22 = 2E22
I'm gonna dig into this a bit further, but this should be a good start for fixing this issue.