[Scummvm-git-logs] scummvm master -> 0772833cc50963347f4b5310891073f2fee25968
athrxx
noreply at scummvm.org
Fri Feb 2 01:39:15 UTC 2024
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:
0772833cc5 SCUMM: (INDY3/MAC) - sound player fixes
Commit: 0772833cc50963347f4b5310891073f2fee25968
https://github.com/scummvm/scummvm/commit/0772833cc50963347f4b5310891073f2fee25968
Author: athrxx (athrxx at scummvm.org)
Date: 2024-02-02T02:37:53+01:00
Commit Message:
SCUMM: (INDY3/MAC) - sound player fixes
- fix Berlin track
- fix playback for certain output rate
- minor improvements
Changed paths:
engines/scumm/players/player_mac_indy3.cpp
diff --git a/engines/scumm/players/player_mac_indy3.cpp b/engines/scumm/players/player_mac_indy3.cpp
index afed6ec072f..bb8cc2215f4 100644
--- a/engines/scumm/players/player_mac_indy3.cpp
+++ b/engines/scumm/players/player_mac_indy3.cpp
@@ -31,6 +31,7 @@
namespace Scumm {
#define ASC_DEVICE_RATE 0x56EE8BA3
+#define VBL_UPDATE_RATE 0x003C25BD
#define PCM_BUFFER_SIZE 1024
#define RATECNV_BIT_PRECSN 24
@@ -141,11 +142,14 @@ private:
class I3MMusicDriver : public I3MSoundDriver {
public:
- I3MMusicDriver(Common::Mutex &mutex, bool isStereo) : I3MSoundDriver(mutex, ASC_DEVICE_RATE, isStereo) {}
+ I3MMusicDriver(uint16 numChannels, Common::Mutex &mutex, bool isStereo) : I3MSoundDriver(mutex, ASC_DEVICE_RATE, isStereo), _numChan(numChannels) {}
virtual void start() = 0;
virtual void stop() = 0;
virtual void setDuration(uint16 duration) = 0;
virtual void setRate(uint8 chan, uint16 rate) = 0;
+ uint16 numChannels() const { return _numChan; }
+protected:
+ const uint16 _numChan;
};
class I3MFourToneSynthDriver final : public I3MMusicDriver {
@@ -173,13 +177,12 @@ private:
};
Channel *_chan;
- const uint16 _numChan;
};
-class I3MLQSynthDriver final : public I3MMusicDriver {
+class I3MSquareWaveSynthDriver final : public I3MMusicDriver {
public:
- I3MLQSynthDriver(Common::Mutex &mutex, bool isStereo) : I3MMusicDriver(mutex, isStereo) {}
- ~I3MLQSynthDriver() override {}
+ I3MSquareWaveSynthDriver(Common::Mutex &mutex, bool isStereo) : I3MMusicDriver(1, mutex, isStereo) {}
+ ~I3MSquareWaveSynthDriver() override {}
void feed(int8 *dst, uint32 len, Audio::Mixer::SoundType type, bool expectStereo) override {}
void start() override {}
@@ -281,9 +284,9 @@ private:
uint16 _envPhase;
uint16 _envRate;
uint16 _tempo;
- uint16 _envCutoff;
+ uint16 _envSust;
int16 _transpose;
- uint16 _envLen;
+ uint16 _envAtt;
uint16 _envShape;
uint16 _envStep;
uint16 _envStepLen;
@@ -342,8 +345,8 @@ public:
AudioStream_I3M::AudioStream_I3M(I3MPlayer *drv, uint32 scummVMOutputrate, bool stereo, bool interpolate) : Audio::AudioStream(), _drv(drv), _vblSmpQty(0), _vblSmpQtyRem(0), _frameSize(stereo ? 2 : 1),
_vblCountDown(0), _vblCountDownRem(0), _outputRate(scummVMOutputrate), _vblCbProc(nullptr), _isStereo(stereo), _interp(interpolate) {
assert(_drv);
- _vblSmpQty = _outputRate / 60;
- _vblSmpQtyRem = _outputRate % 60;
+ _vblSmpQty = (_outputRate << 16) / VBL_UPDATE_RATE;
+ _vblSmpQtyRem = (_outputRate << 16) % VBL_UPDATE_RATE;
_vblCountDown = _vblSmpQty;
_vblCountDownRem = 0;
}
@@ -408,9 +411,12 @@ int AudioStream_I3M::readBuffer(int16 *buffer, const int numSamples) {
for (int i = _isStereo ? numSamples >> 1 : numSamples; i; --i) {
if (!--_vblCountDown) {
+ _vblCountDown = _vblSmpQty;
_vblCountDownRem += _vblSmpQtyRem;
- _vblCountDown = _vblSmpQty + _vblCountDownRem / _vblSmpQty;
- _vblCountDownRem %= _vblSmpQty;
+ while (_vblCountDownRem >= (_vblSmpQty << 16)) {
+ _vblCountDownRem -= (_vblSmpQty << 16);
+ ++_vblCountDown;
+ }
runVblTask();
}
@@ -441,17 +447,18 @@ int AudioStream_I3M::readBuffer(int16 *buffer, const int numSamples) {
if (incr) {
_buffers[ii].pos += incr;
- if (_buffers[ii].pos == _buffers[ii].end) {
- _buffers[ii].pos -= _buffers[ii].size;
- generateData(_buffers[ii].pos, _buffers[ii].size, stype[ii], _isStereo);
- }
-
const int8 *lpos = _buffers[ii].pos;
if (lpos >= _buffers[ii].start + _frameSize)
lpos -= _frameSize;
_buffers[ii].lastL = lpos[0];
if (_isStereo)
_buffers[ii].lastR = lpos[1];
+
+ if (_buffers[ii].pos >= _buffers[ii].end) {
+ uint32 refreshSize = MIN<uint32>(_vblCountDown * _frameSize, _buffers[ii].size);
+ _buffers[ii].pos -= refreshSize;
+ generateData(_buffers[ii].pos, refreshSize, stype[ii], _isStereo);
+ }
}
}
@@ -740,7 +747,7 @@ uint32 I3MLowLevelPCMDriver::calcRate(uint32 outRate, uint32 factor, uint32 data
}
I3MFourToneSynthDriver::I3MFourToneSynthDriver(Common::Mutex &mutex, bool isStereo) :
- I3MMusicDriver(mutex, isStereo), _duration(0), _pos(0), _chan(nullptr), _numChan(4) {
+ I3MMusicDriver(4, mutex, isStereo), _duration(0), _pos(0), _chan(nullptr) {
_chan = new Channel[_numChan];
}
@@ -767,7 +774,8 @@ void I3MFourToneSynthDriver::feed(int8 *dst, uint32 len, Audio::Mixer::SoundType
int16 smp = 0;
for (int i = 0; i < _numChan; ++i) {
_chan[i].phase += _chan[i].rate;
- smp += _chan[i].waveform[(_chan[i].phase >> 16) & 0xff];
+ if (_chan[i].waveform != nullptr)
+ smp += _chan[i].waveform[(_chan[i].phase >> 16) & 0xff];
}
smp = CLIP<int8>(smp >> 2, -128, 127);
@@ -813,6 +821,7 @@ void I3MFourToneSynthDriver::setWaveForm(uint8 chan, const uint8 *data, uint32 d
Common::StackLock lock(_mutex);
delete[] _chan[chan].waveform;
+ _chan[chan].waveform = nullptr;
if (data == nullptr || dataSize == 0)
return;
dataSize = MIN<uint32>(256, dataSize);
@@ -827,6 +836,9 @@ void I3MFourToneSynthDriver::setRate(uint8 chan, uint16 rate) {
assert(chan < _numChan);
Common::StackLock lock(_mutex);
+ if (rate && rate < 1600)
+ rate = rate;
+
_chan[chan].rate = rate ? (0x5060000 / (rate >> ((rate < 1600) ? 8 : 6))) : 0;
}
@@ -896,7 +908,7 @@ bool I3MPlayer::startDevices(uint32 outputRate, uint32 pcmDeviceRate, uint32 fee
if (!mdrv || !_sdrv)
return false;
- for (int i = 0; i < 4; ++i)
+ for (int i = 0; i < mdrv->numChannels(); ++i)
mdrv->setWaveForm(i, _fourToneSynthWaveForm, sizeof(_fourToneSynthWaveForm));
_qualHi = true;
_mdrv = mdrv;
@@ -984,12 +996,12 @@ void I3MPlayer::setQuality(int qual) {
if (isHiQuality()) {
I3MFourToneSynthDriver *mdrv = new I3MFourToneSynthDriver(_mixer->mutex(), false);
assert(mdrv);
- for (int i = 0; i < 4; ++i)
+ for (int i = 0; i < mdrv->numChannels(); ++i)
mdrv->setWaveForm(i, _fourToneSynthWaveForm, sizeof(_fourToneSynthWaveForm));
_mdrv = mdrv;
_qualHi = true;
} else {
- _mdrv = new I3MLQSynthDriver(_mixer->mutex(), false);
+ _mdrv = new I3MSquareWaveSynthDriver(_mixer->mutex(), false);
_qualHi = false;
assert(_mdrv);
}
@@ -1184,7 +1196,7 @@ void I3MPlayer::updateSong() {
}
}
- for (int i = 0; i < _numMusicChannels; ++i)
+ for (int i = 0; i < _mdrv->numChannels(); ++i)
_mdrv->setRate(i, _lastSong ? _musicChannels[i]->checkPeriod() : 0);
if (_songPlaying)
_mdrv->setDuration(10);
@@ -1208,8 +1220,8 @@ I3MPlayer::MusicChannel::MusicChannel(I3MPlayer *pl) : _player(pl), _vars(nullpt
const uint16 *mVars[] = {
/* 0 */ &_frameLen, &_curPos, &_freqCur, &_freqIncr, &_freqEff,
- /* 5 */ &_envPhase, &_envRate, &_tempo, &_envCutoff, (uint16*)&_transpose,
- /* 10 */ &_envLen, &_envShape, &_envStep, &_envStepLen, &_modType,
+ /* 5 */ &_envPhase, &_envRate, &_tempo, &_envSust, (uint16*)&_transpose,
+ /* 10 */ &_envAtt, &_envShape, &_envStep, &_envStepLen, &_modType,
/* 15 */ &_modState, &_modStep, &_modSensitivity, &_modRange, &_localVars[0],
/* 20 */ &_localVars[1], &_localVars[2], &_localVars[3], &_localVars[4]
};
@@ -1257,7 +1269,7 @@ void I3MPlayer::MusicChannel::nextTick() {
_freqCur += _freqIncr;
uint16 v = _modState + _modStep;
- int frqAdjust = 0;
+ uint16 frqAdjust = 0;
if (v != 0) {
if (v >= _modRange)
@@ -1270,8 +1282,8 @@ void I3MPlayer::MusicChannel::nextTick() {
_freqEff = _freqCur + frqAdjust;
- if (_envLen && !--_envLen) {
- _envStep = 4;
+ if (_envAtt && !--_envAtt) {
+ _envStep = 16;
_envStepLen = 1;
}
@@ -1281,15 +1293,15 @@ void I3MPlayer::MusicChannel::nextTick() {
if (!_envStepLen || --_envStepLen)
return;
- int ix = _envShape + _envStep++;
+ int ix = _envShape + (_envStep >> 2);
assert(ix < ARRAYSIZE(_envShapes));
const uint32 *in = &_envShapes[ix];
- for (; (*in & 0xffff) == 0xffff; ++in) {
+ for (_envStep += 4; (*in & 0xffff) == 0xffff; ++in) {
_envPhase = *in >> 16;
if (_envPhase == 0)
_envRate = 0;
- ++_envStep;
+ _envStep += 4;
}
_envStepLen = *in & 0xffff;
@@ -1359,12 +1371,12 @@ void I3MPlayer::MusicChannel::noteOn(uint16 duration, uint8 note) {
_envStep = 0;
_envStepLen = 1;
_frameLen = duration;
- _envLen = _frameLen - _envCutoff;
+ _envAtt = _frameLen - _envSust;
int n = note + _transpose;
while (n < 0)
n += 12;
- _freqEff = _freqCur = noteFreqTable[_hq ? 0 : 1][n % 12] >> ( n / 12);
+ _freqEff = _freqCur = noteFreqTable[_hq ? 0 : 1][n % 12] >> (n / 12);
}
uint16 I3MPlayer::MusicChannel::checkPeriod() const {
@@ -1627,6 +1639,7 @@ void Player_Mac_Indy3::restoreAfterLoad() {
}
#undef ASC_DEVICE_RATE
+#undef VBL_RATE
#undef PCM_BUFFER_SIZE
#undef RATECNV_BIT_PRECSN
More information about the Scummvm-git-logs
mailing list