aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/kyra/kyra3.cpp2
-rw-r--r--engines/kyra/sound.h6
-rw-r--r--engines/kyra/sound_digital.cpp83
3 files changed, 76 insertions, 15 deletions
diff --git a/engines/kyra/kyra3.cpp b/engines/kyra/kyra3.cpp
index 8814e19cf7..1b7e4a5b2c 100644
--- a/engines/kyra/kyra3.cpp
+++ b/engines/kyra/kyra3.cpp
@@ -183,7 +183,7 @@ void KyraEngine_v3::playMenuAudioFile() {
uint32 temp = 0;
_res->fileHandle(_menuAudioFile, &temp, *handle);
if (handle->isOpen()) {
- _musicSoundChannel = _soundDigital->playSound(handle, true, -1);
+ _musicSoundChannel = _soundDigital->playSound(handle, true);
}
}
diff --git a/engines/kyra/sound.h b/engines/kyra/sound.h
index ea8501cc62..e43239efc1 100644
--- a/engines/kyra/sound.h
+++ b/engines/kyra/sound.h
@@ -39,6 +39,8 @@ class SoundHandle;
namespace Kyra {
+class AUDStream;
+
class Sound {
public:
Sound(KyraEngine *engine, Audio::Mixer *mixer);
@@ -221,9 +223,10 @@ public:
bool init();
- int playSound(Common::File *fileHandle, bool loop = false, int channel = -1);
+ int playSound(Common::File *fileHandle, bool loop = false, bool fadeIn = false, int channel = -1);
bool isPlaying(int channel);
void stopSound(int channel);
+ void beginFadeOut(int channel);
private:
KyraEngine *_vm;
Audio::Mixer *_mixer;
@@ -231,6 +234,7 @@ private:
struct Sound {
Common::File *fileHandle;
Audio::SoundHandle handle;
+ AUDStream *stream;
} _sounds[SOUND_STREAMS];
};
diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp
index 1db2e45d86..90e4f0b0da 100644
--- a/engines/kyra/sound_digital.cpp
+++ b/engines/kyra/sound_digital.cpp
@@ -42,6 +42,9 @@ public:
bool endOfData() const { return _endOfData; }
int getRate() const { return _rate; }
+
+ void beginFadeIn();
+ void beginFadeOut();
private:
Common::File *_file;
bool _loop;
@@ -53,12 +56,16 @@ private:
int _bytesLeft;
- uint8 *_outBuffer;
+ byte *_outBuffer;
int _outBufferOffset;
uint _outBufferSize;
- uint8 *_inBuffer;
+ byte *_inBuffer;
uint _inBufferSize;
+
+ int32 _fadeSamples;
+ int32 _fadeCount;
+ int _fading;
int readChunk(int16 *buffer, const int maxSamples);
@@ -90,6 +97,13 @@ AUDStream::AUDStream(Common::File *file, bool loop) : _file(0), _endOfData(true)
_rate = _file->readUint16LE();
_totalSize = _file->readUint32LE();
_loop = loop;
+
+ // TODO: Find the correct number of samples for a fade-in/out. Should
+ // probably take the same amount of time as a palette fade.
+
+ _fadeSamples = 2 * getRate();
+ _fading = 0;
+
// TODO?: add checks
int flags = _file->readByte(); // flags
int type = _file->readByte(); // type
@@ -113,6 +127,18 @@ AUDStream::~AUDStream() {
#endif
}
+void AUDStream::beginFadeIn() {
+ if (_fading == 0)
+ _fadeCount = 0;
+ _fading = 1;
+}
+
+void AUDStream::beginFadeOut() {
+ if (_fading == 0)
+ _fadeCount = _fadeSamples;
+ _fading = -1;
+}
+
int AUDStream::readBuffer(int16 *buffer, const int numSamples) {
int samplesRead = 0, samplesLeft = numSamples;
@@ -273,12 +299,34 @@ int AUDStream::readChunk(int16 *buffer, const int maxSamples) {
samplesProcessed += samples;
_bytesLeft -= samples;
+ // To help avoid overflows for long fade times, we divide both
+ // _fadeSamples and _fadeCount when calculating the new sample.
+
+ int32 div = _fadeSamples / 256;
+
while (samples--) {
- int16 sample = (int8)_outBuffer[_outBufferOffset++];
- *buffer++ = (sample << 8) ^ 0x8000;
+ int16 sample = (_outBuffer[_outBufferOffset++] << 8) ^ 0x8000;
+
+ if (_fading) {
+ sample = (sample * (_fadeCount / 256)) / div;
+ _fadeCount += _fading;
+
+ if (_fadeCount < 0) {
+ _fadeCount = 0;
+ _endOfData = true;
+ } else if (_fadeCount > _fadeSamples) {
+ _fadeCount = _fadeSamples;
+ _fading = 0;
+ }
+ }
+
+ *buffer++ = sample;
}
}
+ if (_fading < 0 && _fadeCount == 0)
+ _fading = false;
+
return samplesProcessed;
}
@@ -298,15 +346,15 @@ bool SoundDigital::init() {
return true;
}
-int SoundDigital::playSound(Common::File *fileHandle, bool loop, int channel) {
+int SoundDigital::playSound(Common::File *fileHandle, bool loop, bool fadeIn, int channel) {
Sound *use = 0;
if (channel != -1 && channel < SOUND_STREAMS) {
stopSound(channel);
use = &_sounds[channel];
} else {
- for (int i = 0; i < SOUND_STREAMS; ++i) {
- if (!_sounds[i].fileHandle) {
- use = &_sounds[i];
+ for (channel = 0; channel < SOUND_STREAMS; ++channel) {
+ if (!_sounds[channel].fileHandle) {
+ use = &_sounds[channel];
break;
}
}
@@ -317,16 +365,19 @@ int SoundDigital::playSound(Common::File *fileHandle, bool loop, int channel) {
}
}
- Audio::AudioStream *stream = new AUDStream(fileHandle, loop);
- if (stream->endOfData()) {
- delete stream;
+ use->stream = new AUDStream(fileHandle, loop);
+ if (use->stream->endOfData()) {
+ delete use->stream;
delete fileHandle;
return -1;
}
+
+ if (fadeIn)
+ use->stream->beginFadeIn();
// TODO: set correct sound type from channel id
- _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &use->handle, stream);
+ _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &use->handle, use->stream);
use->fileHandle = fileHandle;
return use - _sounds;
@@ -348,7 +399,13 @@ void SoundDigital::stopSound(int channel) {
if (_sounds[channel].fileHandle) {
delete _sounds[channel].fileHandle;
- _sounds[channel].fileHandle = 0;
+ _sounds[channel].fileHandle = 0;
+ }
+}
+
+void SoundDigital::beginFadeOut(int channel) {
+ if (isPlaying(channel)) {
+ _sounds[channel].stream->beginFadeOut();
}
}