diff options
Diffstat (limited to 'engines/tinsel/sound.cpp')
-rw-r--r-- | engines/tinsel/sound.cpp | 132 |
1 files changed, 65 insertions, 67 deletions
diff --git a/engines/tinsel/sound.cpp b/engines/tinsel/sound.cpp index e052302cfd..cadc754de6 100644 --- a/engines/tinsel/sound.cpp +++ b/engines/tinsel/sound.cpp @@ -74,7 +74,7 @@ SoundManager::~SoundManager() { */ // playSample for DiscWorld 1 bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) { - // Floppy version has no sample file + // Floppy version has no sample file. if (!_vm->isCD()) return false; @@ -102,7 +102,7 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); // read the length of the sample - uint32 sampleLen = _sampleStream.readUint32(); + uint32 sampleLen = _sampleStream.readUint32LE(); if (_sampleStream.eos() || _sampleStream.err()) error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); @@ -177,6 +177,32 @@ bool SoundManager::playSample(int id, Audio::Mixer::SoundType type, Audio::Sound return true; } +void SoundManager::playDW1MacMusic(Common::File &s, uint32 length) { + // TODO: It's a bad idea to load the music track in a buffer. + // We should use a SubReadStream instead, and keep midi.dat open. + // However, the track lengths aren't that big (about 1-4MB), + // so this shouldn't be a major issue. + byte *soundData = (byte *)malloc(length); + assert(soundData); + + // read all of the sample + if (s.read(soundData, length) != length) + error(FILE_IS_CORRUPT, MIDI_FILE); + + Common::SeekableReadStream *memStream = new Common::MemoryReadStream(soundData, length); + + Audio::SoundHandle *handle = &_channels[kChannelDW1MacMusic].handle; + + // Stop any previously playing music track + _vm->_mixer->stopHandle(*handle); + + // TODO: Compression support (MP3/OGG/FLAC) for midi.dat in DW1 Mac + Audio::RewindableAudioStream *musicStream = Audio::makeRawStream(memStream, 22050, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES); + + if (musicStream) + _vm->_mixer->playStream(Audio::Mixer::kMusicSoundType, handle, Audio::makeLoopingAudioStream(musicStream, 0)); +} + // playSample for DiscWorld 2 bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int priority, Audio::Mixer::SoundType type, Audio::SoundHandle *handle) { @@ -247,7 +273,7 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p uint32 dwSampleIndex = _sampleIndex[id]; if (dwSampleIndex == 0) { - warning("Tinsel2 playSample, non-existant sample %d", id); + warning("Tinsel2 playSample, non-existent sample %d", id); return false; } @@ -257,7 +283,7 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); // read the length of the sample - uint32 sampleLen = _sampleStream.readUint32(); + uint32 sampleLen = _sampleStream.readUint32LE(); if (_sampleStream.eos() || _sampleStream.err()) error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); @@ -270,12 +296,12 @@ bool SoundManager::playSample(int id, int sub, bool bLooped, int x, int y, int p // Skipping for (int32 i = 0; i < sub; i++) { - sampleLen = _sampleStream.readUint32(); + sampleLen = _sampleStream.readUint32LE(); _sampleStream.skip(sampleLen); if (_sampleStream.eos() || _sampleStream.err()) error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); } - sampleLen = _sampleStream.readUint32(); + sampleLen = _sampleStream.readUint32LE(); if (_sampleStream.eos() || _sampleStream.err()) error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); } @@ -369,7 +395,6 @@ bool SoundManager::offscreenChecks(int x, int &y) { } int8 SoundManager::getPan(int x) { - if (x == -1) return 0; @@ -416,14 +441,13 @@ bool SoundManager::sampleExists(int id) { /** * Returns true if a sample is currently playing. */ -bool SoundManager::sampleIsPlaying(int id) { +bool SoundManager::sampleIsPlaying() { if (!TinselV2) return _vm->_mixer->isSoundHandleActive(_channels[kChannelTinsel1].handle); for (int i = 0; i < kNumChannels; i++) - if (_channels[i].sampleNum == id) - if (_vm->_mixer->isSoundHandleActive(_channels[i].handle)) - return true; + if (_vm->_mixer->isSoundHandleActive(_channels[i].handle)) + return true; return false; } @@ -432,8 +456,6 @@ bool SoundManager::sampleIsPlaying(int id) { * Stops any currently playing sample. */ void SoundManager::stopAllSamples() { - // stop currently playing sample - if (!TinselV2) { _vm->_mixer->stopHandle(_channels[kChannelTinsel1].handle); return; @@ -466,12 +488,21 @@ void SoundManager::setSFXVolumes(uint8 volume) { _vm->_mixer->setChannelVolume(_channels[i].handle, volume); } +void SoundManager::showSoundError(const char *errorMsg, const char *soundFile) { + Common::String msg; + msg = Common::String::format(errorMsg, soundFile); + GUI::MessageDialog dialog(msg, "OK"); + dialog.runModal(); + + error("%s", msg.c_str()); +} + /** * Opens and inits all sound sample files. */ void SoundManager::openSampleFiles() { // Floppy and demo versions have no sample files, except for the Discworld 2 demo - if (!_vm->isCD() || TinselV0) + if (!_vm->isCD()) return; TinselFile f; @@ -480,42 +511,26 @@ void SoundManager::openSampleFiles() { // already allocated return; - // open sample index file in binary mode + // Open sample index (*.idx) in binary mode if (f.open(_vm->getSampleIndex(g_sampleLanguage))) { - // get length of index file - f.seek(0, SEEK_END); // move to end of file - _sampleIndexLen = f.pos(); // get file pointer - f.seek(0, SEEK_SET); // back to beginning - + uint32 fileSize = f.size(); + _sampleIndex = (uint32 *)malloc(fileSize); if (_sampleIndex == NULL) { - // allocate a buffer for the indices - _sampleIndex = (uint32 *)malloc(_sampleIndexLen); - - // make sure memory allocated - if (_sampleIndex == NULL) { - // disable samples if cannot alloc buffer for indices - // TODO: Disabled sound if we can't load the sample index? - return; - } + showSoundError(NO_MEM, _vm->getSampleIndex(g_sampleLanguage)); + return; } - // load data - if (f.read(_sampleIndex, _sampleIndexLen) != (uint32)_sampleIndexLen) - // file must be corrupt if we get to here - error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); - - // close the file - f.close(); - - // convert file size to size in DWORDs - _sampleIndexLen /= sizeof(uint32); + _sampleIndexLen = fileSize / 4; // total sample of indices (DWORDs) -#ifdef SCUMM_BIG_ENDIAN - // Convert all ids from LE to native format + // Load data for (int i = 0; i < _sampleIndexLen; ++i) { - _sampleIndex[i] = SWAP_BYTES_32(_sampleIndex[i]); + _sampleIndex[i] = f.readUint32LE(); + if (f.err()) { + showSoundError(FILE_READ_ERROR, _vm->getSampleIndex(g_sampleLanguage)); + } } -#endif + + f.close(); // Detect format of soundfile by looking at 1st sample-index switch (TO_BE_32(_sampleIndex[0])) { @@ -523,48 +538,31 @@ void SoundManager::openSampleFiles() { debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected MP3 sound-data"); _soundMode = kMP3Mode; break; - case MKTAG('O','G','G',' '): debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected OGG sound-data"); _soundMode = kVorbisMode; break; - case MKTAG('F','L','A','C'): debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected FLAC sound-data"); _soundMode = kFLACMode; break; - default: debugC(DEBUG_DETAILED, kTinselDebugSound, "Detected original sound-data"); break; } - // Normally the 1st sample-index points to nothing at all + + // Normally the 1st sample index points to nothing at all. We use it to + // determine if the game's sample files have been compressed, thus restore + // it here _sampleIndex[0] = 0; } else { - char buf[50]; - sprintf(buf, CANNOT_FIND_FILE, _vm->getSampleIndex(g_sampleLanguage)); - GUI::MessageDialog dialog(buf, "OK"); - dialog.runModal(); - - error(CANNOT_FIND_FILE, _vm->getSampleIndex(g_sampleLanguage)); + showSoundError(FILE_READ_ERROR, _vm->getSampleIndex(g_sampleLanguage)); } - // open sample file in binary mode + // Open sample file (*.smp) in binary mode if (!_sampleStream.open(_vm->getSampleFile(g_sampleLanguage))) { - char buf[50]; - sprintf(buf, CANNOT_FIND_FILE, _vm->getSampleFile(g_sampleLanguage)); - GUI::MessageDialog dialog(buf, "OK"); - dialog.runModal(); - - error(CANNOT_FIND_FILE, _vm->getSampleFile(g_sampleLanguage)); + showSoundError(FILE_READ_ERROR, _vm->getSampleFile(g_sampleLanguage)); } - -/* - // gen length of the largest sample - sampleBuffer.size = _sampleStream.readUint32LE(); - if (_sampleStream.eos() || _sampleStream.err()) - error(FILE_IS_CORRUPT, _vm->getSampleFile(g_sampleLanguage)); -*/ } void SoundManager::closeSampleStream() { |