[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