[Scummvm-git-logs] scummvm master -> 15a1455e0d4a24427f8054ef18863a39a13b9d9d

mikrosk noreply at scummvm.org
Thu Nov 9 17:20:19 UTC 2023


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

Summary:
f7d78ec70a BACKENDS: ATARI: Implement internal downsampling to 8-bit
43eb596d40 BACKENDS: ATARI: Set ST-MIDI driver for all audio
15a1455e0d BACKENDS: ATARI: Allow mixing into mono


Commit: f7d78ec70a8e8c6d2eec68f8688f1cf1fb8fd2f2
    https://github.com/scummvm/scummvm/commit/f7d78ec70a8e8c6d2eec68f8688f1cf1fb8fd2f2
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-11-09T18:20:06+01:00

Commit Message:
BACKENDS: ATARI: Implement internal downsampling to 8-bit

So we don't rely on STFA's questionable algorithms and we can use
X-SOUND, too.

Changed paths:
    backends/mixer/atari/atari-mixer.cpp
    backends/mixer/atari/atari-mixer.h
    backends/module.mk
    backends/platform/atari/osystem_atari.cpp
    backends/platform/atari/osystem_atari.h
    backends/platform/atari/readme.txt


diff --git a/backends/mixer/atari/atari-mixer.cpp b/backends/mixer/atari/atari-mixer.cpp
index fc6d3f6c919..66a9a32a464 100644
--- a/backends/mixer/atari/atari-mixer.cpp
+++ b/backends/mixer/atari/atari-mixer.cpp
@@ -78,14 +78,15 @@ void AtariMixerManager::init() {
 		error("Sound system is not available");
 	}
 
