aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/imuse.cpp247
-rw-r--r--scumm/scummvm.cpp2
-rw-r--r--scumm/sound.cpp37
-rw-r--r--scumm/sound.h1
4 files changed, 148 insertions, 139 deletions
diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp
index b1a5a512f2..ddc885dfaa 100644
--- a/scumm/imuse.cpp
+++ b/scumm/imuse.cpp
@@ -4873,25 +4873,12 @@ void IMuseDigital::handler() {
uint32 new_size = _channel[l]._mixerSize;
uint32 mixer_size = new_size;
- new_mixer = false;
if (_channel[l]._mixerTrack == -1) {
- _scumm->_system->lock_mutex(_scumm->_mixer->_mutex);
- for (idx = 0; idx < SoundMixer::NUM_CHANNELS; idx++) {
- if (_scumm->_mixer->_channels[idx] == NULL) {
- _channel[l]._mixerTrack = idx;
- new_mixer = true;
- break;
- }
- }
- }
- if(SoundMixer::NUM_CHANNELS == idx) {
- warning("IMuseDigital::handler() no free SoundMixer channel");
- return;
- }
-
- if (new_mixer == true) {
+ new_mixer = true;
mixer_size *= 2;
new_size *= 2;
+ } else {
+ new_mixer = false;
}
if (_channel[l]._isLoop == false) {
@@ -4937,19 +4924,18 @@ void IMuseDigital::handler() {
}
} else if (_channel[l]._bits == 8) {
for(i = 0; i < (mixer_size / 2); i++) {
- buf[i * 2 + 0] = (byte)(((int16)(buf[i * 2 + 0] * _channel[l]._volumeRight)) >> 8);
- buf[i * 2 + 1] = (byte)(((int16)(buf[i * 2 + 1] * _channel[l]._volume)) >> 8);
+ buf[i * 2 + 0] = (byte)(((int8)(buf[i * 2 + 0] ^ 0x80) * _channel[l]._volumeRight) >> 8) ^ 0x80;
+ buf[i * 2 + 1] = (byte)(((int8)(buf[i * 2 + 1] ^ 0x80) * _channel[l]._volume) >> 8) ^ 0x80;
}
}
if (new_mixer) {
- _scumm->_mixer->playStream(NULL, _channel[l]._mixerTrack, buf, mixer_size,
+ _channel[l]._mixerTrack = _scumm->_mixer->playStream(NULL, -1, buf, mixer_size,
_channel[l]._freq, _channel[l]._mixerFlags);
} else {
_scumm->_mixer->append(_channel[l]._mixerTrack, buf, mixer_size,
_channel[l]._freq, _channel[l]._mixerFlags);
}
- _scumm->_system->unlock_mutex(_scumm->_mixer->_mutex);
if ((new_size != mixer_size) && (_channel[l]._isLoop == true)) {
_channel[l]._offset = _channel[l]._jump[0]._dest + (mixer_size - new_size);
@@ -4979,109 +4965,140 @@ void IMuseDigital::startSound(int sound) {
_channel[l]._volumeRight = 127;
_channel[l]._volume = 127;
_channel[l]._volumeFade = -1;
- ptr += 16;
-
- uint32 tag, size = 0;
-
- for (;;) {
- tag = READ_BE_UINT32(ptr); ptr += 4;
- switch(tag) {
- case MKID_BE('FRMT'):
- ptr += 12;
- _channel[l]._bits = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._freq = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._channels = READ_BE_UINT32(ptr); ptr += 4;
- break;
- case MKID_BE('TEXT'):
- size = READ_BE_UINT32(ptr); ptr += size + 4;
- break;
- case MKID_BE('REGN'):
- ptr += 4;
- if (_channel[l]._numRegions >= MAX_IMUSE_REGIONS) {
- warning("IMuseDigital::startSound(%d) Not enough space for Region");
- ptr += 8;
- break;
- }
- _channel[l]._region[_channel[l]._numRegions]._offset = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._region[_channel[l]._numRegions]._length = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._numRegions++;
- break;
- case MKID_BE('STOP'):
- ptr += 4;
- _channel[l]._offsetStop = READ_BE_UINT32(ptr); ptr += 4;
- break;
- case MKID_BE('JUMP'):
- ptr += 4;
- if (_channel[l]._numJumps >= MAX_IMUSE_JUMPS) {
- warning("IMuseDigital::startSound(%d) Not enough space for Jump");
- ptr += 16;
- break;
+
+ uint32 tag, size = 0, r, t;
+
+ if (READ_UINT32_UNALIGNED(ptr) == MKID('Crea')) {
+ _channel[l]._bits = 8;
+ _channel[l]._channels = 1;
+ _channel[l]._mixerTrack = -1;
+ _channel[l]._mixerSize = (22050 / 5) * 2;
+ _channel[l]._mixerFlags = SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
+ byte * t_ptr= _scumm->_sound->readCreativeVocFile(ptr, size, _channel[l]._freq);
+ if (_channel[l]._freq == 22222) {
+ _channel[l]._freq = 22050;
+ }
+ if (_channel[l]._freq == 11025) {
+ _channel[l]._mixerSize /= 2;
+ }
+ if (_channel[l]._bits == 8) {
+ _channel[l]._mixerFlags |= SoundMixer::FLAG_UNSIGNED;
+ if (_channel[l]._channels == 1) {
+ size *= 2;
+ _channel[l]._channels = 2;
+ _channel[l]._data = (byte *)malloc(size);
+ for (t = 0; t < size / 2; t++) {
+ *(_channel[l]._data + t * 2 + 0) = *(t_ptr + t);
+ *(_channel[l]._data + t * 2 + 1) = *(t_ptr + t);
}
- _channel[l]._jump[_channel[l]._numJumps]._offset = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._jump[_channel[l]._numJumps]._dest = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._jump[_channel[l]._numJumps]._id = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._jump[_channel[l]._numJumps]._numLoops = READ_BE_UINT32(ptr); ptr += 4;
- _channel[l]._isLoop = true;
- _channel[l]._numJumps++;
- break;
- case MKID_BE('DATA'):
- size = READ_BE_UINT32(ptr); ptr += 4;
- break;
- default:
- error("IMuseDigital::startSound(%d) Unknown sfx header %c%c%c%c", tag>>24, tag>>16, tag>>8, tag);
+ } else {
+ _channel[l]._data = (byte *)malloc(size);
+ memcpy(_channel[l]._data, t_ptr, size);
+ }
+ free(t_ptr);
+ _channel[l]._size = size;
+ }
+ } else if (READ_UINT32_UNALIGNED(ptr) == MKID('iMUS')) {
+ ptr += 16;
+ for (;;) {
+ tag = READ_BE_UINT32(ptr); ptr += 4;
+ switch(tag) {
+ case MKID_BE('FRMT'):
+ ptr += 12;
+ _channel[l]._bits = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._freq = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._channels = READ_BE_UINT32(ptr); ptr += 4;
+ break;
+ case MKID_BE('TEXT'):
+ size = READ_BE_UINT32(ptr); ptr += size + 4;
+ break;
+ case MKID_BE('REGN'):
+ ptr += 4;
+ if (_channel[l]._numRegions >= MAX_IMUSE_REGIONS) {
+ warning("IMuseDigital::startSound(%d) Not enough space for Region");
+ ptr += 8;
+ break;
+ }
+ _channel[l]._region[_channel[l]._numRegions]._offset = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._region[_channel[l]._numRegions]._length = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._numRegions++;
+ break;
+ case MKID_BE('STOP'):
+ ptr += 4;
+ _channel[l]._offsetStop = READ_BE_UINT32(ptr); ptr += 4;
+ break;
+ case MKID_BE('JUMP'):
+ ptr += 4;
+ if (_channel[l]._numJumps >= MAX_IMUSE_JUMPS) {
+ warning("IMuseDigital::startSound(%d) Not enough space for Jump");
+ ptr += 16;
+ break;
+ }
+ _channel[l]._jump[_channel[l]._numJumps]._offset = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._jump[_channel[l]._numJumps]._dest = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._jump[_channel[l]._numJumps]._id = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._jump[_channel[l]._numJumps]._numLoops = READ_BE_UINT32(ptr); ptr += 4;
+ _channel[l]._isLoop = true;
+ _channel[l]._numJumps++;
+ break;
+ case MKID_BE('DATA'):
+ size = READ_BE_UINT32(ptr); ptr += 4;
+ break;
+ default:
+ error("IMuseDigital::startSound(%d) Unknown sfx header %c%c%c%c", tag>>24, tag>>16, tag>>8, tag);
+ }
+ if (tag == MKID_BE('DATA')) break;
}
- if (tag == MKID_BE('DATA')) break;
- }
- uint32 header_size = ptr - s_ptr;
- _channel[l]._offsetStop -= header_size;
- if (_channel[l]._bits == 12) {
- _channel[l]._offsetStop = (_channel[l]._offsetStop / 3) * 4;
- }
- uint32 r, t;
- for (r = 0; r < _channel[l]._numRegions; r++) {
- _channel[l]._region[r]._offset -= header_size;
+ uint32 header_size = ptr - s_ptr;
+ _channel[l]._offsetStop -= header_size;
if (_channel[l]._bits == 12) {
- _channel[l]._region[r]._offset = (_channel[l]._region[r]._offset / 3) * 4;
- _channel[l]._region[r]._length = (_channel[l]._region[r]._length / 3) * 4;
+ _channel[l]._offsetStop = (_channel[l]._offsetStop / 3) * 4;
}
- }
- if (_channel[l]._numJumps > 0) {
- for (r = 0; r < _channel[l]._numJumps; r++) {
- _channel[l]._jump[r]._offset -= header_size;
- _channel[l]._jump[r]._dest -= header_size;
+ for (r = 0; r < _channel[l]._numRegions; r++) {
+ _channel[l]._region[r]._offset -= header_size;
if (_channel[l]._bits == 12) {
- _channel[l]._jump[r]._offset = (_channel[l]._jump[r]._offset / 3) * 4;
- _channel[l]._jump[r]._dest = (_channel[l]._jump[r]._dest / 3) * 4;
+ _channel[l]._region[r]._offset = (_channel[l]._region[r]._offset / 3) * 4;
+ _channel[l]._region[r]._length = (_channel[l]._region[r]._length / 3) * 4;
}
}
- }
- _channel[l]._mixerTrack = -1;
- _channel[l]._mixerSize = (22050 / 5) * 2;
- _channel[l]._mixerFlags = SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
- if (_channel[l]._bits == 12) {
- _channel[l]._mixerSize *= 2;
- _channel[l]._mixerFlags |= SoundMixer::FLAG_16BITS;
- _channel[l]._size = _scumm->_sound->decode12BitsSample(ptr, &_channel[l]._data, size, (_channel[l]._channels == 2) ? false : true);
- }
- if (_channel[l]._bits == 8) {
- _channel[l]._mixerFlags |= SoundMixer::FLAG_UNSIGNED;
- if (_channel[l]._channels == 1) {
- size *= 2;
- _channel[l]._channels = 2;
- _channel[l]._data = (byte *)malloc(size);
- for (t = 0; t < size; t++) {
- *(_channel[l]._data + l * 2 + 0) = *(ptr + l);
- *(_channel[l]._data + l * 2 + 1) = *(ptr + l);
+ if (_channel[l]._numJumps > 0) {
+ for (r = 0; r < _channel[l]._numJumps; r++) {
+ _channel[l]._jump[r]._offset -= header_size;
+ _channel[l]._jump[r]._dest -= header_size;
+ if (_channel[l]._bits == 12) {
+ _channel[l]._jump[r]._offset = (_channel[l]._jump[r]._offset / 3) * 4;
+ _channel[l]._jump[r]._dest = (_channel[l]._jump[r]._dest / 3) * 4;
+ }
}
- } else {
- _channel[l]._data = (byte *)malloc(size);
- memcpy(_channel[l]._data, ptr, size);
}
- _channel[l]._size = size;
- }
- if (_channel[l]._freq == 11025) {
- _channel[l]._mixerSize /= 2;
+ _channel[l]._mixerTrack = -1;
+ _channel[l]._mixerSize = (22050 / 5) * 2;
+ _channel[l]._mixerFlags = SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_STEREO | SoundMixer::FLAG_REVERSE_STEREO;
+ if (_channel[l]._bits == 12) {
+ _channel[l]._mixerSize *= 2;
+ _channel[l]._mixerFlags |= SoundMixer::FLAG_16BITS;
+ _channel[l]._size = _scumm->_sound->decode12BitsSample(ptr, &_channel[l]._data, size, (_channel[l]._channels == 2) ? false : true);
+ }
+ if (_channel[l]._bits == 8) {
+ _channel[l]._mixerFlags |= SoundMixer::FLAG_UNSIGNED;
+ if (_channel[l]._channels == 1) {
+ size *= 2;
+ _channel[l]._channels = 2;
+ _channel[l]._data = (byte *)malloc(size);
+ for (t = 0; t < size / 2; t++) {
+ *(_channel[l]._data + t * 2 + 0) = *(ptr + t);
+ *(_channel[l]._data + t * 2 + 1) = *(ptr + t);
+ }
+ } else {
+ _channel[l]._data = (byte *)malloc(size);
+ memcpy(_channel[l]._data, ptr, size);
+ }
+ _channel[l]._size = size;
+ }
+ if (_channel[l]._freq == 11025) {
+ _channel[l]._mixerSize /= 2;
+ }
}
_channel[l]._toBeRemoved = false;
_channel[l]._used = true;
@@ -5110,7 +5127,7 @@ void IMuseDigital::stopAll() {
int32 IMuseDigital::doCommand(int a, int b, int c, int d, int e, int f, int g, int h) {
byte cmd = a & 0xFF;
byte param = a >> 8;
- byte sample = b;
+ int32 sample = b;
byte sub_cmd = c >> 8;
int8 channel = -1, l;
@@ -5121,7 +5138,7 @@ int32 IMuseDigital::doCommand(int a, int b, int c, int d, int e, int f, int g, i
switch (cmd) {
case 12:
switch (sub_cmd) {
- case 5: // params seems always to be set 0
+ case 5:
debug(1, "IMuseDigital::doCommand stub cmd=%d,param=%d,sample=%d,sub_cmd=%d,params=(%d,%d,%d)", param, cmd, sample, sub_cmd, d, e, f);
return 0;
case 6: // volume control (0-127)
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index 9ff67648d6..78f7b373ac 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -134,7 +134,7 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst)
_mixer->setMusicVolume(kDefaultMusicVolume);
// Init iMuse
- if (_gameId == GID_DIG) {
+ if (_features & GF_AFTER_V7) {
_imuseDigital = new IMuseDigital(this);
_imuse = NULL;
} else {
diff --git a/scumm/sound.cpp b/scumm/sound.cpp
index 6fc38a817f..1243128b5c 100644
--- a/scumm/sound.cpp
+++ b/scumm/sound.cpp
@@ -125,15 +125,15 @@ void Sound::processSoundQues() {
_soundQuePos = 0;
}
-static char * read_creative_voc_file(byte * ptr, int & size, int & rate) {
+byte * Sound::readCreativeVocFile(byte * ptr, uint32 & size, uint32 & rate) {
assert(strncmp((char*)ptr, "Creative Voice File\x1A", 20) == 0);
- int offset = READ_LE_UINT16(ptr+20);
- short version = READ_LE_UINT16(ptr+22);
- short code = READ_LE_UINT16(ptr+24);
+ int32 offset = READ_LE_UINT16(ptr + 20);
+ short version = READ_LE_UINT16(ptr + 22);
+ short code = READ_LE_UINT16(ptr + 24);
assert(version == 0x010A || version == 0x0114);
assert(code == ~version + 0x1234);
bool quit = 0;
- char * ret_sound = 0; size = 0;
+ byte * ret_sound = 0; size = 0;
while(!quit) {
int len = READ_LE_UINT32(ptr + offset);
offset += 4;
@@ -149,9 +149,9 @@ static char * read_creative_voc_file(byte * ptr, int & size, int & rate) {
debug(9, "VOC Data Bloc : %d, %d, %d", rate, packing, len);
if(packing == 0) {
if(size) {
- ret_sound = (char*)realloc(ret_sound, size + len);
+ ret_sound = (byte*)realloc(ret_sound, size + len);
} else {
- ret_sound = (char*)malloc(len);
+ ret_sound = (byte*)malloc(len);
}
memcpy(ret_sound + size, ptr + offset, len);
size += len;
@@ -184,10 +184,9 @@ void Sound::playSound(int sound) {
sound, _scumm->getResourceRoomNr(rtSound, sound));
ptr = _scumm->getResourceAddress(rtSound, sound);
if (ptr) {
- if ((READ_UINT32_UNALIGNED(ptr) == MKID('iMUS')) && (_scumm->_imuseDigital)){
- if (_scumm->_imuseDigital) {
- _scumm->_imuseDigital->startSound(sound);
- }
+ if (READ_UINT32_UNALIGNED(ptr) == MKID('iMUS')){
+ _scumm->_imuseDigital->startSound(sound);
+ return;
}
else if (READ_UINT32_UNALIGNED(ptr) == MKID('SOUN')) {
ptr += 8;
@@ -234,10 +233,7 @@ void Sound::playSound(int sound) {
return;
}
else if (READ_UINT32_UNALIGNED(ptr) == MKID('Crea')) {
- char * sounddata = read_creative_voc_file(ptr, size, rate);
- if(sounddata != NULL) {
- _scumm->_mixer->playRaw(NULL, sounddata, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE, sound);
- }
+ _scumm->_imuseDigital->startSound(sound);
return;
}
else if (READ_UINT32_UNALIGNED(ptr) == MKID('ADL ')) {
@@ -583,14 +579,6 @@ int Sound::isSoundRunning(int sound) {
return _scumm->_imuseDigital->getSoundStatus(sound);
}
- // Check raw mixer channels, to make sure we're not playing an exotic
- // sound type manually.
- for (i = 0; i < _scumm->_mixer->NUM_CHANNELS; i++) {
- if (_scumm->_mixer->_channels[i] && (_scumm->_mixer->_channels[i]->_id == sound)) {
- return 1;
- }
- }
-
se = _scumm->_imuse;
if (!se)
return 0;
@@ -855,6 +843,9 @@ File * Sound::openSfxFile() {
}
void Sound::stopSfxSound() {
+ if (_scumm->_imuseDigital) {
+ _scumm->_imuseDigital->stopAll();
+ }
_scumm->_mixer->stopAll();
}
diff --git a/scumm/sound.h b/scumm/sound.h
index b0986f455a..09b75ffc27 100644
--- a/scumm/sound.h
+++ b/scumm/sound.h
@@ -123,6 +123,7 @@ public:
void bundleMusicHandler(Scumm * scumm);
void stopBundleMusic();
void playBundleSound(char *sound);
+ byte * readCreativeVocFile(byte * ptr, uint32 & size, uint32 & rate);
int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned);
int playSfxSound_MP3(void *sound, uint32 size);