void Sound::engine() { // first of all, add any random sfx to the queue... for (uint16 cnt = 0; cnt < TOTAL_FX_PER_ROOM; cnt++) { uint16 fxNo = _roomsFixedFx[Logic::_scriptVars[SCREEN]][cnt]; if (fxNo) { if (_fxList[fxNo].type == FX_RANDOM) { if (_rnd.getRandomNumber(_fxList[fxNo].delay) == 0) addToQueue(fxNo); } } else break; } // now process the queue for (uint8 cnt2 = 0; cnt2 < _endOfQueue; cnt2++) { if (_fxQueue[cnt2].delay > 0) { _fxQueue[cnt2].delay--; if (_fxQueue[cnt2].delay == 0) playSample(&_fxQueue[cnt2]); } else { if (!_mixer->isSoundHandleActive(_fxQueue[cnt2].handle)) { // sound finished _resMan->resClose(getSampleId(_fxQueue[cnt2].id)); if (cnt2 != _endOfQueue - 1) _fxQueue[cnt2] = _fxQueue[_endOfQueue - 1]; _endOfQueue--; } } } }
int Sound::addToQueue(int32 fxNo) { bool alreadyInQueue = false; for (uint8 cnt = 0; (cnt < _endOfQueue) && (!alreadyInQueue); cnt++) if (_fxQueue[cnt].id == (uint32)fxNo) alreadyInQueue = true; if (!alreadyInQueue) { if (_endOfQueue == MAX_FXQ_LENGTH) { warning("Sound queue overflow"); return 0; } uint32 sampleId = getSampleId(fxNo); if ((sampleId & 0xFF) != 0xFF) { _resMan->resOpen(sampleId); _fxQueue[_endOfQueue].id = fxNo; if (_fxList[fxNo].type == FX_SPOT) _fxQueue[_endOfQueue].delay = _fxList[fxNo].delay + 1; else _fxQueue[_endOfQueue].delay = 1; _endOfQueue++; return 1; } return 0; } return 0; }
void Sound::playSample(QueueElement *elem) { uint8 *sampleData = (uint8 *)_resMan->fetchRes(getSampleId(elem->id)); for (uint16 cnt = 0; cnt < MAX_ROOMS_PER_FX; cnt++) { if (_fxList[elem->id].roomVolList[cnt].roomNo) { if ((_fxList[elem->id].roomVolList[cnt].roomNo == (int)Logic::_scriptVars[SCREEN]) || (_fxList[elem->id].roomVolList[cnt].roomNo == -1)) { uint8 volL = (_fxList[elem->id].roomVolList[cnt].leftVol * 10 * _sfxVolL) / 255; uint8 volR = (_fxList[elem->id].roomVolList[cnt].rightVol * 10 * _sfxVolR) / 255; int8 pan = (volR - volL) / 2; uint8 volume = (volR + volL) / 2; if (SwordEngine::isPsx()) { uint32 size = READ_LE_UINT32(sampleData); Audio::AudioStream *audStream = Audio::makeLoopingAudioStream(Audio::makeXAStream(new Common::MemoryReadStream(sampleData + 4, size - 4), 11025), (_fxList[elem->id].type == FX_LOOP) ? 0 : 1); _mixer->playStream(Audio::Mixer::kSFXSoundType, &elem->handle, audStream, elem->id, volume, pan); } else { uint32 size = READ_LE_UINT32(sampleData + 0x28); uint8 flags; if (READ_LE_UINT16(sampleData + 0x22) == 16) flags = Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN; else flags = Audio::FLAG_UNSIGNED; if (READ_LE_UINT16(sampleData + 0x16) == 2) flags |= Audio::FLAG_STEREO; Audio::AudioStream *stream = Audio::makeLoopingAudioStream( Audio::makeRawStream(sampleData + 0x2C, size, 11025, flags, DisposeAfterUse::NO), (_fxList[elem->id].type == FX_LOOP) ? 0 : 1); _mixer->playStream(Audio::Mixer::kSFXSoundType, &elem->handle, stream, elem->id, volume, pan); } } } else break; } }
Sound::~Sound() { // clean up fx queue _mixer->stopAll(); for (uint8 cnt = 0; cnt < _endOfQueue; cnt++) if (_fxQueue[cnt].delay == 0) _resMan->resClose(getSampleId(_fxQueue[cnt].id)); _endOfQueue = 0; closeCowSystem(); }
void Sound::fnStopFx(int32 fxNo) { _mixer->stopID(fxNo); for (uint8 cnt = 0; cnt < _endOfQueue; cnt++) if (_fxQueue[cnt].id == (uint32)fxNo) { if (!_fxQueue[cnt].delay) // sound was started _resMan->resClose(getSampleId(_fxQueue[cnt].id)); if (cnt != _endOfQueue - 1) _fxQueue[cnt] = _fxQueue[_endOfQueue - 1]; _endOfQueue--; return; } debug(8, "fnStopFx: id not found in queue"); }