ScummVM API documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
dimuse_engine.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #if !defined(SCUMM_IMUSE_DIGI_H) && defined(ENABLE_SCUMM_7_8)
23 #define SCUMM_IMUSE_DIGI_H
24 
25 #include "common/scummsys.h"
26 #include "common/mutex.h"
27 #include "common/serializer.h"
28 #include "common/textconsole.h"
29 #include "common/util.h"
30 
31 #include "scumm/scumm_v7.h"
32 #include "scumm/music.h"
33 #include "scumm/sound.h"
34 #include "scumm/file.h"
35 #include "scumm/debugger.h"
36 
37 #include "scumm/imuse_digi/dimuse_defs.h"
38 #include "scumm/imuse_digi/dimuse_internalmixer.h"
39 #include "scumm/imuse_digi/dimuse_groups.h"
40 #include "scumm/imuse_digi/dimuse_fades.h"
41 #include "scumm/imuse_digi/dimuse_files.h"
42 #include "scumm/imuse_digi/dimuse_triggers.h"
43 #include "scumm/imuse_digi/dimuse_bndmgr.h"
44 #include "scumm/imuse_digi/dimuse_sndmgr.h"
45 #include "scumm/imuse_digi/dimuse_tables.h"
46 
47 #include "scumm/smush/smush_player.h"
48 
49 #include "audio/mixer.h"
50 #include "audio/decoders/raw.h"
51 
52 namespace Audio {
53 class AudioStream;
54 class Mixer;
55 class QueuingAudioStream;
56 }
57 
58 namespace Scumm {
59 class ScummEngine_v7;
60 class SmushPlayer;
61 
62 struct imuseDigTable;
63 struct imuseComiTable;
64 struct IMuseDigiDispatch;
65 struct IMuseDigiTrack;
66 struct IMuseDigiStreamZone;
67 
68 class IMuseDigital : public MusicEngine {
69 private:
70  Common::Mutex *_mutex;
71  ScummEngine_v7 *_vm;
72  Audio::Mixer *_mixer;
73  SmushPlayer *_splayer;
74 
75  IMuseDigiInternalMixer *_internalMixer;
76  IMuseDigiGroupsHandler *_groupsHandler;
77  IMuseDigiFadesHandler *_fadesHandler;
78  IMuseDigiTriggersHandler *_triggersHandler;
79  IMuseDigiFilesHandler *_filesHandler;
80 
81  int _callbackFps;
82  static void timer_handler(void *refConf);
83  void callback();
84 
85  bool _isEarlyDiMUSE;
86  bool _isEngineDisabled;
87  bool _checkForUnderrun;
88  int _underrunCooldown;
89  bool _lowLatencyMode;
90 
91  int _internalFeedSize;
92  int _internalSampleRate;
93 
94  // These three are manipulated in the waveOut functions
95  uint8 *_outputAudioBuffer;
96  int _outputFeedSize;
97  int _outputSampleRate;
98 
99  // Used in low latency mode only
100  uint8 *_outputLowLatencyAudioBuffers[DIMUSE_MAX_TRACKS];
101 
102  int _maxQueuedStreams; // maximum number of streams which can be queued before they are played
103  int _nominalBufferCount;
104 
105  int _currentSpeechVolume, _currentSpeechFrequency, _currentSpeechPan;
106  int _curMixerMusicVolume, _curMixerSpeechVolume, _curMixerSFXVolume;
107  bool _radioChatterSFX;
108 
109  int32 _attributes[188]; // internal attributes for each music file to store and check later
110  int32 _nextSeqToPlay;
111  int32 _curMusicState;
112  int32 _curMusicSeq;
113  int32 _curMusicCue;
114 
115  char *_audioNames; // filenames of sound SFX used in FT
116  int32 _numAudioNames; // number of above filenames
117  uint8 _currentVOCHeader[52]; // Header for the current sound for early DiMUSE
118 
119  int _stopSequenceFlag;
120  int _scriptInitializedFlag;
121  char _emptyMarker[1];
122  bool _spooledMusicEnabled;
123 
124  int _usecPerInt; // Microseconds between each callback (will be set to 50 Hz)
125  int _callbackInterruptFlag;
126  void diMUSEHeartbeat();
127 
128  void setFtMusicState(int stateId);
129  void setFtMusicSequence(int seqId);
130  void playFtMusic(const char *songName, int opcode, int volume);
131  void setDigMusicState(int stateId);
132  void setDigMusicSequence(int seqId);
133  void playDigMusic(const char *songName, const imuseDigTable *table, int attribPos, bool sequence);
134  void setComiMusicState(int stateId);
135  void setComiMusicSequence(int seqId);
136  void playComiMusic(const char *songName, const imuseComiTable *table, int attribPos, bool sequence);
137  void playComiDemoMusic(const char *songName, const imuseComiTable *table, int attribPos, bool sequence);
138  int getSoundIdByName(const char *soundName);
139  bool isMusicStreamIdle();
140  bool isMusicCritical();
141 
142  // Script
143  int scriptParse(int cmd, int a, int b);
144  int scriptInit();
145  int scriptTerminate();
146  void scriptRefresh();
147  void scriptSetState(int soundId);
148  void scriptSetSequence(int soundId);
149  void scriptSetCuePoint(int cueId);
150  int scriptSetAttribute(int attrIndex, int attrVal);
151 
152  // CMDs
153  int _cmdsPauseCount;
154  int _cmdsRunning60HzCount;
155  int _cmdsRunning10HzCount;
156 
157  int cmdsInit();
158  int cmdsDeinit();
159  int cmdsTerminate();
160  int cmdsPause();
161  int cmdsResume();
162  void cmdsSaveLoad(Common::Serializer &ser);
163  int cmdsStartSound(int soundId, int priority);
164  int cmdsStopSound(int soundId);
165  int cmdsStopAllSounds();
166  int cmdsGetNextSound(int soundId);
167  int cmdsSetParam(int soundId, int opcode, int value);
168  int cmdsGetParam(int soundId, int opcode);
169  int cmdsSetHook(int soundId, int hookId);
170  int cmdsGetHook(int soundId);
171 
172  // Streamer
173  IMuseDigiStream _streams[DIMUSE_MAX_STREAMS];
174  IMuseDigiStream *_lastStreamLoaded;
175  int _streamerBailFlag;
176 
177  int streamerInit();
178  IMuseDigiStream *streamerAllocateSound(int soundId, int bufId, int32 maxRead);
179  int streamerClearSoundInStream(IMuseDigiStream *streamPtr);
180  int streamerProcessStreams();
181  uint8 *streamerGetStreamBuffer(IMuseDigiStream *streamPtr, int size);
182  uint8 *streamerGetStreamBufferAtOffset(IMuseDigiStream *streamPtr, int32 offset, int size);
183  int streamerSetReadIndex(IMuseDigiStream *streamPtr, int offset);
184  int streamerSetLoadIndex(IMuseDigiStream *streamPtr, int offset);
185  int streamerGetFreeBufferAmount(IMuseDigiStream *streamPtr);
186  int streamerSetSoundToStreamFromOffset(IMuseDigiStream *streamPtr, int soundId, int32 offset);
187  void streamerQueryStream(IMuseDigiStream *streamPtr, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
188  int streamerFeedStream(IMuseDigiStream *streamPtr, uint8 *srcBuf, int32 sizeToFeed, int paused);
189  int streamerFetchData(IMuseDigiStream *streamPtr);
190  void streamerSetLoopFlag(IMuseDigiStream *streamPtr, int offset);
191  void streamerRemoveLoopFlag(IMuseDigiStream *streamPtr);
192 
193  // Tracks
194  IMuseDigiTrack _tracks[DIMUSE_MAX_TRACKS];
195  IMuseDigiTrack *_trackList;
196 
197  int _trackCount;
198  int _tracksPauseTimer;
199  int _tracksMicroSecsToFeed;
200 
201  int tracksInit();
202  void tracksPause();
203  void tracksResume();
204  void tracksSaveLoad(Common::Serializer &ser);
205  void tracksSetGroupVol();
206  void tracksCallback();
207  void tracksLowLatencyCallback();
208  int tracksStartSound(int soundId, int tryPriority, int group);
209  int tracksStopSound(int soundId);
210  int tracksStopAllSounds();
211  int tracksGetNextSound(int soundId);
212  int tracksQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
213  int tracksFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused);
214  void tracksClear(IMuseDigiTrack *trackPtr);
215  int tracksSetParam(int soundId, int opcode, int value);
216  int tracksGetParam(int soundId, int opcode);
217  int tracksLipSync(int soundId, int syncId, int msPos, int32 &width, int32 &height);
218  int tracksSetHook(int soundId, int hookId);
219  int tracksGetHook(int soundId);
220  IMuseDigiTrack *tracksReserveTrack(int priority);
221  void tracksDeinit();
222 
223  // Dispatch
224  IMuseDigiDispatch _dispatches[DIMUSE_MAX_DISPATCHES];
225  IMuseDigiStreamZone _streamZones[DIMUSE_MAX_STREAMZONES];
226  uint8 *_dispatchBuffer;
227  uint8 _ftCrossfadeBuffer[30000]; // Used by FT & DIG demo
228  int32 _dispatchSize;
229  uint8 *_dispatchSmallFadeBufs;
230  uint8 *_dispatchLargeFadeBufs;
231  int32 _dispatchFadeSize;
232  int _dispatchLargeFadeFlags[DIMUSE_LARGE_FADES];
233  int _dispatchSmallFadeFlags[DIMUSE_SMALL_FADES];
234  int _dispatchFadeStartedFlag;
235  int _dispatchBufferedHookId;
236  int32 _dispatchJumpFadeSize;
237  int32 _dispatchCurStreamBufSize;
238  int32 _dispatchCurStreamCriticalSize;
239  int32 _dispatchCurStreamFreeSpace;
240  int _dispatchCurStreamPaused;
241 
242  int dispatchInit();
243  IMuseDigiDispatch *dispatchGetDispatchByTrackId(int trackId);
244  void dispatchSaveLoad(Common::Serializer &ser);
245  int dispatchRestoreStreamZones();
246  int dispatchAllocateSound(IMuseDigiTrack *trackPtr, int groupId);
247  int dispatchRelease(IMuseDigiTrack *trackPtr);
248  int dispatchSwitchStream(int oldSoundId, int newSoundId, int fadeLength, int exitTriggerSyncFlag, int offsetFadeSyncFlag);
249  int dispatchSwitchStream(int oldSoundId, int newSoundId, uint8 *crossfadeBuffer, int crossfadeBufferSize, int vocLoopFlag);
250  void dispatchProcessDispatches(IMuseDigiTrack *trackPtr, int feedSize, int sampleRate);
251  void dispatchProcessDispatches(IMuseDigiTrack *trackPtr, int feedSize);
252  void dispatchPredictFirstStream();
253  int dispatchNavigateMap(IMuseDigiDispatch *dispatchPtr);
254  int dispatchGetMap(IMuseDigiDispatch *dispatchPtr);
255  int dispatchConvertMap(uint8 *rawMap, int32 *destMap);
256  uint8 *dispatchGetNextMapEvent(int32 *mapPtr, int32 soundOffset, uint8 *mapEvent);
257  void dispatchPredictStream(IMuseDigiDispatch *dispatchPtr);
258  uint8 *dispatchCheckForJump(int32 *mapPtr, IMuseDigiStreamZone *strZnPtr, int &candidateHookId);
259  void dispatchPrepareToJump(IMuseDigiDispatch *dispatchPtr, IMuseDigiStreamZone *strZnPtr, uint8 *jumpParamsFromMap, int calledFromGetNextMapEvent);
260  void dispatchStreamNextZone(IMuseDigiDispatch *dispatchPtr, IMuseDigiStreamZone *strZnPtr);
261  IMuseDigiStreamZone *dispatchAllocateStreamZone();
262  uint8 *dispatchAllocateFade(int32 &fadeSize, const char *functionName);
263  void dispatchDeallocateFade(IMuseDigiDispatch *dispatchPtr, const char *functionName);
264  int dispatchGetFadeSize(IMuseDigiDispatch *dispatchPtr, int fadeLength);
265  void dispatchValidateFadeSize(IMuseDigiDispatch *dispatchPtr, int32 &dispatchSize, const char *functionName);
266  int dispatchUpdateFadeMixVolume(IMuseDigiDispatch *dispatchPtr, int32 remainingFade);
267  int dispatchUpdateFadeSlope(IMuseDigiDispatch *dispatchPtr);
268  void dispatchVOCLoopCallback(int soundId);
269  int dispatchSeekToNextChunk(IMuseDigiDispatch *dispatchPtr);
270 
271  // Wave (mainly a wrapper for Tracks functions)
272  int waveInit();
273  int waveTerminate();
274  int wavePause();
275  int waveResume();
276  void waveSaveLoad(Common::Serializer &ser);
277  void waveUpdateGroupVolumes();
278  int waveStartSound(int soundId, int priority);
279  int waveStopSound(int soundId);
280  int waveStopAllSounds();
281  int waveGetNextSound(int soundId);
282  int waveSetParam(int soundId, int opcode, int value);
283  int waveGetParam(int soundId, int opcode);
284  int waveSetHook(int soundId, int hookId);
285  int waveGetHook(int soundId);
286  int waveStartStream(int soundId, int priority, int groupId);
287  int waveSwitchStream(int oldSoundId, int newSoundId, int fadeLengthMs, int fadeSyncFlag2, int fadeSyncFlag1);
288  int waveSwitchStream(int oldSoundId, int newSoundId, uint8 *crossfadeBuffer, int crossfadeBufferSize, int vocLoopFlag);
289  int waveProcessStreams();
290  int waveQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
291  int waveFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused);
292  int waveLipSync(int soundId, int syncId, int msPos, int32 &width, int32 &height);
293 
294  // Waveapi
295  waveOutParamsStruct waveOutSettings;
296 
297  int _waveOutSampleRate;
298  int _waveOutBytesPerSample;
299  int _waveOutNumChannels;
300  int _waveOutZeroLevel;
301  int _waveOutPreferredFeedSize;
302  uint8 *_waveOutMixBuffer;
303  uint8 *_waveOutOutputBuffer;
304 
305  int _waveOutXorTrigger;
306  int _waveOutWriteIndex;
307  int _waveOutDisableWrite;
308 
309  int waveOutInit(waveOutParamsStruct *waveOutSettings);
310  void waveOutWrite(uint8 **audioBuffer, int &feedSize, int &sampleRate);
311  int waveOutDeinit();
312  void waveOutCallback();
313  byte waveOutGetStreamFlags();
314 
315  // Low latency mode
316  void waveOutLowLatencyWrite(uint8 **audioBuffer, int &feedSize, int &sampleRate, int idx);
317  void waveOutEmptyBuffer(int idx);
318 
319  uint8 *_waveOutLowLatencyOutputBuffer;
320 
321 public:
322  IMuseDigital(ScummEngine_v7 *scumm, int sampleRate, Audio::Mixer *mixer, Common::Mutex *mutex, bool lowLatencyMode = false);
323  ~IMuseDigital() override;
324 
325  // Wrapper functions used by the main engine
326 
327  void startSound(int sound) override { error("IMuseDigital::startSound(int) should be never called"); }
328  void setMusicVolume(int vol) override {}
329  void stopSound(int sound) override;
330  void stopAllSounds() override;
331  int getSoundStatus(int sound) const override { return 0; }
332  int isSoundRunning(int soundId); // Needed because getSoundStatus is a const function, and I needed a workaround
333  int startVoice(int soundId, const char *soundName, byte speakingActorId);
334  int startVoice(const char *fileName, ScummFile *file, uint32 offset, uint32 size);
335  void saveLoadEarly(Common::Serializer &ser);
336  void setRadioChatterSFX(bool state);
337  void setAudioNames(int32 num, char *names);
338  int startSfx(int soundId, int priority) ;
339  void setPriority(int soundId, int priority);
340  void setVolume(int soundId, int volume);
341  void setPan(int soundId, int pan);
342  void setFrequency(int soundId, int frequency);
343  int getCurSpeechVolume() const;
344  int getCurSpeechPan() const;
345  int getCurSpeechFrequency() const;
346  void pause(bool pause);
347  void parseScriptCmds(int cmd, int soundId, int sub_cmd, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p);
348  void refreshScripts();
349  void flushTracks();
350  void disableEngine();
351  bool isEngineDisabled();
352  void stopSMUSHAudio();
353  void receiveAudioFromSMUSH(uint8 *srcBuf, int32 inFrameCount, int32 feedSize, int32 mixBufStartIndex, int volume, int pan, bool is11025Hz);
354  void setSmushPlayer(SmushPlayer *splayer);
355  void floodMusicBuffer();
356  void fillStreamsWhileMusicCritical(int fillTimesAfter);
357  bool queryNextSoundFile(int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
358  int getSampleRate();
359  int getFeedSize();
360 
361  bool isFTSoundEngine(); // Used in the handlers to check if we're using the FT version of the engine
362 
363  int32 getCurMusicPosInMs();
364  int32 getCurVoiceLipSyncWidth();
365  int32 getCurVoiceLipSyncHeight();
366  int32 getCurMusicLipSyncWidth(int syncId);
367  int32 getCurMusicLipSyncHeight(int syncId);
368  void getSpeechLipSyncInfo(int32 &width, int32 &height);
369  void getMusicLipSyncInfo(int syncId, int32 &width, int32 &height);
370  int32 getSoundElapsedTimeInMs(int soundId);
371 
372  // General engine functions
373  int diMUSETerminate();
374  int diMUSEInitialize();
375  int diMUSEPause();
376  int diMUSEResume();
377  void diMUSESaveLoad(Common::Serializer &ser);
378  int diMUSESetGroupVol(int groupId, int volume);
379  int diMUSEStartSound(int soundId, int priority);
380  int diMUSEStopSound(int soundId);
381  int diMUSEStopAllSounds();
382  int diMUSEGetNextSound(int soundId);
383  int diMUSESetParam(int soundId, int paramId, int value);
384  int diMUSEGetParam(int soundId, int paramId);
385  int diMUSEFadeParam(int soundId, int opcode, int destValue, int fadeLength);
386  int diMUSESetHook(int soundId, int hookId);
387 
388  int diMUSESetTrigger(int soundId, int marker, int opcode,
389  int d = -1, int e = -1, int f = -1, int g = -1,
390  int h = -1, int i = -1, int j = -1, int k = -1,
391  int l = -1, int m = -1, int n = -1);
392 
393  int diMUSEStartStream(int soundId, int priority, int groupId);
394  int diMUSESwitchStream(int oldSoundId, int newSoundId, int fadeDelay, int fadeSyncFlag2, int fadeSyncFlag1);
395  int diMUSESwitchStream(int oldSoundId, int newSoundId, uint8 *crossfadeBuffer, int crossfadeBufferSize, int vocLoopFlag);
396  int diMUSEProcessStreams();
397  int diMUSEQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused);
398  int diMUSEFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused);
399  int diMUSELipSync(int soundId, int syncId, int msPos, int32 &width, int32 &height);
400  int diMUSEGetMusicGroupVol();
401  int diMUSEGetSFXGroupVol();
402  int diMUSEGetVoiceGroupVol();
403  int diMUSESetMusicGroupVol(int volume);
404  int diMUSESetSFXGroupVol(int volume);
405  int diMUSESetVoiceGroupVol(int volume);
406  void diMUSEUpdateGroupVolumes();
407  int diMUSEInitializeScript();
408  void diMUSERefreshScript();
409  int diMUSESetState(int soundId);
410  int diMUSESetSequence(int soundId);
411  int diMUSESetCuePoint(int cueId);
412  int diMUSESetAttribute(int attrIndex, int attrVal);
413  void diMUSEEnableSpooledMusic();
414  void diMUSEDisableSpooledMusic();
415 
416  // Utils
417  int addTrackToList(IMuseDigiTrack **listPtr, IMuseDigiTrack *listPtr_Item);
418  int removeTrackFromList(IMuseDigiTrack **listPtr, IMuseDigiTrack *itemPtr);
419  int addStreamZoneToList(IMuseDigiStreamZone **listPtr, IMuseDigiStreamZone *listPtr_Item);
420  int removeStreamZoneFromList(IMuseDigiStreamZone **listPtr, IMuseDigiStreamZone *itemPtr);
421  int clampNumber(int value, int minValue, int maxValue);
422  int clampTuning(int value, int minValue, int maxValue);
423  int checkHookId(int &trackHookId, int sampleHookId);
424  int roundRobinSetBufferCount();
425  void adaptBufferCount();
426 
427  // CMDs
428  int cmdsHandleCmd(int cmd, uint8 *ptr = nullptr,
429  int a = -1, int b = -1, int c = -1, int d = -1, int e = -1,
430  int f = -1, int g = -1, int h = -1, int i = -1, int j = -1,
431  int k = -1, int l = -1, int m = -1, int n = -1);
432 
433  // Script
434  int scriptTriggerCallback(char *marker);
435 
436  // Debugger utility functions
437  void listStates();
438  void listSeqs();
439  void listCues();
440  void listTracks();
441  void listGroups();
442 };
443 
444 } // End of namespace Scumm
445 
446 #endif
Definition: serializer.h:79
Definition: mixer.h:59
Definition: mutex.h:67
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: actor.h:30
Definition: system.h:38