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 "gob/gob.h"
24 #include "gob/sound/sound.h"
25 #include "gob/global.h"
26 #include "gob/util.h"
27 #include "gob/dataio.h"
28 #include "gob/game.h"
29 #include "gob/inter.h"
30 
31 #include "gob/sound/bgatmosphere.h"
32 #include "gob/sound/pcspeaker.h"
33 #include "gob/sound/soundblaster.h"
34 #include "gob/sound/adlplayer.h"
35 #include "gob/sound/musplayer.h"
36 #include "gob/sound/infogrames.h"
37 #include "gob/sound/protracker.h"
38 #include "gob/sound/cdrom.h"
39 
40 namespace Gob {
41 
Sound(GobEngine * vm)42 Sound::Sound(GobEngine *vm) : _vm(vm) {
43 	_pcspeaker = new PCSpeaker(*_vm->_mixer);
44 	_blaster = new SoundBlaster(*_vm->_mixer);
45 
46 	_adlPlayer = 0;
47 	_mdyPlayer = 0;
48 	_infogrames = 0;
49 	_protracker = 0;
50 	_cdrom = 0;
51 	_bgatmos = 0;
52 
53 	_hasAdLib = (!_vm->_noMusic && _vm->hasAdLib());
54 
55 	_hasAdLibBg = _hasAdLib;
56 
57 	if (!_vm->_noMusic && (_vm->getPlatform() == Common::kPlatformAmiga)) {
58 		_infogrames = new Infogrames(*_vm->_mixer);
59 		_protracker = new Protracker(*_vm->_mixer);
60 	}
61 	if (_vm->isCD())
62 		_cdrom = new CDROM;
63 	if (_vm->getGameType() == kGameTypeWoodruff)
64 		_bgatmos = new BackgroundAtmosphere(*_vm->_mixer);
65 	if ((_vm->getGameType() == kGameTypeUrban) ||
66 	    (_vm->getGameType() == kGameTypeAdibou2)) {
67 		_bgatmos = new BackgroundAtmosphere(*_vm->_mixer);
68 		_bgatmos->setShadable(false);
69 	}
70 }
71 
~Sound()72 Sound::~Sound() {
73 	delete _pcspeaker;
74 	delete _blaster;
75 	delete _adlPlayer;
76 	delete _mdyPlayer;
77 	delete _infogrames;
78 	delete _protracker;
79 	delete _cdrom;
80 	delete _bgatmos;
81 
82 	for (int i = 0; i < kSoundsCount; i++)
83 		_sounds[i].free();
84 }
85 
convToSigned(byte * buffer,int length)86 void Sound::convToSigned(byte *buffer, int length) {
87 	while (length-- > 0)
88 		*buffer++ ^= 0x80;
89 }
90 
sampleGetBySlot(int slot)91 SoundDesc *Sound::sampleGetBySlot(int slot) {
92 	if ((slot < 0) || (slot >= kSoundsCount))
93 		return 0;
94 
95 	return &_sounds[slot];
96 }
97 
sampleGetBySlot(int slot) const98 const SoundDesc *Sound::sampleGetBySlot(int slot) const {
99 	if ((slot < 0) || (slot >= kSoundsCount))
100 		return 0;
101 
102 	return &_sounds[slot];
103 }
104 
sampleGetNextFreeSlot() const105 int Sound::sampleGetNextFreeSlot() const {
106 	for (int i = 0; i < kSoundsCount; i++)
107 		if (_sounds[i].empty())
108 			return i;
109 
110 	return -1;
111 }
112 
sampleLoad(SoundDesc * sndDesc,SoundType type,const char * fileName)113 bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName) {
114 	if (!sndDesc)
115 		return false;
116 
117 	debugC(2, kDebugSound, "Loading sample \"%s\"", fileName);
118 
119 	int32 size;
120 	byte *data = _vm->_dataIO->getFile(fileName, size);
121 
122 	if (!data || !sndDesc->load(type, data, size)) {
123 		delete[] data;
124 
125 		warning("Sound::sampleLoad(): Failed to load sound \"%s\"", fileName);
126 		return false;
127 	}
128 
129 	return true;
130 }
131 
sampleFree(SoundDesc * sndDesc,bool noteAdLib,int index)132 void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdLib, int index) {
133 	if (!sndDesc || sndDesc->empty())
134 		return;
135 
136 	if (sndDesc->getType() == SOUND_ADL) {
137 
138 		if (noteAdLib) {
139 			if (_adlPlayer)
140 				if ((index == -1) || (_adlPlayer->getIndex() == index))
141 					_adlPlayer->unload();
142 		}
143 
144 	} else {
145 
146 		if (_blaster)
147 			_blaster->stopSound(0, sndDesc);
148 
149 	}
150 
151 	sndDesc->free();
152 }
153 
speakerOn(int16 frequency,int32 length)154 void Sound::speakerOn(int16 frequency, int32 length) {
155 	if (!_pcspeaker)
156 		return;
157 
158 	debugC(1, kDebugSound, "PCSpeaker: Playing tone (%d, %d)", frequency, length);
159 
160 	_pcspeaker->speakerOn(frequency, length);
161 }
162 
speakerOff()163 void Sound::speakerOff() {
164 	if (!_pcspeaker)
165 		return;
166 
167 	debugC(1, kDebugSound, "PCSpeaker: Stopping tone");
168 
169 	_pcspeaker->speakerOff();
170 }
171 
speakerOnUpdate(uint32 millis)172 void Sound::speakerOnUpdate(uint32 millis) {
173 	if (!_pcspeaker)
174 		return;
175 
176 	_pcspeaker->onUpdate(millis);
177 }
178 
infogramesLoadInstruments(const char * fileName)179 bool Sound::infogramesLoadInstruments(const char *fileName) {
180 	if (!_infogrames)
181 		return false;
182 
183 	debugC(1, kDebugSound, "Infogrames: Loading instruments \"%s\"", fileName);
184 
185 	return _infogrames->loadInstruments(fileName);
186 }
187 
infogramesLoadSong(const char * fileName)188 bool Sound::infogramesLoadSong(const char *fileName) {
189 	if (!_infogrames)
190 		return false;
191 
192 	debugC(1, kDebugSound, "Infogrames: Loading song \"%s\"", fileName);
193 
194 	return _infogrames->loadSong(fileName);
195 }
196 
protrackerPlay(const char * fileName)197 bool Sound::protrackerPlay(const char *fileName) {
198 	if (!_protracker)
199 		return false;
200 
201 	debugC(1, kDebugSound, "Protracker: Playing song \"%s\"", fileName);
202 
203 	return _protracker->play(fileName);
204 }
205 
protrackerStop()206 void Sound::protrackerStop() {
207 	if (!_protracker)
208 		return;
209 
210 	debugC(1, kDebugSound, "Protracker: Stopping playback");
211 
212 	_protracker->stop();
213 }
214 
infogramesPlay()215 void Sound::infogramesPlay() {
216 	if (!_infogrames)
217 		return;
218 
219 	debugC(1, kDebugSound, "Infogrames: Starting playback");
220 
221 	_infogrames->play();
222 }
223 
infogramesStop()224 void Sound::infogramesStop() {
225 	if (!_infogrames)
226 		return;
227 
228 	debugC(1, kDebugSound, "Infogrames: Stopping playback");
229 
230 	_infogrames->stop();
231 }
232 
adlibLoadADL(const char * fileName)233 bool Sound::adlibLoadADL(const char *fileName) {
234 	if (!_hasAdLib)
235 		return false;
236 
237 	if (!_adlPlayer)
238 		_adlPlayer = new ADLPlayer();
239 
240 	debugC(1, kDebugSound, "AdLib: Loading ADL data (\"%s\")", fileName);
241 
242 	Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName);
243 	if (!stream) {
244 		warning("Can't open ADL file \"%s\"", fileName);
245 		return false;
246 	}
247 
248 	bool loaded = _adlPlayer->load(*stream);
249 
250 	delete stream;
251 
252 	return loaded;
253 }
254 
adlibLoadADL(byte * data,uint32 size,int index)255 bool Sound::adlibLoadADL(byte *data, uint32 size, int index) {
256 	if (!_hasAdLib)
257 		return false;
258 
259 	if (!_adlPlayer)
260 		_adlPlayer = new ADLPlayer();
261 
262 	debugC(1, kDebugSound, "AdLib: Loading ADL data (%d)", index);
263 
264 	return _adlPlayer->load(data, size, index);
265 }
266 
adlibUnload()267 void Sound::adlibUnload() {
268 	if (!_hasAdLib)
269 		return;
270 
271 	debugC(1, kDebugSound, "AdLib: Unloading data");
272 
273 	if (_adlPlayer)
274 		_adlPlayer->unload();
275 	if (_mdyPlayer)
276 		_mdyPlayer->unload();
277 }
278 
adlibLoadMDY(const char * fileName)279 bool Sound::adlibLoadMDY(const char *fileName) {
280 	if (!_hasAdLib)
281 		return false;
282 
283 	createMDYPlayer();
284 
285 	debugC(1, kDebugSound, "AdLib: Loading MDY data (\"%s\")", fileName);
286 
287 	Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName);
288 	if (!stream) {
289 		warning("Can't open MDY file \"%s\"", fileName);
290 		return false;
291 	}
292 
293 	bool loaded = _mdyPlayer->loadMUS(*stream);
294 
295 	delete stream;
296 
297 	return loaded;
298 }
299 
adlibLoadTBR(const char * fileName)300 bool Sound::adlibLoadTBR(const char *fileName) {
301 	if (!_hasAdLib)
302 		return false;
303 
304 	createMDYPlayer();
305 
306 	Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fileName);
307 	if (!stream) {
308 		warning("Can't open TBR file \"%s\"", fileName);
309 		return false;
310 	}
311 
312 	debugC(1, kDebugSound, "AdLib: Loading MDY instruments (\"%s\")", fileName);
313 
314 	bool loaded = _mdyPlayer->loadSND(*stream);
315 
316 	delete stream;
317 
318 	return loaded;
319 }
320 
adlibPlayTrack(const char * trackname)321 void Sound::adlibPlayTrack(const char *trackname) {
322 	if (!_hasAdLib)
323 		return;
324 
325 	createADLPlayer();
326 
327 	if (_adlPlayer->isPlaying())
328 		return;
329 
330 	if (adlibLoadADL(trackname))
331 		adlibPlay();
332 }
333 
adlibPlayBgMusic()334 void Sound::adlibPlayBgMusic() {
335 	if (!_hasAdLib || _hasAdLibBg)
336 		return;
337 
338 	createADLPlayer();
339 
340 	static const char *const tracksMac[] = {
341 //		"musmac1.adl", // This track seems to be missing instruments...
342 		"musmac2.adl",
343 		"musmac3.adl",
344 		"musmac4.adl",
345 		"musmac5.adl",
346 		"musmac6.adl"
347 	};
348 
349 	static const char *const tracksWin[] = {
350 		"musmac1.mid",
351 		"musmac2.mid",
352 		"musmac3.mid",
353 		"musmac4.mid",
354 		"musmac5.mid"
355 	};
356 
357 	const char *track = 0;
358 	if (_vm->getPlatform() == Common::kPlatformWindows)
359 		track = tracksWin[_vm->_util->getRandom(ARRAYSIZE(tracksWin))];
360 	else
361 		track = tracksMac[_vm->_util->getRandom(ARRAYSIZE(tracksMac))];
362 
363 	if (!track || !_vm->_dataIO->hasFile(track)) {
364 		_hasAdLibBg = false;
365 		return;
366 	}
367 
368 	adlibPlayTrack(track);
369 }
370 
adlibPlay()371 void Sound::adlibPlay() {
372 	if (!_hasAdLib)
373 		return;
374 
375 	debugC(1, kDebugSound, "AdLib: Starting playback");
376 
377 	if (_adlPlayer)
378 		_adlPlayer->startPlay();
379 	if (_mdyPlayer)
380 		_mdyPlayer->startPlay();
381 }
382 
adlibStop()383 void Sound::adlibStop() {
384 	if (!_hasAdLib)
385 		return;
386 
387 	debugC(1, kDebugSound, "AdLib: Stopping playback");
388 
389 	if (_adlPlayer)
390 		_adlPlayer->stopPlay();
391 	if (_mdyPlayer)
392 		_mdyPlayer->stopPlay();
393 }
394 
adlibIsPlaying() const395 bool Sound::adlibIsPlaying() const {
396 	if (!_hasAdLib)
397 		return false;
398 
399 	if (_adlPlayer && _adlPlayer->isPlaying())
400 		return true;
401 	if (_mdyPlayer && _mdyPlayer->isPlaying())
402 		return true;
403 
404 	return false;
405 }
406 
adlibGetIndex() const407 int Sound::adlibGetIndex() const {
408 	if (!_hasAdLib)
409 		return -1;
410 
411 	if (_adlPlayer)
412 		return _adlPlayer->getIndex();
413 
414 	return -1;
415 }
416 
adlibGetRepeating() const417 int32 Sound::adlibGetRepeating() const {
418 	if (!_hasAdLib)
419 		return false;
420 
421 	if (_adlPlayer)
422 		return _adlPlayer->getRepeating();
423 	if (_mdyPlayer)
424 		return _mdyPlayer->getRepeating();
425 
426 	return false;
427 }
428 
adlibSyncVolume()429 void Sound::adlibSyncVolume() {
430 	if (!_hasAdLib)
431 		return;
432 
433 	if (_adlPlayer)
434 		_adlPlayer->syncVolume();
435 	if (_mdyPlayer)
436 		_mdyPlayer->syncVolume();
437 }
438 
adlibSetRepeating(int32 repCount)439 void Sound::adlibSetRepeating(int32 repCount) {
440 	if (!_hasAdLib)
441 		return;
442 
443 	if (_adlPlayer)
444 		_adlPlayer->setRepeating(repCount);
445 	if (_mdyPlayer)
446 		_mdyPlayer->setRepeating(repCount);
447 }
448 
blasterPlay(SoundDesc * sndDesc,int16 repCount,int16 frequency,int16 fadeLength)449 void Sound::blasterPlay(SoundDesc *sndDesc, int16 repCount,
450 		int16 frequency, int16 fadeLength) {
451 	if (!_blaster || !sndDesc)
452 		return;
453 
454 	debugC(1, kDebugSound, "SoundBlaster: Playing sample (%d, %d, %d)",
455 			repCount, frequency, fadeLength);
456 
457 	blasterStopComposition();
458 
459 	_blaster->playSample(*sndDesc, repCount, frequency, fadeLength);
460 }
461 
blasterRepeatComposition(int32 repCount)462 void Sound::blasterRepeatComposition(int32 repCount) {
463 	_blaster->repeatComposition(repCount);
464 }
465 
blasterStop(int16 fadeLength,SoundDesc * sndDesc)466 void Sound::blasterStop(int16 fadeLength, SoundDesc *sndDesc) {
467 	if (!_blaster)
468 		return;
469 
470 	debugC(1, kDebugSound, "SoundBlaster: Stopping playback");
471 
472 	_blaster->stopSound(fadeLength, sndDesc);
473 }
474 
blasterPlayComposition(const int16 * composition,int16 freqVal,SoundDesc * sndDescs,int8 sndCount)475 void Sound::blasterPlayComposition(const int16 *composition, int16 freqVal,
476 		SoundDesc *sndDescs, int8 sndCount) {
477 	if (!_blaster)
478 		return;
479 
480 	debugC(1, kDebugSound, "SoundBlaster: Playing composition (%d, %d)",
481 			freqVal, sndCount);
482 
483 	blasterWaitEndPlay();
484 	_blaster->stopComposition();
485 
486 	if (!sndDescs)
487 		sndDescs = _sounds;
488 
489 	_blaster->playComposition(composition, freqVal, sndDescs, sndCount);
490 }
491 
blasterStopComposition()492 void Sound::blasterStopComposition() {
493 	if (!_blaster)
494 		return;
495 
496 	debugC(1, kDebugSound, "SoundBlaster: Stopping composition");
497 
498 	_blaster->stopComposition();
499 }
500 
blasterPlayingSound() const501 char Sound::blasterPlayingSound() const {
502 	if (!_blaster)
503 		return 0;
504 
505 	return _blaster->getPlayingSound();
506 }
507 
blasterSetRepeating(int32 repCount)508 void Sound::blasterSetRepeating(int32 repCount) {
509 	if (!_blaster)
510 		return;
511 
512 	_blaster->setRepeating(repCount);
513 }
514 
blasterWaitEndPlay(bool interruptible,bool stopComp)515 void Sound::blasterWaitEndPlay(bool interruptible, bool stopComp) {
516 	if (!_blaster)
517 		return;
518 
519 	debugC(1, kDebugSound, "SoundBlaster: Waiting for playback to end");
520 
521 	if (stopComp)
522 		_blaster->endComposition();
523 
524 	while (_blaster->isPlaying() && !_vm->shouldQuit()) {
525 		if (interruptible && (_vm->_util->checkKey() == kKeyEscape)) {
526 			WRITE_VAR(57, (uint32) -1);
527 			return;
528 		}
529 		_vm->_util->longDelay(200);
530 	}
531 
532 	_blaster->stopSound(0);
533 }
534 
cdLoadLIC(const Common::String & fname)535 void Sound::cdLoadLIC(const Common::String &fname) {
536 	if (!_cdrom)
537 		return;
538 
539 	debugC(1, kDebugSound, "CDROM: Loading LIC \"%s\"", fname.c_str());
540 
541 	Common::SeekableReadStream *stream = _vm->_dataIO->getFile(fname);
542 	if (!stream)
543 		return;
544 
545 	_cdrom->readLIC(*stream);
546 
547 	delete stream;
548 }
549 
cdUnloadLIC()550 void Sound::cdUnloadLIC() {
551 	if (!_cdrom)
552 		return;
553 
554 	debugC(1, kDebugSound, "CDROM: Unloading LIC");
555 
556 	_cdrom->freeLICBuffer();
557 }
558 
cdPlayBgMusic()559 void Sound::cdPlayBgMusic() {
560 	if (!_cdrom)
561 		return;
562 
563 	static const char *const tracks[][2] = {
564 		{"avt00.tot",  "mine"},
565 		{"avt001.tot", "nuit"},
566 		{"avt002.tot", "campagne"},
567 		{"avt003.tot", "extsor1"},
568 		{"avt004.tot", "interieure"},
569 		{"avt005.tot", "zombie"},
570 		{"avt006.tot", "zombie"},
571 		{"avt007.tot", "campagne"},
572 		{"avt008.tot", "campagne"},
573 		{"avt009.tot", "extsor1"},
574 		{"avt010.tot", "extsor1"},
575 		{"avt011.tot", "interieure"},
576 		{"avt012.tot", "zombie"},
577 		{"avt014.tot", "nuit"},
578 		{"avt015.tot", "interieure"},
579 		{"avt016.tot", "statue"},
580 		{"avt017.tot", "zombie"},
581 		{"avt018.tot", "statue"},
582 		{"avt019.tot", "mine"},
583 		{"avt020.tot", "statue"},
584 		{"avt021.tot", "mine"},
585 		{"avt022.tot", "zombie"}
586 	};
587 
588 	for (int i = 0; i < ARRAYSIZE(tracks); i++)
589 		if (_vm->isCurrentTot(tracks[i][0])) {
590 			debugC(1, kDebugSound, "CDROM: Playing background music \"%s\" (\"%s\")", tracks[i][1], tracks[i][0]);
591 			_cdrom->startTrack(tracks[i][1]);
592 			break;
593 		}
594 }
595 
cdPlayMultMusic()596 void Sound::cdPlayMultMusic() {
597 	if (!_cdrom)
598 		return;
599 
600 	static const char *const tracks[][6] = {
601 		{"avt005.tot", "fra1", "all1", "ang1", "esp1", "ita1"},
602 		{"avt006.tot", "fra2", "all2", "ang2", "esp2", "ita2"},
603 		{"avt012.tot", "fra3", "all3", "ang3", "esp3", "ita3"},
604 		{"avt016.tot", "fra4", "all4", "ang4", "esp4", "ita4"},
605 		{"avt019.tot", "fra5", "all5", "ang5", "esp5", "ita5"},
606 		{"avt022.tot", "fra6", "all6", "ang6", "esp6", "ita6"}
607 	};
608 
609 	// Default to "ang?" for other languages (including EN_USA)
610 	int language = _vm->_global->_language <= 4 ? _vm->_global->_language : 2;
611 	for (int i = 0; i < ARRAYSIZE(tracks); i++)
612 		if (_vm->isCurrentTot(tracks[i][0])) {
613 			debugC(1, kDebugSound, "CDROM: Playing mult music \"%s\" (\"%s\")", tracks[i][language + 1], tracks[i][0]);
614 			_cdrom->startTrack(tracks[i][language + 1]);
615 			break;
616 		}
617 }
618 
cdPlay(const Common::String & trackName)619 void Sound::cdPlay(const Common::String &trackName) {
620 	if (!_cdrom)
621 		return;
622 	debugC(1, kDebugSound, "CDROM: Playing track \"%s\"", trackName.c_str());
623 
624 // WORKAROUND - In Fascination CD, in the storage room, a track has the wrong
625 // name in the scripts, and therefore doesn't play. This fixes the problem.
626 	if ((_vm->getGameType() == kGameTypeFascination) && trackName.equalsIgnoreCase("boscle"))
627 		_cdrom->startTrack("bosscle");
628 // WORKAROUND - In Goblins 3 CD, in the chess room, a couple of tracks have the wrong name
629 // in the scripts, and therefore don't play. This fixes the problem (ticket #11335).
630 	else if ((_vm->getGameType() == kGameTypeGob3) && trackName.matchString("ECHEQUI?")) {
631 		char name[] = "ECHIQUI1";
632 		name[7] = trackName[7];
633 		_cdrom->startTrack(name);
634 	} else
635 		_cdrom->startTrack(trackName.c_str());
636 }
637 
cdStop()638 void Sound::cdStop() {
639 	if (!_cdrom)
640 		return;
641 
642 	debugC(1, kDebugSound, "CDROM: Stopping playback");
643 	_cdrom->stopPlaying();
644 }
645 
cdIsPlaying() const646 bool Sound::cdIsPlaying() const {
647 	if (!_cdrom)
648 		return false;
649 
650 	return _cdrom->isPlaying();
651 }
652 
cdGetTrackPos(const char * keyTrack) const653 int32 Sound::cdGetTrackPos(const char *keyTrack) const {
654 	if (!_cdrom)
655 		return -1;
656 
657 	return _cdrom->getTrackPos(keyTrack);
658 }
659 
cdGetCurrentTrack() const660 const char *Sound::cdGetCurrentTrack() const {
661 	if (!_cdrom)
662 		return "";
663 
664 	return _cdrom->getCurTrack();
665 }
666 
cdTest(int trySubst,const char * label)667 void Sound::cdTest(int trySubst, const char *label) {
668 	if (!_cdrom)
669 		return;
670 
671 	_cdrom->testCD(trySubst, label);
672 }
673 
bgPlay(const char * file,SoundType type)674 void Sound::bgPlay(const char *file, SoundType type) {
675 	if (!_bgatmos)
676 		return;
677 
678 	debugC(1, kDebugSound, "BackgroundAtmosphere: Playing \"%s\"", file);
679 
680 	_bgatmos->stopBA();
681 	_bgatmos->queueClear();
682 
683 	SoundDesc *sndDesc = new SoundDesc;
684 	if (!sampleLoad(sndDesc, type, file)) {
685 		delete sndDesc;
686 		return;
687 	}
688 
689 	_bgatmos->queueSample(*sndDesc);
690 	_bgatmos->playBA();
691 }
692 
bgPlay(const char * base,const char * ext,SoundType type,int count)693 void Sound::bgPlay(const char *base, const char *ext, SoundType type, int count) {
694 	if (!_bgatmos)
695 		return;
696 
697 	debugC(1, kDebugSound, "BackgroundAtmosphere: Playing \"%s\" (%d)", base, count);
698 
699 	_bgatmos->stopBA();
700 	_bgatmos->queueClear();
701 
702 	SoundDesc *sndDesc;
703 
704 	for (int i = 1; i <= count; i++) {
705 		Common::String fileName = Common::String::format("%s%02d.%s", base, i, ext);
706 
707 		sndDesc = new SoundDesc;
708 		if (sampleLoad(sndDesc, type, fileName.c_str()))
709 			_bgatmos->queueSample(*sndDesc);
710 		else
711 			delete sndDesc;
712 	}
713 
714 	_bgatmos->playBA();
715 }
716 
bgStop()717 void Sound::bgStop() {
718 	if (!_bgatmos)
719 		return;
720 
721 	debugC(1, kDebugSound, "BackgroundAtmosphere: Stopping playback");
722 
723 	_bgatmos->stopBA();
724 	_bgatmos->queueClear();
725 }
726 
bgSetPlayMode(Sound::BackgroundPlayMode mode)727 void Sound::bgSetPlayMode(Sound::BackgroundPlayMode mode) {
728 	if (!_bgatmos)
729 		return;
730 
731 	_bgatmos->setPlayMode(mode);
732 }
733 
bgShade()734 void Sound::bgShade() {
735 	if (!_bgatmos)
736 		return;
737 
738 	debugC(1, kDebugSound, "BackgroundAtmosphere: Shading playback");
739 
740 	_bgatmos->shade();
741 }
742 
bgUnshade()743 void Sound::bgUnshade() {
744 	if (!_bgatmos)
745 		return;
746 
747 	debugC(1, kDebugSound, "BackgroundAtmosphere: Unshading playback");
748 
749 	_bgatmos->unshade();
750 }
751 
createMDYPlayer()752 void Sound::createMDYPlayer() {
753 	if (_mdyPlayer)
754 		return;
755 
756 	delete _adlPlayer;
757 	_adlPlayer = 0;
758 
759 	_mdyPlayer = new MUSPlayer();
760 }
761 
createADLPlayer()762 void Sound::createADLPlayer() {
763 	if (_adlPlayer)
764 		return;
765 
766 	delete _mdyPlayer;
767 	_mdyPlayer= 0;
768 
769 	_adlPlayer = new ADLPlayer();
770 }
771 
772 } // End of namespace Gob
773