[Scummvm-git-logs] scummvm master -> 15425aa66beff92b82cd60930a5fd791c4e40f65

lephilousophe noreply at scummvm.org
Fri Jan 24 21:40:49 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
15425aa66b AUDIO: Fix playback in OPL3 mono mode


Commit: 15425aa66beff92b82cd60930a5fd791c4e40f65
    https://github.com/scummvm/scummvm/commit/15425aa66beff92b82cd60930a5fd791c4e40f65
Author: Raffaello Bertini (raffaellobertini at gmail.com)
Date: 2025-01-24T22:40:35+01:00

Commit Message:
AUDIO: Fix playback in OPL3 mono mode

If running an OPL2 track on a DOS_BOX OPL3 emulator,
The buffer will be divided by 2 like if it is stereo,
but it will generate a mono audio stream, as opl3Active
flag is disabled, so it will act as an OPL2.
The error results in wrong sound produced.
This fix the issue when OPL3 is used as an OPL2 and therefore
as a mono audio source.

The current error should be easily reproducible if
using OPL3 with .ADL Westwood's files.

This bug it might have never been noticed because those files,
in kyra engine, are using always OPL2 (kAdlib) is used.

When DosBox OPL3 Emulator is run as OPL2 compatibilty mode,
requires to call the GenerateBlock2 method as the internal
stereo mode used in GenerateBlock3 is not activated.

This fix covers all scenarios:
- OPL2: default common base case, non stereo.
- DUAL_OPL2: This is kind of OPL3 mode,
             I don't think is really fully supported,
- OPL3 in OPL2 mode: In this scenario the audio buffer is stereo, but
                     the emulator is generating mono audio.
- OPL3 in OPL3 mode: this is the full stereo mode of OPL3.

Changed paths:
    audio/adlib.cpp
    audio/softsynth/opl/dosbox.cpp


diff --git a/audio/adlib.cpp b/audio/adlib.cpp
index fa5c361d6f4..dddf1b1bd30 100644
--- a/audio/adlib.cpp
+++ b/audio/adlib.cpp
@@ -1440,7 +1440,7 @@ int MidiDriver_ADLIB::open() {
 		_opl = OPL::Config::create(OPL::Config::kOpl3);
 	}
 
-	// Initialize plain OPL2 when no OPL3 is intiailized already.
+	// Initialize plain OPL2 when no OPL3 is initialized already.
 	if (!_opl) {
 #endif
 		_opl = OPL::Config::create();
diff --git a/audio/softsynth/opl/dosbox.cpp b/audio/softsynth/opl/dosbox.cpp
index 35024b27297..8e2edc622ae 100644
--- a/audio/softsynth/opl/dosbox.cpp
+++ b/audio/softsynth/opl/dosbox.cpp
@@ -298,27 +298,44 @@ void OPL::dualWrite(uint8 index, uint8 reg, uint8 val) {
 }
 
 void OPL::generateSamples(int16 *buffer, int length) {
-	// For stereo OPL cards, we divide the sample count by 2,
-	// to match stereo AudioStream behavior.
-	if (_type != Config::kOpl2)
-		length >>= 1;
-
 	const uint bufferLength = 512;
 	int32 tempBuffer[bufferLength * 2];
 
-	if (_emulator->opl3Active) {
-		while (length > 0) {
-			const uint readSamples = MIN<uint>(length, bufferLength);
+	if (isStereo()) {
+		// For stereo OPL cards, we divide the sample count by 2,
+		// to match stereo AudioStream behavior.
+		length >>= 1;
+		if (_emulator->opl3Active) {
+			// DUAL_OPL2 or OPL3 in OPL3 mode (stereo)
+			while (length > 0) {
+				const uint readSamples = MIN<uint>(length, bufferLength);
+				const uint readSamples2 = (readSamples << 1);
 
-			_emulator->GenerateBlock3(readSamples, tempBuffer);
+				_emulator->GenerateBlock3(readSamples, tempBuffer);
 
-			for (uint i = 0; i < (readSamples << 1); ++i)
-				buffer[i] = tempBuffer[i];
+				for (uint i = 0; i < readSamples2; ++i)
+					buffer[i] = tempBuffer[i];
 
-			buffer += (readSamples << 1);
-			length -= readSamples;
+				buffer += readSamples2;
+				length -= readSamples;
+			}
+		} else {
+			// OPL3 (stereo) in OPL2 compatibility mode (mono)
+			while (length > 0) {
+				const uint readSamples = MIN<uint>(length, bufferLength);
+				const uint readSamples2 = (readSamples << 1);
+
+				_emulator->GenerateBlock2(readSamples, tempBuffer);
+
+				for (uint i = 0, j = 0; i < readSamples; ++i, j += 2)
+					buffer[j] = buffer[j + 1] = tempBuffer[i];
+
+				buffer += readSamples2;
+				length -= readSamples;
+			}
 		}
 	} else {
+		// OPL2
 		while (length > 0) {
 			const uint readSamples = MIN<uint>(length, bufferLength << 1);
 




More information about the Scummvm-git-logs mailing list