joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.82k stars 383 forks source link

OPL2board audio distortions and cut-outs (Linux) #3694

Closed KGOrphanides closed 2 years ago

KGOrphanides commented 2 years ago

Describe the bug

OPL2board Audio playback is unusably out of time, stuttery and distorted on Linux.

Steps to reproduce the behaviour

Expected behavior

Undistorted music to play through OPL2board's 3.5mm port.

What operating system(s) this bug have occurred on?

Pop!_OS 22.04

What version(s) of DOSBox-X have this bug?

0.83.13 to 0.84.2. Affects SDL1 and SDL2 builds, as well as Flatpak

Used configuration

[mixer]
nosound         = false
sample accurate = true
swapstereo      = false
rate            = 49761
blocksize       = 8192
prebuffer       = 250

[sblaster]
sbtype                       = none
sbbase                       = 220
irq                          = 7
dma                          = 1
hdma                         = 5
enable speaker               = false
sbmixer                      = false
oplmode                      = opl2
oplemu                       = opl2board
oplrate                      = 49716
oplport                      = ttyACM0
retrowave_bus                = serial
retrowave_port               = 
hardwarebase                 = 220
goldplay                     = true
blaster environment variable = true

Output log

Output log isn't visibly helpful, as correct performance is indistinguishable from errored performance. Here it is with --debug enabled. See Additional information for both a log and a video of the issue with debugging enabled for the opl2board.h.

Additional information

Compiling DOSBox-X with #define OPL2_AUDIO_BOARD_DEBUG 1 in opl2board.h allows us to view every signal being sent to the OPL2board, and the timing of the messages appears to match that of the garbled audio. Occasionally, audio will be sent/received at the correct rate, under which conditions the messages also appear at the correct rate for the music being played.

This can be most easily observed by putting mixer setting block size at maximum (8192) and prebuffer at 250, but this is by no means reliably reproducible, to the point where the impact may be coincidental. Noise and loss of event timing may be delayed by as much as 30 seconds, but inevitably occurs.

I've videoed this comparison at: https://theos-cloud.eu/index.php/s/JWwoeoqPyegdZDp Cut-out occurs at around 27 seconds, example of distortion at 54 seconds.

Here's the dosbox-x.conf file that's performed best so far and was used when making that video: https://theos-cloud.eu/index.php/s/BWg63cdP9mkLoJA

And a log of the same effect, taken separately: https://theos-cloud.eu/index.php/s/XnWZMjpZiAx3XYQ

I previously commented on a similar bug report about the OPL3 Duo! board, in the same family as my OPL2board, but as they're handled separately in code and I don't have an OPL3 Duo to test with, I've opened a dedicated issue report for this specific hardware.

Wondering if this might be a reversion, I went back to version 0.83.13, when opl2board support was introduced, and the issue is present there. I also reverted to a contemporary version of the ArduinoOPL2 SerialPassthrough sketch. This has only a minor difference which made no practical impact on the problem.

Do we know what Linux system + OPL2board spec the original implementation was tested under? I've tested on multiple Ubuntu-derived distros since autumn 2021. Perhaps I'm missing a key configuration step that isn't documented in either the DOSBox-X or ArduinoOPL2 docs, or there's something unexpected happening with the handling of virtual com ports in this family of distros.

Have you checked that no similar bug report(s) exist?

Code of Conduct & Contributing Guidelines

zhblue commented 2 years ago

i had similar problem , but after added a 100 ohm resistor between WR and RD , it seems fixed somehow .

KGOrphanides commented 2 years ago

i had similar problem , but after added a 100 ohm resistor between WR and RD , it seems fixed somehow .

Oh, that's interesting. You mean between pins 5 and 6 on the YM3812, right?

I'd dismissed the idea of a hardware issue, as the board works for everything else I've used it for, but if I get the same issue on the Windows machine I've been told I can borrow, that's definitely something to try.

zhblue commented 2 years ago

I'm using a OPL3 (ymf262), but yes ,the 5-6 pin of ym3812.

KGOrphanides commented 2 years ago

Okay, it works on Windows. I've also used a second OPL2board to establish that I wasn't experiencing a one-off hardware glitch.

Specifically, it works on Windows after writing SerialPassthrough to the Arduino from the Windows machine - using the default Arduino Uno COM port (COM3 in this case) in the DOSBox-X connection information to continue using the version of the same SerialPassthrough script, written to Arduino on a Linux system, results in the same distortion. However, moving the hardware rig back to Linux makes no difference to performance over here.

This indicates that it's to do with USB serial handling of ttyACM0 on Linux. I'll look into that, approach the hardware maker, and see if I can see any obvious issues that DOSBox-X's libserial.h might point me towards. Whether that's something that can be ameliorated on the DOSBox-X side remains to be seen at this point.

ETA: Since beginning to investigate potentially issues with ttyACM0, I've seen a number of posts discussing issues with transmitting binary data across that port, due to terminals' default configuration favouring ASCII and thus by default dumping certain character strings, for example.

However, disabling all of that with commands such as stty -F /dev/ttyACM0 115200 -brkint -icrnl -imaxbel -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke min 0 or stty -F /dev/ttyACM0 raw has made no impact so far.

zhblue commented 2 years ago

I wrote a Win32 exe to play vgm files via COM using the same protocol. https://github.com/zhblue/OPL3USB/blob/main/vgmplay2usb/WinForm.exe Maybe you can try it with some VGM files in the same directory.

DhrBaksteen commented 2 years ago

I'm thinking that here the address / data pairs have switched order on the side of the Arduino due to it dropping a byte. The current implementation for the OPL2 board is too simplistic to protect against any data integrity issues.

I suspect that for the OPL3 Duo board this issue does not happen, because Nuke.YKT's protocol is used to transmit the data and it makes sure address / data cannot get mixed up. This needs to be veified and if it's the case then for the OPL2 board it should also use Nuke.YKT's protocol to send the data. I'll find some time to look in to this...

KGOrphanides commented 2 years ago

Inspired by @zhblue's last comment, I installed Wine, symlinked the Linux and Wine serial ports, and OPL2board sound on DOSBox-X works perfectly (detailed instructions to reproduce follow).

Might point to something different about the way serial data transfer is handled in DOSBox when built for Windows vs Linux? That'll be my next thing to look at.

Anyway, if you'd like to see the weirdness, grab a PC running Linux and:

zomgugoff commented 2 years ago

Hey there, I'm the person that reported the issue with the OPL3 Duo! board. Using the above described method did not help with it. I am still getting the same distorted audio.

...No, I apparently updated my launch script to run the native version for some reason. It does work properly with the OPL3 Duo! via Wine.