-	if (obtained.channels != 2 && obtained.format != AudioFormatSigned16MSB) {
-		error("Sound system currently supports only 16-bit signed stereo samples (big endian)");
+	if (obtained.channels != 2 ||
+		(obtained.format != AudioFormatSigned8 && obtained.format != AudioFormatSigned16MSB)) {
+		error("Sound system currently supports only 8/16-bit signed stereo samples");
 	}
 
 	_outputRate = obtained.frequency;
 
 	ConfMan.setInt("output_rate", _outputRate);
-	debug("setting %d Hz mixing frequency", _outputRate);
+	debug("setting %d Hz mixing frequency (%d-bit)", _outputRate, obtained.format == AudioFormatSigned8 ? 8 : 16);
 
 	_samples = 8192;
 	while (_samples * 16 > _outputRate * 2)
@@ -102,16 +103,20 @@ void AtariMixerManager::init() {
 
 	ConfMan.flushToDisk();
 
-	_atariSampleBufferSize = _samples * 4;
+	size_t atariSampleBufferSize = _samples * 4;
+	if (obtained.format == AudioFormatSigned8) {
+		atariSampleBufferSize /= 2;
+		_downsample = true;
+	}
 
-	_atariSampleBuffer = (byte*)Mxalloc(_atariSampleBufferSize * 2, MX_STRAM);
+	_atariSampleBuffer = (byte*)Mxalloc(atariSampleBufferSize * 2, MX_STRAM);
 	if (!_atariSampleBuffer)
 		error("Failed to allocate memory in ST RAM");
 
 	_atariPhysicalSampleBuffer = _atariSampleBuffer;
-	_atariLogicalSampleBuffer = _atariSampleBuffer + _atariSampleBufferSize;
+	_atariLogicalSampleBuffer = _atariSampleBuffer + atariSampleBufferSize;
 
-	Setbuffer(SR_PLAY, _atariSampleBuffer, _atariSampleBuffer + 2 * _atariSampleBufferSize);
+	Setbuffer(SR_PLAY, _atariSampleBuffer, _atariSampleBuffer + 2 * atariSampleBufferSize);
 
 	_samplesBuf = new uint8[_samples * 4];
 
@@ -178,8 +183,44 @@ void AtariMixerManager::update() {
 		processed = _mixer->mixCallback(_samplesBuf, _samples * 4);
 
 		if (processed > 0) {
-			memcpy(_atariPhysicalSampleBuffer, _samplesBuf, processed * 4);
-			memset(_atariPhysicalSampleBuffer + processed, 0, (_samples - processed) * 4);
+			if (!_downsample) {
+				memcpy(_atariPhysicalSampleBuffer, _samplesBuf, processed * 4);
+				memset(_atariPhysicalSampleBuffer + processed, 0, (_samples - processed) * 4);
+			} else {
+				// use the trick with move.b (a7)+,dx which skips two bytes at once
+				// basically supplying move.w (src)+,dx; asr.w #8,dx; move.b dx,(dst)+
+				__asm__ volatile(
+					"	move.l	%%a7,%%d0\n"
+					"	move.l	%0,%%a7\n"
+					"	moveq	#0x0f,%%d1\n"
+					"	and.l	%2,%%d1\n"
+					"	neg.l	%%d1\n"
+					"	lsr.l	#4,%2\n"
+					"	jmp		(2f,%%pc,%%d1.l*2)\n"
+					"1:	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"	move.b	(%%a7)+,(%1)+\n"
+					"2:	dbra	%2,1b\n"
+					"	move.l	%%d0,%%a7\n"
+					: // outputs
+					: "g"(_samplesBuf), "a"(_atariPhysicalSampleBuffer), "d"(processed * 4/2) // inputs
+					: "d0", "d1", "cc" AND_MEMORY
+				);
+				memset(_atariPhysicalSampleBuffer + processed, 0, (_samples - processed) * 4/2);
+			}
 			startPlayback(kPlayingFromPhysicalBuffer);
 		}
 	} else {
@@ -206,7 +247,44 @@ void AtariMixerManager::update() {
 		if (buf) {
 			processed = _mixer->mixCallback(_samplesBuf, _samples * 4);
 			if (processed > 0) {
-				memcpy(buf, _samplesBuf, processed * 4);
+				if (!_downsample) {
+					memcpy(buf, _samplesBuf, processed * 4);
+					memset(buf + processed, 0, (_samples - processed) * 4);
+				} else {
+					// use the trick with move.b (a7)+,dx which skips two bytes at once
+					// basically supplying move.w (src)+,dx; asr.w #8,dx; move.b dx,(dst)+
+					__asm__ volatile(
+						"	move.l	%%a7,%%d0\n"
+						"	move.l	%0,%%a7\n"
+						"	moveq	#0x0f,%%d1\n"
+						"	and.l	%2,%%d1\n"
+						"	neg.l	%%d1\n"
+						"	lsr.l	#4,%2\n"
+						"	jmp		(2f,%%pc,%%d1.l*2)\n"
+						"1:	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"	move.b	(%%a7)+,(%1)+\n"
+						"2:	dbra	%2,1b\n"
+						"	move.l	%%d0,%%a7\n"
+						: // outputs
+						: "g"(_samplesBuf), "a"(buf), "d"(processed * 4/2) // inputs
+						: "d0", "d1", "cc" AND_MEMORY
+					);
+					memset(buf + processed, 0, (_samples - processed) * 4/2);
+				}
 			} else {
 				stopPlayback(kPlaybackStopped);
 			}
diff --git a/backends/mixer/atari/atari-mixer.h b/backends/mixer/atari/atari-mixer.h
index d18c41849af..2ca56989e13 100644
--- a/backends/mixer/atari/atari-mixer.h
+++ b/backends/mixer/atari/atari-mixer.h
@@ -59,7 +59,7 @@ private:
 	byte *_atariSampleBuffer = nullptr;
 	byte *_atariPhysicalSampleBuffer = nullptr;
 	byte *_atariLogicalSampleBuffer = nullptr;
-	size_t _atariSampleBufferSize;	// one buffer (logical/physical)
+	bool _downsample = false;
 
 	PlaybackState _playbackState = kPlaybackStopped;
 };
diff --git a/backends/module.mk b/backends/module.mk
index d8bfa2d6eeb..bee6c1b5b2f 100644
--- a/backends/module.mk
+++ b/backends/module.mk
@@ -370,8 +370,7 @@ MODULE_OBJS += \
 	graphics/atari/atari_c2p-asm.o \
 	graphics/atari/atari-graphics.o \
 	graphics/atari/atari-graphics-asm.o \
-	mixer/atari/atari-mixer.o \
-	mixer/null/null-mixer.o
+	mixer/atari/atari-mixer.o
 endif
 
 ifeq ($(BACKEND),ds)
diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index d1542c92e42..4f310e72cd8 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -53,7 +53,6 @@
 #include "backends/graphics/atari/atari-graphics.h"
 #include "backends/keymapper/hardware-input.h"
 #include "backends/mixer/atari/atari-mixer.h"
-#include "backends/mixer/null/null-mixer.h"
 #include "backends/mutex/null/null-mutex.h"
 #include "backends/saves/default/default-saves.h"
 #include "backends/timer/default/default-timer.h"
@@ -314,14 +313,7 @@ void OSystem_Atari::initBackend() {
 	}
 #endif
 
-	long cookie;
-	if (Getcookie(C__SND, &cookie) == C_FOUND && (cookie & SND_16BIT)) {
-		_mixerManager = new AtariMixerManager();
-	} else {
-		warning("Mixer manager requires 16-bit stereo mode, disabling");
-		_mixerManager = new NullMixerManager();
-		_useNullMixer = true;
-	}
+	_mixerManager = new AtariMixerManager();
 	// Setup and start mixer
 	_mixerManager->init();
 
@@ -465,10 +457,7 @@ void OSystem_Atari::update() {
 		}
 	}
 
-	if (_useNullMixer)
-		((NullMixerManager *)_mixerManager)->update();
-	else
-		((AtariMixerManager *)_mixerManager)->update();
+	((AtariMixerManager *)_mixerManager)->update();
 }
 
 OSystem *OSystem_Atari_create() {
diff --git a/backends/platform/atari/osystem_atari.h b/backends/platform/atari/osystem_atari.h
index 786ff6bf4b3..b4c3f4c6ced 100644
--- a/backends/platform/atari/osystem_atari.h
+++ b/backends/platform/atari/osystem_atari.h
@@ -53,7 +53,6 @@ private:
 
 	bool _videoInitialized = false;
 	bool _timerInitialized = false;
-	bool _useNullMixer = false;
 
 	int16 _vdi_handle;
 	int _vdi_width;
diff --git a/backends/platform/atari/readme.txt b/backends/platform/atari/readme.txt
index 8821cba3cdf..1524c76d774 100644
--- a/backends/platform/atari/readme.txt
+++ b/backends/platform/atari/readme.txt
@@ -249,12 +249,12 @@ stay black.
 Audio mixing
 ------------
 
-ScummVM works internally with 16-bit stereo samples. This mode is not available
-on the TT so a substitute solution must be used. This solution is called STFA
-by The Removers: http://removers.free.fr/softs/stfa.php. Install, activate STFA
-BIOS in the CPX, done. Now you have 16-bit DMA available, too but beware, it is
-also quite CPU demanding so very few games can actually make use of it (see the
-chapter about audio performance considerations below).
+ScummVM works internally with 16-bit stereo samples so on the TT a simple
+downsampling to 8-bit resolution is used. However there's still one piece
+missing - an XBIOS emulator (so ScummVM doesn't have to access hardware
+directly). There are two options (both available from
+https://mikrosk.github.io/xbios): STFA and X-SOUND, any of these will do. Or
+executing ScummVM in EmuTOS which contains the same routines as X-SOUND.
 
 
 Performance considerations/pitfalls
@@ -300,8 +300,8 @@ for MAME OPL only).
 
 On the TT, in most cases it makes sense to use ScummVM only if you own a
 native MIDI synthesizer (like mt32-pi: https://github.com/dwhinham/mt32-pi).
-MIDI emulation is out of question and STFA takes a good chunk of CPU time for
-downsampling to 8-bit resolution which could be utilized elsewhere.
+MIDI emulation is out of question and downsampling to 8-bit resolution takes
+a good chunk of CPU time which could be utilized elsewhere.
 
 CD music slows everything down
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Commit: 43eb596d40aff1309f80b54e54caa0bd39f3b71b
    https://github.com/scummvm/scummvm/commit/43eb596d40aff1309f80b54e54caa0bd39f3b71b
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-11-09T18:20:06+01:00

Commit Message:
BACKENDS: ATARI: Set ST-MIDI driver for all audio

Also, MT-32 and MIDI are set to "auto" so no need to change those, too.

Changed paths:
    backends/platform/atari/osystem_atari.cpp


diff --git a/backends/platform/atari/osystem_atari.cpp b/backends/platform/atari/osystem_atari.cpp
index 4f310e72cd8..4c3fc80dcb4 100644
--- a/backends/platform/atari/osystem_atari.cpp
+++ b/backends/platform/atari/osystem_atari.cpp
@@ -304,12 +304,17 @@ void OSystem_Atari::initBackend() {
 	atariEventSource->setGraphicsManager(atariGraphicsManager);
 
 #ifdef DISABLE_FANCY_THEMES
-	// On the slim build force "STMIDI" as GM MIDI device, i.e. do not attempt
+	// On the slim build force "STMIDI" as the audio driver, i.e. do not attempt
 	// to emulate anything by default. That prevents mixing silence and enable
-	// us to stop DMA playback which takes cycles especially on TT with STFA's
-	// emulation.
+	// us to stop DMA playback which takes unnecessary cycles.
+	if (!ConfMan.hasKey("music_driver")) {
+		ConfMan.set("music_driver", "stmidi");
+	}
 	if (!ConfMan.hasKey("gm_device")) {
-		ConfMan.set("gm_device", "stmidi");
+		ConfMan.set("gm_device", "auto");
+	}
+	if (!ConfMan.hasKey("mt32_device")) {
+		ConfMan.set("mt32_device", "auto");
 	}
 #endif
 


Commit: 15a1455e0d4a24427f8054ef18863a39a13b9d9d
    https://github.com/scummvm/scummvm/commit/15a1455e0d4a24427f8054ef18863a39a13b9d9d
Author: Miro Kropacek (miro.kropacek at gmail.com)
Date: 2023-11-09T18:20:06+01:00

Commit Message:
BACKENDS: ATARI: Allow mixing into mono

Please note that Falcon 16-bit playback doesn't allow only one channel.

Changed paths:
    backends/mixer/atari/atari-mixer.cpp
    backends/mixer/atari/atari-mixer.h


diff --git a/backends/mixer/atari/atari-mixer.cpp b/backends/mixer/atari/atari-mixer.cpp
index 66a9a32a464..c6f86aa5647 100644
--- a/backends/mixer/atari/atari-mixer.cpp
+++ b/backends/mixer/atari/atari-mixer.cpp
@@ -33,6 +33,7 @@
 #include "../../../../atari_sound_setup.git/atari_sound_setup.h"
 
 #define DEFAULT_OUTPUT_RATE 24585
+#define DEFAULT_OUTPUT_CHANNELS 2
 #define DEFAULT_SAMPLES 2048	// 83ms
 
 void AtariAudioShutdown() {
@@ -50,6 +51,12 @@ AtariMixerManager::AtariMixerManager() : MixerManager() {
 	if (_outputRate <= 0)
 		_outputRate = DEFAULT_OUTPUT_RATE;
 
+	ConfMan.registerDefault("output_channels", DEFAULT_OUTPUT_CHANNELS);
+
+	_outputChannels = ConfMan.getInt("output_channels");
+	if (_outputChannels <= 0 || _outputChannels > 2)
+		_outputChannels = DEFAULT_OUTPUT_CHANNELS;
+
 	g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false);
 }
 
@@ -70,7 +77,7 @@ void AtariMixerManager::init() {
 	AudioSpec desired, obtained;
 
 	desired.frequency = _outputRate;
-	desired.channels = 2;
+	desired.channels = _outputChannels;
 	desired.format = AudioFormatSigned16MSB;
 	desired.samples = DEFAULT_SAMPLES;
 
@@ -78,15 +85,18 @@ void AtariMixerManager::init() {
 		error("Sound system is not available");
 	}
 
-	if (obtained.channels != 2 ||
-		(obtained.format != AudioFormatSigned8 && obtained.format != AudioFormatSigned16MSB)) {
-		error("Sound system currently supports only 8/16-bit signed stereo samples");
+	if (obtained.format != AudioFormatSigned8 && obtained.format != AudioFormatSigned16MSB) {
+		error("Sound system currently supports only 8/16-bit signed big endian samples");
 	}
 
 	_outputRate = obtained.frequency;
+	_outputChannels = obtained.channels;
 
 	ConfMan.setInt("output_rate", _outputRate);
-	debug("setting %d Hz mixing frequency (%d-bit)", _outputRate, obtained.format == AudioFormatSigned8 ? 8 : 16);
+	ConfMan.setInt("output_channels", _outputChannels);
+
+	debug("setting %d Hz mixing frequency (%d-bit, %s)",
+		  _outputRate, obtained.format == AudioFormatSigned8 ? 8 : 16, _outputChannels == 1 ? "mono" : "stereo");
 
 	_samples = 8192;
 	while (_samples * 16 > _outputRate * 2)
@@ -103,7 +113,7 @@ void AtariMixerManager::init() {
 
 	ConfMan.flushToDisk();
 
-	size_t atariSampleBufferSize = _samples * 4;
+	size_t atariSampleBufferSize = _samples * _outputChannels * 2;	// 16-bit by default
 	if (obtained.format == AudioFormatSigned8) {
 		atariSampleBufferSize /= 2;
 		_downsample = true;
@@ -118,9 +128,9 @@ void AtariMixerManager::init() {
 
 	Setbuffer(SR_PLAY, _atariSampleBuffer, _atariSampleBuffer + 2 * atariSampleBufferSize);
 
-	_samplesBuf = new uint8[_samples * 4];
+	_samplesBuf = new uint8[_samples * _outputChannels * 2];	// always 16-bit
 
-	_mixer = new Audio::MixerImpl(_outputRate, _samples);
+	_mixer = new Audio::MixerImpl(_outputRate, _outputChannels == 2, _samples);
 	_mixer->setReady(true);
 
 	_audioSuspended = false;
@@ -176,17 +186,14 @@ void AtariMixerManager::update() {
 
 	assert(_mixer);
 
-	uint32 processed = 0;
+	int processed = 0;
 	if (_playbackState == kPlaybackStopped) {
 		// playback stopped means that we are not playing anything (DMA
 		// pointer is not updating) but the mixer may have something available
-		processed = _mixer->mixCallback(_samplesBuf, _samples * 4);
+		processed = _mixer->mixCallback(_samplesBuf, _samples * _outputChannels * 2);
 
 		if (processed > 0) {
-			if (!_downsample) {
-				memcpy(_atariPhysicalSampleBuffer, _samplesBuf, processed * 4);
-				memset(_atariPhysicalSampleBuffer + processed, 0, (_samples - processed) * 4);
-			} else {
+			if (_downsample) {
 				// use the trick with move.b (a7)+,dx which skips two bytes at once
 				// basically supplying move.w (src)+,dx; asr.w #8,dx; move.b dx,(dst)+
 				__asm__ volatile(
@@ -216,10 +223,13 @@ void AtariMixerManager::update() {
 					"2:	dbra	%2,1b\n"
 					"	move.l	%%d0,%%a7\n"
 					: // outputs
-					: "g"(_samplesBuf), "a"(_atariPhysicalSampleBuffer), "d"(processed * 4/2) // inputs
+					: "g"(_samplesBuf), "a"(_atariPhysicalSampleBuffer), "d"(processed * _outputChannels * 2/2) // inputs
 					: "d0", "d1", "cc" AND_MEMORY
 				);
-				memset(_atariPhysicalSampleBuffer + processed, 0, (_samples - processed) * 4/2);
+				memset(_atariPhysicalSampleBuffer + processed * _outputChannels * 2/2, 0, (_samples - processed) * _outputChannels * 2/2);
+			} else {
+				memcpy(_atariPhysicalSampleBuffer, _samplesBuf, processed * _outputChannels * 2);
+				memset(_atariPhysicalSampleBuffer + processed * _outputChannels * 2, 0, (_samples - processed) * _outputChannels * 2);
 			}
 			startPlayback(kPlayingFromPhysicalBuffer);
 		}
@@ -245,12 +255,9 @@ void AtariMixerManager::update() {
 		}
 
 		if (buf) {
-			processed = _mixer->mixCallback(_samplesBuf, _samples * 4);
+			processed = _mixer->mixCallback(_samplesBuf, _samples * _outputChannels * 2);
 			if (processed > 0) {
-				if (!_downsample) {
-					memcpy(buf, _samplesBuf, processed * 4);
-					memset(buf + processed, 0, (_samples - processed) * 4);
-				} else {
+				if (_downsample) {
 					// use the trick with move.b (a7)+,dx which skips two bytes at once
 					// basically supplying move.w (src)+,dx; asr.w #8,dx; move.b dx,(dst)+
 					__asm__ volatile(
@@ -280,10 +287,13 @@ void AtariMixerManager::update() {
 						"2:	dbra	%2,1b\n"
 						"	move.l	%%d0,%%a7\n"
 						: // outputs
-						: "g"(_samplesBuf), "a"(buf), "d"(processed * 4/2) // inputs
+						: "g"(_samplesBuf), "a"(buf), "d"(processed * _outputChannels * 2/2) // inputs
 						: "d0", "d1", "cc" AND_MEMORY
 					);
-					memset(buf + processed, 0, (_samples - processed) * 4/2);
+					memset(buf + processed * _outputChannels * 2/2, 0, (_samples - processed) * _outputChannels * 2/2);
+				} else {
+					memcpy(buf, _samplesBuf, processed * _outputChannels * 2);
+					memset(buf + processed* _outputChannels * 2, 0, (_samples - processed) * _outputChannels * 2);
 				}
 			} else {
 				stopPlayback(kPlaybackStopped);
diff --git a/backends/mixer/atari/atari-mixer.h b/backends/mixer/atari/atari-mixer.h
index 2ca56989e13..146a5600e7f 100644
--- a/backends/mixer/atari/atari-mixer.h
+++ b/backends/mixer/atari/atari-mixer.h
@@ -52,8 +52,9 @@ private:
 	void startPlayback(PlaybackState playbackState);
 	void stopPlayback(PlaybackState playbackState);
 
-	uint32 _outputRate;
-	uint32 _samples = 0;
+	int _outputRate = 0;
+	int _outputChannels = 0;
+	int _samples = 0;
 	uint8 *_samplesBuf = nullptr;
 
 	byte *_atariSampleBuffer = nullptr;




More information about the Scummvm-git-logs mailing list