aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2015-02-14 15:58:47 +0100
committerWillem Jan Palenstijn2015-02-15 14:05:56 +0100
commit1c5722f014d1f5a34c79d8d1cb7f5ed86e0b822d (patch)
tree5db2827defb37659356dab6ef88a5a8b7a80ae07 /engines/sci
parent5028487038fd3572d68af3cd253fc28917245e63 (diff)
downloadscummvm-rg350-1c5722f014d1f5a34c79d8d1cb7f5ed86e0b822d.tar.gz
scummvm-rg350-1c5722f014d1f5a34c79d8d1cb7f5ed86e0b822d.tar.bz2
scummvm-rg350-1c5722f014d1f5a34c79d8d1cb7f5ed86e0b822d.zip
SCI: Allow channel remapping from audio thread too
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/sound/midiparser_sci.cpp12
-rw-r--r--engines/sci/sound/music.cpp42
-rw-r--r--engines/sci/sound/music.h7
3 files changed, 39 insertions, 22 deletions
diff --git a/engines/sci/sound/midiparser_sci.cpp b/engines/sci/sound/midiparser_sci.cpp
index 7ebe47633a..25facacced 100644
--- a/engines/sci/sound/midiparser_sci.cpp
+++ b/engines/sci/sound/midiparser_sci.cpp
@@ -487,8 +487,11 @@ void MidiParser_SCI::trackState(uint32 b) {
s._sustain = (op2 != 0);
break;
case 0x4B: // voices
- if (s._voices != op2)
- warning("Voice change (%d to %d) without remapping", s._voices, op2);
+ if (s._voices != op2) {
+ // CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+ debugC(2, kDebugLevelSound, "Dynamic voice change (%d to %d)", s._voices, op2);
+ _music->needsRemap();
+ }
s._voices = op2;
_pSnd->_chan[channel]._voices = op2; // Also sync our MusicEntry
break;
@@ -500,8 +503,9 @@ void MidiParser_SCI::trackState(uint32 b) {
bool m = op2;
if (_pSnd->_chan[channel]._mute != m) {
_pSnd->_chan[channel]._mute = m;
- // TODO: If muting/unmuting a channel, remap channels.
- warning("Mute change without immediate remapping (mainThread = %d)", _mainThreadCalled);
+ // CHECKME: Should we directly call remapChannels() if _mainThreadCalled?
+ _music->needsRemap();
+ debugC(2, kDebugLevelSound, "Dynamic mute change (mainThread = %d)", _mainThreadCalled);
}
}
break;
diff --git a/engines/sci/sound/music.cpp b/engines/sci/sound/music.cpp
index dab02c9eb7..37bf6a7b1b 100644
--- a/engines/sci/sound/music.cpp
+++ b/engines/sci/sound/music.cpp
@@ -145,6 +145,7 @@ void SciMusic::init() {
_currentlyPlayingSample = NULL;
_timeCounter = 0;
+ _needsRemap = false;
}
void SciMusic::miditimerCallback(void *p) {
@@ -159,6 +160,11 @@ void SciMusic::onTimer() {
// sending out queued commands that were "sent" via main thread
sendMidiCommandsFromQueue();
+ // remap channels, if requested
+ if (_needsRemap)
+ remapChannels(false);
+ _needsRemap = false;
+
for (MusicList::iterator i = _playList.begin(); i != end; ++i)
(*i)->onTimer();
}
@@ -920,12 +926,12 @@ int ChannelRemapping::lowestPrio() const {
}
-void SciMusic::remapChannels() {
+void SciMusic::remapChannels(bool mainThread) {
if (_soundVersion <= SCI_VERSION_0_LATE)
return;
- // NB: This function should only be called from the main thread,
- // with _mutex locked
+ // NB: This function should only be called with _mutex locked
+ // Make sure to set the mainThread argument correctly.
ChannelRemapping *map = determineChannelMap();
@@ -978,9 +984,9 @@ void SciMusic::remapChannels() {
for (int j = 0; j < 16; ++j) {
if (!channelMapped[j]) {
- song->pMidiParser->mainThreadBegin();
+ if (mainThread) song->pMidiParser->mainThreadBegin();
song->pMidiParser->remapChannel(j, -1);
- song->pMidiParser->mainThreadEnd();
+ if (mainThread) song->pMidiParser->mainThreadEnd();
#ifdef DEBUG_REMAP
if (channelUsed[j])
debug(" Unmapping song %d, channel %d", songIndex, j);
@@ -1012,9 +1018,9 @@ void SciMusic::remapChannels() {
#ifdef DEBUG_REMAP
debug(" Mapping (dontRemap) song %d, channel %d to device channel %d", songIndex, _channelMap[i]._channel, i);
#endif
- _channelMap[i]._song->pMidiParser->mainThreadBegin();
+ if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadBegin();
_channelMap[i]._song->pMidiParser->remapChannel(_channelMap[i]._channel, i);
- _channelMap[i]._song->pMidiParser->mainThreadEnd();
+ if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadEnd();
}
}
@@ -1067,9 +1073,9 @@ void SciMusic::remapChannels() {
#ifdef DEBUG_REMAP
debug(" Mapping song %d, channel %d to device channel %d", songIndex, _channelMap[j]._channel, j);
#endif
- _channelMap[j]._song->pMidiParser->mainThreadBegin();
+ if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadBegin();
_channelMap[j]._song->pMidiParser->remapChannel(_channelMap[j]._channel, j);
- _channelMap[j]._song->pMidiParser->mainThreadEnd();
+ if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadEnd();
break;
}
}
@@ -1079,7 +1085,7 @@ void SciMusic::remapChannels() {
// And finally, stop any empty channels
for (int i = _driverLastChannel; i >= _driverFirstChannel; --i) {
if (!_channelMap[i]._song && currentMap[i]._song)
- resetDeviceChannel(i);
+ resetDeviceChannel(i, mainThread);
}
delete map;
@@ -1307,14 +1313,18 @@ ChannelRemapping *SciMusic::determineChannelMap() {
return map;
}
-void SciMusic::resetDeviceChannel(int devChannel) {
- // NB: This function should only be called from the main thread
-
+void SciMusic::resetDeviceChannel(int devChannel, bool mainThread) {
assert(devChannel >= 0 && devChannel <= 0x0F);
- putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
- putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
- putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+ if (mainThread) {
+ putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
+ putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
+ putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
+ } else {
+ _pMidiDrv->send(0x0040B0 | devChannel); // sustain off
+ _pMidiDrv->send(0x007BB0 | devChannel); // notes off
+ _pMidiDrv->send(0x004BB0 | devChannel); // release voices
+ }
}
diff --git a/engines/sci/sound/music.h b/engines/sci/sound/music.h
index 8770748c3d..a610f32d89 100644
--- a/engines/sci/sound/music.h
+++ b/engines/sci/sound/music.h
@@ -228,6 +228,8 @@ public:
byte getCurrentReverb();
+ void needsRemap() { _needsRemap = true; }
+
virtual void saveLoadWithSerializer(Common::Serializer &ser);
// Mutex for music code. Used to guard access to the song playlist, to the
@@ -249,9 +251,9 @@ protected:
bool _useDigitalSFX;
// remapping:
- void remapChannels();
+ void remapChannels(bool mainThread = true);
ChannelRemapping *determineChannelMap();
- void resetDeviceChannel(int devChannel);
+ void resetDeviceChannel(int devChannel, bool mainThread);
private:
MusicList _playList;
@@ -260,6 +262,7 @@ private:
MusicEntry *_usedChannel[16];
int8 _channelRemap[16];
int8 _globalReverb;
+ bool _needsRemap;
DeviceChannelUsage _channelMap[16];