[Scummvm-git-logs] scummvm master -> d165b1dc93582f43f08bbea54a2f3969d626b08e
athrxx
noreply at scummvm.org
Sun Dec 15 15:04:15 UTC 2024
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:
89f6c1c83b SCUMM: (IMS/Mac) - fix orginal instrument glitch
d165b1dc93 SCUMM: (IMS/Mac) - fix DOTT music volume
Commit: 89f6c1c83b4aa9929a82a50f0593857287ea73f5
https://github.com/scummvm/scummvm/commit/89f6c1c83b4aa9929a82a50f0593857287ea73f5
Author: athrxx (athrxx at scummvm.org)
Date: 2024-12-15T15:22:31+01:00
Commit Message:
SCUMM: (IMS/Mac) - fix orginal instrument glitch
(SAM final credits track)
Changed paths:
engines/scumm/imuse/drivers/macintosh.cpp
diff --git a/engines/scumm/imuse/drivers/macintosh.cpp b/engines/scumm/imuse/drivers/macintosh.cpp
index a866152dc7b..b2c5c6e3270 100644
--- a/engines/scumm/imuse/drivers/macintosh.cpp
+++ b/engines/scumm/imuse/drivers/macintosh.cpp
@@ -41,7 +41,7 @@ enum : byte {
struct ChanControlNode;
struct DeviceChannel {
DeviceChannel(const uint32 *pitchtable) : pitchTable(pitchtable), frequency(0), phase(0), end(nullptr), pos(nullptr), smpBuffStart(nullptr),
- smpBuffEnd(nullptr), loopStart(nullptr), loopEnd(nullptr), pitch(0), mute(true), release(false), instr(nullptr),
+ smpBuffEnd(nullptr), loopStart(nullptr), loopEnd(nullptr), pitch(0), mute(true), release(false), instr(nullptr), rhtm(false),
prog(0), baseFreq(0), note(0), volumeL(0), volumeR(0), rate(0), totalLevelL(0), totalLevelR(0), node(nullptr), prev(nullptr), next(nullptr) {}
~DeviceChannel() {}
@@ -64,6 +64,7 @@ struct DeviceChannel {
uint32 rate;
uint16 prog;
byte note;
+ bool rhtm;
bool mute;
bool release;
const ChanControlNode *node;
@@ -318,7 +319,7 @@ void DeviceChannel::recalcFrequency() {
int cpos = (pitch >> 7) + 60 - baseFreq;
if (cpos < 0)
frequency = (uint32)-1;
- else if (pitch & 0x7F)
+ else if ((pitch & 0x7F) && cpos < 0x7F)
frequency = pitchTable[cpos] + (((pitchTable[cpos + 1] - pitchTable[cpos]) * (pitch & 0x7F)) >> 7);
else
frequency = pitchTable[cpos];
@@ -456,6 +457,11 @@ void IMSMacSoundSystem::noteOn(const ChanControlNode *node) {
debug(6, "NOTE ON: ims part %d, chan node %d, note %d, instr id %d (%s)", node->in ? node->in->getNumber() : node->number, node->number, node->note, node->prog, c->instr.get()->name());
+ // SAMNMAX: This is a workaround to fix a hanging note in the final credits track. The issue is present in the original game,too.
+ bool fixHangingNote = (c->instr.get()->id() == 321 && c->note == 40);
+ if (fixHangingNote)
+ debug(7, "%s:() Triggered hanging note workaround.", __FUNCTION__);
+
recalcVolume(c);
const MacLowLevelPCMDriver::PCMSound *s = c->instr.get()->data();
@@ -463,7 +469,7 @@ void IMSMacSoundSystem::noteOn(const ChanControlNode *node) {
c->rate = s->rate;
c->smpBuffStart = s->data.get();
c->smpBuffEnd = c->smpBuffStart + s->len;
- if ((_version == 0 && (int32)s->loopst >= (int32)s->loopend - 12) || (_version > 0 && (!s->loopst || !s->loopend || node->rhythmPart || (int32)s->loopst > (int32)s->len - 10))) {
+ if ((_version == 0 && (int32)s->loopst >= (int32)s->loopend - 12) || (_version > 0 && (fixHangingNote || !s->loopst || !s->loopend || node->rhythmPart || (int32)s->loopst > (int32)s->len - 10))) {
c->loopStart = nullptr;
c->loopEnd = c->smpBuffEnd;
} else {
@@ -603,8 +609,8 @@ void IMSMacSoundSystem::dblBuffCallback(MacLowLevelPCMDriver::DoubleBuffer *dblB
*t++ += a1[*c.pos];
if (_stereo)
*t++ += a2[*c.pos];
+ }
}
- }
const int16 *s = _mixBuffer16Bit;
sil <<= 7;
@@ -861,8 +867,8 @@ bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFil
if (ins->sndRes[0] != nullptr)
memset(ins->noteSmplsMapping, 0, 128);
- int8 numRanges = CLIP<int8>(b[13], 0, 7);
- assert(sz >= 16 + (uint)numRanges * 8);
+ byte numRanges = CLIP<int8>(b[13], 0, 7);
+ assert(sz >= 16 + numRanges * 8);
for (int ii = 0; ii < numRanges; ++ii) {
ins->sndRes.push_back(getSndResource(READ_BE_INT16(b + 16 + ii * 8)));
@@ -884,7 +890,7 @@ bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFil
Common::SharedPtr<MacSndResource> NewMacSoundSystem::getNoteRangeSndResource(uint16 id, byte note) {
assert(note < 128);
Common::SharedPtr<MacSndResource> res;
- for (Common::Array<Common::SharedPtr<Instrument> >::iterator it = _instruments.begin(); res == nullptr && it != _instruments.end(); ++it) {
+ for (Common::Array<Common::SharedPtr<Instrument> >::const_iterator it = _instruments.begin(); res == nullptr && it != _instruments.end(); ++it) {
uint16 cid = (*it)->id;
if (cid == id)
res = (*it)->sndRes[(*it)->noteSmplsMapping[note]];
@@ -894,9 +900,10 @@ Common::SharedPtr<MacSndResource> NewMacSoundSystem::getNoteRangeSndResource(uin
void NewMacSoundSystem::setInstrument(DeviceChannel *chan) {
assert(chan && chan->node);
- if (chan->instr == nullptr || (!chan->node->rhythmPart && chan->prog != chan->node->prog) || chan->note != chan->node->note) {
+ if (chan->instr == nullptr || chan->node->rhythmPart != chan->rhtm || (!chan->node->rhythmPart && chan->prog != chan->node->prog) || chan->note != chan->node->note) {
chan->note = chan->node->note;
- chan->prog = chan->node->prog;
+ chan->prog = chan->node->rhythmPart ? 0 : chan->node->prog;
+ chan->rhtm = chan->node->rhythmPart;
chan->instr = chan->node->rhythmPart ? getSndResource(6000 + chan->note) : getNoteRangeSndResource(chan->prog, chan->note);
}
}
@@ -1074,6 +1081,7 @@ void IMuseChannel_Macintosh::noteOn(byte note, byte velocity) {
node->in = this;
node->prio = _prio;
}
+ node->prog = 0;
node->volume = _volume * 6 / 7;
node->rhythmPart = true;
}
Commit: d165b1dc93582f43f08bbea54a2f3969d626b08e
https://github.com/scummvm/scummvm/commit/d165b1dc93582f43f08bbea54a2f3969d626b08e
Author: athrxx (athrxx at scummvm.org)
Date: 2024-12-15T15:22:35+01:00
Commit Message:
SCUMM: (IMS/Mac) - fix DOTT music volume
(and other minor adjustments)
The DOTT Mac imuse driver always sets master
volume to max. The SAMNMAX driver does not
have a hack like this.
Changed paths:
engines/scumm/imuse/drivers/macintosh.cpp
engines/scumm/imuse/imuse.cpp
engines/scumm/players/mac_sound_lowlevel.h
engines/scumm/players/player_mac_new.cpp
engines/scumm/vars.cpp
diff --git a/engines/scumm/imuse/drivers/macintosh.cpp b/engines/scumm/imuse/drivers/macintosh.cpp
index b2c5c6e3270..aa5ab88f31f 100644
--- a/engines/scumm/imuse/drivers/macintosh.cpp
+++ b/engines/scumm/imuse/drivers/macintosh.cpp
@@ -388,13 +388,27 @@ bool IMSMacSoundSystem::init(const char *const *instrFileNames, int numInstrFile
int16 *d1 = &_mixTable[m];
int16 *d2 = &_mixTable[m - 1];
- byte base = _internal16Bit? 0 : 128;
- uint16 ml = _internal16Bit ? _numChannels : 1;
- uint16 sv = _stereo ? 2 : 1;
- for (uint32 i = 0; i < m; ++i) {
- int val = (((((i * (m - _numChannels)) << 7) >> 1) / (((_numChannels >> 1) - 1) * i + m - _numChannels) + base) * ml * sv) >> 7;
- *d1++ = base + val;
- *d2-- = base -val - 1;
+ if (_version == 0) {
+ byte sh = _internal16Bit ? 5 : 0;
+ byte div = _internal16Bit ? 1 : _numChannels;
+ byte base = _internal16Bit? 0 : 128;
+ for (uint32 i = 0; i < m; ++i) {
+ uint16 val = (i << sh) / div;
+ *d1++ = base + val;
+ *d2-- = base - val - 1;
+ }
+ } else if (_internal16Bit) {
+ for (uint32 i = 0; i < m; ++i) {
+ uint16 val = (((i * _numChannels * 127) << 6) / (((_numChannels >> 1) - 1) * i + _numChannels * 127)) << 1;
+ *d1++ = val;
+ *d2-- = -val - 1;
+ }
+ } else {
+ for (uint32 i = 0; i < m; ++i) {
+ uint16 val = ((((i * _numChannels * 127) << 7) >> 1) / (((_numChannels >> 1) - 1) * i + _numChannels * 127) + 128) >> 7;
+ *d1++ = (byte)(128 + val);
+ *d2-- = (byte)(128 - val - 1);
+ }
}
_macstr = new MacPlayerAudioStream(this, _mixer->getOutputRate(), _stereo, false, internal16Bit);
@@ -412,9 +426,14 @@ bool IMSMacSoundSystem::init(const char *const *instrFileNames, int numInstrFile
// Only MI2 and FOA have MIDI sound effects. Also, the later versions use a different update method.
if (_version == 0) {
_macstr->addVolumeGroup(Audio::Mixer::kSFXSoundType);
- _macstr->setVblCallback(&_vblTskProc);
+ _macstr->setVblCallback(&_vblTskProc);
}
+ // The stream will by default expect 8-bit data and scale that to 16-bit. Or at least only low amplitude 16-bit data that only needs minor adjustment.
+ // For full range 16-bit input, we need some post-process downscaling, otherwise the application of the ScummVM global volume setting will cause overflows.
+ if (internal16Bit)
+ _macstr->scaleVolume(0, 5);
+
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, _macstr, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
return true;
@@ -609,8 +628,8 @@ void IMSMacSoundSystem::dblBuffCallback(MacLowLevelPCMDriver::DoubleBuffer *dblB
*t++ += a1[*c.pos];
if (_stereo)
*t++ += a2[*c.pos];
- }
}
+ }
const int16 *s = _mixBuffer16Bit;
sil <<= 7;
@@ -820,7 +839,7 @@ NewMacSoundSystem::~NewMacSoundSystem() {
bool NewMacSoundSystem::start() {
_musicChan = _sdrv->createChannel(Audio::Mixer::kMusicSoundType, MacLowLevelPCMDriver::kSampledSynth, _stereo ? 0xCC : 0x8C, nullptr);
- return _musicChan ? _sdrv->playDoubleBuffer(_musicChan, _stereo ? 2 : 1, _internal16Bit ? 16 : 8, 0x56220000, &_dbCbProc, _internal16Bit ? _numChannels : 1) : false;
+ return _musicChan ? _sdrv->playDoubleBuffer(_musicChan, _stereo ? 2 : 1, _internal16Bit ? 16 : 8, 0x56220000, &_dbCbProc, _internal16Bit ? _numChannels : 1) : false;
}
bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFileNames) {
@@ -868,7 +887,7 @@ bool NewMacSoundSystem::loadInstruments(const char *const *fileNames, int numFil
memset(ins->noteSmplsMapping, 0, 128);
byte numRanges = CLIP<int8>(b[13], 0, 7);
- assert(sz >= 16 + numRanges * 8);
+ assert(sz >= 16u + numRanges * 8u);
for (int ii = 0; ii < numRanges; ++ii) {
ins->sndRes.push_back(getSndResource(READ_BE_INT16(b + 16 + ii * 8)));
@@ -1109,13 +1128,11 @@ void IMuseChannel_Macintosh::controlChange(byte control, byte value) {
dataEntry(value);
break;
case 7:
- case 10:
- if (control == 7)
- _volume = value;
- else
- _panPos = value;
+ case 10: {
+ byte ¶m = (control == 7) ? _volume : _panPos;
+ param = value;
updateVolume();
- break;
+ } break;
case 17:
if (_version == 2)
_polyphony = value;
diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp
index 7f2d936d88c..7276ca4fa4d 100644
--- a/engines/scumm/imuse/imuse.cpp
+++ b/engines/scumm/imuse/imuse.cpp
@@ -48,7 +48,7 @@ IMuseInternal::IMuseInternal(ScummEngine *vm, MidiDriverFlags sndType, bool nati
_vm(vm),
_native_mt32(nativeMT32),
_newSystem(vm && vm->_game.id == GID_SAMNMAX),
- _dynamicChanAllocation(vm && (vm->_game.id != GID_MONKEY2 && vm->_game.id != GID_INDY4)), // For the non-iMuse games that (unfortunately) run on this player we need to pretend we're on the more modern version
+ _dynamicChanAllocation(vm && vm->_game.id != GID_MONKEY2 && vm->_game.id != GID_INDY4), // For the non-iMuse games that (unfortunately) run on this player we need to pretend we're on the more modern version
_midi_adlib(nullptr),
_midi_native(nullptr),
_sysex(nullptr),
@@ -1228,7 +1228,8 @@ int IMuseInternal::query_queue(int param) {
}
int IMuseInternal::setImuseMasterVolume(uint vol) {
- if (vol > 255)
+ // The DOTT Macintosh driver ignores the vol argument and always sets the volume to max.
+ if (vol > 255 || (_soundType == MDT_MACINTOSH && _game_id == GID_TENTACLE))
vol = 255;
if (_master_volume == vol)
return 0;
diff --git a/engines/scumm/players/mac_sound_lowlevel.h b/engines/scumm/players/mac_sound_lowlevel.h
index 2ab09f36ed9..d20267695d5 100644
--- a/engines/scumm/players/mac_sound_lowlevel.h
+++ b/engines/scumm/players/mac_sound_lowlevel.h
@@ -188,7 +188,7 @@ public:
void initBuffers(uint32 feedBufferSize);
void initDrivers();
void addVolumeGroup(Audio::Mixer::SoundType type);
- void scaleVolume(uint scale) { _scale = scale; }
+ void scaleVolume(uint upscale, uint downscale) { _upscale = upscale; _downscale = downscale; }
typedef Common::Functor0Mem<void, VblTaskClientDriver> CallbackProc;
void setVblCallback(const CallbackProc *proc);
void clearBuffer();
@@ -207,7 +207,8 @@ private:
VblTaskClientDriver *_drv;
int _numGroups;
- uint16 _scale;
+ uint16 _upscale;
+ uint16 _downscale;
uint32 _vblSmpQty;
uint32 _vblSmpQtyRem;
diff --git a/engines/scumm/players/player_mac_new.cpp b/engines/scumm/players/player_mac_new.cpp
index 901c270dc95..3c0fe60599f 100644
--- a/engines/scumm/players/player_mac_new.cpp
+++ b/engines/scumm/players/player_mac_new.cpp
@@ -176,7 +176,7 @@ uint32 fixMul(uint32 fx1, uint32 fx2) {
MacPlayerAudioStream::MacPlayerAudioStream(VblTaskClientDriver *drv, uint32 scummVMOutputrate, bool stereo, bool interpolate, bool internal16Bit) : Audio::AudioStream(), _drv(drv),
_vblSmpQty(0), _vblSmpQtyRem(0), _frameSize((stereo ? 2 : 1) * (internal16Bit ? 2 : 1)), _vblCountDown(0), _vblCountDownRem(0), _outputRate(scummVMOutputrate),
- _vblCbProc(nullptr), _numGroups(1), _isStereo(stereo), _interp(interpolate), _smpInternalSize(internal16Bit ? 2 : 1), _scale(1) {
+ _vblCbProc(nullptr), _numGroups(1), _isStereo(stereo), _interp(interpolate), _smpInternalSize(internal16Bit ? 2 : 1), _upscale(0), _downscale(0) {
assert(_drv);
_buffers = new SmpBuffer[2];
_vblSmpQty = (_outputRate << 16) / VBL_UPDATE_RATE;
@@ -287,14 +287,14 @@ int MacPlayerAudioStream::readBuffer(int16 *buffer, const int numSamples) {
int diff = smpN - _buffers[ii].lastL;
if (diff && _buffers[ii].rateConvAcc && interp)
diff = (diff * _buffers[ii].rateConvAcc) >> RATECNV_BIT_PRECSN;
- smpL += (int32)((_buffers[ii].lastL + diff) * (_buffers[ii].volume * _scale / numch));
+ smpL += (int32)((_buffers[ii].lastL + diff) * ((_buffers[ii].volume << _upscale) / numch));
if (_isStereo) {
smpN = _smpInternalSize == 2 ? *reinterpret_cast<int16*>(&_buffers[ii].pos[2]) : _buffers[ii].pos[1];
diff = smpN - _buffers[ii].lastR;
if (diff && _buffers[ii].rateConvAcc && interp)
diff = (diff * _buffers[ii].rateConvAcc) >> RATECNV_BIT_PRECSN;
- smpR += (int32)((_buffers[ii].lastR + diff) * (_buffers[ii].volume * _scale / numch));
+ smpR += (int32)((_buffers[ii].lastR + diff) * ((_buffers[ii].volume << _upscale) / numch));
}
}
@@ -331,9 +331,9 @@ int MacPlayerAudioStream::readBuffer(int16 *buffer, const int numSamples) {
}
}
- *buffer++ = CLIP<int32>((smpL / _numGroups) >> 2, -32768, 32767);
+ *buffer++ = CLIP<int32>((smpL / _numGroups) >> (2 + _downscale), -32768, 32767);
if (_isStereo)
- *buffer++ = CLIP<int32>((smpR / _numGroups) >> 2, -32768, 32767);
+ *buffer++ = CLIP<int32>((smpR / _numGroups) >> (2 + _downscale), -32768, 32767);
}
return numSamples;
}
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 634daccffbd..1389fd0d21a 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -857,23 +857,29 @@ void ScummEngine::setSoundCardVarToCurrentConfig() {
if (VAR_SOUNDCARD == 0xFF)
return;
+ switch (_sound->_musicType) {
+ case MDT_MACINTOSH:
+ switch (_game.id) {
+ case GID_INDY3:
+ VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_v3_low_quality_music") && ConfMan.getBool("mac_v3_low_quality_music")) ? 10 : 11;
+ break;
+ case GID_LOOM:
+ VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_snd_quality") && ConfMan.getInt("mac_snd_quality") > 0 && ConfMan.getInt("mac_snd_quality") < 4) ? 10 : 11;
+ break;
+ case GID_MONKEY:
+ VAR(VAR_SOUNDCARD) = 0xFFFF;
+ break;
+ default:
+ VAR(VAR_SOUNDCARD) = (_game.version >= 6) ? 0 : 4;
+ break;
+ }
+ break;
// VAR_SOUNDCARD modes
// 0 PC Speaker
// 1 Tandy
// 2 CMS
// 3 AdLib
// 4 Roland
- switch (_sound->_musicType) {
- case MDT_MACINTOSH:
- if (_game.id == GID_INDY3)
- VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_v3_low_quality_music") && ConfMan.getBool("mac_v3_low_quality_music")) ? 10 : 11;
- else if (_game.id == GID_LOOM)
- VAR(VAR_SOUNDCARD) = (ConfMan.hasKey("mac_snd_quality") && ConfMan.getInt("mac_snd_quality") > 0 && ConfMan.getInt("mac_snd_quality") < 4) ? 10 : 11;
- else if (_game.id == GID_MONKEY)
- VAR(VAR_SOUNDCARD) = 0xffff;
- else // GID_MONKEY2 || GID_INDY4
- VAR(VAR_SOUNDCARD) = 4;
- break;
case MDT_NONE:
case MDT_PCSPK:
VAR(VAR_SOUNDCARD) = 0;
More information about the Scummvm-git-logs
mailing list