diff options
author | David Corrales | 2007-08-05 19:34:20 +0000 |
---|---|---|
committer | David Corrales | 2007-08-05 19:34:20 +0000 |
commit | 6856535010bd2fa4449bcfde1c88dc06cd46e26f (patch) | |
tree | b81a2234c2beff0312c93e039d6cafda4babeca6 /engines/saga/music.cpp | |
parent | 1400d28bfb37fc94f3c44dec0a4d0cef65fb8fb7 (diff) | |
parent | ec1803f838d5efc7decf75c05a1fb4a9633751e5 (diff) | |
download | scummvm-rg350-6856535010bd2fa4449bcfde1c88dc06cd46e26f.tar.gz scummvm-rg350-6856535010bd2fa4449bcfde1c88dc06cd46e26f.tar.bz2 scummvm-rg350-6856535010bd2fa4449bcfde1c88dc06cd46e26f.zip |
Merged fsnode with trunk: r27971:28460
svn-id: r28462
Diffstat (limited to 'engines/saga/music.cpp')
-rw-r--r-- | engines/saga/music.cpp | 160 |
1 files changed, 87 insertions, 73 deletions
diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index 71b6964530..04e79c174d 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -22,6 +22,9 @@ * $Id$ * */ + +// MIDI and digital music class + #include "saga/saga.h" #include "saga/rscfile.h" @@ -38,14 +41,12 @@ namespace Saga { #define BUFFER_SIZE 4096 -// I haven't decided yet if it's a good idea to make looping part of the audio -// stream class, or if I should use a "wrapper" class, like I did for Broken -// Sword 2, to make it easier to add support for compressed music... but I'll -// worry about that later. - -class RAWInputStream : public Audio::AudioStream { +class DigitalMusicInputStream : public Audio::AudioStream { private: + Audio::AudioStream *_compressedStream; ResourceContext *_context; + ResourceData * resourceData; + GameSoundTypes soundType; Common::File *_file; uint32 _filePos; uint32 _startPos; @@ -56,6 +57,7 @@ private: const int16 *_bufferEnd; const int16 *_pos; const GameSoundInfo *_musicInfo; + Common::MemoryReadStream *_memoryStream; void refill(); bool eosIntern() const { @@ -63,7 +65,10 @@ private: } public: - RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart); + DigitalMusicInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart); + ~DigitalMusicInputStream(); + + void createCompressedStream(); int readBuffer(int16 *buffer, const int numSamples); @@ -72,17 +77,36 @@ public: int getRate() const { return _musicInfo->frequency; } }; -RAWInputStream::RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart) +DigitalMusicInputStream::DigitalMusicInputStream(SagaEngine *vm, ResourceContext *context, uint32 resourceId, bool looping, uint32 loopStart) : _context(context), _finished(false), _looping(looping), _bufferEnd(_buf + BUFFER_SIZE) { - ResourceData * resourceData; + byte compressedHeader[10]; resourceData = vm->_resource->getResourceData(context, resourceId); _file = context->getFile(resourceData); _musicInfo = vm->getMusicInfo(); if (_musicInfo == NULL) { - error("RAWInputStream() wrong musicInfo"); + error("DigitalMusicInputStream() wrong musicInfo"); + } + + _compressedStream = NULL; + + if (Common::File::exists("music.cmp")) { + // Read compressed header to determine compression type + _file->seek((long)resourceData->offset, SEEK_SET); + _file->read(compressedHeader, 9); + + if (compressedHeader[0] == char(0)) { + soundType = kSoundMP3; + } else if (compressedHeader[0] == char(1)) { + soundType = kSoundOGG; + } else if (compressedHeader[0] == char(2)) { + soundType = kSoundFLAC; + } + + createCompressedStream(); + resourceData->offset += 9; // Skip compressed header } // Determine the end position @@ -96,22 +120,59 @@ RAWInputStream::RAWInputStream(SagaEngine *vm, ResourceContext *context, uint32 refill(); } -int RAWInputStream::readBuffer(int16 *buffer, const int numSamples) { +DigitalMusicInputStream::~DigitalMusicInputStream() { + delete _compressedStream; +} + +void DigitalMusicInputStream::createCompressedStream() { + uint numLoops = _looping ? 0 : 1; + _memoryStream = _file->readStream(resourceData->size); + + switch (soundType) { +#ifdef USE_MAD + case kSoundMP3: + debug(1, "Playing MP3 compressed digital music"); + _compressedStream = Audio::makeMP3Stream(_memoryStream, true, 0, 0, numLoops); + break; +#endif +#ifdef USE_VORBIS + case kSoundOGG: + debug(1, "Playing OGG compressed digital music"); + _compressedStream = Audio::makeVorbisStream(_memoryStream, true, 0, 0, numLoops); + break; +#endif +#ifdef USE_FLAC + case kSoundFLAC: + debug(1, "Playing FLAC compressed digital music"); + _compressedStream = Audio::makeFlacStream(_memoryStream, true, 0, 0, numLoops); + break; +#endif + default: + // Unknown compression + error("Trying to play a compressed digital music, but the compression is not known"); + break; + } +} + +int DigitalMusicInputStream::readBuffer(int16 *buffer, const int numSamples) { + if (_compressedStream != NULL) + return _compressedStream->readBuffer(buffer, numSamples); + int samples = 0; while (samples < numSamples && !eosIntern()) { - const int len = MIN(numSamples - samples, (int) (_bufferEnd - _pos)); + int len = 0; + len = MIN(numSamples - samples, (int) (_bufferEnd - _pos)); memcpy(buffer, _pos, len * 2); buffer += len; _pos += len; samples += len; - if (_pos >= _bufferEnd) { + if (_pos >= _bufferEnd) refill(); - } } return samples; } -void RAWInputStream::refill() { +void DigitalMusicInputStream::refill() { if (_finished) return; @@ -282,7 +343,7 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver, int enable xmidiParser = MidiParser::createParser_XMIDI(); smfParser = MidiParser::createParser_SMF(); - _musicContext = _vm->_resource->getContext(GAME_MUSICFILE); + _digitalMusicContext = _vm->_resource->getContext(GAME_MUSICFILE); _songTableLen = 0; _songTable = 0; @@ -373,6 +434,10 @@ void Music::play(uint32 resourceId, MusicFlags flags) { _player->stopMusic(); _mixer->stopHandle(_musicHandle); + if (!_vm->_musicVolume) { + return; + } + int realTrackNumber; if (_vm->getGameType() == GType_ITE) { @@ -405,7 +470,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) { if (_vm->getGameType() == GType_ITE) { if (resourceId >= 9 && resourceId <= 34) { - if (_musicContext != NULL) { + if (_digitalMusicContext != NULL) { //TODO: check resource size loopStart = 0; // fix ITE sunstatm score @@ -413,61 +478,8 @@ void Music::play(uint32 resourceId, MusicFlags flags) { loopStart = 4 * 18727; } - if (!(_vm->getFeatures() & GF_COMPRESSED_SOUNDS)) { - // uncompressed digital music - audioStream = new RAWInputStream(_vm, _musicContext, resourceId - 9, flags == MUSIC_LOOP, loopStart); - } else { - // compressed digital music - ResourceData * musicResourceData; - Common::File *_file; - byte compressedHeader[10]; - GameSoundTypes soundType; - - musicResourceData = _vm->_resource->getResourceData(_musicContext, resourceId - 9); - _file = _musicContext->getFile(musicResourceData); - - if (_vm->getMusicInfo() == NULL) { - error("RAWInputStream() wrong musicInfo"); - } - - _file->seek((long)musicResourceData->offset, SEEK_SET); - - _file->read(compressedHeader, 9); - - if (compressedHeader[0] == char(0)) { - soundType = kSoundMP3; - } else if (compressedHeader[0] == char(1)) { - soundType = kSoundOGG; - } else if (compressedHeader[0] == char(2)) { - soundType = kSoundFLAC; - } - - switch (soundType) { -#ifdef USE_MAD - case kSoundMP3: - debug(1, "Playing MP3 compressed digital music"); - audioStream = Audio::makeMP3Stream(_file, musicResourceData->size); - break; -#endif -#ifdef USE_VORBIS - case kSoundOGG: - debug(1, "Playing OGG compressed digital music"); - audioStream = Audio::makeVorbisStream(_file, musicResourceData->size); - break; -#endif -#ifdef USE_FLAC - case kSoundFLAC: - debug(1, "Playing FLAC compressed digital music"); - audioStream = Audio::makeFlacStream(_file, musicResourceData->size); - break; -#endif - default: - // Unknown compression - error("Trying to play a compressed digital music, but the compression is not known"); - break; - } - - } + // digital music + audioStream = new DigitalMusicInputStream(_vm, _digitalMusicContext, resourceId - 9, flags == MUSIC_LOOP, loopStart); } } } @@ -512,8 +524,10 @@ void Music::play(uint32 resourceId, MusicFlags flags) { // Oddly enough, the intro music (song 1) is very // different in the two files. I have no idea why. + // Note that the IHNM demo has only got one music file + // (music.rsc). It is assumed that it contains FM music - if (hasAdlib()) { + if (hasAdlib() || _vm->getGameId() == GID_IHNM_DEMO) { context = _vm->_resource->getContext(GAME_MUSICFILE_FM); } else { context = _vm->_resource->getContext(GAME_MUSICFILE_GM); |