SCI/new music code: Moved processing of digital sound effects outside the MIDI worker thread. Some cleanup

svn-id: r46834
This commit is contained in:
Filippos Karapetis 2010-01-01 16:05:26 +00:00
parent 74ae4ecc48
commit 153cf54850
4 changed files with 56 additions and 49 deletions

View file

@ -358,7 +358,7 @@ void SciMusic::soundInitSnd(MusicEntry *pSnd) {
void SciMusic::onTimer() {
const MusicList::iterator end = _playList.end();
for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
(*i)->onTimer(_soundVersion, _pMixer);
(*i)->onTimer(_soundVersion);
}
}
@ -374,7 +374,7 @@ void SciMusic::soundPlay(MusicEntry *pSnd) {
sortPlayList();
}
_mutex.unlock();
_mutex.unlock(); // unlock to perform mixer-related calls
if (pSnd->pStreamAud && !_pMixer->isSoundHandleActive(pSnd->hCurrentAud)) {
SegManager *segMan = ((SciEngine *)g_engine)->getEngineState()->_segMan; // HACK
@ -493,6 +493,7 @@ void SciMusic::soundSetMasterVolume(uint16 vol) {
void SciMusic::printPlayList(Console *con) {
Common::StackLock lock(_mutex);
const char *musicStatus[] = { "Stopped", "Initialized", "Paused", "Playing" };
const MusicList::iterator end = _playList.end();
@ -533,29 +534,21 @@ MusicEntry::MusicEntry() {
MusicEntry::~MusicEntry() {
}
void MusicEntry::onTimer(SciVersion soundVersion, Audio::Mixer *mixer) {
void MusicEntry::onTimer(SciVersion soundVersion) {
if (status != kSoundPlaying)
return;
if (fadeStep)
doFade(mixer);
doFade();
// Only process MIDI streams in this thread, not digital sound effects
if (pMidiParser) {
pMidiParser->onTimer();
ticker = (uint16)pMidiParser->getTick();
} else if (pStreamAud) {
// TODO: We need to update loop selector here, when sample is looping
if (!mixer->isSoundHandleActive(hCurrentAud)) {
ticker = SIGNAL_OFFSET;
signal = SIGNAL_OFFSET;
status = kSoundStopped;
} else {
ticker = (uint16)(mixer->getSoundElapsedTime(hCurrentAud) * 0.06);
}
}
}
void MusicEntry::doFade(Audio::Mixer *mixer) {
void MusicEntry::doFade() {
if (fadeTicker)
fadeTicker--;
else {
@ -569,10 +562,9 @@ void MusicEntry::doFade(Audio::Mixer *mixer) {
}
volume = fadeVolume;
// Only process MIDI streams in this thread, not digital sound effects
if (pMidiParser)
pMidiParser->setVolume(volume);
if (pStreamAud)
mixer->setChannelVolume(hCurrentAud, volume);
}
}

View file

@ -103,8 +103,8 @@ public:
MusicEntry();
~MusicEntry();
void doFade(Audio::Mixer *mixer);
void onTimer(SciVersion soundVersion, Audio::Mixer *mixer);
void doFade();
void onTimer(SciVersion soundVersion);
#ifndef USE_OLD_MUSIC_FUNCTIONS
virtual void saveLoadWithSerializer(Common::Serializer &ser);

View file

@ -760,27 +760,34 @@ void SoundCommandParser::cmdUpdateCues(reg_t obj, int16 value) {
PUT_SEL32V(_segMan, obj, frame, frame);
}
#else
updateCues(obj);
#endif
}
#ifndef USE_OLD_MUSIC_FUNCTIONS
void SoundCommandParser::updateSci0Cues() {
Common::StackLock(_music->_mutex);
const MusicList::iterator end = _music->getPlayListEnd();
for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
updateCues((*i)->soundObj);
}
}
void SoundCommandParser::updateCues(reg_t obj) {
_music->_mutex.lock();
MusicEntry *musicSlot = _music->getSlot(obj);
if (!musicSlot) {
warning("cmdUpdateCues: Slot not found");
_music->_mutex.unlock();
return;
}
_music->_mutex.unlock(); // unlock to perform mixer-related calls
// Update digital sound effect slots here
Audio::Mixer *mixer = g_system->getMixer();
if (musicSlot->pStreamAud) {
// TODO: We need to update loop selector here, when sample is looping
if (!mixer->isSoundHandleActive(musicSlot->hCurrentAud)) {
musicSlot->ticker = SIGNAL_OFFSET;
musicSlot->signal = SIGNAL_OFFSET;
musicSlot->status = kSoundStopped;
} else {
musicSlot->ticker = (uint16)(mixer->getSoundElapsedTime(musicSlot->hCurrentAud) * 0.06);
// Handle fading
if (musicSlot->fadeStep)
mixer->setChannelVolume(musicSlot->hCurrentAud, musicSlot->volume);
}
}
_music->_mutex.lock(); // and lock again
switch (musicSlot->signal) {
case 0:
@ -811,8 +818,10 @@ void SoundCommandParser::updateCues(reg_t obj) {
PUT_SEL32V(_segMan, obj, sec, musicSlot->ticker % 3600 / 60);
PUT_SEL32V(_segMan, obj, frame, musicSlot->ticker);
}
}
_music->_mutex.unlock();
#endif
}
void SoundCommandParser::cmdSendMidi(reg_t obj, int16 value) {
#ifdef USE_OLD_MUSIC_FUNCTIONS
@ -937,23 +946,33 @@ void SoundCommandParser::cmdSuspendSound(reg_t obj, int16 value) {
warning("STUB: cmdSuspendSound");
}
#ifndef USE_OLD_MUSIC_FUNCTIONS
void SoundCommandParser::updateSci0Cues() {
Common::StackLock(_music->_mutex);
const MusicList::iterator end = _music->getPlayListEnd();
for (MusicList::iterator i = _music->getPlayListStart(); i != end; ++i) {
cmdUpdateCues((*i)->soundObj, 0);
}
}
#endif
void SoundCommandParser::clearPlayList() {
#ifndef USE_OLD_MUSIC_FUNCTIONS
Common::StackLock lock(_music->_mutex);
_music->clearPlayList();
#endif
}
void SoundCommandParser::syncPlayList(Common::Serializer &s) {
#ifndef USE_OLD_MUSIC_FUNCTIONS
Common::StackLock lock(_music->_mutex);
_music->saveLoadWithSerializer(s);
#endif
}
void SoundCommandParser::reconstructPlayList(int savegame_version) {
#ifndef USE_OLD_MUSIC_FUNCTIONS
Common::StackLock lock(_music->_mutex);
const MusicList::iterator end = _music->getPlayListEnd();

View file

@ -60,6 +60,13 @@ public:
void printPlayList(Console *con);
#ifndef USE_OLD_MUSIC_FUNCTIONS
/**
* Synchronizes the current state of the music list to the rest of the engine, so that
* the changes that the sound thread makes to the music are registered with the engine
* scripts. In SCI0, we invoke this from kAnimate (which is called very often). SCI01
* and later have a specific callback function, cmdUpdateCues, which is called regularly
* by the engine scripts themselves, so the engine itself polls for changes to the music
*/
void updateSci0Cues();
#endif
@ -79,17 +86,6 @@ private:
reg_t _acc;
int _midiCmd, _controller, _param;
#ifndef USE_OLD_MUSIC_FUNCTIONS
/**
* Synchronizes the current state of the music list to the rest of the engine, so that
* the changes that the sound thread makes to the music are registered with the engine
* scripts. In SCI0, we invoke this from kAnimate (which is called very often). SCI01
* and later have a specific callback function, cmdUpdateCues, which is called regularly
* by the engine scripts themselves, so the engine itself polls for changes to the music
*/
void updateCues(reg_t obj);
#endif
void cmdInitHandle(reg_t obj, int16 value);
void cmdPlayHandle(reg_t obj, int16 value);
void cmdDummy(reg_t obj, int16 value);