aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/sound/drivers/pc9801.cpp
diff options
context:
space:
mode:
authorathrxx2019-01-23 21:28:21 +0100
committerFilippos Karapetis2019-04-02 20:45:35 +0300
commit5d4e22ebc9f679cea041beead8269d626d7906f9 (patch)
tree3e39f76870e0a97d9b7c200aa8f3aac565c85fb4 /engines/sci/sound/drivers/pc9801.cpp
parent037eec31446b64ec56b24e31d5be392390a694ba (diff)
downloadscummvm-rg350-5d4e22ebc9f679cea041beead8269d626d7906f9.tar.gz
scummvm-rg350-5d4e22ebc9f679cea041beead8269d626d7906f9.tar.bz2
scummvm-rg350-5d4e22ebc9f679cea041beead8269d626d7906f9.zip
SCI: (PC-98 driver) - frequency bug workaround
The square sound channels will be out of spec when playing on the lowest octave. The result is a rather ugly noise. This bug makes a rather subtle appearance if the channel remapping is accurate, but it becomes quite obvious in the SQ4 intro with the current implementation. This commit turns off the channel when trying to play out of spec.
Diffstat (limited to 'engines/sci/sound/drivers/pc9801.cpp')
-rw-r--r--engines/sci/sound/drivers/pc9801.cpp26
1 files changed, 18 insertions, 8 deletions
diff --git a/engines/sci/sound/drivers/pc9801.cpp b/engines/sci/sound/drivers/pc9801.cpp
index 8a1521a0e2..2b99d6b2a2 100644
--- a/engines/sci/sound/drivers/pc9801.cpp
+++ b/engines/sci/sound/drivers/pc9801.cpp
@@ -111,7 +111,7 @@ protected:
private:
virtual void programChange(uint8 program) = 0;
- virtual void prepareFrequencyAndVolume(bool updateVolume);
+ virtual bool prepareFrequencyAndVolume(bool updateVolume);
virtual void sendSoundOnOff(bool noteOn) = 0;
virtual void sendFrequency() = 0;
virtual void sendVolume() = 0;
@@ -156,7 +156,7 @@ public:
private:
void programChange(uint8 program);
- void prepareFrequencyAndVolume(bool updateVolume);
+ bool prepareFrequencyAndVolume(bool updateVolume);
void processSounds();
void sendSoundOnOff(bool noteOn);
void sendVolume();
@@ -406,7 +406,9 @@ void SoundChannel_PC9801::processNoteEvent(uint8 note, bool noteOn) {
_flags |= kChanVbrRestartEnv;
}
- prepareFrequencyAndVolume(noteOn);
+ if (!prepareFrequencyAndVolume(noteOn))
+ noteOn = false;
+
sendSoundOnOff(noteOn);
}
@@ -480,6 +482,8 @@ int SoundChannel_PC9801::recalculateFrequency(uint16 note, uint16 modifier, uint
if (_type != 2)
res |= (block << 11);
+ else if (block == 0)
+ return -1;
if (pb)
res += (((pb * pitchVbrMultiplier) & 0x0FF0) >> 8);
@@ -591,12 +595,15 @@ void SoundChannel_PC9801::writeReg(uint8 part, uint8 reg, uint8 val) {
_pc98a->writeReg(part, reg, val);
}
-void SoundChannel_PC9801::prepareFrequencyAndVolume(bool updateVolume) {
+bool SoundChannel_PC9801::prepareFrequencyAndVolume(bool updateVolume) {
if (recalculateFrequency(_note, 0, &_frequencyBlock, &_frequencyCourse, &_frequencyNoteModifier) == -1)
- return;
+ return false;
+
sendFrequency();
if (updateVolume)
sendVolume();
+
+ return true;
}
SoundChannel_PC9801_FM4OP::SoundChannel_PC9801_FM4OP(uint8 id, PC98AudioCore *pc98a, MidiPart_PC9801 **parts, SciVersion version, SciSpan<const uint8> instrumentData, uint8 patchSize, bool &soundOn)
@@ -736,14 +743,17 @@ void SoundChannel_PC9801_FM2OP::programChange(uint8 program) {
writeReg(_regPrt, i, data[pos++]);
}
-void SoundChannel_PC9801_FM2OP::prepareFrequencyAndVolume(bool updateVolume) {
+bool SoundChannel_PC9801_FM2OP::prepareFrequencyAndVolume(bool updateVolume) {
if (recalculateFrequency(_note, _opFreqOffset[_operatorFrqIndex[0]], 0, &_frequencyCourse, &_frequencyNoteModifier) == -1)
- return;
+ return false;
if (recalculateFrequency(_note, _opFreqOffset[_operatorFrqIndex[1]], 0, &_frequencyCourse2, &_frequencyNoteModifier2) == -1)
- return;
+ return false;
+
sendFrequency();
if (updateVolume)
sendVolume();
+
+ return true;
}
void SoundChannel_PC9801_FM2OP::sendSoundOnOff(bool noteOn) {