1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "audio/audiostream.h"
24 #include "audio/decoders/raw.h"
25 #include "common/config-manager.h"
26 #include "common/translation.h"
27 #include "gui/error.h"
28 
29 #include "sci/sci.h"
30 #include "sci/console.h"
31 #include "sci/resource/resource.h"
32 #include "sci/engine/features.h"
33 #include "sci/engine/kernel.h"
34 #include "sci/engine/state.h"
35 #include "sci/sound/midiparser_sci.h"
36 #include "sci/sound/music.h"
37 
38 //#define DEBUG_REMAP
39 
40 namespace Sci {
41 
SciMusic(SciVersion soundVersion,bool useDigitalSFX)42 SciMusic::SciMusic(SciVersion soundVersion, bool useDigitalSFX)
43 	: _soundVersion(soundVersion), _soundOn(true), _masterVolume(15), _globalReverb(0), _useDigitalSFX(useDigitalSFX), _needsResume(soundVersion > SCI_VERSION_0_LATE), _globalPause(0) {
44 
45 	// Reserve some space in the playlist, to avoid expensive insertion
46 	// operations
47 	_playList.reserve(10);
48 
49 	for (int i = 0; i < 16; i++) {
50 		_usedChannel[i] = 0;
51 		_channelRemap[i] = -1;
52 		_channelMap[i]._song = 0;
53 		_channelMap[i]._channel = -1;
54 	}
55 
56 	_queuedCommands.reserve(1000);
57 }
58 
~SciMusic()59 SciMusic::~SciMusic() {
60 	if (_pMidiDrv) {
61 		_pMidiDrv->close();
62 		delete _pMidiDrv;
63 	}
64 }
65 
init()66 void SciMusic::init() {
67 	// system init
68 	_pMixer = g_system->getMixer();
69 	// SCI sound init
70 	_dwTempo = 0;
71 
72 	const Common::Platform platform = g_sci->getPlatform();
73 	uint32 deviceFlags;
74 	if (g_sci->_features->generalMidiOnly()) {
75 		deviceFlags = MDT_MIDI;
76 	} else {
77 		deviceFlags = MDT_PCSPK | MDT_PCJR | MDT_ADLIB | MDT_MIDI;
78 	}
79 
80 	// Default to MIDI for Windows versions of SCI1.1 games, as their
81 	// soundtrack is written for GM.
82 	if (g_sci->_features->useAltWinGMSound())
83 		deviceFlags |= MDT_PREFER_GM;
84 
85 	// SCI_VERSION_0_EARLY games apparently don't support the CMS. At least there
86 	// is no patch resource 101 and I also haven't seen any CMS driver file so far.
87 	if (getSciVersion() > SCI_VERSION_0_EARLY && getSciVersion() <= SCI_VERSION_1_1)
88 		deviceFlags |= MDT_CMS;
89 
90 	if (platform == Common::kPlatformFMTowns) {
91 		if (getSciVersion() > SCI_VERSION_1_EARLY)
92 			deviceFlags = MDT_TOWNS;
93 		else
94 			deviceFlags |= MDT_TOWNS;
95 	}
96 
97 	if (platform == Common::kPlatformPC98)
98 		deviceFlags |= MDT_PC98;
99 
100 	uint32 dev = MidiDriver::detectDevice(deviceFlags);
101 	_musicType = MidiDriver::getMusicType(dev);
102 
103 	if (g_sci->_features->useAltWinGMSound() && _musicType != MT_GM) {
104 		warning("A Windows CD version with an alternate MIDI soundtrack has been chosen, "
105 				"but no MIDI music device has been selected. Reverting to the DOS soundtrack");
106 		g_sci->_features->forceDOSTracks();
107 #ifdef ENABLE_SCI32
108 	} else if (g_sci->_features->generalMidiOnly() && _musicType != MT_GM) {
109 		warning("This game only supports General MIDI, but a non-GM device has "
110 				"been selected. Some music may be wrong or missing");
111 #endif
112 	}
113 
114 	switch (_musicType) {
115 	case MT_ADLIB:
116 		// FIXME: There's no Amiga sound option, so we hook it up to AdLib
117 		if (platform == Common::kPlatformMacintosh || platform == Common::kPlatformAmiga) {
118 			if (getSciVersion() <= SCI_VERSION_0_LATE)
119 				_pMidiDrv = MidiPlayer_AmigaMac0_create(_soundVersion, platform);
120 			else
121 				_pMidiDrv = MidiPlayer_AmigaMac1_create(_soundVersion, platform);
122 		} else
123 			_pMidiDrv = MidiPlayer_AdLib_create(_soundVersion);
124 		break;
125 	case MT_PCJR:
126 		_pMidiDrv = MidiPlayer_PCJr_create(_soundVersion);
127 		break;
128 	case MT_PCSPK:
129 		_pMidiDrv = MidiPlayer_PCSpeaker_create(_soundVersion);
130 		break;
131 	case MT_CMS:
132 		_pMidiDrv = MidiPlayer_CMS_create(_soundVersion);
133 		break;
134 	case MT_TOWNS:
135 		_pMidiDrv = MidiPlayer_FMTowns_create(_soundVersion);
136 		break;
137 	case MT_PC98:
138 		_pMidiDrv = MidiPlayer_PC9801_create(_soundVersion);
139 		break;
140 	default:
141 		if (ConfMan.getInt("midi_mode") == kMidiModeFB01
142 		    || (ConfMan.hasKey("native_fb01") && ConfMan.getBool("native_fb01")))
143 			_pMidiDrv = MidiPlayer_Fb01_create(_soundVersion);
144 		else
145 			_pMidiDrv = MidiPlayer_Midi_create(_soundVersion);
146 	}
147 
148 	if (_pMidiDrv && !_pMidiDrv->open()) {
149 		_pMidiDrv->setTimerCallback(this, &miditimerCallback);
150 		_dwTempo = _pMidiDrv->getBaseTempo();
151 	} else {
152 		if (g_sci->getGameId() == GID_FUNSEEKER ||
153 			(g_sci->getGameId() == GID_GK2 && g_sci->isDemo())) {
154 			// HACK: The Fun Seeker's Guide demo doesn't have patch 3 and the version
155 			// of the Adlib driver (adl.drv) that it includes is unsupported. That demo
156 			// doesn't have any sound anyway, so this shouldn't be fatal.
157 		} else {
158 			const char *missingFiles = _pMidiDrv->reportMissingFiles();
159 			if (missingFiles) {
160 				Common::U32String message = _(
161 					"The selected audio driver requires the following file(s):\n\n"
162 				);
163 				message += Common::U32String(missingFiles);
164 				message += _("\n\n"
165 					"Some audio drivers (at least for some games) were made\n"
166 					"available by Sierra as aftermarket patches and thus might not\n"
167 					"have been installed as part of the original game setup.\n\n"
168 					"Please copy these file(s) into your game data directory.\n\n"
169 					"However, please note that the file(s) might not be available\n"
170 					"separately but only as content of (patched) resource bundles.\n"
171 					"In that case you may need to apply the original Sierra patch.\n\n"
172 				);
173 				::GUI::displayErrorDialog(message);
174 			}
175 			error("Failed to initialize sound driver");
176 		}
177 	}
178 
179 	// Find out what the first possible channel is (used, when doing channel
180 	// remapping).
181 	_driverFirstChannel = _pMidiDrv->getFirstChannel();
182 	_driverLastChannel = _pMidiDrv->getLastChannel();
183 	if (getSciVersion() <= SCI_VERSION_0_LATE)
184 		_globalReverb = _pMidiDrv->getReverb();	// Init global reverb for SCI0
185 
186 	_currentlyPlayingSample = NULL;
187 	_timeCounter = 0;
188 	_needsRemap = false;
189 }
190 
miditimerCallback(void * p)191 void SciMusic::miditimerCallback(void *p) {
192 	SciMusic *sciMusic = (SciMusic *)p;
193 
194 	Common::StackLock lock(sciMusic->_mutex);
195 	sciMusic->onTimer();
196 }
197 
onTimer()198 void SciMusic::onTimer() {
199 	const MusicList::iterator end = _playList.end();
200 	// sending out queued commands that were "sent" via main thread
201 	sendMidiCommandsFromQueue();
202 
203 	// remap channels, if requested
204 	if (_needsRemap)
205 		remapChannels(false);
206 	_needsRemap = false;
207 
208 	for (MusicList::iterator i = _playList.begin(); i != end; ++i)
209 		(*i)->onTimer();
210 }
211 
putMidiCommandInQueue(byte status,byte firstOp,byte secondOp)212 void SciMusic::putMidiCommandInQueue(byte status, byte firstOp, byte secondOp) {
213 	putMidiCommandInQueue(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16));
214 }
215 
putMidiCommandInQueue(uint32 midi)216 void SciMusic::putMidiCommandInQueue(uint32 midi) {
217 	_queuedCommands.push_back(MidiCommand(MidiCommand::kTypeMidiMessage, midi));
218 }
219 
putTrackInitCommandInQueue(MusicEntry * psnd)220 void SciMusic::putTrackInitCommandInQueue(MusicEntry *psnd) {
221 	_queuedCommands.push_back(MidiCommand(MidiCommand::kTypeTrackInit, psnd));
222 }
223 
removeTrackInitCommandsFromQueue(MusicEntry * psnd)224 void SciMusic::removeTrackInitCommandsFromQueue(MusicEntry *psnd) {
225 	for (MidiCommandQueue::iterator i = _queuedCommands.begin(); i != _queuedCommands.end(); )
226 		i = (i->_type ==  MidiCommand::kTypeTrackInit && i->_dataPtr == (void*)psnd) ? _queuedCommands.erase(i) : i + 1;
227 }
228 
229 // This sends the stored commands from queue to driver (is supposed to get
230 // called only during onTimer()). At least mt32 emulation doesn't like getting
231 // note-on commands from main thread (if we directly send, we would get a crash
232 // during piano scene in lsl5).
sendMidiCommandsFromQueue()233 void SciMusic::sendMidiCommandsFromQueue() {
234 	uint curCommand = 0;
235 	uint commandCount = _queuedCommands.size();
236 
237 	while (curCommand < commandCount) {
238 		if (_queuedCommands[curCommand]._type == MidiCommand::kTypeTrackInit) {
239 			if (_queuedCommands[curCommand]._dataPtr) {
240 				MusicList::iterator psnd = Common::find(_playList.begin(), _playList.end(), static_cast<MusicEntry*>(_queuedCommands[curCommand]._dataPtr));
241 				if (psnd != _playList.end() && (*psnd)->pMidiParser)
242 					(*psnd)->pMidiParser->initTrack();
243 			}
244 		} else {
245 			_pMidiDrv->send(_queuedCommands[curCommand]._dataVal);
246 		}
247 		curCommand++;
248 	}
249 	_queuedCommands.clear();
250 }
251 
clearPlayList()252 void SciMusic::clearPlayList() {
253 	// we must NOT lock our mutex here. Playlist is modified inside soundKill() which will lock the mutex
254 	//  during deletion. If we lock it here, a deadlock may occur within soundStop() because that one
255 	//  calls the mixer, which will also lock the mixer mutex and if the mixer thread is active during
256 	//  that time, we will get a deadlock.
257 	while (!_playList.empty()) {
258 		soundStop(_playList[0]);
259 		soundKill(_playList[0]);
260 	}
261 }
262 
pauseAll(bool pause)263 void SciMusic::pauseAll(bool pause) {
264 	const MusicList::iterator end = _playList.end();
265 	if (pause)
266 		_globalPause++;
267 	else
268 		_globalPause = MAX<int>(_globalPause - 1, 0);
269 	for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
270 #ifdef ENABLE_SCI32
271 		// The entire DAC will have been paused by the caller;
272 		// do not pause the individual samples too
273 		if (_soundVersion >= SCI_VERSION_2 && (*i)->isSample) {
274 			continue;
275 		}
276 #endif
277 		soundToggle(*i, pause);
278 	}
279 }
280 
stopAll()281 void SciMusic::stopAll() {
282 	const MusicList::iterator end = _playList.end();
283 	for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
284 		soundStop(*i);
285 	}
286 }
287 
stopAllSamples()288 void SciMusic::stopAllSamples() {
289 	const MusicList::iterator end = _playList.end();
290 	for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
291 		if ((*i)->isSample) {
292 			soundStop(*i);
293 		}
294 	}
295 }
296 
soundSetSoundOn(bool soundOnFlag)297 void SciMusic::soundSetSoundOn(bool soundOnFlag) {
298 	Common::StackLock lock(_mutex);
299 
300 	_soundOn = soundOnFlag;
301 	_pMidiDrv->playSwitch(soundOnFlag);
302 }
303 
soundGetVoices()304 uint16 SciMusic::soundGetVoices() {
305 	Common::StackLock lock(_mutex);
306 
307 	return _pMidiDrv->getPolyphony();
308 }
309 
getSlot(reg_t obj)310 MusicEntry *SciMusic::getSlot(reg_t obj) {
311 	Common::StackLock lock(_mutex);
312 
313 	const MusicList::iterator end = _playList.end();
314 	for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
315 		if ((*i)->soundObj == obj)
316 			return *i;
317 	}
318 
319 	return NULL;
320 }
321 
getFirstSlotWithStatus(SoundStatus status)322 MusicEntry *SciMusic::getFirstSlotWithStatus(SoundStatus status) {
323 	for (MusicList::iterator i = _playList.begin(); i != _playList.end(); ++i) {
324 		if ((*i)->status == status)
325 			return *i;
326 	}
327 	return 0;
328 }
329 
setGlobalReverb(int8 reverb)330 void SciMusic::setGlobalReverb(int8 reverb) {
331 	Common::StackLock lock(_mutex);
332 	if (reverb != 127) {
333 		// Set global reverb normally
334 		_globalReverb = reverb;
335 
336 		// Check the reverb of the active song...
337 		const MusicList::iterator end = _playList.end();
338 		for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
339 			if ((*i)->status == kSoundPlaying) {
340 				if ((*i)->reverb == 127)			// Active song has no reverb
341 					_pMidiDrv->setReverb(reverb);	// Set the global reverb
342 				break;
343 			}
344 		}
345 	} else {
346 		// Set reverb of the active song
347 		const MusicList::iterator end = _playList.end();
348 		for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
349 			if ((*i)->status == kSoundPlaying) {
350 				_pMidiDrv->setReverb((*i)->reverb);	// Set the song's reverb
351 				break;
352 			}
353 		}
354 	}
355 }
356 
getCurrentReverb()357 byte SciMusic::getCurrentReverb() {
358 	Common::StackLock lock(_mutex);
359 	return _pMidiDrv->getReverb();
360 }
361 
362 // A larger priority value has higher priority. For equal priority values,
363 // songs that have been added later have higher priority.
musicEntryCompare(const MusicEntry * l,const MusicEntry * r)364 static bool musicEntryCompare(const MusicEntry *l, const MusicEntry *r) {
365 	return (l->priority > r->priority) || (l->priority == r->priority && l->time > r->time);
366 }
367 
sortPlayList()368 void SciMusic::sortPlayList() {
369 	// Sort the play list in descending priority order
370 	Common::sort(_playList.begin(), _playList.end(), musicEntryCompare);
371 }
372 
soundInitSnd(MusicEntry * pSnd)373 void SciMusic::soundInitSnd(MusicEntry *pSnd) {
374 	// Remove all currently mapped channels of this MusicEntry first,
375 	// since they will no longer be valid.
376 	for (int i = 0; i < 16; ++i) {
377 		if (_channelMap[i]._song == pSnd) {
378 			_channelMap[i]._song = 0;
379 			_channelMap[i]._channel = -1;
380 		}
381 	}
382 
383 	int channelFilterMask = 0;
384 	SoundResource::Track *track = pSnd->soundRes->getTrackByType(_pMidiDrv->getPlayId());
385 
386 	// If MIDI device is selected but there is no digital track in sound
387 	// resource try to use Adlib's digital sample if possible. Also, if the
388 	// track couldn't be found, load the digital track, as some games depend on
389 	// this (e.g. the Longbow demo).
390 	if (!track || (_useDigitalSFX && track->digitalChannelNr == -1)) {
391 		SoundResource::Track *digital = pSnd->soundRes->getDigitalTrack();
392 		if (digital)
393 			track = digital;
394 	}
395 
396 	pSnd->time = ++_timeCounter;
397 
398 	if (track) {
399 		bool playSample;
400 
401 		if (_soundVersion <= SCI_VERSION_0_LATE && !_useDigitalSFX) {
402 			// For SCI0 the digital sample is present in the same track as the
403 			// MIDI. If the user specifically requests not to use the digital
404 			// samples, play the MIDI data instead. If the MIDI portion of the
405 			// track is empty however, play the digital sample anyway. This is
406 			// necessary for e.g. the "Where am I?" sample in the SQ3 intro.
407 			playSample = false;
408 
409 			if (track->channelCount == 2) {
410 				SoundResource::Channel &chan = track->channels[0];
411 				if (chan.data.size() < 2 || chan.data[1] == SCI_MIDI_EOT) {
412 					playSample = true;
413 				}
414 			}
415 		} else
416 			playSample = (track->digitalChannelNr != -1 && (_useDigitalSFX || track->channelCount == 1));
417 
418 		// Play digital sample
419 		if (playSample) {
420 			const SciSpan<const byte> &channelData = track->channels[track->digitalChannelNr].data;
421 			delete pSnd->pStreamAud;
422 			byte flags = Audio::FLAG_UNSIGNED;
423 			// Amiga SCI1 games had signed sound data
424 			if (_soundVersion >= SCI_VERSION_1_EARLY && g_sci->getPlatform() == Common::kPlatformAmiga)
425 				flags = 0;
426 			int endPart = track->digitalSampleEnd > 0 ? (track->digitalSampleSize - track->digitalSampleEnd) : 0;
427 			const uint size = track->digitalSampleSize - track->digitalSampleStart - endPart;
428 			pSnd->pStreamAud = Audio::makeRawStream(channelData.getUnsafeDataAt(track->digitalSampleStart),
429 								size, track->digitalSampleRate, flags, DisposeAfterUse::NO);
430 			assert(pSnd->pStreamAud);
431 			delete pSnd->pLoopStream;
432 			pSnd->pLoopStream = 0;
433 			pSnd->soundType = Audio::Mixer::kSFXSoundType;
434 			pSnd->hCurrentAud = Audio::SoundHandle();
435 			pSnd->playBed = false;
436 			pSnd->overridePriority = false;
437 			pSnd->isSample = true;
438 		} else {
439 			// play MIDI track
440 			Common::StackLock lock(_mutex);
441 			pSnd->soundType = Audio::Mixer::kMusicSoundType;
442 			if (pSnd->pMidiParser == NULL) {
443 				pSnd->pMidiParser = new MidiParser_SCI(_soundVersion, this);
444 				pSnd->pMidiParser->setMidiDriver(_pMidiDrv);
445 				pSnd->pMidiParser->setTimerRate(_dwTempo);
446 				pSnd->pMidiParser->setMasterVolume(_masterVolume);
447 			}
448 
449 			pSnd->pauseCounter = 0;
450 
451 			// Find out what channels to filter for SCI0
452 			channelFilterMask = pSnd->soundRes->getChannelFilterMask(_pMidiDrv->getPlayId(), _pMidiDrv->hasRhythmChannel());
453 
454 			for (int i = 0; i < 16; ++i)
455 				pSnd->_usedChannels[i] = 0xFF;
456 			for (int i = 0; i < track->channelCount; ++i) {
457 				// skip digital channel
458 				if (i == track->digitalChannelNr) {
459 					continue;
460 				}
461 
462 				SoundResource::Channel &chan = track->channels[i];
463 
464 				assert(chan.number < ARRAYSIZE(pSnd->_chan));
465 				pSnd->_usedChannels[i] = chan.number;
466 				pSnd->_chan[chan.number]._dontRemap = (chan.flags & 2);
467 				pSnd->_chan[chan.number]._prio = chan.prio;
468 				pSnd->_chan[chan.number]._voices = chan.poly;
469 
470 				// CHECKME: Some SCI versions use chan.flags & 1 for this:
471 				pSnd->_chan[chan.number]._dontMap = false;
472 
473 				// FIXME: Most MIDI tracks use the first 10 bytes for
474 				// fixed MIDI commands. SSCI skips those the first iteration,
475 				// but _does_ update channel state (including volume) with
476 				// them. Specifically, prio/voices, patch, volume, pan.
477 				// This should probably be implemented in
478 				// MidiParser_SCI::loadMusic.
479 			}
480 
481 			pSnd->pMidiParser->mainThreadBegin();
482 			// loadMusic() below calls jumpToTick.
483 			// Disable sound looping and hold before jumpToTick is called,
484 			// otherwise the song may keep looping forever when it ends in
485 			// jumpToTick (e.g. LSL3, when going left from room 210).
486 			uint16 prevLoop = pSnd->loop;
487 			int16 prevHold = pSnd->hold;
488 			pSnd->loop = 0;
489 			pSnd->hold = -1;
490 			pSnd->playBed = false;
491 			pSnd->overridePriority = false;
492 
493 			pSnd->pMidiParser->loadMusic(track, pSnd, channelFilterMask, _soundVersion);
494 			pSnd->reverb = pSnd->pMidiParser->getSongReverb();
495 
496 			// Restore looping and hold
497 			pSnd->loop = prevLoop;
498 			pSnd->hold = prevHold;
499 			pSnd->pMidiParser->mainThreadEnd();
500 		}
501 	}
502 }
503 
soundPlay(MusicEntry * pSnd,bool restoring)504 void SciMusic::soundPlay(MusicEntry *pSnd, bool restoring) {
505 	_mutex.lock();
506 
507 	if (_soundVersion <= SCI_VERSION_1_EARLY && pSnd->playBed) {
508 		// If pSnd->playBed, and version <= SCI1_EARLY, then kill
509 		// existing sounds with playBed enabled.
510 
511 		uint playListCount = _playList.size();
512 		for (uint i = 0; i < playListCount; i++) {
513 			if (_playList[i] != pSnd && _playList[i]->playBed) {
514 				debugC(2, kDebugLevelSound, "Automatically stopping old playBed song from soundPlay");
515 				MusicEntry *old = _playList[i];
516 				_mutex.unlock();
517 				soundStop(old);
518 				_mutex.lock();
519 				break;
520 			}
521 		}
522 	}
523 
524 	uint playListCount = _playList.size();
525 	uint playListNo = playListCount;
526 	MusicEntry *alreadyPlaying = NULL;
527 
528 	// searching if sound is already in _playList
529 	for (uint i = 0; i < playListCount; i++) {
530 		if (_playList[i] == pSnd)
531 			playListNo = i;
532 		if ((_playList[i]->status == kSoundPlaying) && (_playList[i]->pMidiParser))
533 			alreadyPlaying = _playList[i];
534 	}
535 	if (playListNo == playListCount) { // not found
536 		_playList.push_back(pSnd);
537 	}
538 
539 	pSnd->time = ++_timeCounter;
540 	sortPlayList();
541 
542 	_mutex.unlock();	// unlock to perform mixer-related calls
543 
544 	if (pSnd->pMidiParser) {
545 		// Original SCI0 doesn't use this function to restore sound. The function it has
546 		// for that will not check priorities.
547 		if ((_soundVersion <= SCI_VERSION_0_LATE) && alreadyPlaying && !restoring) {
548 			// Music already playing in SCI0?
549 			if (pSnd->priority > alreadyPlaying->priority) {
550 				// And new priority higher? pause previous music and play new one immediately.
551 				// Example of such case: lsl3, when getting points (jingle is played then)
552 				soundPause(alreadyPlaying);
553 			} else {
554 				// And new priority equal or lower? queue up music and play it afterwards done by
555 				//  SoundCommandParser::updateSci0Cues()
556 				// Example of such case: iceman room 14
557 				pSnd->status = kSoundPaused;
558 				return;
559 			}
560 		}
561 	}
562 
563 	if (pSnd->isSample) {
564 #ifdef ENABLE_SCI32
565 		if (_soundVersion >= SCI_VERSION_2) {
566 			// TODO: Sound number, loop state, and volume come from soundObj
567 			// in SSCI. Getting them from MusicEntry could cause a bug if the
568 			// soundObj was updated by a game script and not copied back to
569 			// MusicEntry.
570 			g_sci->_audio32->restart(ResourceId(kResourceTypeAudio, pSnd->resourceId), true, pSnd->loop != 0 && pSnd->loop != 1, pSnd->volume, pSnd->soundObj, false);
571 			return;
572 		}
573 #endif
574 		if (_currentlyPlayingSample && _pMixer->isSoundHandleActive(_currentlyPlayingSample->hCurrentAud)) {
575 			// Another sample is already playing, we have to stop that one
576 			// SSCI is only able to play 1 sample at a time
577 			// In Space Quest 5 room 250 the player is able to open the air-hatch and kill himself.
578 			//  In that situation the scripts are playing 2 samples at the same time and the first sample
579 			//  is not supposed to play.
580 			// TODO: SSCI actually calls kDoAudio(play) internally, which stops other samples from being played
581 			//        but such a change isn't trivial, because we also handle Sound resources in here, that contain samples
582 			_pMixer->stopHandle(_currentlyPlayingSample->hCurrentAud);
583 			warning("kDoSound: sample already playing, old resource %d, new resource %d", _currentlyPlayingSample->resourceId, pSnd->resourceId);
584 		}
585 		// Sierra SCI ignores volume set when playing samples via kDoSound
586 		//  At least freddy pharkas/CD has a script bug that sets volume to 0
587 		//  when playing the "score" sample
588 		if (pSnd->loop > 1) {
589 			pSnd->pLoopStream = new Audio::LoopingAudioStream(pSnd->pStreamAud,	pSnd->loop, DisposeAfterUse::NO);
590 			_pMixer->playStream(pSnd->soundType, &pSnd->hCurrentAud,
591 									pSnd->pLoopStream, -1, _pMixer->kMaxChannelVolume, 0,
592 									DisposeAfterUse::NO);
593 		} else {
594 			// Rewind in case we play the same sample multiple times
595 			// (non-looped) like in pharkas right at the start
596 			pSnd->pStreamAud->rewind();
597 			_pMixer->playStream(pSnd->soundType, &pSnd->hCurrentAud,
598 									pSnd->pStreamAud, -1, _pMixer->kMaxChannelVolume, 0,
599 									DisposeAfterUse::NO);
600 		}
601 		// Remember the sample, that is now playing
602 		_currentlyPlayingSample = pSnd;
603 	} else {
604 		if (pSnd->pMidiParser) {
605 			Common::StackLock lock(_mutex);
606 			pSnd->pMidiParser->mainThreadBegin();
607 
608 			// The track init always needs to be done. Otherwise some sounds will not be properly set up (bug #11476).
609 			// It is also safe to do this for paused tracks, since the jumpToTick() command further down will parse through
610 			// the song from the beginning up to the resume position and ensure that the actual current voice mapping,
611 			// instrument and volume settings etc. are correct.
612 			// First glance at disasm might suggest that it has to be called only once per sound. But the truth is that
613 			// when calling the sound driver opcode for sound restoring (opcode no. 9, we don't have that) it will
614 			// internally also call initTrack(). And it wouldn't make sense otherwise, since without that the channel setup
615 			// from the last sound would still be active.
616 			pSnd->pMidiParser->initTrack();
617 
618 			if (pSnd->status != kSoundPaused)
619 				pSnd->pMidiParser->sendInitCommands();
620 			pSnd->pMidiParser->setVolume(pSnd->volume);
621 
622 			// Disable sound looping and hold before jumpToTick is called,
623 			// otherwise the song may keep looping forever when it ends in jumpToTick.
624 			// This is needed when loading saved games, or when a game
625 			// stops the same sound twice (e.g. LSL3 Amiga, going left from
626 			// room 210 to talk with Kalalau). Fixes bugs #5404 and #5503.
627 			uint16 prevLoop = pSnd->loop;
628 			int16 prevHold = pSnd->hold;
629 			pSnd->loop = 0;
630 			pSnd->hold = -1;
631 
632 			bool fastForward = (pSnd->status == kSoundPaused) || (pSnd->status == kSoundPlaying && restoring);
633 			if (!fastForward) {
634 				pSnd->pMidiParser->jumpToTick(0);
635 			} else {
636 				// Fast forward to the last position and perform associated events when loading
637 				pSnd->pMidiParser->jumpToTick(pSnd->ticker, true, true, true);
638 			}
639 
640 			// Restore looping and hold
641 			pSnd->loop = prevLoop;
642 			pSnd->hold = prevHold;
643 			pSnd->pMidiParser->mainThreadEnd();
644 		}
645 	}
646 
647 	pSnd->status = kSoundPlaying;
648 
649 	_mutex.lock();
650 	remapChannels();
651 	_mutex.unlock();
652 }
653 
soundStop(MusicEntry * pSnd)654 void SciMusic::soundStop(MusicEntry *pSnd) {
655 	SoundStatus previousStatus = pSnd->status;
656 	pSnd->status = kSoundStopped;
657 
658 	if (pSnd->isSample) {
659 #ifdef ENABLE_SCI32
660 		if (_soundVersion >= SCI_VERSION_2) {
661 			g_sci->_audio32->stop(ResourceId(kResourceTypeAudio, pSnd->resourceId), pSnd->soundObj);
662 		} else {
663 #endif
664 			if (_currentlyPlayingSample == pSnd)
665 				_currentlyPlayingSample = NULL;
666 			_pMixer->stopHandle(pSnd->hCurrentAud);
667 #ifdef ENABLE_SCI32
668 		}
669 #endif
670 	}
671 
672 	if (pSnd->pMidiParser) {
673 		Common::StackLock lock(_mutex);
674 		pSnd->pMidiParser->mainThreadBegin();
675 		// We shouldn't call stop in case it's paused, otherwise we would send
676 		// allNotesOff() again
677 		if (previousStatus == kSoundPlaying)
678 			pSnd->pMidiParser->stop();
679 		pSnd->pMidiParser->mainThreadEnd();
680 		remapChannels();
681 	}
682 
683 	pSnd->fadeStep = 0; // end fading, if fading was in progress
684 
685 	// SSCI0 resumes the next available sound from the (priority ordered) list with a paused status.
686 	if (_soundVersion <= SCI_VERSION_0_LATE && (pSnd = getFirstSlotWithStatus(kSoundPaused)))
687 		soundResume(pSnd);
688 }
689 
soundSetVolume(MusicEntry * pSnd,byte volume)690 void SciMusic::soundSetVolume(MusicEntry *pSnd, byte volume) {
691 	assert(volume <= MUSIC_VOLUME_MAX);
692 	if (!pSnd->isSample && pSnd->pMidiParser) {
693 		Common::StackLock lock(_mutex);
694 		pSnd->pMidiParser->mainThreadBegin();
695 		pSnd->pMidiParser->setVolume(volume);
696 		pSnd->pMidiParser->mainThreadEnd();
697 	}
698 }
699 
700 // this is used to set volume of the sample, used for fading only!
soundSetSampleVolume(MusicEntry * pSnd,byte volume)701 void SciMusic::soundSetSampleVolume(MusicEntry *pSnd, byte volume) {
702 	assert(volume <= MUSIC_VOLUME_MAX);
703 	assert(pSnd->pStreamAud);
704 	_pMixer->setChannelVolume(pSnd->hCurrentAud, volume * 2); // Mixer is 0-255, SCI is 0-127
705 }
706 
soundSetPriority(MusicEntry * pSnd,byte prio)707 void SciMusic::soundSetPriority(MusicEntry *pSnd, byte prio) {
708 	Common::StackLock lock(_mutex);
709 
710 	pSnd->priority = prio;
711 	pSnd->time = ++_timeCounter;
712 	sortPlayList();
713 }
714 
soundKill(MusicEntry * pSnd)715 void SciMusic::soundKill(MusicEntry *pSnd) {
716 	pSnd->status = kSoundStopped;
717 
718 	_mutex.lock();
719 	remapChannels();
720 
721 	if (pSnd->pMidiParser) {
722 		pSnd->pMidiParser->mainThreadBegin();
723 		pSnd->pMidiParser->unloadMusic();
724 		pSnd->pMidiParser->mainThreadEnd();
725 		delete pSnd->pMidiParser;
726 		pSnd->pMidiParser = NULL;
727 	}
728 
729 	_mutex.unlock();
730 
731 	if (pSnd->isSample) {
732 #ifdef ENABLE_SCI32
733 		if (_soundVersion >= SCI_VERSION_2) {
734 			g_sci->_audio32->stop(ResourceId(kResourceTypeAudio, pSnd->resourceId), pSnd->soundObj);
735 		} else {
736 #endif
737 			if (_currentlyPlayingSample == pSnd) {
738 				// Forget about this sound, in case it was currently playing
739 				_currentlyPlayingSample = NULL;
740 			}
741 			_pMixer->stopHandle(pSnd->hCurrentAud);
742 #ifdef ENABLE_SCI32
743 		}
744 #endif
745 		delete pSnd->pStreamAud;
746 		pSnd->pStreamAud = NULL;
747 		delete pSnd->pLoopStream;
748 		pSnd->pLoopStream = 0;
749 		pSnd->isSample = false;
750 	}
751 
752 	_mutex.lock();
753 	uint sz = _playList.size(), i;
754 	// Remove sound from playlist
755 	for (i = 0; i < sz; i++) {
756 		if (_playList[i] == pSnd) {
757 			delete _playList[i]->soundRes;
758 			delete _playList[i];
759 			_playList.remove_at(i);
760 			break;
761 		}
762 	}
763 	_mutex.unlock();
764 }
765 
soundPause(MusicEntry * pSnd)766 void SciMusic::soundPause(MusicEntry *pSnd) {
767 	// SCI seems not to be pausing samples played back by kDoSound at all
768 	//  It only stops looping samples (actually doesn't loop them again before they are unpaused)
769 	//  Examples: Space Quest 1 death by acid drops (pause is called even specifically for the sample, see bug #5097)
770 	//             Eco Quest 1 during the intro when going to the abort-menu
771 	//             In both cases sierra sci keeps playing
772 	//            Leisure Suit Larry 1 doll scene - it seems that pausing here actually just stops
773 	//             further looping from happening
774 	//  This is a somewhat bigger change, I'm leaving in the old code in here just in case
775 	//  I'm currently pausing looped sounds directly, non-looped sounds won't get paused
776 	if ((pSnd->pStreamAud) && (!pSnd->pLoopStream))
777 		return;
778 	pSnd->pauseCounter++;
779 	if (pSnd->status != kSoundPlaying)
780 		return;
781 	_needsResume = true;
782 	pSnd->status = kSoundPaused;
783 	if (pSnd->pStreamAud) {
784 		_pMixer->pauseHandle(pSnd->hCurrentAud, true);
785 	} else {
786 		if (pSnd->pMidiParser) {
787 			Common::StackLock lock(_mutex);
788 			pSnd->pMidiParser->mainThreadBegin();
789 			pSnd->pMidiParser->pause();
790 			pSnd->pMidiParser->mainThreadEnd();
791 			remapChannels();
792 		}
793 	}
794 }
795 
soundResume(MusicEntry * pSnd)796 void SciMusic::soundResume(MusicEntry *pSnd) {
797 	if (pSnd->pauseCounter > 0)
798 		pSnd->pauseCounter--;
799 	if (pSnd->pauseCounter != 0)
800 		return;
801 	if (pSnd->status != kSoundPaused || (_globalPause && !_needsResume))
802 		return;
803 	_needsResume = (_soundVersion > SCI_VERSION_0_LATE);
804 	if (pSnd->pStreamAud) {
805 		_pMixer->pauseHandle(pSnd->hCurrentAud, false);
806 		pSnd->status = kSoundPlaying;
807 	} else {
808 		soundPlay(pSnd, true);
809 	}
810 }
811 
soundToggle(MusicEntry * pSnd,bool pause)812 void SciMusic::soundToggle(MusicEntry *pSnd, bool pause) {
813 #ifdef ENABLE_SCI32
814 	if (_soundVersion >= SCI_VERSION_2_1_EARLY && pSnd->isSample) {
815 		if (pause) {
816 			g_sci->_audio32->pause(ResourceId(kResourceTypeAudio, pSnd->resourceId), pSnd->soundObj);
817 		} else {
818 			g_sci->_audio32->resume(ResourceId(kResourceTypeAudio, pSnd->resourceId), pSnd->soundObj);
819 		}
820 
821 		return;
822 	}
823 #endif
824 
825 	if (pause)
826 		soundPause(pSnd);
827 	else
828 		soundResume(pSnd);
829 }
830 
soundGetMasterVolume()831 uint16 SciMusic::soundGetMasterVolume() {
832 	if (ConfMan.getBool("mute")) {
833 		// When a game is muted, the master volume is set to zero so that
834 		// mute applies to external MIDI devices, but this should not be
835 		// communicated to the game as it will cause the UI to be drawn with
836 		// the wrong (zero) volume for music
837 		return (ConfMan.getInt("music_volume") + 1) * MUSIC_MASTERVOLUME_MAX / Audio::Mixer::kMaxMixerVolume;
838 	}
839 
840 	return _masterVolume;
841 }
842 
soundSetMasterVolume(uint16 vol)843 void SciMusic::soundSetMasterVolume(uint16 vol) {
844 	_masterVolume = vol;
845 
846 	Common::StackLock lock(_mutex);
847 
848 	const MusicList::iterator end = _playList.end();
849 	for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
850 		if ((*i)->pMidiParser)
851 			(*i)->pMidiParser->setMasterVolume(vol);
852 	}
853 }
854 
sendMidiCommand(uint32 cmd)855 void SciMusic::sendMidiCommand(uint32 cmd) {
856 	Common::StackLock lock(_mutex);
857 	_pMidiDrv->send(cmd);
858 }
859 
sendMidiCommand(MusicEntry * pSnd,uint32 cmd)860 void SciMusic::sendMidiCommand(MusicEntry *pSnd, uint32 cmd) {
861 	Common::StackLock lock(_mutex);
862 	if (!pSnd->pMidiParser) {
863 		// FPFP calls kDoSound SendMidi to mute and unmute its gameMusic2 sound
864 		//  object but some scenes set this to an audio sample. In Act 2, room
865 		//  660 sets this to audio of restaurant customers talking. Walking up
866 		//  the hotel stairs from room 500 to 235 calls gameMusic2:mute and
867 		//  triggers this if gameMusic2 hasn't changed. Bug #10952
868 		warning("tried to cmdSendMidi on non midi slot (%04x:%04x)", PRINT_REG(pSnd->soundObj));
869 		return;
870 	}
871 
872 	pSnd->pMidiParser->mainThreadBegin();
873 	pSnd->pMidiParser->sendFromScriptToDriver(cmd);
874 	pSnd->pMidiParser->mainThreadEnd();
875 }
876 
printPlayList(Console * con)877 void SciMusic::printPlayList(Console *con) {
878 	Common::StackLock lock(_mutex);
879 
880 	const char *musicStatus[] = { "Stopped", "Initialized", "Paused", "Playing" };
881 
882 	for (uint32 i = 0; i < _playList.size(); i++) {
883 		MusicEntry *song = _playList[i];
884 		con->debugPrintf("%d: %04x:%04x (%s), resource id: %d, status: %s, %s type\n",
885 						i, PRINT_REG(song->soundObj),
886 						g_sci->getEngineState()->_segMan->getObjectName(song->soundObj),
887 						song->resourceId, musicStatus[song->status],
888 						song->pMidiParser ? "MIDI" : "digital audio");
889 	}
890 }
891 
printSongInfo(reg_t obj,Console * con)892 void SciMusic::printSongInfo(reg_t obj, Console *con) {
893 	Common::StackLock lock(_mutex);
894 
895 	const char *musicStatus[] = { "Stopped", "Initialized", "Paused", "Playing" };
896 
897 	const MusicList::iterator end = _playList.end();
898 	for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
899 		MusicEntry *song = *i;
900 		if (song->soundObj == obj) {
901 			con->debugPrintf("Resource id: %d, status: %s\n", song->resourceId, musicStatus[song->status]);
902 			con->debugPrintf("dataInc: %d, hold: %d, loop: %d\n", song->dataInc, song->hold, song->loop);
903 			con->debugPrintf("signal: %d, priority: %d\n", song->signal, song->priority);
904 			con->debugPrintf("ticker: %d, volume: %d\n", song->ticker, song->volume);
905 
906 			if (song->pMidiParser) {
907 				con->debugPrintf("Type: MIDI\n");
908 				if (song->soundRes) {
909 					SoundResource::Track *track = song->soundRes->getTrackByType(_pMidiDrv->getPlayId());
910 					con->debugPrintf("Channels: %d\n", track->channelCount);
911 				}
912 			} else if (song->pStreamAud || song->pLoopStream) {
913 				con->debugPrintf("Type: digital audio (%s), sound active: %s\n",
914 					song->pStreamAud ? "non looping" : "looping",
915 					_pMixer->isSoundHandleActive(song->hCurrentAud) ? "yes" : "no");
916 				if (song->soundRes) {
917 					con->debugPrintf("Sound resource information:\n");
918 					SoundResource::Track *track = song->soundRes->getTrackByType(_pMidiDrv->getPlayId());
919 					if (track && track->digitalChannelNr != -1) {
920 						con->debugPrintf("Sample size: %d, sample rate: %d, channels: %d, digital channel number: %d\n",
921 							track->digitalSampleSize, track->digitalSampleRate, track->channelCount, track->digitalChannelNr);
922 					}
923 				}
924 			}
925 
926 			return;
927 		}
928 	}
929 
930 	con->debugPrintf("Song object not found in playlist");
931 }
932 
MusicEntry()933 MusicEntry::MusicEntry() {
934 	soundObj = NULL_REG;
935 
936 	soundRes = 0;
937 	resourceId = 0;
938 
939 	dataInc = 0;
940 	ticker = 0;
941 	signal = 0;
942 	priority = 0;
943 	loop = 0;
944 	volume = MUSIC_VOLUME_DEFAULT;
945 	hold = -1;
946 	reverb = -1;
947 
948 	pauseCounter = 0;
949 	sampleLoopCounter = 0;
950 
951 	fadeTo = 0;
952 	fadeStep = 0;
953 	fadeTicker = 0;
954 	fadeTickerStep = 0;
955 	fadeSetVolume = false;
956 	fadeCompleted = false;
957 	stopAfterFading = false;
958 
959 	status = kSoundStopped;
960 
961 	soundType = Audio::Mixer::kMusicSoundType;
962 
963 	pStreamAud = 0;
964 	pLoopStream = 0;
965 	pMidiParser = 0;
966 	isSample = false;
967 
968 	for (int i = 0; i < 16; ++i) {
969 		_usedChannels[i] = 0xFF;
970 		_chan[i]._prio = 127;
971 		_chan[i]._voices = 0;
972 		_chan[i]._dontRemap = false;
973 		_chan[i]._mute = false;
974 	}
975 }
976 
~MusicEntry()977 MusicEntry::~MusicEntry() {
978 }
979 
onTimer()980 void MusicEntry::onTimer() {
981 	if (!signal) {
982 		if (!signalQueue.empty()) {
983 			// no signal set, but signal in queue, set that one
984 			signal = signalQueue[0];
985 			signalQueue.remove_at(0);
986 		}
987 	}
988 
989 	if (status != kSoundPlaying || !loop)
990 		return;
991 
992 	// Fade MIDI and digital sound effects
993 	if (fadeStep)
994 		doFade();
995 
996 	// Only process MIDI streams in this thread, not digital sound effects
997 	if (pMidiParser) {
998 		pMidiParser->onTimer();
999 		ticker = (uint16)pMidiParser->getTick();
1000 	}
1001 }
1002 
doFade()1003 void MusicEntry::doFade() {
1004 	if (fadeTicker)
1005 		fadeTicker--;
1006 	else {
1007 		fadeTicker = fadeTickerStep;
1008 		volume += fadeStep;
1009 		if (((fadeStep > 0) && (volume >= fadeTo)) || ((fadeStep < 0) && (volume <= fadeTo))) {
1010 			volume = fadeTo;
1011 			fadeStep = 0;
1012 			fadeCompleted = true;
1013 		}
1014 
1015 		// Only process MIDI streams in this thread, not digital sound effects
1016 		if (pMidiParser) {
1017 			pMidiParser->setVolume(volume);
1018 		}
1019 
1020 		fadeSetVolume = true; // set flag so that SoundCommandParser::cmdUpdateCues will set the volume of the stream
1021 	}
1022 }
1023 
setSignal(int newSignal)1024 void MusicEntry::setSignal(int newSignal) {
1025 	// For SCI0, we cache the signals to set, as some songs might
1026 	// update their signal faster than kGetEvent is called (which is where
1027 	// we manually invoke kDoSoundUpdateCues for SCI0 games). SCI01 and
1028 	// newer handle signalling inside kDoSoundUpdateCues. Refer to bug #5218
1029 	if (g_sci->_features->detectDoSoundType() <= SCI_VERSION_0_LATE) {
1030 		if (!signal) {
1031 			signal = newSignal;
1032 		} else {
1033 			// signal already set and waiting for getting to scripts, queue new one
1034 			signalQueue.push_back(newSignal);
1035 		}
1036 	} else {
1037 		// Set the signal directly for newer games, otherwise the sound
1038 		// object might be deleted already later on (refer to bug #5243)
1039 		signal = newSignal;
1040 	}
1041 }
1042 
1043 
swap(int i,int j)1044 void ChannelRemapping::swap(int i, int j) {
1045 	DeviceChannelUsage t1;
1046 	int t2;
1047 	bool t3;
1048 
1049 	t1 = _map[i]; _map[i] = _map[j]; _map[j] = t1;
1050 	t2 = _prio[i]; _prio[i] = _prio[j]; _prio[j] = t2;
1051 	t2 = _voices[i]; _voices[i] = _voices[j]; _voices[j] = t2;
1052 	t3 = _dontRemap[i]; _dontRemap[i] = _dontRemap[j]; _dontRemap[j] = t3;
1053 }
1054 
evict(int i)1055 void ChannelRemapping::evict(int i) {
1056 	_freeVoices += _voices[i];
1057 
1058 	_map[i]._song = 0;
1059 	_map[i]._channel = -1;
1060 	_prio[i] = 0;
1061 	_voices[i] = 0;
1062 	_dontRemap[i] = false;
1063 }
1064 
clear()1065 void ChannelRemapping::clear() {
1066 	for (int i = 0; i < 16; ++i) {
1067 		_map[i]._song = 0;
1068 		_map[i]._channel = -1;
1069 		_prio[i] = 0;
1070 		_voices[i] = 0;
1071 		_dontRemap[i] = false;
1072 	}
1073 }
1074 
operator =(ChannelRemapping & other)1075 ChannelRemapping& ChannelRemapping::operator=(ChannelRemapping& other) {
1076 	for (int i = 0; i < 16; ++i) {
1077 		_map[i] = other._map[i];
1078 		_prio[i] = other._prio[i];
1079 		_voices[i] = other._voices[i];
1080 		_dontRemap[i] = other._dontRemap[i];
1081 	}
1082 	_freeVoices = other._freeVoices;
1083 
1084 	return *this;
1085 }
1086 
lowestPrio() const1087 int ChannelRemapping::lowestPrio() const {
1088 	int max = 0;
1089 	int channel = -1;
1090 	for (int i = 0; i < 16; ++i) {
1091 		if (_prio[i] > max) {
1092 			max = _prio[i];
1093 			channel = i;
1094 		}
1095 	}
1096 	return channel;
1097 }
1098 
1099 
remapChannels(bool mainThread)1100 void SciMusic::remapChannels(bool mainThread) {
1101 	if (_soundVersion <= SCI_VERSION_0_LATE)
1102 		return;
1103 
1104 	// NB: This function should only be called with _mutex locked
1105 	// Make sure to set the mainThread argument correctly.
1106 
1107 
1108 	ChannelRemapping *map = determineChannelMap();
1109 
1110 	DeviceChannelUsage currentMap[16];
1111 
1112 #ifdef DEBUG_REMAP
1113 	debug("Remap results:");
1114 #endif
1115 
1116 	// Save current map, and then start from an empty map
1117 	for (int i = 0; i < 16; ++i) {
1118 		currentMap[i] = _channelMap[i];
1119 		_channelMap[i]._song = 0;
1120 		_channelMap[i]._channel = -1;
1121 	}
1122 
1123 	// Inform MidiParsers of any unmapped channels
1124 	const MusicList::iterator end = _playList.end();
1125 	int songIndex = -1;
1126 	for (MusicList::iterator i = _playList.begin(); i != end; ++i) {
1127 		MusicEntry *song = *i;
1128 		songIndex++;
1129 
1130 		if (!song || !song->pMidiParser)
1131 			continue;
1132 
1133 		bool channelMapped[16];
1134 #ifdef DEBUG_REMAP
1135 		bool channelUsed[16];
1136 #endif
1137 		for (int j = 0; j < 16; ++j) {
1138 			channelMapped[j] = false;
1139 #ifdef DEBUG_REMAP
1140 			channelUsed[j] = false;
1141 #endif
1142 		}
1143 
1144 		for (int j = 0; j < 16; ++j) {
1145 			if (map->_map[j]._song == song) {
1146 				int channel = map->_map[j]._channel;
1147 				assert(channel >= 0 && channel <= 0x0F);
1148 				channelMapped[channel] = true;
1149 			}
1150 #ifdef DEBUG_REMAP
1151 			if (song->_usedChannels[j] <= 0x0F)
1152 				channelUsed[song->_usedChannels[j]] = true;
1153 #endif
1154 		}
1155 
1156 		for (int j = 0; j < 16; ++j) {
1157 			if (!channelMapped[j]) {
1158 				if (mainThread) song->pMidiParser->mainThreadBegin();
1159 				song->pMidiParser->remapChannel(j, -1);
1160 				if (mainThread) song->pMidiParser->mainThreadEnd();
1161 #ifdef DEBUG_REMAP
1162 				if (channelUsed[j])
1163 					debug(" Unmapping song %d, channel %d", songIndex, j);
1164 #endif
1165 			}
1166 		}
1167 	}
1168 
1169 	// Now reshuffle the channels on the device.
1170 
1171 	// First, set up any dontRemap channels
1172 	for (int i = 0; i < 16; ++i) {
1173 
1174 		if (!map->_map[i]._song || !map->_map[i]._song->pMidiParser || !map->_dontRemap[i])
1175 			continue;
1176 
1177 		songIndex = -1;
1178 		for (MusicList::iterator iter = _playList.begin(); iter != end; ++iter) {
1179 			songIndex++;
1180 			if (map->_map[i]._song == *iter)
1181 				break;
1182 		}
1183 
1184 		_channelMap[i] = map->_map[i];
1185 		map->_map[i]._song = 0; // mark as done
1186 
1187 		// If this channel was not yet mapped to the device, reset it
1188 		if (currentMap[i] != _channelMap[i]) {
1189 #ifdef DEBUG_REMAP
1190 			debug(" Mapping (dontRemap) song %d, channel %d to device channel %d", songIndex, _channelMap[i]._channel, i);
1191 #endif
1192 			if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadBegin();
1193 			_channelMap[i]._song->pMidiParser->remapChannel(_channelMap[i]._channel, i);
1194 			if (mainThread) _channelMap[i]._song->pMidiParser->mainThreadEnd();
1195 		}
1196 
1197 	}
1198 
1199 	// Next, we look for channels which were already playing.
1200 	// We keep those on the same device channel as before.
1201 	for (int i = 0; i < 16; ++i) {
1202 
1203 		if (!map->_map[i]._song)
1204 			continue;
1205 
1206 		songIndex = -1;
1207 		for (MusicList::iterator iter = _playList.begin(); iter != end; ++iter) {
1208 			songIndex++;
1209 			if (map->_map[i]._song == *iter)
1210 				break;
1211 		}
1212 
1213 
1214 		for (int j = 0; j < 16; ++j) {
1215 			if (map->_map[i] == currentMap[j]) {
1216 				// found it
1217 				_channelMap[j] = map->_map[i];
1218 				map->_map[i]._song = 0; // mark as done
1219 #ifdef DEBUG_REMAP
1220 				debug(" Keeping song %d, channel %d on device channel %d", songIndex, _channelMap[j]._channel, j);
1221 #endif
1222 				break;
1223 			}
1224 		}
1225 	}
1226 
1227 	// Then, remap the rest.
1228 	for (int i = 0; i < 16; ++i) {
1229 
1230 		if (!map->_map[i]._song || !map->_map[i]._song->pMidiParser)
1231 			continue;
1232 
1233 		songIndex = -1;
1234 		for (MusicList::iterator iter = _playList.begin(); iter != end; ++iter) {
1235 			songIndex++;
1236 			if (map->_map[i]._song == *iter)
1237 				break;
1238 		}
1239 
1240 		for (int j = _driverLastChannel; j >= _driverFirstChannel; --j) {
1241 			if (_channelMap[j]._song == 0) {
1242 				_channelMap[j] = map->_map[i];
1243 				map->_map[i]._song = 0;
1244 #ifdef DEBUG_REMAP
1245 				debug(" Mapping song %d, channel %d to device channel %d", songIndex, _channelMap[j]._channel, j);
1246 #endif
1247 				if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadBegin();
1248 				_channelMap[j]._song->pMidiParser->remapChannel(_channelMap[j]._channel, j);
1249 				if (mainThread) _channelMap[j]._song->pMidiParser->mainThreadEnd();
1250 				break;
1251 			}
1252 		}
1253 
1254 	}
1255 
1256 	// And finally, stop any empty channels
1257 	for (int i = _driverLastChannel; i >= _driverFirstChannel; --i) {
1258 		if (!_channelMap[i]._song && currentMap[i]._song)
1259 			resetDeviceChannel(i, mainThread);
1260 	}
1261 
1262 	delete map;
1263 }
1264 
1265 
determineChannelMap()1266 ChannelRemapping *SciMusic::determineChannelMap() {
1267 #ifdef DEBUG_REMAP
1268 	debug("Remap: avail chans: %d-%d", _driverFirstChannel, _driverLastChannel);
1269 #endif
1270 
1271 	ChannelRemapping *map = new ChannelRemapping;
1272 	ChannelRemapping backupMap;
1273 	map->clear();
1274 	map->_freeVoices = _pMidiDrv->getPolyphony();
1275 
1276 	if (_playList.empty())
1277 		return map;
1278 
1279 	// TODO: set reverb, either from first song, or from global???
1280 
1281 	MusicList::iterator songIter;
1282 	int songIndex = -1;
1283 	for (songIter = _playList.begin(); songIter != _playList.end(); ++songIter) {
1284 		songIndex++;
1285 		MusicEntry *song = *songIter;
1286 		if (song->status != kSoundPlaying)
1287 			continue;
1288 
1289 		// If song is digital, skip.
1290 		// CHECKME: Is this condition correct?
1291 		if (!song->pMidiParser) {
1292 #ifdef DEBUG_REMAP
1293 			debug(" Song %d (%p), digital?", songIndex, (void*)song);
1294 #endif
1295 			continue;
1296 		}
1297 
1298 
1299 #ifdef DEBUG_REMAP
1300 		const char* name = g_sci->getEngineState()->_segMan->getObjectName(song->soundObj);
1301 		debug(" Song %d (%p) [%s], prio %d%s", songIndex, (void*)song, name, song->priority, song->playBed ? ", bed" : "");
1302 #endif
1303 
1304 		// Store backup. If we fail to map this song, we will revert to this.
1305 		backupMap = *map;
1306 
1307 		bool songMapped = true;
1308 
1309 		for (int i = 0; i < 16; ++i) {
1310 			int c = song->_usedChannels[i];
1311 			if (c == 0xFF || c == 0xFE || c == 0x0F)
1312 				continue;
1313 			const MusicEntryChannel &channel = song->_chan[c];
1314 			if (channel._dontMap) {
1315 #ifdef DEBUG_REMAP
1316 				debug("  Channel %d dontMap, skipping", c);
1317 #endif
1318 				continue;
1319 			}
1320 			if (channel._mute) {
1321 #ifdef DEBUG_REMAP
1322 				debug("  Channel %d muted, skipping", c);
1323 #endif
1324 				continue;
1325 			}
1326 
1327 			bool dontRemap = channel._dontRemap || song->playBed;
1328 
1329 #ifdef DEBUG_REMAP
1330 			debug("  Channel %d: prio %d, %d voice%s%s", c, channel._prio, channel._voices, channel._voices == 1 ? "" : "s", dontRemap ? ", dontRemap" : "" );
1331 #endif
1332 
1333 			DeviceChannelUsage dc = { song, c };
1334 
1335 			// our target
1336 			int devChannel = -1;
1337 
1338 			if (dontRemap && map->_map[c]._song == 0) {
1339 				// unremappable channel, with channel still free
1340 				devChannel = c;
1341 			}
1342 
1343 			// try to find a free channel
1344 			if (devChannel == -1) {
1345 				for (int j = 0; j < 16; ++j) {
1346 					if (map->_map[j] == dc) {
1347 						// already mapped?! (Can this happen?)
1348 						devChannel = j;
1349 						break;
1350 					}
1351 					if (map->_map[j]._song)
1352 						continue;
1353 
1354 					if (j >= _driverFirstChannel && j <= _driverLastChannel)
1355 						devChannel = j;
1356 				}
1357 			}
1358 
1359 			int prio = channel._prio;
1360 			if (prio > 0) {
1361 				// prio > 0 means non-essential
1362 				prio = (16 - prio) + 16*songIndex;
1363 			}
1364 
1365 			if (devChannel == -1 && prio > 0) {
1366 				// no empty channel, but this isn't an essential channel,
1367 				// so we just skip it.
1368 #ifdef DEBUG_REMAP
1369 				debug("   skipping non-essential");
1370 #endif
1371 				continue;
1372 			}
1373 
1374 			// try to empty a previous channel if this is an essential channel
1375 			if (devChannel == -1) {
1376 				devChannel = map->lowestPrio();
1377 				if (devChannel != -1)
1378 					map->evict(devChannel);
1379 			}
1380 
1381 			if (devChannel == -1) {
1382 				// failed to map this song.
1383 #ifdef DEBUG_REMAP
1384 				debug("   no free (or lower priority) channel found");
1385 #endif
1386 				songMapped = false;
1387 				break;
1388 			}
1389 
1390 			if (map->_map[devChannel] == dc) {
1391 				// already mapped?! (Can this happen?)
1392 				continue;
1393 			}
1394 
1395 			int neededVoices = channel._voices;
1396 			// do we have enough free voices?
1397 			if (map->_freeVoices < neededVoices) {
1398 				// We only care for essential channels.
1399 				// Note: In early SCI1 interpreters, a song started by 'playBed'
1400 				// would not be skipped even if some channels couldn't be
1401 				// mapped due to voice limits. So, we treat all channels as
1402 				// non-essential here for playBed songs.
1403 				if (prio > 0 || (song->playBed && _soundVersion <= SCI_VERSION_1_EARLY)) {
1404 #ifdef DEBUG_REMAP
1405 					debug("   not enough voices; need %d, have %d. Skipping this channel.", neededVoices, map->_freeVoices);
1406 #endif
1407 					continue;
1408 				}
1409 				do {
1410 					int j = map->lowestPrio();
1411 					if (j == -1) {
1412 #ifdef DEBUG_REMAP
1413 						debug("   not enough voices; need %d, have %d", neededVoices, map->_freeVoices);
1414 #endif
1415 						// failed to free enough voices.
1416 						songMapped = false;
1417 						break;
1418 					}
1419 #ifdef DEBUG_REMAP
1420 					debug("   creating room for voices; evict %d", j);
1421 #endif
1422 					map->evict(j);
1423 				} while (map->_freeVoices < neededVoices);
1424 
1425 				if (!songMapped) {
1426 					// failed to map this song.
1427 					break;
1428 				}
1429 			}
1430 
1431 			// We have a channel and enough free voices now.
1432 #ifdef DEBUG_REMAP
1433 			debug("   trying to map to %d", devChannel);
1434 #endif
1435 
1436 			map->_map[devChannel] = dc;
1437 			map->_voices[devChannel] = neededVoices;
1438 			map->_prio[devChannel] = prio;
1439 			map->_dontRemap[devChannel] = dontRemap;
1440 			map->_freeVoices -= neededVoices;
1441 
1442 			if (!dontRemap || devChannel == c) {
1443 				// If this channel fits here, we're done.
1444 #ifdef DEBUG_REMAP
1445 				debug("    OK");
1446 #endif
1447 				continue;
1448 			}
1449 
1450 			// If this channel can't be remapped, we need to move it or fail.
1451 
1452 			if (!map->_dontRemap[c]) {
1453 				// Target channel can be remapped, so just swap
1454 				map->swap(devChannel, c);
1455 				continue;
1456 			}
1457 #ifdef DEBUG_REMAP
1458 			debug("    but %d is already dontRemap", c);
1459 #endif
1460 
1461 			if (prio > 0) {
1462 				// Channel collision, but this channel is non-essential,
1463 				// so drop it.
1464 				// TODO: Maybe we should have checked this before making room?
1465 				map->evict(devChannel);
1466 				continue;
1467 			}
1468 
1469 			if (map->_prio[c] > 0) {
1470 				// Channel collision, but the other channel is non-essential,
1471 				// so we take its place.
1472 				map->evict(c);
1473 				map->swap(devChannel, c);
1474 				continue;
1475 			}
1476 
1477 			// Otherwise, we have two essential channels claiming the same
1478 			// device channel.
1479 			songMapped = false;
1480 			break;
1481 		}
1482 
1483 		if (!songMapped) {
1484 			// We failed to map this song, so unmap all its channels.
1485 #ifdef DEBUG_REMAP
1486 			debug(" Failed song");
1487 #endif
1488 			*map = backupMap;
1489 		}
1490 	}
1491 
1492 	return map;
1493 }
1494 
resetDeviceChannel(int devChannel,bool mainThread)1495 void SciMusic::resetDeviceChannel(int devChannel, bool mainThread) {
1496 	assert(devChannel >= 0 && devChannel <= 0x0F);
1497 
1498 	if (mainThread) {
1499 		putMidiCommandInQueue(0x0040B0 | devChannel); // sustain off
1500 		putMidiCommandInQueue(0x007BB0 | devChannel); // notes off
1501 		putMidiCommandInQueue(0x004BB0 | devChannel); // release voices
1502 	} else {
1503 		_pMidiDrv->send(0x0040B0 | devChannel); // sustain off
1504 		_pMidiDrv->send(0x007BB0 | devChannel); // notes off
1505 		_pMidiDrv->send(0x004BB0 | devChannel); // release voices
1506 	}
1507 }
1508 
1509 
1510 
1511 } // End of namespace Sci
1512