aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorFilippos Karapetis2016-10-09 23:38:39 +0300
committerFilippos Karapetis2016-10-09 23:38:39 +0300
commit0a4c1eeca1ebd67cb0dcd891aba9a3c05e8e8a80 (patch)
tree833b69046bcba512007045913e94d22e11f953c1 /engines
parentc1e44df357a310a6020e472881e0d1ed29c8ab37 (diff)
downloadscummvm-rg350-0a4c1eeca1ebd67cb0dcd891aba9a3c05e8e8a80.tar.gz
scummvm-rg350-0a4c1eeca1ebd67cb0dcd891aba9a3c05e8e8a80.tar.bz2
scummvm-rg350-0a4c1eeca1ebd67cb0dcd891aba9a3c05e8e8a80.zip
CHEWY: Move all sound functions into sound.*
Diffstat (limited to 'engines')
-rw-r--r--engines/chewy/graphics.cpp2
-rw-r--r--engines/chewy/sound.cpp113
-rw-r--r--engines/chewy/sound.h29
-rw-r--r--engines/chewy/video/cfo_decoder.cpp65
-rw-r--r--engines/chewy/video/cfo_decoder.h16
5 files changed, 168 insertions, 57 deletions
diff --git a/engines/chewy/graphics.cpp b/engines/chewy/graphics.cpp
index de95b11440..5db2a76398 100644
--- a/engines/chewy/graphics.cpp
+++ b/engines/chewy/graphics.cpp
@@ -115,7 +115,7 @@ void Graphics::drawText(Common::String text, uint x, uint y) {
}
void Graphics::playVideo(uint num) {
- CfoDecoder *cfoDecoder = new CfoDecoder(_vm->_mixer);
+ CfoDecoder *cfoDecoder = new CfoDecoder(_vm->_sound);
VideoResource *videoResource = new VideoResource("cut.tap");
Common::SeekableReadStream *videoStream = videoResource->getVideoStream(num);
diff --git a/engines/chewy/sound.cpp b/engines/chewy/sound.cpp
index e0e84e2101..5e519f47f9 100644
--- a/engines/chewy/sound.cpp
+++ b/engines/chewy/sound.cpp
@@ -41,41 +41,112 @@ Sound::~Sound() {
delete _speechRes;
}
-void Sound::playSound(int num, bool loop) {
+void Sound::playSound(int num, bool loop, uint channel) {
SoundChunk *sound = _soundRes->getSound(num);
byte *data = (byte *)malloc(sound->size);
memcpy(data, sound->data, sound->size);
+ playSound(data, sound->size, loop, channel);
+
+ delete[] sound->data;
+ delete sound;
+}
+
+void Sound::playSound(byte *data, uint32 size, bool loop, uint channel, DisposeAfterUse::Flag dispose) {
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
Audio::makeRawStream(data,
- sound->size, 22050, Audio::FLAG_UNSIGNED,
- DisposeAfterUse::YES),
+ size, 22050, Audio::FLAG_UNSIGNED,
+ dispose),
loop ? 0 : 1);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, stream);
+ _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[channel], stream);
+}
- delete[] sound->data;
- delete sound;
+void Sound::pauseSound(uint channel) {
+ assert(channel < MAX_SOUND_EFFECTS);
+ _mixer->pauseHandle(_soundHandle[channel], true);
+}
+
+void Sound::resumeSound(uint channel) {
+ assert(channel < MAX_SOUND_EFFECTS);
+ _mixer->pauseHandle(_soundHandle[channel], false);
+}
+
+void Sound::stopSound(uint channel) {
+ assert(channel < MAX_SOUND_EFFECTS);
+ _mixer->stopHandle(_soundHandle[channel]);
+}
+
+bool Sound::isSoundActive(uint channel) {
+ assert(channel < MAX_SOUND_EFFECTS);
+ return _mixer->isSoundHandleActive(_soundHandle[channel]);
+}
+
+void Sound::setSoundVolume(uint volume) {
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
+}
+
+void Sound::setSoundChannelVolume(uint channel, uint volume) {
+ assert(channel < MAX_SOUND_EFFECTS);
+ _mixer->setChannelVolume(_soundHandle[channel], volume);
+}
+
+void Sound::setSoundChannelBalance(uint channel, uint balance) {
+ assert(channel < MAX_SOUND_EFFECTS);
+ _mixer->setChannelBalance(_soundHandle[channel], balance);
}
void Sound::playMusic(int num, bool loop) {
uint32 musicNum = _soundRes->getChunkCount() - 1 - num;
Chunk *chunk = _soundRes->getChunk(musicNum);
byte *data = _soundRes->getChunkData(musicNum);
+
+ playMusic(data, chunk->size, loop);
+
+ delete[] data;
+ delete chunk;
+}
+
+void Sound::playMusic(byte *data, uint32 size, bool loop, DisposeAfterUse::Flag dispose) {
+ byte *modData = nullptr;
+ uint32 modSize;
// TODO: TMF music files are similar to MOD files. With the following
// incorrect implementation, the PCM parts of these files can be played
warning("The current music playing implementation is wrong");
+ modSize = size;
+ modData = (byte *)malloc(modSize);
+ memcpy(modData, data, size);
Audio::AudioStream *stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(data,
- chunk->size, 22050, Audio::FLAG_UNSIGNED,
- DisposeAfterUse::YES),
+ Audio::makeRawStream(modData,
+ modSize, 22050, Audio::FLAG_UNSIGNED,
+ dispose),
loop ? 0 : 1);
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream);
}
+void Sound::pauseMusic() {
+ _mixer->pauseHandle(_musicHandle, true);
+}
+
+void Sound::resumeMusic() {
+ _mixer->pauseHandle(_musicHandle, false);
+}
+
+void Sound::stopMusic() {
+ _mixer->stopHandle(_musicHandle);
+}
+
+bool Sound::isMusicActive() {
+ return _mixer->isSoundHandleActive(_musicHandle);
+}
+
+void Sound::setMusicVolume(uint volume) {
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
+}
+
void Sound::playSpeech(int num) {
SoundChunk *sound = _speechRes->getSound(num);
byte *data = (byte *)malloc(sound->size);
@@ -93,4 +164,28 @@ void Sound::playSpeech(int num) {
delete sound;
}
+void Sound::pauseSpeech() {
+ _mixer->pauseHandle(_speechHandle, true);
+}
+
+void Sound::resumeSpeech() {
+ _mixer->pauseHandle(_speechHandle, false);
+}
+
+void Sound::stopSpeech() {
+ _mixer->stopHandle(_speechHandle);
+}
+
+bool Sound::isSpeechActive() {
+ return _mixer->isSoundHandleActive(_speechHandle);
+}
+
+void Sound::setSpeechVolume(uint volume) {
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, volume);
+}
+
+void Sound::stopAll() {
+ _mixer->stopAll();
+}
+
} // End of namespace Chewy
diff --git a/engines/chewy/sound.h b/engines/chewy/sound.h
index 7884eadb63..9b7acab59f 100644
--- a/engines/chewy/sound.h
+++ b/engines/chewy/sound.h
@@ -30,18 +30,43 @@ namespace Chewy {
class SoundResource;
+#define MAX_SOUND_EFFECTS 14
+
class Sound {
public:
Sound(Audio::Mixer *mixer);
virtual ~Sound();
- void playSound(int num, bool loop = false);
+ void playSound(int num, bool loop = false, uint channel = 0);
+ void playSound(byte *data, uint32 size, bool loop = false, uint channel = 0, DisposeAfterUse::Flag dispose = DisposeAfterUse::YES);
+ void pauseSound(uint channel);
+ void resumeSound(uint channel);
+ void stopSound(uint channel);
+ bool isSoundActive(uint channel);
+ void setSoundVolume(uint volume);
+ void setSoundChannelVolume(uint channel, uint volume);
+ void setSoundChannelBalance(uint channel, uint balance);
+
void playMusic(int num, bool loop = false);
+ void playMusic(byte *data, uint32 size, bool loop = false, DisposeAfterUse::Flag dispose = DisposeAfterUse::YES);
+ void pauseMusic();
+ void resumeMusic();
+ void stopMusic();
+ bool isMusicActive();
+ void setMusicVolume(uint volume);
+
void playSpeech(int num);
+ void pauseSpeech();
+ void resumeSpeech();
+ void stopSpeech();
+ bool isSpeechActive();
+ void setSpeechVolume(uint volume);
+
+ void stopAll();
private:
Audio::Mixer *_mixer;
- Audio::SoundHandle _soundHandle;
+ Audio::SoundHandle _soundHandle[MAX_SOUND_EFFECTS];
Audio::SoundHandle _musicHandle;
Audio::SoundHandle _speechHandle;
diff --git a/engines/chewy/video/cfo_decoder.cpp b/engines/chewy/video/cfo_decoder.cpp
index 94363dc1be..30f48d27cd 100644
--- a/engines/chewy/video/cfo_decoder.cpp
+++ b/engines/chewy/video/cfo_decoder.cpp
@@ -20,15 +20,12 @@
*
*/
-#include "audio/audiostream.h"
-#include "audio/mixer.h"
-#include "audio/decoders/raw.h"
#include "common/events.h"
-#include "common/stream.h"
#include "common/system.h"
#include "engines/engine.h"
#include "video/flic_decoder.h"
+#include "chewy/sound.h"
#include "chewy/video/cfo_decoder.h"
namespace Chewy {
@@ -70,12 +67,12 @@ bool CfoDecoder::loadStream(Common::SeekableReadStream *stream) {
uint16 width = stream->readUint16LE();
uint16 height = stream->readUint16LE();
- addTrack(new CfoVideoTrack(stream, frameCount, width, height, _mixer));
+ addTrack(new CfoVideoTrack(stream, frameCount, width, height, _sound));
return true;
}
-CfoDecoder::CfoVideoTrack::CfoVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, Audio::Mixer *mixer) :
- Video::FlicDecoder::FlicVideoTrack(stream, frameCount, width, height, true) {
+CfoDecoder::CfoVideoTrack::CfoVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, Sound *sound) :
+ Video::FlicDecoder::FlicVideoTrack(stream, frameCount, width, height, true), _sound(sound) {
readHeader();
for (int i = 0; i < MAX_SOUND_EFFECTS; i++) {
@@ -83,15 +80,18 @@ CfoDecoder::CfoVideoTrack::CfoVideoTrack(Common::SeekableReadStream *stream, uin
_soundEffectSize[i] = 0;
}
- _mixer = mixer;
+ _musicData = nullptr;
+ _musicSize = 0;
}
CfoDecoder::CfoVideoTrack::~CfoVideoTrack() {
- _mixer->stopAll();
+ _sound->stopAll();
for (int i = 0; i < MAX_SOUND_EFFECTS; i++) {
delete[] _soundEffects[i];
}
+
+ delete[] _musicData;
}
void CfoDecoder::CfoVideoTrack::readHeader() {
@@ -105,7 +105,7 @@ void CfoDecoder::CfoVideoTrack::readHeader() {
#define FRAME_TYPE 0xF1FA
#define CUSTOM_FRAME_TYPE 0xFAF1
-const Graphics::Surface *CfoDecoder::CfoVideoTrack::decodeNextFrame() {
+const ::Graphics::Surface *CfoDecoder::CfoVideoTrack::decodeNextFrame() {
uint16 frameType;
// Read chunk
@@ -164,7 +164,7 @@ void CfoDecoder::CfoVideoTrack::handleFrame() {
/* PSTAMP - skip for now */
break;
default:
- error("FlicDecoder::decodeNextFrame(): unknown subchunk type (type = 0x%02X)", frameType);
+ error("CfoDecoder::decodeNextFrame(): unknown subchunk type (type = 0x%02X)", frameType);
break;
}
@@ -176,7 +176,6 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
uint16 chunkCount = _fileStream->readUint16LE();
uint16 delay, number, channel, volume, repeat, balance;
- Audio::AudioStream *stream;
// Read subchunks
for (uint32 i = 0; i < chunkCount; ++i) {
@@ -196,9 +195,9 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
break;
case kChunkLoadMusic:
// Used in videos 0, 18, 34, 71
- warning("kChunkLoadMusic");
- // TODO
- _fileStream->skip(frameSize);
+ _musicSize = frameSize;
+ _musicData = new byte[frameSize];
+ _fileStream->read(_musicData, frameSize);
break;
case kChunkLoadRaw:
error("Unused chunk kChunkLoadRaw found");
@@ -214,9 +213,7 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
break;
case kChunkPlayMusic:
// Used in videos 0, 18, 34, 71
- warning("kChunkPlayMusic");
- // TODO
- _fileStream->skip(frameSize);
+ _sound->playMusic(_musicData, _musicSize, false, DisposeAfterUse::NO);
break;
case kChunkPlaySeq:
error("Unused chunk kChunkPlaySeq found");
@@ -225,7 +222,11 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
error("Unused chunk kChunkPlayPattern found");
break;
case kChunkStopMusic:
- _mixer->stopHandle(_musicHandle);
+ _sound->stopMusic();
+
+ // Game videos do not restart music after stopping it
+ delete[] _musicData;
+ _musicSize = 0;
break;
case kChunkWaitMusicEnd:
do {
@@ -233,12 +234,11 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
while (g_system->getEventManager()->pollEvent(event)) {} // ignore events
g_system->updateScreen();
g_system->delayMillis(10);
- } while (_mixer->isSoundHandleActive(_musicHandle));
+ } while (_sound->isMusicActive());
break;
case kChunkSetMusicVolume:
volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
-
- _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, volume);
+ _sound->setMusicVolume(volume);
break;
case kChunkSetLoopMode:
error("Unused chunk kChunkSetLoopMode found");
@@ -252,28 +252,19 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
repeat = _fileStream->readUint16LE();
assert(number < MAX_SOUND_EFFECTS);
- assert(channel < MAX_SOUND_EFFECTS);
-
- stream = Audio::makeLoopingAudioStream(
- Audio::makeRawStream(_soundEffects[number],
- _soundEffectSize[number], 22050, Audio::FLAG_UNSIGNED,
- DisposeAfterUse::NO),
- (repeat == 0) ? 1 : repeat);
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
- _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle[channel], stream);
+ _sound->setSoundVolume(volume);
+ _sound->playSound(_soundEffects[number], _soundEffectSize[number], repeat, channel, DisposeAfterUse::NO);
break;
case kChunkSetSoundVolume:
volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
-
- _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, volume);
+ _sound->setSoundVolume(volume);
break;
case kChunkSetChannelVolume:
channel = _fileStream->readUint16LE();
volume = _fileStream->readUint16LE() * Audio::Mixer::kMaxChannelVolume / 63;
- assert(channel < MAX_SOUND_EFFECTS);
- _mixer->setChannelVolume(_soundHandle[channel], volume);
+ _sound->setSoundChannelVolume(channel, volume);
break;
case kChunkFreeSoundEffect:
number = _fileStream->readUint16LE();
@@ -294,9 +285,7 @@ void CfoDecoder::CfoVideoTrack::handleCustomFrame() {
case kChunkSetBalance:
channel = _fileStream->readUint16LE();
balance = (_fileStream->readUint16LE() * 2) - 127;
- assert(channel < MAX_SOUND_EFFECTS);
-
- _mixer->setChannelBalance(_soundHandle[channel], balance);
+ _sound->setSoundChannelBalance(channel, balance);
break;
case kChunkSetSpeed:
error("Unused chunk kChunkSetSpeed found");
diff --git a/engines/chewy/video/cfo_decoder.h b/engines/chewy/video/cfo_decoder.h
index b15b00e0b2..26b97ec4ff 100644
--- a/engines/chewy/video/cfo_decoder.h
+++ b/engines/chewy/video/cfo_decoder.h
@@ -23,7 +23,6 @@
#ifndef CHEWY_VIDEO_CFO_DECODER_H
#define CHEWY_VIDEO_CFO_DECODER_H
-#include "audio/mixer.h"
#include "graphics/surface.h"
#include "video/flic_decoder.h"
@@ -31,20 +30,22 @@ namespace Chewy {
#define MAX_SOUND_EFFECTS 14
+class Sound;
+
// A FLIC decoder, with a modified header and additional custom frames
class CfoDecoder : public Video::FlicDecoder {
public:
- CfoDecoder(Audio::Mixer *mixer) : Video::FlicDecoder() { _mixer = mixer; }
+ CfoDecoder(Sound *sound) : Video::FlicDecoder(), _sound(sound) {}
virtual ~CfoDecoder() {}
bool loadStream(Common::SeekableReadStream *stream);
private:
- Audio::Mixer *_mixer;
+ Sound *_sound;
class CfoVideoTrack : public Video::FlicDecoder::FlicVideoTrack {
public:
- CfoVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, Audio::Mixer *mixer);
+ CfoVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, Sound *sound);
virtual ~CfoVideoTrack();
void readHeader();
@@ -58,11 +59,12 @@ private:
void handleFrame();
void handleCustomFrame();
- Audio::Mixer *_mixer;
- Audio::SoundHandle _musicHandle;
- Audio::SoundHandle _soundHandle[MAX_SOUND_EFFECTS];
+ Sound *_sound;
+
byte *_soundEffects[MAX_SOUND_EFFECTS];
uint32 _soundEffectSize[MAX_SOUND_EFFECTS];
+ byte *_musicData;
+ uint32 _musicSize;
};
};