diff options
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/module.mk | 17 | ||||
-rw-r--r-- | engines/gob/sound/soundblaster.cpp | 164 | ||||
-rw-r--r-- | engines/gob/sound/soundblaster.h | 59 | ||||
-rw-r--r-- | engines/gob/sound/soundmixer.cpp | 205 | ||||
-rw-r--r-- | engines/gob/sound/soundmixer.h | 95 |
5 files changed, 331 insertions, 209 deletions
diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 4ff9bdf920..9f407daee5 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -1,13 +1,6 @@ MODULE := engines/gob MODULE_OBJS := \ - sound/sound.o \ - sound/sounddesc.o \ - sound/pcspeaker.o \ - sound/adlib.o \ - sound/infogrames.o \ - sound/soundblaster.o \ - sound/cdrom.o \ dataio.o \ detection.o \ draw.o \ @@ -57,7 +50,15 @@ MODULE_OBJS := \ util.o \ video.o \ video_v1.o \ - video_v2.o + video_v2.o \ + sound/sound.o \ + sound/sounddesc.o \ + sound/pcspeaker.o \ + sound/adlib.o \ + sound/infogrames.o \ + sound/soundmixer.o \ + sound/soundblaster.o \ + sound/cdrom.o # This module can be built as a plugin ifeq ($(ENABLE_GOB), DYNAMIC_PLUGIN) diff --git a/engines/gob/sound/soundblaster.cpp b/engines/gob/sound/soundblaster.cpp index f5339404b4..bacb16a6d3 100644 --- a/engines/gob/sound/soundblaster.cpp +++ b/engines/gob/sound/soundblaster.cpp @@ -27,48 +27,20 @@ namespace Gob { -SoundBlaster::SoundBlaster(Audio::Mixer &mixer) : _mixer(&mixer) { - _playingSound = 0; +SoundBlaster::SoundBlaster(Audio::Mixer &mixer) : SoundMixer(mixer) { _curSoundDesc = 0; - _rate = _mixer->getOutputRate(); - _end = true; - _data = 0; - _length = 0; - _freq = 0; - _repCount = 0; - - _offset = 0; - _offsetFrac = 0; - _offsetInc = 0; - - _cur = 0; - _last = 0; - - _fade = false; - _fadeVol = 65536; - _fadeVolStep = 0; - _fadeSamples = 0; - _curFadeSamples = 0; - _compositionSamples = 0; _compositionSampleCount = 0; _compositionPos = -1; - - _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle, - this, -1, 255, 0, false, true); } SoundBlaster::~SoundBlaster() { - _mixer->stopHandle(_handle); } -bool SoundBlaster::isPlaying() const { - return !_end; -} - -char SoundBlaster::getPlayingSound() const { - return _playingSound; +void SoundBlaster::playSample(SoundDesc &sndDesc, int16 repCount, + int16 frequency, int16 fadeLength) { + SoundMixer::play(sndDesc, repCount, frequency, fadeLength); } void SoundBlaster::stopSound(int16 fadeLength, SoundDesc *sndDesc) { @@ -77,25 +49,10 @@ void SoundBlaster::stopSound(int16 fadeLength, SoundDesc *sndDesc) { if (sndDesc && (sndDesc != _curSoundDesc)) return; - if (fadeLength <= 0) { - _data = 0; - _end = true; - _playingSound = 0; + if (fadeLength <= 0) _curSoundDesc = 0; - return; - } - - _fade = true; - _fadeVol = 65536; - _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); - _fadeVolStep = MAX((int32) 1, (int32) (65536 / _fadeSamples)); - _curFadeSamples = 0; -} -void SoundBlaster::setRepeating(int32 repCount) { - Common::StackLock slock(_mutex); - - _repCount = repCount; + SoundMixer::stop(fadeLength); } void SoundBlaster::stopComposition() { @@ -146,115 +103,24 @@ void SoundBlaster::playComposition(int16 *composition, int16 freqVal, void SoundBlaster::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { - if (frequency <= 0) - frequency = sndDesc._frequency; - _curSoundDesc = &sndDesc; - sndDesc._repCount = repCount - 1; - sndDesc._frequency = frequency; - - _data = (int8 *) sndDesc.getData(); - _length = sndDesc.size(); - _freq = frequency; - - _repCount = repCount; - _end = false; - _playingSound = 1; - - _offset = 0; - _offsetFrac = 0; - _offsetInc = (_freq << FRAC_BITS) / _rate; - - _last = _cur; - _cur = _data[0]; - - _curFadeSamples = 0; - if (fadeLength == 0) { - _fade = false; - _fadeVol = 65536; - _fadeSamples = 0; - _fadeVolStep = 0; - } else { - _fade = true; - _fadeVol = 0; - _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); - _fadeVolStep = - MAX((int32) 1, (int32) (65536 / _fadeSamples)); - } -} - -void SoundBlaster::playSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, - int16 fadeLength) { - Common::StackLock slock(_mutex); - - if (!_end) - return; - - setSample(sndDesc, repCount, frequency, fadeLength); + SoundMixer::setSample(sndDesc, repCount, frequency, fadeLength); } void SoundBlaster::checkEndSample() { if (_compositionPos != -1) nextCompositionPos(); - else if ((_repCount == -1) || (--_repCount > 0)) { - _offset = 0; - _offsetFrac = 0; - _end = false; - _playingSound = 1; - } else { - _end = true; - _playingSound = 0; - } + else + SoundMixer::checkEndSample(); } -int SoundBlaster::readBuffer(int16 *buffer, const int numSamples) { - Common::StackLock slock(_mutex); - - for (int i = 0; i < numSamples; i++) { - if (!_data) - return i; - if (_end || (_offset >= _length)) - checkEndSample(); - if (_end) - return i; - - // Linear interpolation. See sound/rate.cpp - - int16 val = (_last + (((_cur - _last) * _offsetFrac + - FRAC_HALF) >> FRAC_BITS)) << 8; - *buffer++ = (val * _fadeVol) >> 16; - - _offsetFrac += _offsetInc; - - // Was there an integral change? - if (fracToInt(_offsetFrac) > 0) { - _last = _cur; - _cur = _data[_offset]; - _offset += fracToInt(_offsetFrac); - _offsetFrac &= FRAC_LO_MASK; - } - - if (_fade) { - - if (++_curFadeSamples >= _fadeSamples) { - if (_fadeVolStep > 0) { - _data = 0; - _end = true; - _playingSound = 0; - _compositionPos = -1; - _curSoundDesc = 0; - } else { - _fadeVol = 65536; - _fade = false; - } - } else - _fadeVol -= _fadeVolStep; - - if (_fadeVol < 0) - _fadeVol = 0; - - } +void SoundBlaster::endFade() { + if (_fadeVolStep > 0) { + _compositionPos = -1; + _curSoundDesc = 0; } - return numSamples; + + SoundMixer::endFade(); } } // End of namespace Gob diff --git a/engines/gob/sound/soundblaster.h b/engines/gob/sound/soundblaster.h index 575d4994be..c57e4a443e 100644 --- a/engines/gob/sound/soundblaster.h +++ b/engines/gob/sound/soundblaster.h @@ -27,23 +27,18 @@ #define GOB_SOUND_SOUNDBLASTER_H #include "common/mutex.h" -#include "common/frac.h" -#include "sound/audiostream.h" #include "sound/mixer.h" -#include "sound/softsynth/pcspk.h" + +#include "gob/sound/sounddesc.h" +#include "gob/sound/soundmixer.h" namespace Gob { -class SoundBlaster : public Audio::AudioStream { +class SoundBlaster : public SoundMixer { public: - char _playingSound; - SoundBlaster(Audio::Mixer &mixer); ~SoundBlaster(); - bool loadSample(SoundDesc &sndDesc, const char *fileName); - void freeSample(SoundDesc &sndDesc); - void playSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength = 0); void stopSound(int16 fadeLength, SoundDesc *sndDesc = 0); @@ -53,61 +48,21 @@ public: void stopComposition(); void endComposition(); - bool isPlaying() const; - char getPlayingSound() const; - - void setRepeating(int32 repCount); - void waitEndPlay(bool interruptible = false, bool stopComp = true); - - static void convToSigned(byte *buffer, int length) { - while (length-- > 0) - *buffer++ ^= 0x80; - } - - int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return false; } - bool endOfData() const { return _end; } - bool endOfStream() const { return false; } - int getRate() const { return _rate; } - protected: - Audio::Mixer *_mixer; - - Audio::SoundHandle *_activeHandle; - Audio::SoundHandle _compositionHandle; + Common::Mutex _mutex; SoundDesc *_compositionSamples; int8 _compositionSampleCount; int16 _composition[50]; int8 _compositionPos; - Audio::SoundHandle _handle; - Common::Mutex _mutex; SoundDesc *_curSoundDesc; - bool _end; - int8 *_data; - uint32 _length; - uint32 _rate; - int32 _freq; - int32 _repCount; - - uint32 _offset; - frac_t _offsetFrac; - frac_t _offsetInc; - - int16 _cur; - int16 _last; - - bool _fade; - int32 _fadeVol; - int32 _fadeVolStep; - uint8 _fadeLength; - uint32 _fadeSamples; - uint32 _curFadeSamples; void setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength); void checkEndSample(); + void endFade(); + void nextCompositionPos(); }; diff --git a/engines/gob/sound/soundmixer.cpp b/engines/gob/sound/soundmixer.cpp new file mode 100644 index 0000000000..f85073ad61 --- /dev/null +++ b/engines/gob/sound/soundmixer.cpp @@ -0,0 +1,205 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "gob/sound/soundmixer.h" + +namespace Gob { + +SoundMixer::SoundMixer(Audio::Mixer &mixer) : _mixer(&mixer) { + _playingSound = 0; + + _rate = _mixer->getOutputRate(); + _end = true; + _data = 0; + _length = 0; + _freq = 0; + _repCount = 0; + + _offset = 0; + _offsetFrac = 0; + _offsetInc = 0; + + _cur = 0; + _last = 0; + + _fade = false; + _fadeVol = 65536; + _fadeVolStep = 0; + _fadeSamples = 0; + _curFadeSamples = 0; + + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle, + this, -1, 255, 0, false, true); +} + +SoundMixer::~SoundMixer() { + _mixer->stopHandle(_handle); +} + +bool SoundMixer::isPlaying() const { + return !_end; +} + +char SoundMixer::getPlayingSound() const { + return _playingSound; +} + +void SoundMixer::stop(int16 fadeLength) { + Common::StackLock slock(_mutex); + + if (fadeLength <= 0) { + _data = 0; + _end = true; + _playingSound = 0; + return; + } + + _fade = true; + _fadeVol = 65536; + _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); + _fadeVolStep = MAX((int32) 1, (int32) (65536 / _fadeSamples)); + _curFadeSamples = 0; +} + +void SoundMixer::setRepeating(int32 repCount) { + Common::StackLock slock(_mutex); + + _repCount = repCount; +} + +void SoundMixer::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, + int16 fadeLength) { + + if (frequency <= 0) + frequency = sndDesc._frequency; + + sndDesc._repCount = repCount - 1; + sndDesc._frequency = frequency; + + _data = (int8 *) sndDesc.getData(); + _length = sndDesc.size(); + _freq = frequency; + + _repCount = repCount; + _end = false; + _playingSound = 1; + + _offset = 0; + _offsetFrac = 0; + _offsetInc = (_freq << FRAC_BITS) / _rate; + + _last = _cur; + _cur = _data[0]; + + _curFadeSamples = 0; + if (fadeLength == 0) { + _fade = false; + _fadeVol = 65536; + _fadeSamples = 0; + _fadeVolStep = 0; + } else { + _fade = true; + _fadeVol = 0; + _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); + _fadeVolStep = - MAX((int32) 1, (int32) (65536 / _fadeSamples)); + } +} + +void SoundMixer::play(SoundDesc &sndDesc, int16 repCount, int16 frequency, + int16 fadeLength) { + Common::StackLock slock(_mutex); + + if (!_end) + return; + + setSample(sndDesc, repCount, frequency, fadeLength); +} + +void SoundMixer::checkEndSample() { + if ((_repCount == -1) || (--_repCount > 0)) { + _offset = 0; + _offsetFrac = 0; + _end = false; + _playingSound = 1; + } else { + _end = true; + _playingSound = 0; + } +} + +int SoundMixer::readBuffer(int16 *buffer, const int numSamples) { + Common::StackLock slock(_mutex); + + for (int i = 0; i < numSamples; i++) { + if (!_data) + return i; + if (_end || (_offset >= _length)) + checkEndSample(); + if (_end) + return i; + + // Linear interpolation. See sound/rate.cpp + + int16 val = (_last + (((_cur - _last) * _offsetFrac + + FRAC_HALF) >> FRAC_BITS)) << 8; + *buffer++ = (val * _fadeVol) >> 16; + + _offsetFrac += _offsetInc; + + // Was there an integral change? + if (fracToInt(_offsetFrac) > 0) { + _last = _cur; + _cur = _data[_offset]; + _offset += fracToInt(_offsetFrac); + _offsetFrac &= FRAC_LO_MASK; + } + + if (_fade) { + + if (++_curFadeSamples >= _fadeSamples) + endFade(); + else + _fadeVol -= _fadeVolStep; + + if (_fadeVol < 0) + _fadeVol = 0; + + } + } + return numSamples; +} + +void SoundMixer::endFade() { + if (_fadeVolStep > 0) { + _data = 0; + _end = true; + _playingSound = 0; + } else { + _fadeVol = 65536; + _fade = false; + } +} + +} // End of namespace Gob diff --git a/engines/gob/sound/soundmixer.h b/engines/gob/sound/soundmixer.h new file mode 100644 index 0000000000..e22cd7b473 --- /dev/null +++ b/engines/gob/sound/soundmixer.h @@ -0,0 +1,95 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GOB_SOUND_SOUNDMIXER_H +#define GOB_SOUND_SOUNDMIXER_H + +#include "common/mutex.h" +#include "common/frac.h" +#include "sound/audiostream.h" +#include "sound/mixer.h" + +#include "gob/sound/sounddesc.h" + +namespace Gob { + +class SoundMixer : public Audio::AudioStream { +public: + SoundMixer(Audio::Mixer &mixer); + ~SoundMixer(); + + virtual void play(SoundDesc &sndDesc, int16 repCount, + int16 frequency, int16 fadeLength = 0); + virtual void stop(int16 fadeLength); + + bool isPlaying() const; + char getPlayingSound() const; + + void setRepeating(int32 repCount); + + int readBuffer(int16 *buffer, const int numSamples); + bool isStereo() const { return false; } + bool endOfData() const { return _end; } + bool endOfStream() const { return false; } + int getRate() const { return _rate; } + +protected: + Audio::Mixer *_mixer; + + Audio::SoundHandle _handle; + Common::Mutex _mutex; + + bool _end; + int8 *_data; + uint32 _length; + uint32 _rate; + int32 _freq; + int32 _repCount; + + uint32 _offset; + frac_t _offsetFrac; + frac_t _offsetInc; + + int16 _cur; + int16 _last; + + bool _fade; + int32 _fadeVol; + int32 _fadeVolStep; + uint8 _fadeLength; + uint32 _fadeSamples; + uint32 _curFadeSamples; + + char _playingSound; + + virtual void setSample(SoundDesc &sndDesc, int16 repCount, + int16 frequency, int16 fadeLength); + virtual void checkEndSample(); + virtual void endFade(); +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_SOUNDMIXER_H |