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 #ifndef TSAGE_SOUND_H
24 #define TSAGE_SOUND_H
25 
26 #include "common/scummsys.h"
27 #include "common/mutex.h"
28 #include "common/queue.h"
29 #include "audio/mixer.h"
30 #include "common/list.h"
31 #include "tsage/saveload.h"
32 #include "tsage/core.h"
33 
34 namespace Audio {
35 class QueuingAudioStream;
36 }
37 
38 namespace OPL {
39 class OPL;
40 }
41 
42 namespace TsAGE {
43 
44 class Sound;
45 
46 #define SOUND_ARR_SIZE 16
47 #define ROLAND_DRIVER_NUM 2
48 #define ADLIB_DRIVER_NUM 3
49 #define SBLASTER_DRIVER_NUM 4
50 #define CALLBACKS_PER_SECOND 60
51 
52 struct trackInfoStruct {
53 	int _numTracks;
54 	int _chunks[SOUND_ARR_SIZE];
55 	int _voiceTypes[SOUND_ARR_SIZE];
56 };
57 
58 enum SoundDriverStatus {SNDSTATUS_FAILED = 0, SNDSTATUS_DETECTED = 1, SNDSTATUS_SKIPPED = 2};
59 enum VoiceType {VOICETYPE_0 = 0, VOICETYPE_1 = 1};
60 
61 class SoundDriverEntry {
62 public:
63 	int _driverNum;
64 	SoundDriverStatus _status;
65 	int _field2, _field6;
66 	Common::String _shortDescription;
67 	Common::String _longDescription;
68 };
69 
70 struct GroupData {
71 	uint32 _groupMask;
72 	const byte *_pData;
73 };
74 
75 struct RegisterValue {
76 	uint8 _regNum;
77 	uint8 _value;
78 
RegisterValueRegisterValue79 	RegisterValue(int regNum, int value) {
80 		_regNum = regNum; _value = value;
81 	}
82 };
83 
84 class SoundDriver {
85 public:
86 	Common::String _shortDescription, _longDescription;
87 	int _minVersion, _maxVersion;
88 	// The following fields were originally held in separate arrays in the SoundManager class
89 	uint32 _groupMask;
90 	const GroupData *_groupOffset;
91 	int _driverResID;
92 public:
93 	SoundDriver();
~SoundDriver()94 	virtual ~SoundDriver() {}
95 
getShortDriverDescription()96 	const Common::String &getShortDriverDescription() { return _shortDescription; }
getLongDriverDescription()97 	const Common::String &getLongDriverDescription() { return _longDescription; }
98 
open()99 	virtual bool open() { return true; }						// Method #0
close()100 	virtual void close() {}										// Method #1
reset()101 	virtual bool reset() { return true; }						// Method #2
getGroupData()102 	virtual const GroupData *getGroupData() { return NULL; }	// Method #3
installPatch(const byte * data,int size)103 	virtual void installPatch(const byte *data, int size) {}	// Method #4
poll()104 	virtual void poll() {}										// Method #5
method6()105 	virtual void method6() {}									// Method #6
setMasterVolume(int volume)106 	virtual int setMasterVolume(int volume) { return 0; }		// Method #7
proc16()107 	virtual void proc16() {}									// Method #8
proc18(int al,VoiceType voiceType)108 	virtual void proc18(int al, VoiceType voiceType) {}			// Method #9
proc20(int al,VoiceType voiceType)109 	virtual void proc20(int al, VoiceType voiceType) {}			// Method #10
proc22(int al,VoiceType voiceType,int v3)110 	virtual void proc22(int al, VoiceType voiceType, int v3) {}	// Method #11
proc24(int channel,int voiceIndex,Sound * sound,int v1,int v2)111 	virtual void proc24(int channel, int voiceIndex, Sound *sound, int v1, int v2) {}
setProgram(int channel,int program)112 	virtual void setProgram(int channel, int program) {}			// Method #13
setVolume1(int channel,int v2,int v3,int volume)113 	virtual void setVolume1(int channel, int v2, int v3, int volume) {}
setPitchBlend(int channel,int pitchBlend)114 	virtual void setPitchBlend(int channel, int pitchBlend) {}		// Method #15
playSound(const byte * channelData,int dataOffset,int program,int channel,int v0,int v1)115 	virtual void playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1) {}// Method #16
updateVoice(int channel)116 	virtual void updateVoice(int channel) {}						// Method #17
proc36()117 	virtual void proc36() {}										// Method #18
proc38(int channel,int cmd,int value)118 	virtual void proc38(int channel, int cmd, int value) {}			// Method #19
setPitch(int channel,int pitchBlend)119 	virtual void setPitch(int channel, int pitchBlend) {}			// Method #20
proc42(int channel,int cmd,int value,int * v1,int * v2)120 	virtual void proc42(int channel, int cmd, int value, int *v1, int *v2) {}	// Method #21
121 };
122 
123 struct VoiceStructEntryType0 {
124 	Sound *_sound;
125 	int _channelNum;
126 	int _priority;
127 	bool _fieldA;
128 	Sound *_sound2;
129 	int _channelNum2;
130 	int _priority2;
131 	bool _field12;
132 	Sound *_sound3;
133 	int _channelNum3;
134 	int _priority3;
135 };
136 
137 struct VoiceStructEntryType1 {
138 	int _field4;
139 	int _field5;
140 	int _field6;
141 	Sound *_sound;
142 	int _channelNum;
143 	int _priority;
144 	Sound *_sound2;
145 	int _channelNum2;
146 	int _priority2;
147 	Sound *_sound3;
148 	int _channelNum3;
149 	int _priority3;
150 };
151 
152 struct VoiceStructEntry {
153 	int _voiceNum;
154 	int _field1;
155 	SoundDriver *_driver;
156 
157 	VoiceStructEntryType0 _type0;
158 	VoiceStructEntryType1 _type1;
159 };
160 
161 class VoiceTypeStruct {
162 public:
163 	VoiceType _voiceType;
164 	int _total;
165 	int _numVoices;
166 	int _field3;
167 
168 	Common::Array<VoiceStructEntry> _entries;
169 };
170 
171 class SoundManager : public SaveListener {
172 private:
173 	SoundDriver *instantiateDriver(int driverNum);
174 public:
175 	bool _sndmgrReady;
176 	int _ourSndResVersion, _ourDrvResVersion;
177 	SynchronizedList<Sound *> _playList;
178 	Common::List<SoundDriver *> _installedDrivers;
179 	VoiceTypeStruct *_voiceTypeStructPtrs[SOUND_ARR_SIZE];
180 	uint32 _groupsAvail;
181 	int _masterVol;
182 	int _newVolume;
183 	Common::Mutex _serverDisabledMutex;
184 	Common::Mutex _serverSuspendedMutex;
185 	bool _driversDetected;
186 	SynchronizedList<Sound *> _soundList;
187 	Common::List<SoundDriverEntry> _availableDrivers;
188 	bool _needToRethink;
189 	// Misc flags
190 	bool _soTimeIndexFlag;
191 public:
192 	SoundManager();
193 	~SoundManager();
194 
195 	void dispatch();
196 	virtual void listenerSynchronize(Serializer &s);
197 	virtual void postInit();
198 	void syncSounds();
199 
200 	static void saveNotifier(bool postFlag);
201 	void saveNotifierProc(bool postFlag);
202 	static void loadNotifier(bool postFlag);
203 	void loadNotifierProc(bool postFlag);
204 
205 	void installConfigDrivers();
206 	Common::List<SoundDriverEntry> &buildDriverList(bool detectFlag);
207 	Common::List<SoundDriverEntry> &getDriverList(bool detectFlag);
208 	void dumpDriverList();
209 	void installDriver(int driverNum);
210 	bool isInstalled(int driverNum) const;
211 	void unInstallDriver(int driverNum);
212 	void checkResVersion(const byte *soundData);
213 	int determineGroup(const byte *soundData);
214 	int extractPriority(const byte *soundData);
215 	int extractLoop(const byte *soundData);
216 	bool isOnPlayList(Sound *sound);
217 	void extractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum);
218 	void addToSoundList(Sound *sound);
219 	void removeFromSoundList(Sound *sound);
220 	void addToPlayList(Sound *sound);
221 	void removeFromPlayList(Sound *sound);
222 	void rethinkVoiceTypes();
223 	void updateSoundVol(Sound *sound);
224 	void updateSoundPri(Sound *sound);
225 	void updateSoundLoop(Sound *sound);
226 	void setMasterVol(int volume);
227 	int getMasterVol() const;
228 	void loadSound(int soundNum, bool showErrors);
229 	void unloadSound(int soundNum);
230 	bool isFading();
231 
232 	// _sf methods
233 	static SoundManager &sfManager();
234 	static void sfTerminate();
235 	static int sfDetermineGroup(const byte *soundData);
236 	static void sfAddToPlayList(Sound *sound);
237 	static void sfRemoveFromPlayList(Sound *sound);
238 	static bool sfIsOnPlayList(Sound *sound);
239 	static void sfRethinkSoundDrivers();
240 	static void sfRethinkVoiceTypes();
241 	static void sfUpdateVolume(Sound *sound);
242 	static void sfDereferenceAll();
243 	static void sfUpdatePriority(Sound *sound);
244 	static void sfUpdateLoop(Sound *sound);
245 	static void sfSetMasterVol(int volume);
246 	static void sfExtractTrackInfo(trackInfoStruct *trackInfo, const byte *soundData, int groupNum);
247 	static void sfExtractGroupMask();
248 	static bool sfInstallDriver(SoundDriver *driver);
249 	static void sfUnInstallDriver(SoundDriver *driver);
250 	static void sfInstallPatchBank(SoundDriver *driver, const byte *bankData);
251 	static void sfDoAddToPlayList(Sound *sound);
252 	static bool sfDoRemoveFromPlayList(Sound *sound);
253 	static void sfDoUpdateVolume(Sound *sound);
254 	static void sfSoundServer(void *);
255 	static void sfProcessFading();
256 	static void sfUpdateVoiceStructs();
257 	static void sfUpdateVoiceStructs2();
258 };
259 
260 class Sound: public EventHandler {
261 private:
262 	void _prime(int soundResID, bool dontQueue);
263 	void _primeBuffer(const byte *soundData);
264 	void _unPrime();
265 public:
266 	bool _stoppedAsynchronously;
267 	int _soundResID;
268 	int _group;
269 	int _sndResPriority;
270 	int _fixedPriority;
271 	int _sndResLoop;
272 	int _fixedLoop;
273 	int _priority;
274 	int _volume;
275 	int _loop;
276 	int _pausedCount;
277 	int _mutedCount;
278 	int _hold;
279 	int _cueValue;
280 	int _fadeDest;
281 	int _fadeSteps;
282 	int _fadeTicks;
283 	int _fadeCounter;
284 	bool _stopAfterFadeFlag;
285 	uint32 _timer;
286 	uint32 _newTimeIndex;
287 	int _loopTimer;
288 	int _chProgram[SOUND_ARR_SIZE];
289 	int _chModulation[SOUND_ARR_SIZE];
290 	int _chVolume[SOUND_ARR_SIZE];
291 	int _chPan[SOUND_ARR_SIZE];
292 	int _chDamper[SOUND_ARR_SIZE];
293 	int _chPitchBlend[SOUND_ARR_SIZE];
294 	int _chVoiceType[SOUND_ARR_SIZE];
295 	int _chNumVoices[SOUND_ARR_SIZE];
296 	int _chSubPriority[SOUND_ARR_SIZE];
297 	int _chFlags[SOUND_ARR_SIZE];
298 	bool _chWork[SOUND_ARR_SIZE];
299 	trackInfoStruct _trackInfo;
300 	byte *_channelData[SOUND_ARR_SIZE];
301 	int _trkChannel[SOUND_ARR_SIZE];
302 	int _trkState[SOUND_ARR_SIZE];
303 	int _trkLoopState[SOUND_ARR_SIZE];
304 	int _trkIndex[SOUND_ARR_SIZE];
305 	int _trkLoopIndex[SOUND_ARR_SIZE];
306 	int _trkRest[SOUND_ARR_SIZE];
307 	int _trkLoopRest[SOUND_ARR_SIZE];
308 
309 	bool _primed;
310 	bool _isEmpty;
311 	byte *_remoteReceiver;
312 public:
313 	Sound();
314 	~Sound();
315 
316 	void synchronize(Serializer &s);
317 	void orientAfterRestore();
318 
319 	void play(int soundResID);
320 	void stop();
321 	void prime(int soundResID);
322 	void unPrime();
323 	void go();
324 	void halt(void);
325 	bool isPlaying();
326 	int getSoundNum() const;
327 	bool isPrimed() const;
328 	bool isPaused() const;
329 	bool isMuted() const;
330 	void pause(bool flag);
331 	void mute(bool flag);
332 	void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag);
333 	void setTimeIndex(uint32 timeIndex);
334 	uint32 getTimeIndex() const;
335 	int getCueValue() const;
336 	void setCueValue(int cueValue);
337 	void setVol(int volume);
338 	int getVol() const;
339 	void setPri(int priority);
340 	void setLoop(int flag);
341 	int getPri() const;
342 	int getLoop();
343 	void holdAt(int amount);
344 	void release();
345 	void orientAfterDriverChange();
346 
347 	// _so methods
348 	void soPrimeSound(bool dontQueue);
349 	void soSetTimeIndex(uint timeIndex);
350 	bool soServiceTracks();
351 	void soPrimeChannelData();
352 	void soRemoteReceive();
353 	void soServiceTrackType0(int trackIndex, const byte *channelData);
354 	void soUpdateDamper(VoiceTypeStruct *voiceType, int channelNum, VoiceType mode, int v0);
355 	void soPlaySound(VoiceTypeStruct *vtStruct, const byte *channelData, int channelNum, VoiceType voiceType, int v0, int v1);
356 	void soPlaySound2(VoiceTypeStruct *vtStruct, const byte *channelData, int channelNum, VoiceType voiceType, int v0);
357 	void soProc38(VoiceTypeStruct *vtStruct, int channelNum, VoiceType voiceType, int cmd, int value);
358 	void soProc40(VoiceTypeStruct *vtStruct, int channelNum, int pitchBlend);
359 	void soDoTrackCommand(int channelNum, int command, int value);
360 	bool soDoUpdateTracks(int command, int value);
361 	void soSetTrackPos(int trackIndex, int trackPos, int cueValue);
362 
363 	void soServiceTrackType1(int trackIndex, const byte *channelData);
364 	int soFindSound(VoiceTypeStruct *vtStruct, int channelNum);
365 };
366 
367 class ASound: public EventHandler {
368 public:
369 	Sound _sound;
370 	EventHandler *_endAction;
371 	int _cueValue;
372 
373 	ASound();
374 	~ASound();
375 	virtual void synchronize(Serializer &s);
376 	virtual void dispatch();
377 
378 	void play(int soundNum, EventHandler *endAction = NULL, int volume = 127);
379 	void stop();
380 	void prime(int soundNum, Action *action = NULL);
381 	void unPrime();
go()382 	void go() { _sound.go(); }
hault(void)383 	void hault(void) { _sound.halt(); }
isPlaying()384 	bool isPlaying() { return _sound.isPlaying(); }
getSoundNum()385 	int getSoundNum() const { return _sound.getSoundNum(); }
isPaused()386 	bool isPaused() const { return _sound.isPaused(); }
isMuted()387 	bool isMuted() const { return _sound.isMuted(); }
pause(bool flag)388 	void pause(bool flag) { _sound.pause(flag); }
mute(bool flag)389 	void mute(bool flag) { _sound.mute(flag); }
390 	void fade(int fadeDest, int fadeSteps, int fadeTicks, bool stopAfterFadeFlag, EventHandler *endAction);
fadeIn()391 	void fadeIn() { fade(127, 5, 10, false, NULL); }
fadeOut(Action * action)392 	void fadeOut(Action *action) { fade(0, 5, 10, true, action); }
setTimeIndex(uint32 timeIndex)393 	void setTimeIndex(uint32 timeIndex) { _sound.setTimeIndex(timeIndex); }
getTimeIndex()394 	uint32 getTimeIndex() const { return _sound.getTimeIndex(); }
setPri(int v)395 	void setPri(int v) { _sound.setPri(v); }
setLoop(int total)396 	void setLoop(int total) { _sound.setLoop(total); }
getPri()397 	int getPri() const { return _sound.getPri(); }
getLoop()398 	int getLoop() { return _sound.getLoop(); }
setVol(int volume)399 	void setVol(int volume) { _sound.setVol(volume); }
getVol()400 	int getVol() const { return _sound.getVol(); }
holdAt(int v)401 	void holdAt(int v) { _sound.holdAt(v); }
release()402 	void release() { _sound.release(); }
403 	void fadeSound(int soundNum);
404 };
405 
406 class ASoundExt: public ASound {
407 public:
408 	int _soundNum;
409 
410 	ASoundExt();
411 	void fadeOut2(EventHandler *endAction);
412 	void changeSound(int soundNum);
413 
getClassName()414 	virtual Common::String getClassName() { return "ASoundExt"; }
415 	virtual void synchronize(Serializer &s);
416 	virtual void signal();
417 };
418 
419 class PlayStream: public EventHandler {
420 	class ResFileData {
421 	public:
422 		int _fileChunkSize;
423 		uint _indexSize;
424 		uint _chunkSize;
425 
426 		void load(Common::SeekableReadStream &stream);
427 	};
428 private:
429 	Common::File _file;
430 	ResFileData _resData;
431 	Audio::QueuingAudioStream *_audioStream;
432 	Audio::SoundHandle _soundHandle;
433 	uint16 *_index;
434 	EventHandler *_endAction;
435 	int _voiceNum;
436 
437 	static uint32 getFileOffset(const uint16 *data, int count, int voiceNum);
438 public:
439 	PlayStream();
440 	virtual ~PlayStream();
441 
442 	bool setFile(const Common::String &filename);
443 	bool play(int voiceNum, EventHandler *endAction);
444 	void stop();
445 	bool isPlaying() const;
446 
447 	virtual void remove();
448 	virtual void dispatch();
449 };
450 
451 #define ADLIB_CHANNEL_COUNT 9
452 
453 class AdlibSoundDriver: public SoundDriver {
454 private:
455 	GroupData _groupData;
456 	Audio::Mixer *_mixer;
457 	OPL::OPL *_opl;
458 	byte _portContents[256];
459 	const byte *_patchData;
460 	int _masterVolume;
461 	Common::Mutex _queueMutex;
462 	Common::Queue<RegisterValue> _queue;
463 
464 	bool _channelVoiced[ADLIB_CHANNEL_COUNT];
465 	int _channelVolume[ADLIB_CHANNEL_COUNT];
466 	int _v4405E[ADLIB_CHANNEL_COUNT];
467 	int _v44067[ADLIB_CHANNEL_COUNT];
468 	int _v44070[ADLIB_CHANNEL_COUNT];
469 	int _v44079[ADLIB_CHANNEL_COUNT];
470 	int _v44082[ADLIB_CHANNEL_COUNT + 1];
471 	int _pitchBlend[ADLIB_CHANNEL_COUNT];
472 	int _v4409E[ADLIB_CHANNEL_COUNT];
473 
474 
475 	void write(byte reg, byte value);
476 	void flush();
477 	void updateChannelVolume(int channel);
478 	void setVoice(int channel);
479 	void clearVoice(int channel);
480 	void updateChannel(int channel);
481 	void setFrequency(int channel);
482 public:
483 	AdlibSoundDriver();
484 	virtual ~AdlibSoundDriver();
485 
486 	virtual bool open();
487 	virtual void close();
488 	virtual bool reset();
489 	virtual const GroupData *getGroupData();
490 	virtual void installPatch(const byte *data, int size);
491 	virtual int setMasterVolume(int volume);
492 	virtual void playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1);
493 	virtual void updateVoice(int channel);
494 	virtual void proc38(int channel, int cmd, int value);
495 	virtual void setPitch(int channel, int pitchBlend);
496 
497 private:
498 	void onTimer();
499 };
500 
501 class SoundBlasterDriver: public SoundDriver {
502 private:
503 	GroupData _groupData;
504 	Audio::Mixer *_mixer;
505 	Audio::SoundHandle _soundHandle;
506 	Audio::QueuingAudioStream *_audioStream;
507 	int _sampleRate;
508 
509 	byte _masterVolume;
510 	byte _channelVolume;
511 	const byte *_channelData;
512 public:
513 	SoundBlasterDriver();
514 	virtual ~SoundBlasterDriver();
515 
516 	virtual bool open();
517 	virtual void close();
518 	virtual bool reset();
519 	virtual const GroupData *getGroupData();
520 	virtual int setMasterVolume(int volume);
521 	virtual void playSound(const byte *channelData, int dataOffset, int program, int channel, int v0, int v1);
522 	virtual void updateVoice(int channel);
523 	virtual void proc38(int channel, int cmd, int value);
524 	virtual void proc42(int channel, int cmd, int value, int *v1, int *v2);
525 };
526 
527 
528 } // End of namespace TsAGE
529 
530 #endif
531