diff options
-rw-r--r-- | scumm/imuse.cpp | 247 | ||||
-rw-r--r-- | scumm/scummvm.cpp | 2 | ||||
-rw-r--r-- | scumm/sound.cpp | 37 | ||||
-rw-r--r-- | scumm/sound.h | 1 |
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); |