ArduinoOPL2 icon indicating copy to clipboard operation
ArduinoOPL2 copied to clipboard

Serial issues communicating with DOSBox-X on Linux

Open KGOrphanides opened this issue 1 year ago • 2 comments

I'm trying to get to the bottom of an issue that's preventing the OPL2 Audio Board from working correctly in DOSBox-X on Linux.

OPL2board Audio playback on DOSBox-X is hideous out of time, stuttery and distorted on Linux. I've been investigating this for a couple of days and what I've found so far indicates that it may be the result of issues involving Linux serial port (ttyACM0) handling, and/or the way either the Arduino or DOSBox-X is using it.

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

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

I've ruled out hardware and DOSBox-X configuration issues by borrowing a Windows PC to confirm that everything works on that as it should, and by reproducing the issue on a second OPL2board.

Since beginning to investigate potentially issues with ttyACM0, I've seen a number of posts discussing issues with transmitting some kinds of 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.

In case further detail would help diagnose this, I noted down some of my investigation as I went in the DOSBox-X issue tracker, several salient points of which I've reproduced here.

I'm aware that, as a hardware developer, apparent operating system/third party software issues aren't your problem per se, but if I can, I'd like to help get this working and accurately documented so that the OPL2board and OPL3 Duo can be used with DOSBox-X on Linux, and if you have any insight into the issue I'd be very appreciative.

KGOrphanides avatar Sep 03 '22 19:09 KGOrphanides

Hi @KGOrphanides, this is an interesting issue. My first thought when I look at the video is that the Arduino has gotten out of sync with the serial data, i.e. the address / data pairs have switched order because there was a byte dropped. Is the issue always happening at the same time when you play this game?

If you have an OPL3 Duo board you could validate whether it has the same issue? I'm thinking that it will work on the OPL3 board since DOSBox-X sends the data using Nuke.YKT's protocol instead of simple addres / data pairs. This protocol makes sure that address and data cannot get mixed up and it should also be used for the OPL2 board, regardless of whether this is what's causing your issue or not, but I have high hopes.

I'll try to find some time the coming week to give this a try and report back...

DhrBaksteen avatar Sep 04 '22 12:09 DhrBaksteen

Thanks for picking this up here and over on the other thread, @DhrBaksteen.

Unfortunately, I don't have an OPL3 Duo, but there is an older bug report in which an OPL3 Duo user has what appears to be the same problem.

KGOrphanides avatar Sep 05 '22 08:09 KGOrphanides

If you have problems using OPL3Duo! board with dosbox-x is because serial ports on unix are initialized using wrong defaults. I managed to build dosbox-x with those edits and have the full board working as intended. I may send the fix to upstream in the near future too.

stengun avatar Oct 26 '22 10:10 stengun

@stengun Nice work. I'd been working on the same assumption but it's been slow progress given my lack of experience with serial port configuration. Could I impose on you to share your serial initialisation changes, and I'll gladly try implementing them on my end. (Would these be in libserial.cpp by any chance?)

KGOrphanides avatar Oct 26 '22 22:10 KGOrphanides

@KGOrphanides Sure, this is the change I'm about to propose to upstream. Feel free to compile dosbox-x from that if you want to try.

I stumbled upon this same issue months ago. Having used OPL3Duo! board with another serial library for a personal project (that basically does the same as dosbox-x by forwarding writes and reads, but with MAME) and knowing it worked well with that library I had to check how dosbox-x opened the serial device, and BAM!.

The thing that fixed the board itself was setting Blocking I/O instead of NDELAY, but I took the time to also correct the overall usage of the serial struct.

Let me know if the fix is working for you :smile:

Edit: Here you can see the relevant PR

stengun avatar Oct 27 '22 00:10 stengun

Confirmed working! This is a huge help to an ongoing project of mine, and I really appreciate your work here. (And the explanation that means I now understand a little more about serial config than I did.)

KGOrphanides avatar Oct 27 '22 08:10 KGOrphanides

@KGOrphanides I tried a different approach to solve this problem and would likely be the preferred way if we want this fix pushed upstream. I can test it on OPL3! Duo board but I can't on OPL2 Audio Board. I understood that you own an OPL2 board, if so then could you please test this branch and see if your board still works?

There is still something that is missing tho, but I think it's probably due to the board firmware. Let me know!

stengun avatar Nov 02 '22 18:11 stengun

No, sorry, the new fix doesn't work properly on the OPL2 Board, at least with expected settings. I'm getting distortion and missed notes, albeit not as pronounced as originally.

I see that you've put the changes into the OPL-specific files as an alternative to the more dramatic reworking of serial handling in general, and I definitely see your reasoning for that choice, but it's not doing it the job in this case.

It's late here, but I'll take a look and see if any potential issues that leap out at me tomorrow if I can find a moment. What I lack in wisdom, I make up for in "I've been staring at this for weeks", so I may turn something.

KGOrphanides avatar Nov 02 '22 21:11 KGOrphanides

What I did is using the same method I used to fix the OPL3 board. The reasoning is this: since we have nonblocking IO we have to find a way to simulate a blocking simulation when we write on the port. So I made a buffer and a thread, then I try to write on the serial port constantly. When writes are successful, I remove the written data from the buffer. This approach works well for my board, but I probably wrote something wrong for OPL2. I think I can simulate an opl2 board by changing the firmware a little bit, so I won't bother for testing :smile: after all, both chips are compatible and on start should be on the same state.

PS: what if opl2 board needs also the edits on the unix port init?

stengun avatar Nov 03 '22 05:11 stengun

Ok so using a firmware that fetches stuff like OPL2 board on OPL3 board seems to work with my edits without touching anything. I selected opl2board on dosbox-x with opl mode set to Auto, then saved config and restarted.

I suppose you are using an arduino with the sketch "SerialPassthroug" unmodified.

I'm using an arduino uno SMD.

stengun avatar Nov 03 '22 07:11 stengun

So, I shouldn't test things at night, because I cloned the wrong branch for my original test. /facepalm/ It's working on OPL2 Board.

KGOrphanides avatar Nov 03 '22 10:11 KGOrphanides