diff options
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/sound/adlib.cpp | 65 | ||||
-rw-r--r-- | engines/gob/sound/adlib.h | 16 | ||||
-rw-r--r-- | engines/gob/sound/adlplayer.cpp | 11 | ||||
-rw-r--r-- | engines/gob/sound/adlplayer.h | 2 | ||||
-rw-r--r-- | engines/gob/sound/musplayer.cpp | 18 | ||||
-rw-r--r-- | engines/gob/sound/musplayer.h | 1 |
6 files changed, 50 insertions, 63 deletions
diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp index b92e20b42c..20fbced63c 100644 --- a/engines/gob/sound/adlib.cpp +++ b/engines/gob/sound/adlib.cpp @@ -93,7 +93,7 @@ const uint16 AdLib::kHihatParams [kParamCount] = { 0, 1, 0, 15, 11, 0, 7, 5, 0, 0, 0, 0, 0, 0 }; -AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0), +AdLib::AdLib(Audio::Mixer &mixer, int callbackFreq) : _mixer(&mixer), _opl(0), _toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true) { _rate = _mixer->getOutputRate(); @@ -103,6 +103,7 @@ AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer), _opl(0), createOPL(); initOPL(); + _opl->start(new Common::Functor0Mem<void, AdLib>(this, &AdLib::onTimer), callbackFreq); _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); } @@ -144,38 +145,34 @@ void AdLib::createOPL() { } int AdLib::readBuffer(int16 *buffer, const int numSamples) { + return _opl->readBuffer(buffer, numSamples); +} + +void AdLib::onTimer() { Common::StackLock slock(_mutex); - // Nothing to do, fill with silence - if (!_playing) { - memset(buffer, 0, numSamples * sizeof(int16)); - return numSamples; + // Nothing to do + if (!_playing) + return; + + // Check if there's anything to do on this step + // If not, decrease the poll number and move on + if (_toPoll > 0) { + _toPoll--; + return; } - // Read samples from the OPL, polling in more music when necessary - uint32 samples = numSamples; - while (samples && _playing) { - if (_toPoll) { - const uint32 render = MIN(samples, _toPoll); - - _opl->readBuffer(buffer, render); - - buffer += render; - samples -= render; - _toPoll -= render; - - } else { - // Song ended, fill the rest with silence - if (_ended) { - memset(buffer, 0, samples * sizeof(int16)); - samples = 0; - break; - } - - // Poll more music - _toPoll = pollMusic(_first); - _first = false; + // Poll until we have to delay until the next poll + while (_toPoll == 0 && _playing) { + // Song ended, break out + if (_ended) { + _toPoll = 0; + break; } + + // Poll more music + _toPoll = pollMusic(_first); + _first = false; } // Song ended, loop if requested @@ -195,8 +192,6 @@ int AdLib::readBuffer(int16 *buffer, const int numSamples) { } else _playing = false; } - - return numSamples; } bool AdLib::isStereo() const { @@ -204,7 +199,7 @@ bool AdLib::isStereo() const { } bool AdLib::endOfData() const { - return !_playing; + return false; } bool AdLib::endOfStream() const { @@ -231,10 +226,6 @@ void AdLib::setRepeating(int32 repCount) { _repCount = repCount; } -uint32 AdLib::getSamplesPerSecond() const { - return _rate * (isStereo() ? 2 : 1); -} - void AdLib::startPlay() { Common::StackLock slock(_mutex); @@ -639,4 +630,8 @@ void AdLib::setFreq(uint8 voice, uint16 note, bool on) { writeOPL(0xB0 + voice, value); } +void AdLib::setTimerFrequency(int timerFrequency) { + _opl->setCallbackFrequency(timerFrequency); +} + } // End of namespace Gob diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index 8071249374..6a6215298a 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -37,7 +37,7 @@ namespace Gob { /** Base class for a player of an AdLib music format. */ class AdLib : public Audio::AudioStream { public: - AdLib(Audio::Mixer &mixer); + AdLib(Audio::Mixer &mixer, int callbackFrequency); virtual ~AdLib(); bool isPlaying() const; ///< Are we currently playing? @@ -120,8 +120,6 @@ protected: static const int kOPLMidC = 48; ///< A mid C for the OPL. - /** Return the number of samples per second. */ - uint32 getSamplesPerSecond() const; /** Write a value into an OPL register. */ void writeOPL(byte reg, byte val); @@ -135,7 +133,7 @@ protected: /** The callback function that's called for polling more AdLib commands. * * @param first Is this the first poll since the start of the song? - * @return The number of samples until the next poll. + * @return The number of ticks until the next poll. */ virtual uint32 pollMusic(bool first) = 0; @@ -207,6 +205,11 @@ protected: /** Switch a voice off. */ void noteOff(uint8 voice); + /** + * Set the OPL timer frequency + */ + void setTimerFrequency(int timerFrequency); + private: static const uint8 kOperatorType [kOperatorCount]; static const uint8 kOperatorOffset[kOperatorCount]; @@ -300,6 +303,11 @@ private: void changePitch(uint8 voice, uint16 pitchBend); void setFreq(uint8 voice, uint16 note, bool on); + + /** + * Callback function for OPL + */ + void onTimer(); }; } // End of namespace Gob diff --git a/engines/gob/sound/adlplayer.cpp b/engines/gob/sound/adlplayer.cpp index 384a928360..e5a276032b 100644 --- a/engines/gob/sound/adlplayer.cpp +++ b/engines/gob/sound/adlplayer.cpp @@ -28,7 +28,7 @@ namespace Gob { -ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer), +ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer, 1000), _songData(0), _songDataSize(0), _playPos(0) { } @@ -135,14 +135,7 @@ uint32 ADLPlayer::pollMusic(bool first) { if (delay & 0x80) delay = ((delay & 3) << 8) | *_playPos++; - return getSampleDelay(delay); -} - -uint32 ADLPlayer::getSampleDelay(uint16 delay) const { - if (delay == 0) - return 0; - - return ((uint32)delay * getSamplesPerSecond()) / 1000; + return delay; } void ADLPlayer::rewind() { diff --git a/engines/gob/sound/adlplayer.h b/engines/gob/sound/adlplayer.h index 3edd238343..bd43cc091c 100644 --- a/engines/gob/sound/adlplayer.h +++ b/engines/gob/sound/adlplayer.h @@ -76,8 +76,6 @@ private: bool readHeader (Common::SeekableReadStream &adl, int &timbreCount); bool readTimbres (Common::SeekableReadStream &adl, int timbreCount); bool readSongData(Common::SeekableReadStream &adl); - - uint32 getSampleDelay(uint16 delay) const; }; } // End of namespace Gob diff --git a/engines/gob/sound/musplayer.cpp b/engines/gob/sound/musplayer.cpp index 7001a5724b..bf90d44735 100644 --- a/engines/gob/sound/musplayer.cpp +++ b/engines/gob/sound/musplayer.cpp @@ -27,7 +27,7 @@ namespace Gob { -MUSPlayer::MUSPlayer(Audio::Mixer &mixer) : AdLib(mixer), +MUSPlayer::MUSPlayer(Audio::Mixer &mixer) : AdLib(mixer, 60), _songData(0), _songDataSize(0), _playPos(0), _songID(0) { } @@ -43,15 +43,6 @@ void MUSPlayer::unload() { unloadMUS(); } -uint32 MUSPlayer::getSampleDelay(uint16 delay) const { - if (delay == 0) - return 0; - - uint32 freq = (_ticksPerBeat * _tempo) / 60; - - return ((uint32)delay * getSamplesPerSecond()) / freq; -} - void MUSPlayer::skipToTiming() { while (*_playPos < 0x80) _playPos++; @@ -67,7 +58,7 @@ uint32 MUSPlayer::pollMusic(bool first) { } if (first) - return getSampleDelay(*_playPos++); + return *_playPos++; uint16 delay = 0; while (delay == 0) { @@ -100,6 +91,7 @@ uint32 MUSPlayer::pollMusic(bool first) { uint32 denom = *_playPos++; _tempo = _baseTempo * num + ((_baseTempo * denom) >> 7); + setTimerFrequency((_ticksPerBeat * _tempo) / 60); _playPos++; } else { @@ -182,7 +174,7 @@ uint32 MUSPlayer::pollMusic(bool first) { delay += *_playPos++; } - return getSampleDelay(delay); + return delay; } void MUSPlayer::rewind() { @@ -193,6 +185,8 @@ void MUSPlayer::rewind() { setPercussionMode(_soundMode != 0); setPitchRange(_pitchBendRange); + + setTimerFrequency((_ticksPerBeat * _tempo) / 60); } bool MUSPlayer::loadSND(Common::SeekableReadStream &snd) { diff --git a/engines/gob/sound/musplayer.h b/engines/gob/sound/musplayer.h index c76c5aab38..7c1189b84b 100644 --- a/engines/gob/sound/musplayer.h +++ b/engines/gob/sound/musplayer.h @@ -97,7 +97,6 @@ private: bool readMUSHeader(Common::SeekableReadStream &mus); bool readMUSSong (Common::SeekableReadStream &mus); - uint32 getSampleDelay(uint16 delay) const; void setInstrument(uint8 voice, uint8 instrument); void skipToTiming(); |