aboutsummaryrefslogtreecommitdiff
path: root/scumm/imuse_digi/dimuse_sndmgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scumm/imuse_digi/dimuse_sndmgr.cpp')
-rw-r--r--scumm/imuse_digi/dimuse_sndmgr.cpp93
1 files changed, 84 insertions, 9 deletions
diff --git a/scumm/imuse_digi/dimuse_sndmgr.cpp b/scumm/imuse_digi/dimuse_sndmgr.cpp
index d0eb9ff525..cc9ca79de2 100644
--- a/scumm/imuse_digi/dimuse_sndmgr.cpp
+++ b/scumm/imuse_digi/dimuse_sndmgr.cpp
@@ -22,6 +22,7 @@
#include "common/scummsys.h"
#include "common/util.h"
#include "sound/voc.h"
+#include "sound/vorbis.h"
#include "scumm/scumm.h"
#include "scumm/imuse_digi/dimuse.h"
#include "scumm/imuse_digi/dimuse_sndmgr.h"
@@ -79,6 +80,39 @@ void ImuseDigiSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps, i
} while (tag != MKID_BE('DATA'));
}
+void ImuseDigiSndMgr::prepareSoundFromRMAP(File *file, soundStruct *sound, int32 offset, int32 size) {
+ int l;
+
+ file->seek(offset, SEEK_SET);
+ uint32 tag = file->readUint32BE();
+ assert(tag == 'RMAP');
+ assert(file->readUint32BE() == 1); // version
+ sound->bits = 16;
+ sound->freq = 22050;
+ sound->channels = 2;
+ sound->numRegions = file->readUint32BE();
+ sound->numJumps = file->readUint32BE();
+ sound->numSyncs = file->readUint32BE();
+ sound->region = (_region *)malloc(sizeof(_region) * sound->numRegions);
+ sound->jump = (_jump *)malloc(sizeof(_jump) * sound->numJumps);
+ sound->sync = (_sync *)malloc(sizeof(_sync) * sound->numSyncs);
+ for (l = 0; l < sound->numRegions; l++) {
+ sound->region[l].offset = file->readUint32BE();
+ sound->region[l].length = file->readUint32BE();
+ }
+ for (l = 0; l < sound->numJumps; l++) {
+ sound->jump[l].offset = file->readUint32BE();
+ sound->jump[l].dest = file->readUint32BE();
+ sound->jump[l].hookId = file->readUint32BE();
+ sound->jump[l].fadeDelay = file->readUint32BE();
+ }
+ for (l = 0; l < sound->numSyncs; l++) {
+ sound->sync[l].size = file->readUint32BE();
+ sound->sync[l].ptr = (byte *)malloc(sound->sync[l].size);
+ file->read(sound->sync[l].ptr, sound->sync[l].size);
+ }
+}
+
void ImuseDigiSndMgr::prepareSound(byte *ptr, soundStruct *sound) {
if (READ_UINT32(ptr) == MKID('Crea')) {
bool quit = false;
@@ -224,7 +258,7 @@ bool ImuseDigiSndMgr::openMusicBundle(soundStruct *sound, int disk) {
sound->bundle = new BundleMgr(_cacheBundleDir);
if (_vm->_gameId == GID_CMI) {
if (_vm->_features & GF_DEMO) {
- result = sound->bundle->openFile("music.bun");
+ result = sound->bundle->open("music.bun", sound->compressed);
} else {
char musicfile[20];
if (disk == -1)
@@ -237,13 +271,13 @@ bool ImuseDigiSndMgr::openMusicBundle(soundStruct *sound, int disk) {
// sound->bundle->closeFile();
// }
- result = sound->bundle->openFile(musicfile);
+ result = sound->bundle->open(musicfile, sound->compressed);
// FIXME: Shouldn't we only set _disk if result == true?
_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
}
} else if (_vm->_gameId == GID_DIG)
- result = sound->bundle->openFile("digmusic.bun");
+ result = sound->bundle->open("digmusic.bun", sound->compressed);
else
error("ImuseDigiSndMgr::openMusicBundle() Don't know which bundle file to load");
@@ -258,7 +292,7 @@ bool ImuseDigiSndMgr::openVoiceBundle(soundStruct *sound, int disk) {
sound->bundle = new BundleMgr(_cacheBundleDir);
if (_vm->_gameId == GID_CMI) {
if (_vm->_features & GF_DEMO) {
- result = sound->bundle->openFile("voice.bun");
+ result = sound->bundle->open("voice.bun", sound->compressed);
} else {
char voxfile[20];
if (disk == -1)
@@ -271,13 +305,13 @@ bool ImuseDigiSndMgr::openVoiceBundle(soundStruct *sound, int disk) {
// sound->bundle->closeFile();
// }
- result = sound->bundle->openFile(voxfile);
+ result = sound->bundle->open(voxfile, sound->compressed);
// FIXME: Shouldn't we only set _disk if result == true?
_disk = (byte)_vm->VAR(_vm->VAR_CURRENTDISK);
}
} else if (_vm->_gameId == GID_DIG)
- result = sound->bundle->openFile("digvoice.bun");
+ result = sound->bundle->open("digvoice.bun", sound->compressed);
else
error("ImuseDigiSndMgr::openVoiceBundle() Don't know which bundle file to load");
@@ -323,7 +357,19 @@ ImuseDigiSndMgr::soundStruct *ImuseDigiSndMgr::openSound(int32 soundId, const ch
closeSound(sound);
return NULL;
}
- if (soundName[0] == 0) {
+ if (sound->compressed) {
+ char fileName[24];
+ int32 offset = 0, size = 0;
+ sprintf(fileName, "%s.map", soundName);
+ File *rmapFile = sound->bundle->getFile(fileName, offset, size);
+ prepareSoundFromRMAP(rmapFile, sound, offset, size);
+ strcpy(sound->name, soundName);
+ sound->soundId = soundId;
+ sound->type = soundType;
+ sound->volGroupId = volGroupId;
+ sound->disk = _disk;
+ return sound;
+ } else if (soundName[0] == 0) {
if (sound->bundle->decompressSampleByIndex(soundId, 0, 0x2000, &ptr, 0, header_outside) == 0 || ptr == NULL) {
closeSound(sound);
return NULL;
@@ -362,7 +408,11 @@ void ImuseDigiSndMgr::closeSound(soundStruct *soundHandle) {
_vm->unlock(rtSound, soundHandle->soundId);
}
+ if (soundHandle->compressedStream)
+ delete soundHandle->compressedStream;
+
delete soundHandle->bundle;
+
for (int r = 0; r < soundHandle->numSyncs; r++)
free(soundHandle->sync[r].ptr);
free(soundHandle->region);
@@ -387,6 +437,11 @@ bool ImuseDigiSndMgr::checkForProperHandle(soundStruct *soundHandle) {
return false;
}
+bool ImuseDigiSndMgr::isCompressed(soundStruct *soundHandle) {
+ assert(checkForProperHandle(soundHandle));
+ return soundHandle->compressed;
+}
+
int ImuseDigiSndMgr::getFreq(soundStruct *soundHandle) {
assert(checkForProperHandle(soundHandle));
return soundHandle->freq;
@@ -500,13 +555,33 @@ int32 ImuseDigiSndMgr::getDataFromRegion(soundStruct *soundHandle, int region, b
int header_size = soundHandle->offsetData;
bool header_outside = ((_vm->_gameId == GID_CMI) && !(_vm->_features & GF_DEMO));
- if (soundHandle->bundle) {
+ if ((soundHandle->bundle) && (!soundHandle->compressed)) {
size = soundHandle->bundle->decompressSampleByCurIndex(start + offset, size, buf, header_size, header_outside);
} else if (soundHandle->resPtr) {
*buf = (byte *)malloc(size);
memcpy(*buf, soundHandle->resPtr + start + offset + header_size, size);
+ } else if ((soundHandle->bundle) && (soundHandle->compressed)) {
+ *buf = (byte *)malloc(size);
+ char fileName[24];
+ sprintf(fileName, "%s_reg%03d.ogg", soundHandle->name, region);
+ if (scumm_stricmp(fileName, soundHandle->lastFileName) != 0) {
+ int32 offset = 0, size = 0;
+ File *oggFile = soundHandle->bundle->getFile(fileName, offset, size);
+ if (!soundHandle->compressedStream) {
+ soundHandle->compressedStream = makeVorbisStream(oggFile, size);
+ assert(soundHandle->compressedStream);
+ assert(soundHandle->compressedStream->getRate() == 22050);
+ assert(soundHandle->compressedStream->isStereo());
+ }
+ strcpy(soundHandle->lastFileName, fileName);
+ }
+ size = soundHandle->compressedStream->readBuffer((int16 *)*buf, size / 2) * 2;
+ if (soundHandle->compressedStream->endOfData()) {
+ delete soundHandle->compressedStream;
+ soundHandle->compressedStream = NULL;
+ }
}
-
+
return size;
}