[Scummvm-git-logs] scummvm master -> 749fd8b490b6ea5b685ce7438e4ead3a69f38f30
sev-
noreply at scummvm.org
Fri Nov 18 16:17:04 UTC 2022
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
9f4f22b3bf AUDIO: Support mono audio output in the mixer
749fd8b490 SDL: Allow selecting the audio channel count from the command line
Commit: 9f4f22b3bf2a42db172b05c7e15b776e22d23e3d
https://github.com/scummvm/scummvm/commit/9f4f22b3bf2a42db172b05c7e15b776e22d23e3d
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2022-11-18T17:17:00+01:00
Commit Message:
AUDIO: Support mono audio output in the mixer
Changed paths:
audio/mixer.cpp
audio/mixer.h
audio/mixer_intern.h
audio/rate.cpp
audio/rate.h
backends/mixer/null/null-mixer.cpp
backends/mixer/sdl/sdl-mixer.cpp
backends/platform/android/android.cpp
backends/platform/ios7/ios7_osys_sound.cpp
backends/platform/iphone/osys_sound.cpp
engines/sci/sound/audio32.cpp
engines/sword1/music.cpp
diff --git a/audio/mixer.cpp b/audio/mixer.cpp
index c118b18c40c..3e348402827 100644
--- a/audio/mixer.cpp
+++ b/audio/mixer.cpp
@@ -176,8 +176,8 @@ private:
#pragma mark --- Mixer ---
#pragma mark -
-MixerImpl::MixerImpl(uint sampleRate, uint outBufSize)
- : _mutex(), _sampleRate(sampleRate), _outBufSize(outBufSize), _mixerReady(false), _handleSeed(0), _soundTypeSettings() {
+MixerImpl::MixerImpl(uint sampleRate, bool stereo, uint outBufSize)
+ : _mutex(), _sampleRate(sampleRate), _stereo(stereo), _outBufSize(outBufSize), _mixerReady(false), _handleSeed(0), _soundTypeSettings() {
assert(sampleRate > 0);
@@ -200,6 +200,10 @@ uint MixerImpl::getOutputRate() const {
return _sampleRate;
}
+bool MixerImpl::getOutputStereo() const {
+ return _stereo;
+}
+
uint MixerImpl::getOutputBufSize() const {
return _outBufSize;
}
@@ -280,15 +284,21 @@ int MixerImpl::mixCallback(byte *samples, uint len) {
Common::StackLock lock(_mutex);
int16 *buf = (int16 *)samples;
- // we store stereo, 16-bit samples
- assert(len % 4 == 0);
- len >>= 2;
// Since the mixer callback has been called, the mixer must be ready...
_mixerReady = true;
// zero the buf
- memset(buf, 0, 2 * len * sizeof(int16));
+ memset(buf, 0, len);
+
+ // we store 16-bit samples
+ if (_stereo) {
+ assert(len % 4 == 0);
+ len >>= 2;
+ } else {
+ assert(len % 2 == 0);
+ len >>= 1;
+ }
// mix all channels
int res = 0, tmp;
@@ -524,7 +534,7 @@ Channel::Channel(Mixer *mixer, Mixer::SoundType type, AudioStream *stream,
assert(stream);
// Get a rate converter instance
- _converter = makeRateConverter(_stream->getRate(), mixer->getOutputRate(), _stream->isStereo(), reverseStereo);
+ _converter = makeRateConverter(_stream->getRate(), mixer->getOutputRate(), _stream->isStereo(), mixer->getOutputStereo(), reverseStereo);
}
Channel::~Channel() {
diff --git a/audio/mixer.h b/audio/mixer.h
index 804022ecf00..ff521799617 100644
--- a/audio/mixer.h
+++ b/audio/mixer.h
@@ -305,6 +305,13 @@ public:
*/
virtual uint getOutputRate() const = 0;
+ /**
+ * Check whether the output is stereo.
+ *
+ * @return true if output is stereo, false if not.
+ */
+ virtual bool getOutputStereo() const = 0;
+
/**
* Return the output sample buffer size of the system.
*
diff --git a/audio/mixer_intern.h b/audio/mixer_intern.h
index 424a0d4853f..c7d67771cbd 100644
--- a/audio/mixer_intern.h
+++ b/audio/mixer_intern.h
@@ -64,6 +64,7 @@ private:
Common::Mutex _mutex;
const uint _sampleRate;
+ const bool _stereo;
const uint _outBufSize;
bool _mixerReady;
uint32 _handleSeed;
@@ -81,7 +82,7 @@ private:
public:
- MixerImpl(uint sampleRate, uint outBufSize = 0);
+ MixerImpl(uint sampleRate, bool stereo = true, uint outBufSize = 0);
~MixerImpl();
virtual bool isReady() const { Common::StackLock lock(_mutex); return _mixerReady; }
@@ -129,6 +130,7 @@ public:
virtual int getVolumeForSoundType(SoundType type) const;
virtual uint getOutputRate() const;
+ virtual bool getOutputStereo() const;
virtual uint getOutputBufSize() const;
protected:
diff --git a/audio/rate.cpp b/audio/rate.cpp
index 1bd67c6d181..d85c278d796 100644
--- a/audio/rate.cpp
+++ b/audio/rate.cpp
@@ -62,7 +62,7 @@ enum {
*
* Limited to sampling frequency <= 65535 Hz.
*/
-template<bool stereo, bool reverseStereo>
+template<bool inStereo, bool outStereo, bool reverseStereo>
class SimpleRateConverter : public RateConverter {
protected:
st_sample_t inBuf[INTERMEDIATE_BUFFER_SIZE];
@@ -88,8 +88,8 @@ public:
/*
* Prepare processing.
*/
-template<bool stereo, bool reverseStereo>
-SimpleRateConverter<stereo, reverseStereo>::SimpleRateConverter(st_rate_t inrate, st_rate_t outrate) {
+template<bool inStereo, bool outStereo, bool reverseStereo>
+SimpleRateConverter<inStereo, outStereo, reverseStereo>::SimpleRateConverter(st_rate_t inrate, st_rate_t outrate) {
if ((inrate % outrate) != 0) {
error("Input rate must be a multiple of output rate to use rate effect");
}
@@ -110,12 +110,12 @@ SimpleRateConverter<stereo, reverseStereo>::SimpleRateConverter(st_rate_t inrate
* Processed signed long samples from ibuf to obuf.
* Return number of sample pairs processed.
*/
-template<bool stereo, bool reverseStereo>
-int SimpleRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
+template<bool inStereo, bool outStereo, bool reverseStereo>
+int SimpleRateConverter<inStereo, outStereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
st_sample_t *ostart, *oend;
ostart = obuf;
- oend = obuf + osamp * 2;
+ oend = obuf + osamp * (outStereo ? 2 : 1);
while (obuf < oend) {
@@ -126,31 +126,42 @@ int SimpleRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_samp
inPtr = inBuf;
inLen = input.readBuffer(inBuf, ARRAYSIZE(inBuf));
if (inLen <= 0)
- return (obuf - ostart) / 2;
+ return (obuf - ostart) / (outStereo ? 2 : 1);
}
- inLen -= (stereo ? 2 : 1);
+ inLen -= (inStereo ? 2 : 1);
opos--;
if (opos >= 0) {
- inPtr += (stereo ? 2 : 1);
+ inPtr += (inStereo ? 2 : 1);
}
} while (opos >= 0);
- st_sample_t out0, out1;
- out0 = *inPtr++;
- out1 = (stereo ? *inPtr++ : out0);
+ st_sample_t in0, in1;
+ in0 = *inPtr++;
+ in1 = (inStereo ? *inPtr++ : in0);
// Increment output position
opos += opos_inc;
- // output left channel
- clampedAdd(obuf[reverseStereo ], (out0 * (int)vol_l) / Audio::Mixer::kMaxMixerVolume);
+ st_sample_t out0, out1;
+ out0 = (in0 * (int)vol_l) / Audio::Mixer::kMaxMixerVolume;
+ out1 = (in1 * (int)vol_r) / Audio::Mixer::kMaxMixerVolume;
- // output right channel
- clampedAdd(obuf[reverseStereo ^ 1], (out1 * (int)vol_r) / Audio::Mixer::kMaxMixerVolume);
+ if (outStereo) {
+ // output left channel
+ clampedAdd(obuf[reverseStereo ], out0);
- obuf += 2;
+ // output right channel
+ clampedAdd(obuf[reverseStereo ^ 1], out1);
+
+ obuf += 2;
+ } else {
+ // output mono channel
+ clampedAdd(obuf[0], (out0 + out1) / 2);
+
+ obuf += 1;
+ }
}
- return (obuf - ostart) / 2;
+ return (obuf - ostart) / (outStereo ? 2 : 1);
}
/**
@@ -164,7 +175,7 @@ int SimpleRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_samp
* Limited to sampling frequency <= 65535 Hz.
*/
-template<bool stereo, bool reverseStereo>
+template<bool inStereo, bool outStereo, bool reverseStereo>
class LinearRateConverter : public RateConverter {
protected:
st_sample_t inBuf[INTERMEDIATE_BUFFER_SIZE];
@@ -194,8 +205,8 @@ public:
/*
* Prepare processing.
*/
-template<bool stereo, bool reverseStereo>
-LinearRateConverter<stereo, reverseStereo>::LinearRateConverter(st_rate_t inrate, st_rate_t outrate) {
+template<bool inStereo, bool outStereo, bool reverseStereo>
+LinearRateConverter<inStereo, outStereo, reverseStereo>::LinearRateConverter(st_rate_t inrate, st_rate_t outrate) {
if (inrate >= 131072 || outrate >= 131072) {
error("rate effect can only handle rates < 131072");
}
@@ -219,12 +230,12 @@ LinearRateConverter<stereo, reverseStereo>::LinearRateConverter(st_rate_t inrate
* Processed signed long samples from ibuf to obuf.
* Return number of sample pairs processed.
*/
-template<bool stereo, bool reverseStereo>
-int LinearRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
+template<bool inStereo, bool outStereo, bool reverseStereo>
+int LinearRateConverter<inStereo, outStereo, reverseStereo>::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) {
st_sample_t *ostart, *oend;
ostart = obuf;
- oend = obuf + osamp * 2;
+ oend = obuf + osamp * (outStereo ? 2 : 1);
while (obuf < oend) {
@@ -235,12 +246,12 @@ int LinearRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_samp
inPtr = inBuf;
inLen = input.readBuffer(inBuf, ARRAYSIZE(inBuf));
if (inLen <= 0)
- return (obuf - ostart) / 2;
+ return (obuf - ostart) / (outStereo ? 2 : 1);
}
- inLen -= (stereo ? 2 : 1);
+ inLen -= (inStereo ? 2 : 1);
ilast0 = icur0;
icur0 = *inPtr++;
- if (stereo) {
+ if (inStereo) {
ilast1 = icur1;
icur1 = *inPtr++;
}
@@ -251,25 +262,36 @@ int LinearRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_samp
// still space in the output buffer.
while (opos < (frac_t)FRAC_ONE_LOW && obuf < oend) {
// interpolate
- st_sample_t out0, out1;
- out0 = (st_sample_t)(ilast0 + (((icur0 - ilast0) * opos + FRAC_HALF_LOW) >> FRAC_BITS_LOW));
- out1 = (stereo ?
+ st_sample_t in0, in1;
+ in0 = (st_sample_t)(ilast0 + (((icur0 - ilast0) * opos + FRAC_HALF_LOW) >> FRAC_BITS_LOW));
+ in1 = (inStereo ?
(st_sample_t)(ilast1 + (((icur1 - ilast1) * opos + FRAC_HALF_LOW) >> FRAC_BITS_LOW)) :
- out0);
+ in0);
- // output left channel
- clampedAdd(obuf[reverseStereo ], (out0 * (int)vol_l) / Audio::Mixer::kMaxMixerVolume);
+ st_sample_t out0, out1;
+ out0 = (in0 * (int)vol_l) / Audio::Mixer::kMaxMixerVolume;
+ out1 = (in1 * (int)vol_r) / Audio::Mixer::kMaxMixerVolume;
- // output right channel
- clampedAdd(obuf[reverseStereo ^ 1], (out1 * (int)vol_r) / Audio::Mixer::kMaxMixerVolume);
+ if (outStereo) {
+ // output left channel
+ clampedAdd(obuf[reverseStereo ], out0);
- obuf += 2;
+ // output right channel
+ clampedAdd(obuf[reverseStereo ^ 1], out1);
+
+ obuf += 2;
+ } else {
+ // output mono channel
+ clampedAdd(obuf[0], (out0 + out1) / 2);
+
+ obuf += 1;
+ }
// Increment output position
opos += opos_inc;
}
}
- return (obuf - ostart) / 2;
+ return (obuf - ostart) / (outStereo ? 2 : 1);
}
@@ -279,7 +301,7 @@ int LinearRateConverter<stereo, reverseStereo>::flow(AudioStream &input, st_samp
/**
* Simple audio rate converter for the case that the inrate equals the outrate.
*/
-template<bool stereo, bool reverseStereo>
+template<bool inStereo, bool outStereo, bool reverseStereo>
class CopyRateConverter : public RateConverter {
st_sample_t *_buffer;
st_size_t _bufferSize;
@@ -290,20 +312,20 @@ public:
}
int flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) override {
- assert(input.isStereo() == stereo);
+ assert(input.isStereo() == inStereo);
st_sample_t *ptr;
st_size_t len;
st_sample_t *ostart = obuf;
- if (stereo)
+ if (inStereo)
osamp *= 2;
// Reallocate temp buffer, if necessary
if (osamp > _bufferSize) {
free(_buffer);
- _buffer = (st_sample_t *)malloc(osamp * 2);
+ _buffer = (st_sample_t *)malloc(osamp * sizeof(st_sample_t));
_bufferSize = osamp;
}
@@ -315,20 +337,31 @@ public:
// Mix the data into the output buffer
ptr = _buffer;
- for (; len > 0; len -= (stereo ? 2 : 1)) {
+ for (; len > 0; len -= (inStereo ? 2 : 1)) {
+ st_sample_t in0, in1;
+ in0 = *ptr++;
+ in1 = (inStereo ? *ptr++ : in0);
+
st_sample_t out0, out1;
- out0 = *ptr++;
- out1 = (stereo ? *ptr++ : out0);
+ out0 = (in0 * (int)vol_l) / Audio::Mixer::kMaxMixerVolume;
+ out1 = (in1 * (int)vol_r) / Audio::Mixer::kMaxMixerVolume;
- // output left channel
- clampedAdd(obuf[reverseStereo ], (out0 * (int)vol_l) / Audio::Mixer::kMaxMixerVolume);
+ if (outStereo) {
+ // output left channel
+ clampedAdd(obuf[reverseStereo ], out0);
- // output right channel
- clampedAdd(obuf[reverseStereo ^ 1], (out1 * (int)vol_r) / Audio::Mixer::kMaxMixerVolume);
+ // output right channel
+ clampedAdd(obuf[reverseStereo ^ 1], out1);
- obuf += 2;
+ obuf += 2;
+ } else {
+ // output mono channel
+ clampedAdd(obuf[0], (out0 + out1) / 2);
+
+ obuf += 1;
+ }
}
- return (obuf - ostart) / 2;
+ return (obuf - ostart) / (outStereo ? 2 : 1);
}
int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) override {
@@ -339,30 +372,37 @@ public:
#pragma mark -
-template<bool stereo, bool reverseStereo>
+template<bool inStereo, bool outStereo, bool reverseStereo>
RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate) {
if (inrate != outrate) {
if ((inrate % outrate) == 0 && (inrate < 65536)) {
- return new SimpleRateConverter<stereo, reverseStereo>(inrate, outrate);
+ return new SimpleRateConverter<inStereo, outStereo, reverseStereo>(inrate, outrate);
} else {
- return new LinearRateConverter<stereo, reverseStereo>(inrate, outrate);
+ return new LinearRateConverter<inStereo, outStereo, reverseStereo>(inrate, outrate);
}
} else {
- return new CopyRateConverter<stereo, reverseStereo>();
+ return new CopyRateConverter<inStereo, outStereo, reverseStereo>();
}
}
/**
* Create and return a RateConverter object for the specified input and output rates.
*/
-RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo, bool reverseStereo) {
- if (stereo) {
- if (reverseStereo)
- return makeRateConverter<true, true>(inrate, outrate);
- else
- return makeRateConverter<true, false>(inrate, outrate);
- } else
- return makeRateConverter<false, false>(inrate, outrate);
+RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool instereo, bool outstereo, bool reverseStereo) {
+ if (instereo) {
+ if (outstereo) {
+ if (reverseStereo)
+ return makeRateConverter<true, true, true>(inrate, outrate);
+ else
+ return makeRateConverter<true, true, false>(inrate, outrate);
+ } else
+ return makeRateConverter<true, false, false>(inrate, outrate);
+ } else {
+ if (outstereo) {
+ return makeRateConverter<false, true, false>(inrate, outrate);
+ } else
+ return makeRateConverter<false, false, false>(inrate, outrate);
+ }
}
} // End of namespace Audio
diff --git a/audio/rate.h b/audio/rate.h
index 93d9041ab06..67e34b8de1c 100644
--- a/audio/rate.h
+++ b/audio/rate.h
@@ -84,7 +84,7 @@ public:
virtual int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) = 0;
};
-RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stereo, bool reverseStereo = false);
+RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool instereo, bool outstereo, bool reverseStereo);
/** @} */
} // End of namespace Audio
diff --git a/backends/mixer/null/null-mixer.cpp b/backends/mixer/null/null-mixer.cpp
index 45f41223424..e7f3f79455a 100644
--- a/backends/mixer/null/null-mixer.cpp
+++ b/backends/mixer/null/null-mixer.cpp
@@ -36,7 +36,7 @@ NullMixerManager::~NullMixerManager() {
}
void NullMixerManager::init() {
- _mixer = new Audio::MixerImpl(_outputRate, _samples);
+ _mixer = new Audio::MixerImpl(_outputRate, true, _samples);
assert(_mixer);
_mixer->setReady(true);
}
diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp
index fc9c095970e..f3b9d93e3df 100644
--- a/backends/mixer/sdl/sdl-mixer.cpp
+++ b/backends/mixer/sdl/sdl-mixer.cpp
@@ -73,7 +73,7 @@ void SdlMixerManager::init() {
warning("Could not open audio device: %s", SDL_GetError());
// The mixer is not marked as ready
- _mixer = new Audio::MixerImpl(desired.freq, desired.samples);
+ _mixer = new Audio::MixerImpl(desired.freq, true, desired.samples);
return;
}
@@ -88,7 +88,7 @@ void SdlMixerManager::init() {
warning("Could not open audio device: %s", SDL_GetError());
// The mixer is not marked as ready
- _mixer = new Audio::MixerImpl(desired.freq, desired.samples);
+ _mixer = new Audio::MixerImpl(desired.freq, true, desired.samples);
return;
}
@@ -106,7 +106,7 @@ void SdlMixerManager::init() {
if (_obtained.channels != 2)
error("SDL mixer output requires stereo output device");
- _mixer = new Audio::MixerImpl(_obtained.freq, desired.samples);
+ _mixer = new Audio::MixerImpl(_obtained.freq, true, desired.samples);
assert(_mixer);
_mixer->setReady(true);
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index e947441ebd7..e014520f824 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -470,7 +470,7 @@ void OSystem_Android::initBackend() {
// The division by four happens because the Mixer stores the size in frame units
// instead of bytes; this means that, since we have audio in stereo (2 channels)
// with a word size of 16 bit (2 bytes), we have to divide the effective size by 4.
- _mixer = new Audio::MixerImpl(_audio_sample_rate, _audio_buffer_size / 4);
+ _mixer = new Audio::MixerImpl(_audio_sample_rate, true, _audio_buffer_size / 4);
_mixer->setReady(true);
_timer_thread_exit = false;
diff --git a/backends/platform/ios7/ios7_osys_sound.cpp b/backends/platform/ios7/ios7_osys_sound.cpp
index 648bceac4b4..65008b26f30 100644
--- a/backends/platform/ios7/ios7_osys_sound.cpp
+++ b/backends/platform/ios7/ios7_osys_sound.cpp
@@ -45,7 +45,7 @@ void OSystem_iOS7::mixCallback(void *sys, byte *samples, int len) {
}
void OSystem_iOS7::setupMixer() {
- _mixer = new Audio::MixerImpl(AUDIO_SAMPLE_RATE, WAVE_BUFFER_SIZE);
+ _mixer = new Audio::MixerImpl(AUDIO_SAMPLE_RATE, true, WAVE_BUFFER_SIZE);
s_soundCallback = mixCallback;
s_soundParam = this;
diff --git a/backends/platform/iphone/osys_sound.cpp b/backends/platform/iphone/osys_sound.cpp
index ae6117b9a9f..bc71f3b760d 100644
--- a/backends/platform/iphone/osys_sound.cpp
+++ b/backends/platform/iphone/osys_sound.cpp
@@ -45,7 +45,7 @@ void OSystem_IPHONE::mixCallback(void *sys, byte *samples, int len) {
}
void OSystem_IPHONE::setupMixer() {
- _mixer = new Audio::MixerImpl(AUDIO_SAMPLE_RATE, WAVE_BUFFER_SIZE);
+ _mixer = new Audio::MixerImpl(AUDIO_SAMPLE_RATE, true, WAVE_BUFFER_SIZE);
s_soundCallback = mixCallback;
s_soundParam = this;
diff --git a/engines/sci/sound/audio32.cpp b/engines/sci/sound/audio32.cpp
index fd855331dab..69ffb9cfaae 100644
--- a/engines/sci/sound/audio32.cpp
+++ b/engines/sci/sound/audio32.cpp
@@ -694,7 +694,8 @@ bool Audio32::playRobotAudio(const RobotAudioStream::RobotAudioPacket &packet) {
channel.soundNode = NULL_REG;
channel.volume = kMaxVolume;
channel.pan = -1;
- channel.converter.reset(Audio::makeRateConverter(RobotAudioStream::kRobotSampleRate, getRate(), false));
+ // TODO: Avoid unnecessary channel conversion
+ channel.converter.reset(Audio::makeRateConverter(RobotAudioStream::kRobotSampleRate, getRate(), false, true, false));
// The RobotAudioStream buffer size is
// ((bytesPerSample * channels * sampleRate * 2000ms) / 1000ms) & ~3
// where bytesPerSample = 2, channels = 1, and sampleRate = 22050
@@ -860,7 +861,8 @@ uint16 Audio32::play(int16 channelIndex, const ResourceId resourceId, const bool
}
channel.stream.reset(new MutableLoopAudioStream(audioStream, loop));
- channel.converter.reset(Audio::makeRateConverter(channel.stream->getRate(), getRate(), channel.stream->isStereo(), false));
+ // TODO: Avoid unnecessary channel conversion
+ channel.converter.reset(Audio::makeRateConverter(channel.stream->getRate(), getRate(), channel.stream->isStereo(), true, false));
// SSCI sets up a decompression buffer here for the audio stream, plus
// writes information about the sample to the channel to convert to the
diff --git a/engines/sword1/music.cpp b/engines/sword1/music.cpp
index 33a70991268..f8e56256fc8 100644
--- a/engines/sword1/music.cpp
+++ b/engines/sword1/music.cpp
@@ -303,12 +303,14 @@ void Music::startMusic(int32 tuneId, int32 loopFlag) {
if (SwordEngine::isPsx()) {
if (_handles[newStream].playPSX(tuneId, loopFlag != 0)) {
_mutex.lock();
- _converter[newStream] = Audio::makeRateConverter(_handles[newStream].getRate(), _mixer->getOutputRate(), _handles[newStream].isStereo(), false);
+ // TODO: Avoid unnecessary channel conversion
+ _converter[newStream] = Audio::makeRateConverter(_handles[newStream].getRate(), _mixer->getOutputRate(), _handles[newStream].isStereo(), true, false);
_mutex.unlock();
}
} else if (_handles[newStream].play(_tuneList[tuneId], loopFlag != 0)) {
_mutex.lock();
- _converter[newStream] = Audio::makeRateConverter(_handles[newStream].getRate(), _mixer->getOutputRate(), _handles[newStream].isStereo(), false);
+ // TODO: Avoid unnecessary channel conversion
+ _converter[newStream] = Audio::makeRateConverter(_handles[newStream].getRate(), _mixer->getOutputRate(), _handles[newStream].isStereo(), true, false);
_mutex.unlock();
} else {
if (tuneId != 81) // file 81 was apparently removed from BS.
Commit: 749fd8b490b6ea5b685ce7438e4ead3a69f38f30
https://github.com/scummvm/scummvm/commit/749fd8b490b6ea5b685ce7438e4ead3a69f38f30
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2022-11-18T17:17:00+01:00
Commit Message:
SDL: Allow selecting the audio channel count from the command line
Changed paths:
backends/mixer/sdl/sdl-mixer.cpp
base/commandLine.cpp
dists/scummvm.6
doc/docportal/advanced_topics/command_line.rst
doc/docportal/advanced_topics/configuration_file.rst
diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp
index f3b9d93e3df..ae3ff5dfeac 100644
--- a/backends/mixer/sdl/sdl-mixer.cpp
+++ b/backends/mixer/sdl/sdl-mixer.cpp
@@ -73,7 +73,7 @@ void SdlMixerManager::init() {
warning("Could not open audio device: %s", SDL_GetError());
// The mixer is not marked as ready
- _mixer = new Audio::MixerImpl(desired.freq, true, desired.samples);
+ _mixer = new Audio::MixerImpl(desired.freq, desired.channels >= 2, desired.samples);
return;
}
@@ -88,7 +88,7 @@ void SdlMixerManager::init() {
warning("Could not open audio device: %s", SDL_GetError());
// The mixer is not marked as ready
- _mixer = new Audio::MixerImpl(desired.freq, true, desired.samples);
+ _mixer = new Audio::MixerImpl(desired.freq, desired.channels >= 2, desired.samples);
return;
}
@@ -103,10 +103,11 @@ void SdlMixerManager::init() {
if (_obtained.samples != desired.samples)
warning("SDL mixer output buffer size: %d differs from desired: %d", _obtained.samples, desired.samples);
- if (_obtained.channels != 2)
- error("SDL mixer output requires stereo output device");
+ debug(1, "Output channels: %d", _obtained.channels);
+ if (_obtained.channels != 1 && _obtained.channels != 2)
+ error("SDL mixer output requires mono or stereo output device");
- _mixer = new Audio::MixerImpl(_obtained.freq, true, desired.samples);
+ _mixer = new Audio::MixerImpl(_obtained.freq, _obtained.channels >= 2, desired.samples);
assert(_mixer);
_mixer->setReady(true);
@@ -143,6 +144,12 @@ SDL_AudioSpec SdlMixerManager::getAudioSpec(uint32 outputRate) {
if (freq <= 0)
freq = outputRate;
+ uint32 channels = 2;
+ if (ConfMan.hasKey("output_channels"))
+ channels = ConfMan.getInt("output_channels");
+ if (channels > 2 || channels <= 0)
+ channels = 2;
+
// One SDL "sample" is a complete audio frame (i.e. all channels = 1 sample)
uint32 samples = 0;
@@ -166,7 +173,7 @@ SDL_AudioSpec SdlMixerManager::getAudioSpec(uint32 outputRate) {
memset(&desired, 0, sizeof(desired));
desired.freq = freq;
desired.format = AUDIO_S16SYS;
- desired.channels = 2;
+ desired.channels = channels;
desired.samples = roundDownPowerOfTwo(samples);
desired.callback = sdlCallback;
desired.userdata = this;
diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 831eb10d5fd..099c01c41e9 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -160,6 +160,7 @@ static const char HELP_STRING4[] =
" --dump-midi Dumps MIDI events to 'dump.mid', until quitting from game\n"
" (if file already exists, it will be overwritten)\n"
" --enable-gs Enable Roland GS mode for MIDI playback\n"
+ " --output-channels=CHANNELS Select output channel count (e.g. 2 for stereo)\n"
" --output-rate=RATE Select output sample rate in Hz (e.g. 22050)\n"
" --opl-driver=DRIVER Select AdLib (OPL) emulator (db, mame"
#ifndef DISABLE_NUKED_OPL
@@ -663,6 +664,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
DO_LONG_COMMAND("list-audio-devices")
END_COMMAND
+ DO_LONG_OPTION_INT("output-channels")
+ END_OPTION
+
DO_LONG_OPTION_INT("output-rate")
END_OPTION
diff --git a/dists/scummvm.6 b/dists/scummvm.6
index ec6b83cb2bf..164ab1a0899 100644
--- a/dists/scummvm.6
+++ b/dists/scummvm.6
@@ -326,6 +326,8 @@ Select AdLib (OPL) emulator
.Ar nuked ,
.Ar opl2lpt
.Pc .
+.It Fl -output-channels= Ns Ar RATE
+Set output channel count (e.g. 2 for stereo).
.It Fl -output-rate= Ns Ar RATE
Set output sample rate in Hz (e.g. 22050).
.It Fl -platform= Ns Ar PLATFORM
diff --git a/doc/docportal/advanced_topics/command_line.rst b/doc/docportal/advanced_topics/command_line.rst
index 4d65a075648..bb89472655a 100755
--- a/doc/docportal/advanced_topics/command_line.rst
+++ b/doc/docportal/advanced_topics/command_line.rst
@@ -200,6 +200,7 @@ Short options are listed where they are available.
``--no-filtering``,,"Forces unfiltered graphics mode"
``--no-fullscreen``,``-F``,"Forces windowed mode"
``--opl-driver=DRIVER``,,":ref:`Selects AdLib (OPL) emulator <opl>`"
+ ``--output-channels=CHANNELS``,,"Select output channel count"
``--output-rate=RATE``,,"Selects output sample rate in Hz"
``--path=PATH``,``-p``,"Sets path to where the game is installed"
``--platform=STRING``,,":ref:`Specifes platform of game <platform>`. Allowed values: 2gs, 3do, acorn, amiga, atari, c64, fmtowns, nes, mac, pc pc98, pce, segacd, wii, windows."
diff --git a/doc/docportal/advanced_topics/configuration_file.rst b/doc/docportal/advanced_topics/configuration_file.rst
index d6ae94569b3..55875e97b1d 100755
--- a/doc/docportal/advanced_topics/configuration_file.rst
+++ b/doc/docportal/advanced_topics/configuration_file.rst
@@ -339,6 +339,11 @@ There are many recognized configuration keys. In the table below, each key is ei
- op3lpt
- rwopl3 "
":ref:`originalsaveload <osl>`",boolean,false,
+ ":ref:`output_channels <outputchannels>`",integer,,"
+ Supported values are:
+
+ - 1
+ - 2"
":ref:`output_rate <outputrate>`",integer,,"
Sensible values are:
More information about the Scummvm-git-logs
mailing list