Reorganized the sound code a bit and fixed bug # 1404414 (Missing speech patterns).

svn-id: r20006
This commit is contained in:
Johannes Schickel 2006-01-13 23:06:04 +00:00
parent d04475121e
commit d2de796c31
8 changed files with 207 additions and 79 deletions

View file

@ -96,11 +96,19 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
return 1; return 1;
if (_itemInHand != -1) { if (_itemInHand != -1) {
assert(_putDownFirst); assert(_putDownFirst);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2000);
}
characterSays(_putDownFirst[0], 0, -2); characterSays(_putDownFirst[0], 0, -2);
return 1; return 1;
} }
if (queryGameFlag(0xF1)) { if (queryGameFlag(0xF1)) {
assert(_waitForAmulet); assert(_waitForAmulet);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2001);
}
characterSays(_waitForAmulet[0], 0, -2); characterSays(_waitForAmulet[0], 0, -2);
return 1; return 1;
} }
@ -108,6 +116,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
assert(_blackJewel); assert(_blackJewel);
makeBrandonFaceMouse(); makeBrandonFaceMouse();
drawJewelPress(jewel, 1); drawJewelPress(jewel, 1);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2002);
}
characterSays(_blackJewel[0], 0, -2); characterSays(_blackJewel[0], 0, -2);
return 1; return 1;
} }
@ -135,6 +147,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
} else if (_brandonStatusBit == 0) { } else if (_brandonStatusBit == 0) {
seq_brandonHealing(); seq_brandonHealing();
assert(_healingTip); assert(_healingTip);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2003);
}
characterSays(_healingTip[0], 0, -2); characterSays(_healingTip[0], 0, -2);
} }
break; break;
@ -146,6 +162,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
case 2: case 2:
if (_brandonStatusBit & 1) { if (_brandonStatusBit & 1) {
assert(_wispJewelStrings); assert(_wispJewelStrings);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2004);
}
characterSays(_wispJewelStrings[0], 0, -2); characterSays(_wispJewelStrings[0], 0, -2);
} else { } else {
if (_brandonStatusBit & 2) { if (_brandonStatusBit & 2) {
@ -170,6 +190,10 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
case 3: case 3:
seq_dispelMagicAnimation(); seq_dispelMagicAnimation();
assert(_magicJewelString); assert(_magicJewelString);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2007);
}
characterSays(_magicJewelString[0], 0, -2); characterSays(_magicJewelString[0], 0, -2);
break; break;

View file

@ -34,8 +34,6 @@
#include "sound/mixer.h" #include "sound/mixer.h"
#include "sound/mididrv.h" #include "sound/mididrv.h"
#include "sound/voc.h"
#include "sound/audiostream.h"
#include "gui/message.h" #include "gui/message.h"
@ -264,7 +262,6 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *system)
} }
int KyraEngine::init(GameDetector &detector) { int KyraEngine::init(GameDetector &detector) {
_currentVocFile = 0;
_system->beginGFXTransaction(); _system->beginGFXTransaction();
initCommonGFX(detector); initCommonGFX(detector);
_system->initSize(320, 200); _system->initSize(320, 200);
@ -282,10 +279,10 @@ int KyraEngine::init(GameDetector &detector) {
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
} }
_midi = new MusicPlayer(driver, this); _sound = new SoundPC(driver, _mixer, this);
assert(_midi); assert(_sound);
_midi->hasNativeMT32(native_mt32); static_cast<SoundPC*>(_sound)->hasNativeMT32(native_mt32);
_midi->setVolume(255); _sound->setVolume(255);
_saveFileMan = _system->getSavefileManager(); _saveFileMan = _system->getSavefileManager();
assert(_saveFileMan); assert(_saveFileMan);
@ -431,7 +428,7 @@ KyraEngine::~KyraEngine() {
delete _animator; delete _animator;
delete _screen; delete _screen;
delete _res; delete _res;
delete _midi; delete _sound;
delete _saveFileMan; delete _saveFileMan;
delete _seq; delete _seq;
delete _scriptInterpreter; delete _scriptInterpreter;
@ -869,7 +866,7 @@ void KyraEngine::seq_demo() {
_screen->fadeFromBlack(); _screen->fadeFromBlack();
waitTicks(60); waitTicks(60);
_screen->fadeToBlack(); _screen->fadeToBlack();
_midi->stopMusic(); _sound->stopMusic();
} }
void KyraEngine::seq_intro() { void KyraEngine::seq_intro() {
@ -897,7 +894,7 @@ void KyraEngine::seq_intro() {
_text->setTalkCoords(136); _text->setTalkCoords(136);
waitTicks(30); waitTicks(30);
_seq->setCopyViewOffs(false); _seq->setCopyViewOffs(false);
_midi->stopMusic(); _sound->stopMusic();
if (_features & GF_TALKIE) { if (_features & GF_TALKIE) {
_res->unloadPakFile("INTRO.VRM"); _res->unloadPakFile("INTRO.VRM");
} }
@ -1107,7 +1104,15 @@ void KyraEngine::seq_brandonHealing2() {
freeShapes123(); freeShapes123();
_screen->showMouse(); _screen->showMouse();
assert(_poisonGone); assert(_poisonGone);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2010);
}
characterSays(_poisonGone[0], 0, -2); characterSays(_poisonGone[0], 0, -2);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(2011);
}
characterSays(_poisonGone[1], 0, -2); characterSays(_poisonGone[1], 0, -2);
} }
@ -1121,13 +1126,29 @@ void KyraEngine::seq_poisonDeathNow(int now) {
if (_poisonDeathCounter >= 2) { if (_poisonDeathCounter >= 2) {
snd_playWanderScoreViaMap(1, 1); snd_playWanderScoreViaMap(1, 1);
assert(_thePoison); assert(_thePoison);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(7000);
}
characterSays(_thePoison[0], 0, -2); characterSays(_thePoison[0], 0, -2);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(7001);
}
characterSays(_thePoison[1], 0, -2); characterSays(_thePoison[1], 0, -2);
seq_poisonDeathNowAnim(); seq_poisonDeathNowAnim();
_deathHandler = 3; _deathHandler = 3;
} else { } else {
assert(_thePoison); assert(_thePoison);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(7002);
}
characterSays(_thePoison[2], 0, -2); characterSays(_thePoison[2], 0, -2);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(7004);
}
characterSays(_thePoison[3], 0, -2); characterSays(_thePoison[3], 0, -2);
} }
} }
@ -1190,10 +1211,11 @@ void KyraEngine::seq_playFluteAnimation() {
snd_playSoundEffect(0x63); snd_playSoundEffect(0x63);
delayTime = 9; delayTime = 9;
soundType = 3; soundType = 3;
} else if (queryGameFlag(0x86)) { } else if (!queryGameFlag(0x86)) {
snd_playSoundEffect(0x61); snd_playSoundEffect(0x61);
delayTime = 2; delayTime = 2;
soundType = 1; soundType = 1;
setGameFlag(0x86);
} else { } else {
snd_playSoundEffect(0x62); snd_playSoundEffect(0x62);
delayTime = 2; delayTime = 2;
@ -1219,9 +1241,17 @@ void KyraEngine::seq_playFluteAnimation() {
if (soundType == 1) { if (soundType == 1) {
assert(_fluteString); assert(_fluteString);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(1000);
}
characterSays(_fluteString[0], 0, -2); characterSays(_fluteString[0], 0, -2);
} else if (soundType == 2) { } else if (soundType == 2) {
assert(_fluteString); assert(_fluteString);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(1001);
}
characterSays(_fluteString[1], 0, -2); characterSays(_fluteString[1], 0, -2);
} }
} }
@ -1481,6 +1511,10 @@ void KyraEngine::seq_fillFlaskWithWater(int item, int type) {
if (item >= 60 && item <= 77) { if (item >= 60 && item <= 77) {
assert(_flaskFull); assert(_flaskFull);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
snd_playVoiceFile(8006);
}
characterSays(_flaskFull[0], 0, -2); characterSays(_flaskFull[0], 0, -2);
} else if (item == 78) { } else if (item == 78) {
assert(type >= 0 && type < ARRAYSIZE(flaskTable1)); assert(type >= 0 && type < ARRAYSIZE(flaskTable1));
@ -1499,6 +1533,14 @@ void KyraEngine::seq_fillFlaskWithWater(int item, int type) {
_itemInHand = newItem; _itemInHand = newItem;
assert(_fullFlask); assert(_fullFlask);
assert(type < _fullFlask_Size && type >= 0); assert(type < _fullFlask_Size && type >= 0);
if (_features & GF_TALKIE) {
snd_voiceWaitForFinish();
static const uint16 voiceEntries[] = {
0x1F40, 0x1F41, 0x1F42, 0x1F45
};
assert(type < ARRAYSIZE(voiceEntries));
snd_playVoiceFile(voiceEntries[type]);
}
characterSays(_fullFlask[type], 0, -2); characterSays(_fullFlask[type], 0, -2);
} }
@ -1700,19 +1742,19 @@ void KyraEngine::snd_playTheme(int file, int track) {
debug(9, "KyraEngine::snd_playTheme(%d)", file); debug(9, "KyraEngine::snd_playTheme(%d)", file);
assert(file < _xmidiFilesCount); assert(file < _xmidiFilesCount);
_curMusicTheme = _newMusicTheme = file; _curMusicTheme = _newMusicTheme = file;
_midi->playMusic(_xmidiFiles[file]); _sound->playMusic(_xmidiFiles[file]);
_midi->playTrack(track, false); _sound->playTrack(track, false);
} }
void KyraEngine::snd_playTrack(int track, bool looping) { void KyraEngine::snd_playTrack(int track, bool looping) {
debug(9, "KyraEngine::snd_playTrack(%d, %d)", track, looping); debug(9, "KyraEngine::snd_playTrack(%d, %d)", track, looping);
_midi->playTrack(track, looping); _sound->playTrack(track, looping);
} }
void KyraEngine::snd_setSoundEffectFile(int file) { void KyraEngine::snd_setSoundEffectFile(int file) {
debug(9, "KyraEngine::snd_setSoundEffectFile(%d)", file); debug(9, "KyraEngine::snd_setSoundEffectFile(%d)", file);
assert(file < _xmidiFilesCount); assert(file < _xmidiFilesCount);
_midi->loadSoundEffectFile(_xmidiFiles[file]); _sound->loadSoundEffectFile(_xmidiFiles[file]);
} }
void KyraEngine::snd_playSoundEffect(int track) { void KyraEngine::snd_playSoundEffect(int track) {
@ -1720,7 +1762,7 @@ void KyraEngine::snd_playSoundEffect(int track) {
if (track == 49) { if (track == 49) {
snd_playWanderScoreViaMap(56, 1); snd_playWanderScoreViaMap(56, 1);
} else { } else {
_midi->playSoundEffect(track); _sound->playSoundEffect(track);
} }
} }
@ -1762,7 +1804,7 @@ void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) {
} }
} else { } else {
_lastMusicCommand = 1; _lastMusicCommand = 1;
_midi->beginFadeOut(); _sound->beginFadeOut();
} }
} }
@ -1771,31 +1813,32 @@ void KyraEngine::snd_playVoiceFile(int id) {
char vocFile[9]; char vocFile[9];
assert(id >= 0 && id < 9999); assert(id >= 0 && id < 9999);
sprintf(vocFile, "%03d.VOC", id); sprintf(vocFile, "%03d.VOC", id);
uint32 fileSize = 0; _sound->voicePlay(vocFile);
byte *fileData = 0;
fileData = _res->fileData(vocFile, &fileSize);
assert(fileData);
Common::MemoryReadStream vocStream(fileData, fileSize);
_mixer->stopHandle(_vocHandle);
_currentVocFile = makeVOCStream(vocStream);
if (_currentVocFile)
_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile);
delete fileData;
fileSize = 0;
} }
bool KyraEngine::snd_voicePlaying() { bool KyraEngine::snd_voicePlaying() {
return _mixer->isSoundHandleActive(_vocHandle); return _sound->voiceIsPlaying();
}
void KyraEngine::snd_voiceWaitForFinish(bool ingame) {
debug(9, "KyraEngine::snd_voiceWaitForFinish(%d)", ingame);
while (snd_voicePlaying() && !_fastMode) {
if (ingame) {
delay(10, true);
} else {
waitTicks(10);
}
}
} }
void KyraEngine::snd_startTrack() { void KyraEngine::snd_startTrack() {
debug(9, "KyraEngine::snd_startTrack()"); debug(9, "KyraEngine::snd_startTrack()");
_midi->startTrack(); _sound->startTrack();
} }
void KyraEngine::snd_haltTrack() { void KyraEngine::snd_haltTrack() {
debug(9, "KyraEngine::snd_haltTrack()"); debug(9, "KyraEngine::snd_haltTrack()");
_midi->haltTrack(); _sound->haltTrack();
} }
void KyraEngine::loadMouseShapes() { void KyraEngine::loadMouseShapes() {

View file

@ -118,7 +118,7 @@ struct BeadState {
class Movie; class Movie;
class MusicPlayer; class Sound;
class SeqPlayer; class SeqPlayer;
class Resource; class Resource;
class PAKFile; class PAKFile;
@ -186,7 +186,7 @@ public:
Screen *screen() { return _screen; } Screen *screen() { return _screen; }
ScreenAnimator *animator() { return _animator; } ScreenAnimator *animator() { return _animator; }
TextDisplayer *text() { return _text; } TextDisplayer *text() { return _text; }
MusicPlayer *midi() { return _midi; } Sound *sound() { return _sound; }
uint32 tickLength() const { return _tickLength; } uint32 tickLength() const { return _tickLength; }
Movie *createWSAMovie(); Movie *createWSAMovie();
@ -218,6 +218,7 @@ public:
void snd_playTrack(int track, bool looping = false); void snd_playTrack(int track, bool looping = false);
void snd_playVoiceFile(int id); void snd_playVoiceFile(int id);
bool snd_voicePlaying(); bool snd_voicePlaying();
void snd_voiceWaitForFinish(bool ingame = true);
void snd_playSoundEffect(int track); void snd_playSoundEffect(int track);
void snd_playWanderScoreViaMap(int command, int restart); void snd_playWanderScoreViaMap(int command, int restart);
@ -715,13 +716,11 @@ protected:
int _curMusicTheme; int _curMusicTheme;
int _newMusicTheme; int _newMusicTheme;
int16 _lastMusicCommand; int16 _lastMusicCommand;
AudioStream *_currentVocFile;
Audio::SoundHandle _vocHandle;
Resource *_res; Resource *_res;
Screen *_screen; Screen *_screen;
ScreenAnimator *_animator; ScreenAnimator *_animator;
MusicPlayer *_midi; Sound *_sound;
SeqPlayer *_seq; SeqPlayer *_seq;
Sprites *_sprites; Sprites *_sprites;
TextDisplayer *_text; TextDisplayer *_text;

View file

@ -50,9 +50,7 @@ int KyraEngine::cmd_characterSays(ScriptState *script) {
if (_features & GF_TALKIE) { if (_features & GF_TALKIE) {
debug(3, "cmd_characterSays(0x%X) (%d, '%s', %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); debug(3, "cmd_characterSays(0x%X) (%d, '%s', %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3));
while (snd_voicePlaying() && !_fastMode) { snd_voiceWaitForFinish();
delay(10);
}
snd_playVoiceFile(stackPos(0)); snd_playVoiceFile(stackPos(0));
characterSays(stackPosString(1), stackPos(2), stackPos(3)); characterSays(stackPosString(1), stackPos(2), stackPos(3));
} else { } else {
@ -614,9 +612,7 @@ int KyraEngine::cmd_loadPageFromDisk(ScriptState *script) {
int KyraEngine::cmd_customPrintTalkString(ScriptState *script) { int KyraEngine::cmd_customPrintTalkString(ScriptState *script) {
if (_features & GF_TALKIE) { if (_features & GF_TALKIE) {
debug(3, "cmd_customPrintTalkString(0x%X) (%d, '%s', %d, %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); debug(3, "cmd_customPrintTalkString(0x%X) (%d, '%s', %d, %d, %d)", script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF);
while (snd_voicePlaying() && !_fastMode) { snd_voiceWaitForFinish();
delay(10);
}
snd_playVoiceFile(stackPos(0)); snd_playVoiceFile(stackPos(0));
_text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2); _text->printTalkTextMessage(stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF, 0, 2);
} else { } else {

View file

@ -42,7 +42,7 @@ SeqPlayer::SeqPlayer(KyraEngine* vm, OSystem* system) {
_system = system; _system = system;
_screen = vm->screen(); _screen = vm->screen();
_midi = vm->midi(); _sound = vm->sound();
_res = vm->resource(); _res = vm->resource();
_copyViewOffs = false; _copyViewOffs = false;
@ -374,7 +374,7 @@ void SeqPlayer::s1_fillRect() {
void SeqPlayer::s1_playEffect() { void SeqPlayer::s1_playEffect() {
uint8 track = *_seqData++; uint8 track = *_seqData++;
_vm->waitTicks(3); _vm->waitTicks(3);
_midi->playSoundEffect(track); _sound->playSoundEffect(track);
} }
void SeqPlayer::s1_playTrack() { void SeqPlayer::s1_playTrack() {
@ -387,7 +387,7 @@ void SeqPlayer::s1_playTrack() {
// nothing to do here... // nothing to do here...
break; break;
case 1: case 1:
_midi->beginFadeOut(); _sound->beginFadeOut();
break; break;
case 56: case 56:
_vm->snd_playTheme(KyraEngine::MUSIC_INTRO, 3); _vm->snd_playTheme(KyraEngine::MUSIC_INTRO, 3);
@ -406,7 +406,7 @@ void SeqPlayer::s1_playTrack() {
if (msg == 0) { if (msg == 0) {
// nothing to do here... // nothing to do here...
} else if (msg == 1) { } else if (msg == 1) {
_midi->beginFadeOut(); _sound->beginFadeOut();
} else { } else {
_vm->snd_playTrack(msg); _vm->snd_playTrack(msg);
} }
@ -445,9 +445,7 @@ void SeqPlayer::s1_loadIntroVRM() {
} }
void SeqPlayer::s1_playVocFile() { void SeqPlayer::s1_playVocFile() {
while (_vm->snd_voicePlaying()) { _vm->snd_voiceWaitForFinish(false);
_system->delayMillis(10);
}
uint8 a = *_seqData++; uint8 a = *_seqData++;
_vm->snd_playVoiceFile(a); _vm->snd_playVoiceFile(a);
} }

View file

@ -44,7 +44,7 @@ protected:
KyraEngine *_vm; KyraEngine *_vm;
OSystem *_system; OSystem *_system;
Screen *_screen; Screen *_screen;
MusicPlayer *_midi; Sound *_sound;
Resource *_res; Resource *_res;
uint8 *_handShapes[3]; uint8 *_handShapes[3];

View file

@ -24,9 +24,13 @@
#include "kyra/resource.h" #include "kyra/resource.h"
#include "kyra/sound.h" #include "kyra/sound.h"
#include "sound/mixer.h"
#include "sound/voc.h"
#include "sound/audiostream.h"
namespace Kyra { namespace Kyra {
MusicPlayer::MusicPlayer(MidiDriver *driver, KyraEngine *engine) { SoundPC::SoundPC(MidiDriver *driver, Audio::Mixer *mixer, KyraEngine *engine) : Sound() {
_engine = engine; _engine = engine;
_driver = driver; _driver = driver;
_passThrough = false; _passThrough = false;
@ -49,14 +53,17 @@ MusicPlayer::MusicPlayer(MidiDriver *driver, KyraEngine *engine) {
if (ret != MERR_ALREADY_OPEN && ret != 0) { if (ret != MERR_ALREADY_OPEN && ret != 0) {
error("couldn't open midi driver"); error("couldn't open midi driver");
} }
_currentVocFile = 0;
_mixer = mixer;
} }
MusicPlayer::~MusicPlayer() { SoundPC::~SoundPC() {
_driver->setTimerCallback(NULL, NULL); _driver->setTimerCallback(NULL, NULL);
close(); close();
} }
void MusicPlayer::setVolume(int volume) { void SoundPC::setVolume(int volume) {
if (volume < 0) if (volume < 0)
volume = 0; volume = 0;
else if (volume > 255) else if (volume > 255)
@ -77,7 +84,7 @@ void MusicPlayer::setVolume(int volume) {
} }
} }
int MusicPlayer::open() { int SoundPC::open() {
// Don't ever call open without first setting the output driver! // Don't ever call open without first setting the output driver!
if (!_driver) if (!_driver)
return 255; return 255;
@ -90,13 +97,13 @@ int MusicPlayer::open() {
return 0; return 0;
} }
void MusicPlayer::close() { void SoundPC::close() {
if (_driver) if (_driver)
_driver->close(); _driver->close();
_driver = 0; _driver = 0;
} }
void MusicPlayer::send(uint32 b) { void SoundPC::send(uint32 b) {
if (_passThrough) { if (_passThrough) {
if ((b & 0xFFF0) == 0x007BB0) if ((b & 0xFFF0) == 0x007BB0)
return; return;
@ -140,7 +147,7 @@ void MusicPlayer::send(uint32 b) {
_channel[_virChannel[channel]]->send(b); _channel[_virChannel[channel]]->send(b);
} }
void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) { void SoundPC::metaEvent(byte type, byte *data, uint16 length) {
switch (type) { switch (type) {
case 0x2F: // End of Track case 0x2F: // End of Track
if (_eventFromMusic) { if (_eventFromMusic) {
@ -161,7 +168,7 @@ void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
} }
} }
void MusicPlayer::playMusic(const char *file) { void SoundPC::playMusic(const char *file) {
uint32 size; uint32 size;
uint8 *data = (_engine->resource())->fileData(file, &size); uint8 *data = (_engine->resource())->fileData(file, &size);
@ -173,7 +180,7 @@ void MusicPlayer::playMusic(const char *file) {
playMusic(data, size); playMusic(data, size);
} }
void MusicPlayer::playMusic(uint8 *data, uint32 size) { void SoundPC::playMusic(uint8 *data, uint32 size) {
stopMusic(); stopMusic();
_parserSource = data; _parserSource = data;
@ -193,7 +200,7 @@ void MusicPlayer::playMusic(uint8 *data, uint32 size) {
_parser->property(MidiParser::mpAutoLoop, false); _parser->property(MidiParser::mpAutoLoop, false);
} }
void MusicPlayer::loadSoundEffectFile(const char *file) { void SoundPC::loadSoundEffectFile(const char *file) {
uint32 size; uint32 size;
uint8 *data = (_engine->resource())->fileData(file, &size); uint8 *data = (_engine->resource())->fileData(file, &size);
@ -205,7 +212,7 @@ void MusicPlayer::loadSoundEffectFile(const char *file) {
loadSoundEffectFile(data, size); loadSoundEffectFile(data, size);
} }
void MusicPlayer::loadSoundEffectFile(uint8 *data, uint32 size) { void SoundPC::loadSoundEffectFile(uint8 *data, uint32 size) {
stopSoundEffect(); stopSoundEffect();
_soundEffectSource = data; _soundEffectSource = data;
@ -225,7 +232,7 @@ void MusicPlayer::loadSoundEffectFile(uint8 *data, uint32 size) {
_soundEffect->property(MidiParser::mpAutoLoop, false); _soundEffect->property(MidiParser::mpAutoLoop, false);
} }
void MusicPlayer::stopMusic() { void SoundPC::stopMusic() {
_isLooping = false; _isLooping = false;
_isPlaying = false; _isPlaying = false;
if (_parser) { if (_parser) {
@ -241,7 +248,7 @@ void MusicPlayer::stopMusic() {
} }
} }
void MusicPlayer::stopSoundEffect() { void SoundPC::stopSoundEffect() {
_sfxIsPlaying = false; _sfxIsPlaying = false;
if (_soundEffect) { if (_soundEffect) {
_soundEffect->unloadMusic(); _soundEffect->unloadMusic();
@ -252,8 +259,8 @@ void MusicPlayer::stopSoundEffect() {
} }
} }
void MusicPlayer::onTimer(void *refCon) { void SoundPC::onTimer(void *refCon) {
MusicPlayer *music = (MusicPlayer *)refCon; SoundPC *music = (SoundPC *)refCon;
// this should be set to the fadeToBlack value // this should be set to the fadeToBlack value
static const uint32 musicFadeTime = 2 * 1000; static const uint32 musicFadeTime = 2 * 1000;
@ -295,7 +302,7 @@ void MusicPlayer::onTimer(void *refCon) {
} }
} }
void MusicPlayer::playTrack(uint8 track, bool loop) { void SoundPC::playTrack(uint8 track, bool loop) {
if (_parser) { if (_parser) {
_isPlaying = true; _isPlaying = true;
_isLooping = loop; _isLooping = loop;
@ -306,7 +313,7 @@ void MusicPlayer::playTrack(uint8 track, bool loop) {
} }
} }
void MusicPlayer::playSoundEffect(uint8 track) { void SoundPC::playSoundEffect(uint8 track) {
if (_soundEffect) { if (_soundEffect) {
_sfxIsPlaying = true; _sfxIsPlaying = true;
_soundEffect->setTrack(track); _soundEffect->setTrack(track);
@ -315,10 +322,27 @@ void MusicPlayer::playSoundEffect(uint8 track) {
} }
} }
void MusicPlayer::beginFadeOut() { void SoundPC::beginFadeOut() {
// this should be something like fade out... // this should be something like fade out...
_fadeMusicOut = true; _fadeMusicOut = true;
_fadeStartTime = _engine->_system->getMillis(); _fadeStartTime = _engine->_system->getMillis();
} }
void SoundPC::voicePlay(const char *file) {
uint32 fileSize = 0;
byte *fileData = 0;
fileData = _engine->resource()->fileData(file, &fileSize);
assert(fileData);
Common::MemoryReadStream vocStream(fileData, fileSize);
_mixer->stopHandle(_vocHandle);
_currentVocFile = makeVOCStream(vocStream);
if (_currentVocFile)
_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile);
delete fileData;
fileSize = 0;
}
bool SoundPC::voiceIsPlaying() {
return _mixer->isSoundHandleActive(_vocHandle);
}
} // end of namespace Kyra } // end of namespace Kyra

View file

@ -28,13 +28,50 @@
#include "sound/midiparser.h" #include "sound/midiparser.h"
#include "kyra/kyra.h" #include "kyra/kyra.h"
class AudioStream;
namespace Audio {
class Mixer;
class SoundHandle;
} // end of namespace Audio
namespace Kyra { namespace Kyra {
class MusicPlayer : public MidiDriver { class Sound {
public:
Sound() {}
virtual ~Sound() {}
virtual void setVolume(int volume) = 0;
virtual int getVolume() = 0;
virtual void playMusic(const char *file) = 0;
virtual void playMusic(uint8 *data, uint32 size) = 0;
virtual void stopMusic() = 0;
virtual void playTrack(uint8 track, bool looping = true) = 0;
virtual void haltTrack() = 0;
virtual void startTrack() = 0;
virtual void loadSoundEffectFile(const char *file) = 0;
virtual void loadSoundEffectFile(uint8 *data, uint32 size) = 0;
virtual void stopSoundEffect() = 0;
virtual void playSoundEffect(uint8 track) = 0;
virtual void beginFadeOut() = 0;
virtual bool fadeOut() = 0;
virtual void voicePlay(const char *file) = 0;
virtual void voiceUnload() = 0;
virtual bool voiceIsPlaying() = 0;
};
class SoundPC : public MidiDriver, public Sound {
public: public:
MusicPlayer(MidiDriver *driver, KyraEngine *engine); SoundPC(MidiDriver *driver, Audio::Mixer *mixer, KyraEngine *engine);
~MusicPlayer(); ~SoundPC();
void setVolume(int volume); void setVolume(int volume);
int getVolume() { return _volume; } int getVolume() { return _volume; }
@ -42,17 +79,17 @@ public:
void hasNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; } void hasNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; }
bool isMT32() { return _nativeMT32; } bool isMT32() { return _nativeMT32; }
void playMusic(const char* file); void playMusic(const char *file);
void playMusic(uint8* data, uint32 size); void playMusic(uint8 *data, uint32 size);
void stopMusic(); void stopMusic();
void playTrack(uint8 track, bool looping = true); void playTrack(uint8 track, bool looping);
void haltTrack() { _isPlaying = false; } void haltTrack() { _isPlaying = false; }
void startTrack() { _isPlaying = true; } void startTrack() { _isPlaying = true; }
void setPassThrough(bool b) { _passThrough = b; } void setPassThrough(bool b) { _passThrough = b; }
void loadSoundEffectFile(const char* file); void loadSoundEffectFile(const char *file);
void loadSoundEffectFile(uint8* data, uint32 size); void loadSoundEffectFile(uint8 *data, uint32 size);
void stopSoundEffect(); void stopSoundEffect();
void playSoundEffect(uint8 track); void playSoundEffect(uint8 track);
@ -60,6 +97,10 @@ public:
void beginFadeOut(); void beginFadeOut();
bool fadeOut() { return _fadeMusicOut; } bool fadeOut() { return _fadeMusicOut; }
void voicePlay(const char *file);
void voiceUnload() {};
bool voiceIsPlaying();
//MidiDriver interface implementation //MidiDriver interface implementation
int open(); int open();
void close(); void close();
@ -77,10 +118,10 @@ protected:
static void onTimer(void *data); static void onTimer(void *data);
MidiChannel* _channel[32]; MidiChannel *_channel[32];
int _virChannel[16]; int _virChannel[16];
uint8 _channelVolume[16]; uint8 _channelVolume[16];
MidiDriver* _driver; MidiDriver *_driver;
bool _nativeMT32; bool _nativeMT32;
bool _passThrough; bool _passThrough;
uint8 _volume; uint8 _volume;
@ -95,8 +136,11 @@ protected:
MidiParser *_soundEffect; MidiParser *_soundEffect;
byte *_soundEffectSource; byte *_soundEffectSource;
KyraEngine *_engine; KyraEngine *_engine;
};
Audio::Mixer *_mixer;
AudioStream *_currentVocFile;
Audio::SoundHandle _vocHandle;
};
} // end of namespace Kyra } // end of namespace Kyra
#endif #endif