ScummVM API documentation
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
52namespace Audio {
53class AudioStream;
54class Mixer;
55class QueuingAudioStream;
56}
57
58namespace Scumm {
59class ScummEngine_v7;
60class SmushPlayer;
61
62struct imuseDigTable;
63struct imuseComiTable;
64struct IMuseDigiDispatch;
65struct IMuseDigiTrack;
66struct IMuseDigiStreamZone;
67
68class IMuseDigital : public MusicEngine {
69private:
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
321public:
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: mixer.h:70
Definition: mutex.h:67
Definition: serializer.h:80
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: system.h:39
Definition: actor.h:30