DhrBaksteen / ArduinoOPL2

Arduino library for use with the OPL2 board (YM3812) and OPL3Duo (YMF262)
MIT License
198 stars 39 forks source link

OPL2.play playback issues #40

Closed prochazkaml closed 5 years ago

prochazkaml commented 5 years ago

Hello, I've recently purchased your OPL2 sound board, tested it with my Raspberry Pi and it works great!

I played some of the tunes that were included, which worked fine, but most of the recordings I made didn't sound right, found the issue: in line 127 of file examples_pi/opl2play/opl2play.cpp, replace:

} else {

with

} else if (registerCode < dro.registerMapLength) {

My recordings were made using DOSBox 0.74-2, and after this change they play fine.

DhrBaksteen commented 5 years ago

Hi,

Thanks for reporting this! I'll add this fix to the upcoming release.

Out of interest, what games did you record from? I think that the issue you found has something to do with DosBox using a dual OPL2.

prochazkaml commented 5 years ago

I recorded some tunes from Ultima 6, Duke Nukem 3D, Tyrian and The Secret of Monkey Island. All of these games were set to output to AdLib. I included my recordings in a zip file:

ultima.dro - 1 of the channels has a wrong waveform, out of tune ultima2.dro - high pitched tone at start, then some channels have a wrong waveform tyrian.dro - Some channels have a wrong waveform duke3d.dro - During playback, it sometimes changes tempo/skips a few notes, some channels are missing monkey.dro - The tempo is all over the place, some channels have a bad waveform

The tempo issues are still present after the fix, but that may be because I'm using a Raspberry Pi 1, which is WAY slower than the Pi 2 or 3

tunes.zip

DhrBaksteen commented 5 years ago

Thanks for sharing your captures. It turns out that DosBox is apparently clearing registers on a second OPL2 that is never used.

I've found some other issues as well in both the Raspberry Pi and the Arduino sketch regarding timing. The Tyrian tune was unplayable for example.

prochazkaml commented 5 years ago

Regarding the timing, I have tried another tune and it skipped horribly at the start. The cause is this:

"The iShortDelayCode value must have one added to it, as per v1.0 (so a short delay of 2 == a 3ms delay) The iLongDelayCode value must have one added to it, then be multiplied by 256 (or "<< 8"), so a long delay of 2 == a 768ms delay" (source: http://www.shikadi.net/moddingwiki/DRO_Format)

But your code contains (@ lines 124 & 126 of opl2play.cpp):

"delay(value);" and "delay(value << 8);"

Changing them to:

"delay(value + 1);" and "delay((value + 1) << 8);"

fixes the issue for me.

DhrBaksteen commented 5 years ago

You are right, I missed this on the Pi code. Reopening the issue