FT also use Imuse

svn-id: r5086
This commit is contained in:
Paweł Kołodziejski 2002-10-03 23:16:10 +00:00
parent a9d25bb24a
commit aa2d21d68e
4 changed files with 147 additions and 138 deletions

View File

@ -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;
uint32 tag, size = 0, r, t;
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 (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);
}
} 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)

View File

@ -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 {

View File

@ -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();
}

View File

@ -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);