ScummVM API documentation
sound_intern.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 #ifndef KYRA_SOUND_INTERN_H
23 #define KYRA_SOUND_INTERN_H
24 
25 
26 #include "kyra/sound/sound.h"
27 #include "kyra/sound/sound_pc_v1.h"
28 
29 #include "audio/midiparser.h"
30 #include "audio/miles.h"
31 #include "audio/softsynth/emumidi.h"
32 #include "audio/softsynth/fmtowns_pc98/towns_audio.h"
33 
34 #include "common/mutex.h"
35 
36 class EuphonyPlayer;
38 
39 namespace Audio {
40 class PCSpeakerStream;
41 class MaxTrax;
42 class HalestormDriver;
43 } // End of namespace Audio
44 
45 namespace Common {
46 class MacResManager;
47 } // End of namespace Common
48 
49 namespace Kyra {
50 
51 class MidiOutput;
52 
59 class SoundMidiPC : public Sound {
60 public:
61  SoundMidiPC(KyraEngine_v1 *vm, Audio::Mixer *mixer, MidiDriver *driver, kType type);
62  ~SoundMidiPC() override;
63 
64  kType getMusicType() const override { return _type; }
65 
66  bool init() override;
67 
68  void updateVolumeSettings() override;
69 
70  void initAudioResourceInfo(int set, void *info) override;
71  void selectAudioResourceSet(int set) override;
72  bool hasSoundFile(uint file) const override;
73  void loadSoundFile(uint file) override;
74  void loadSoundFile(const Common::Path &file) override;
75  void loadSfxFile(const Common::Path &file) override;
76 
77  void playTrack(uint8 track) override;
78  void haltTrack() override;
79  bool isPlaying() const override;
80 
81  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
82  void stopAllSoundEffects() override;
83 
84  void beginFadeOut() override;
85 
86  void pause(bool paused) override;
87 private:
88  static void onTimer(void *data);
89 
90  // Our channel handling
91  int _musicVolume, _sfxVolume;
92 
93  uint32 _fadeStartTime;
94  bool _fadeMusicOut;
95 
96  // Midi file related
97  Common::Path _mFileName, _sFileName;
98  byte *_musicFile, *_sfxFile;
99 
100  MidiParser *_music;
101  MidiParser *_sfx[3];
102 
103  const SoundResourceInfo_PC *res() const {return _resInfo[_currentResourceSet]; }
104  SoundResourceInfo_PC *_resInfo[3];
105  int _currentResourceSet;
106 
107  // misc
108  kType _type;
109  Common::Path getFileName(const Common::Path &str);
110 
111  bool _nativeMT32;
112  MidiDriver *_driver;
114 
115  Common::Mutex _mutex;
116 };
117 
118 class SoundTowns_LoK : public Sound {
119 public:
121  ~SoundTowns_LoK() override;
122 
123  kType getMusicType() const override { return kTowns; }
124 
125  bool init() override;
126  void process() override;
127 
128  void initAudioResourceInfo(int set, void *info) override;
129  void selectAudioResourceSet(int set) override;
130  bool hasSoundFile(uint file) const override;
131  void loadSoundFile(uint file) override;
132  void loadSoundFile(const Common::Path &) override {}
133 
134  void playTrack(uint8 track) override;
135  void haltTrack() override;
136 
137  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
138  void stopAllSoundEffects() override;
139 
140  void beginFadeOut() override;
141 
142  void updateVolumeSettings() override;
143  void enableMusic(int enable) override;
144 
145 private:
146  bool loadInstruments();
147  void playEuphonyTrack(uint32 offset, int loop);
148 
149  void fadeOutSoundEffects();
150 
151  int _lastTrack;
152  Audio::SoundHandle _sfxHandle;
153 
154  uint8 *_musicTrackData;
155 
156  uint _sfxFileIndex;
157  uint8 *_sfxFileData;
158  uint8 _sfxChannel;
159 
160  EuphonyPlayer *_player;
161 
162  bool _cdaPlaying;
163 
164  const SoundResourceInfo_Towns *res() const {return _resInfo[_currentResourceSet]; }
165  SoundResourceInfo_Towns *_resInfo[3];
166  int _currentResourceSet;
167 
168  const uint8 *_musicFadeTable;
169  const uint8 *_sfxBTTable;
170  const uint8 *_sfxWDTable;
171 };
172 
173 class SoundPC98_LoK : public Sound {
174 public:
176  ~SoundPC98_LoK() override;
177 
178  kType getMusicType() const override { return kPC98; }
179 
180  bool init() override;
181 
182  void initAudioResourceInfo(int set, void *info) override;
183  void selectAudioResourceSet(int set) override;
184  bool hasSoundFile(uint file) const override;
185  void loadSoundFile(uint file) override;
186  void loadSoundFile(const Common::Path &file) override;
187 
188  void playTrack(uint8 track) override;
189  void haltTrack() override;
190  void beginFadeOut() override;
191 
192  int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, uint8 priority, bool isSfx) override { return -1; }
193  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
194 
195  void updateVolumeSettings() override;
196 
197 private:
198  int _lastTrack;
199  uint8 *_musicTrackData;
200  uint8 *_sfxTrackData;
201  TownsPC98_AudioDriver *_driver;
202 
203  const char *resPattern() {return _resInfo[_currentResourceSet]->c_str(); }
204  Common::String *_resInfo[3];
205  int _currentResourceSet;
206 };
207 
208 class SoundTownsPC98_v2 : public Sound {
209 public:
211  ~SoundTownsPC98_v2() override;
212 
213  kType getMusicType() const override { return _vm->gameFlags().platform == Common::kPlatformFMTowns ? kTowns : kPC98; }
214 
215  bool init() override;
216  void process() override;
217 
218  void initAudioResourceInfo(int set, void *info) override;
219  void selectAudioResourceSet(int set) override;
220  bool hasSoundFile(uint file) const override;
221  void loadSoundFile(uint file) override {}
222  void loadSoundFile(const Common::Path &file) override;
223 
224  void playTrack(uint8 track) override;
225  void haltTrack() override;
226  void beginFadeOut() override;
227 
228  int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume = 255, uint8 priority = 255, bool isSfx = true) override;
229  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
230 
231  void updateVolumeSettings() override;
232 
233 private:
234  Audio::AudioStream *_currentSFX;
235  int _lastTrack;
236  bool _useFmSfx;
237 
238  uint8 *_musicTrackData;
239  uint8 *_sfxTrackData;
240  TownsPC98_AudioDriver *_driver;
241 
242  const SoundResourceInfo_TownsPC98V2 *res() const { return _resInfo[_currentResourceSet]; }
243  SoundResourceInfo_TownsPC98V2 *_resInfo[3];
244  int _currentResourceSet;
245 };
246 
247 // PC Speaker MIDI driver
249 public:
251  ~MidiDriver_PCSpeaker() override;
252 
253  // MidiDriver interface
254  void close() override {}
255 
256  void send(uint32 data) override;
257 
258  MidiChannel *allocateChannel() override { return 0; }
259  MidiChannel *getPercussionChannel() override { return 0; }
260 
261  // MidiDriver_Emulated interface
262  void generateSamples(int16 *buffer, int numSamples) override;
263 
264  // AudioStream interface
265  bool isStereo() const override { return false; }
266  int getRate() const override { return _rate; }
267 private:
268  Common::Mutex _mutex;
269  Audio::PCSpeakerStream *_speaker;
270  int _rate;
271 
272  struct Channel {
273  uint8 pitchBendLow, pitchBendHigh;
274  uint8 hold;
275  uint8 modulation;
276  uint8 voiceProtect;
277  uint8 noteCount;
278  } _channel[2];
279 
280  void resetController(int channel);
281 
282  struct Note {
283  bool enabled;
284  uint8 hardwareChannel;
285  uint8 midiChannel;
286  uint8 note;
287  bool processHold;
288  uint8 flags;
289  uint8 hardwareFlags;
290  uint16 priority;
291  int16 modulation;
292  uint16 precedence;
293  } _note[2];
294 
295  void noteOn(int channel, int note);
296  void noteOff(int channel, int note);
297 
298  void turnNoteOn(int note);
299  void overwriteNote(int note);
300  void turnNoteOff(int note);
301 
302  void setupTone(int note);
303 
304  uint16 _countdown;
305  uint8 _hardwareChannel[1];
306  bool _modulationFlag;
307 
308  uint8 _timerValue;
309  void onTimer() override;
310 
311  static const uint8 _noteTable1[];
312  static const uint8 _noteTable2[];
313 };
314 
315 // for StaticResource (maybe we can find a nicer way to handle it)
317  uint8 note;
318  uint8 patch;
319  uint16 duration;
320  uint8 volume;
321  uint8 pan;
322 };
323 
324 class SoundAmiga_LoK : public Sound {
325 public:
327  ~SoundAmiga_LoK() override;
328 
329  kType getMusicType() const override { return kAmiga; } //FIXME
330 
331  bool init() override;
332 
333  void initAudioResourceInfo(int set, void *info) override;
334  void selectAudioResourceSet(int set) override;
335  bool hasSoundFile(uint file) const override;
336  void loadSoundFile(uint file) override;
337  void loadSoundFile(const Common::Path &) override {}
338 
339  void playTrack(uint8 track) override;
340  void haltTrack() override;
341  void beginFadeOut() override;
342 
343  int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, uint8 priority, bool isSfx) override { return -1; }
344  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
345 
346 protected:
347  Audio::MaxTrax *_driver;
348  Audio::SoundHandle _musicHandle;
349  enum FileType { kFileNone = -1, kFileIntro = 0, kFileGame = 1, kFileFinal = 2 } _fileLoaded;
350 
351  const AmigaSfxTable *_tableSfxIntro;
352  int _tableSfxIntro_Size;
353 
354  const AmigaSfxTable *_tableSfxGame;
355  int _tableSfxGame_Size;
356 };
357 
358 class SoundMacRes;
359 class SoundMac : public Sound {
360 public:
361  SoundMac(KyraEngine_v1 *vm, Audio::Mixer *mixer);
362  ~SoundMac() override;
363 
364  kType getMusicType() const override;
365 
366  bool init() override { return init(musicEnabled() == 1); }
367  bool init(bool hiQuality);
368  void initAudioResourceInfo(int, void*) override {}
369  void selectAudioResourceSet(int set) override;
370  bool hasSoundFile(uint) const override { return true; }
371  void loadSoundFile(uint) override {}
372  void loadSoundFile(const Common::Path &) override {}
373  void playTrack(uint8 track) override;
374  void haltTrack() override;
375  void playSoundEffect(uint16 track, uint8) override;
376  bool isPlaying() const override;
377  void beginFadeOut() override;
378  void updateVolumeSettings() override;
379  void enableMusic(int enable) override;
380 
381 private:
382  void setQuality(bool hi);
383 
384  SoundMacRes *_res;
385  Audio::HalestormDriver *_driver;
386  const int _talkieFlag;
387  bool _ready;
388 
389  const uint16 *_resIDMusic;
390  int _currentResourceSet;
391 
392  static const uint16 _resIDMusicIntro[4];
393  static const uint16 _resIDMusicIngame[35];
394  static const uint8 _musicLoopTable[35];
395  static const uint16 _resIDSfxIntro[2][39];
396  static const uint16 _resIDSfxIngame[2][39];
397 
398  struct SoundEffectDef {
399  uint8 note;
400  uint8 number;
401  uint16 rate;
402  uint8 unk;
403  };
404 
405  static const SoundEffectDef _soundEffectDefsIntro[16];
406  static const SoundEffectDef _soundEffectDefsIngame[120];
407 };
408 
409 #ifdef ENABLE_EOB
410 
411 class SoundTowns_Darkmoon : public Sound, public TownsAudioInterfacePluginDriver {
412 public:
413  SoundTowns_Darkmoon(KyraEngine_v1 *vm, Audio::Mixer *mixer);
414  ~SoundTowns_Darkmoon() override;
415 
416  kType getMusicType() const override { return kTowns; }
417 
418  bool init() override;
419 
420  void timerCallback(int timerId) override;
421 
422  void initAudioResourceInfo(int set, void *info) override;
423  void selectAudioResourceSet(int set) override;
424  bool hasSoundFile(uint file) const override;
425  void loadSoundFile(uint file) override;
426  void loadSoundFile(const Common::Path &name) override;
427 
428  void playTrack(uint8 track) override;
429  void haltTrack() override;
430  bool isPlaying() const override;
431 
432  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
433  void stopAllSoundEffects() override;
434 
435  void beginFadeOut() override;
436 
437  void updateVolumeSettings() override;
438 
439  int checkTrigger() override;
440 
441  void resetTrigger() override;
442 
443 private:
444  struct SoundTableEntry {
445  int8 type;
446  int32 para1;
447  int16 para2;
448  } _soundTable[120];
449 
450  const char *const *_fileList;
451  uint _fileListLen;
452 
453  uint8 _lastSfxChan;
454  uint8 _lastEnvChan;
455  uint8 *_pcmData;
456  uint32 _pcmDataSize;
457  uint8 _pcmVol;
458 
459  int _timer;
460  int _timerSwitch;
461 
462  SoundResourceInfo_TownsEoB *_resource[3];
463 
464  TownsAudioInterface *_intf;
465 };
466 
467 class AudioMaster2;
468 class SoundAmiga_EoB: public Sound {
469 public:
470  SoundAmiga_EoB(KyraEngine_v1 *vm, Audio::Mixer *mixer);
471  ~SoundAmiga_EoB() override;
472 
473  kType getMusicType() const override;
474 
475  bool init() override;
476  void initAudioResourceInfo(int set, void *info) override;
477  void selectAudioResourceSet(int set) override;
478  bool hasSoundFile(uint file) const override { return false; }
479  void loadSoundFile(uint) override {}
480  void loadSoundFile(const Common::Path &file) override;
481  void unloadSoundFile(const Common::String &file) override;
482  void playTrack(uint8 track) override;
483  void haltTrack() override;
484  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
485  void beginFadeOut() override { beginFadeOut(160); }
486  void beginFadeOut(int delay) override;
487  void updateVolumeSettings() override;
488  int checkTrigger() override;
489 
490 private:
491  uint8 *_fileBuffer;
492 
493  KyraEngine_v1 *_vm;
494  AudioMaster2 *_driver;
495  SoundResourceInfo_AmigaEoB *_resInfo[3];
496  Common::String _lastSound;
497 
498  int _currentResourceSet;
499 
500  bool _ready;
501 };
502 
503 class MLALF98;
504 class SoundPC98_EoB : public Sound {
505 public:
506  SoundPC98_EoB(KyraEngine_v1 *vm, Audio::Mixer *mixer);
507  ~SoundPC98_EoB() override;
508 
509  kType getMusicType() const override;
510 
511  bool init() override;
512  void initAudioResourceInfo(int set, void *info) override;
513  void selectAudioResourceSet(int set) override;
514  bool hasSoundFile(uint file) const override { return false; }
515  void loadSoundFile(uint file) override;
516  void loadSoundFile(const Common::Path &file) override {}
517  void loadSfxFile(const Common::Path &file) override;
518  void playTrack(uint8 track) override;
519  void haltTrack() override;
520  void playSoundEffect(uint16 track, uint8) override;
521  void beginFadeOut() override {}
522  void updateVolumeSettings() override;
523 
524 private:
525  KyraEngine_v1 *_vm;
526  MLALF98 *_driver;
527 
528  SoundResourceInfo_PC *_resInfo[3];
529  int _currentResourceSet;
530 
531  uint32 _sfxDelay;
532 
533  bool _ready;
534 };
535 
536 class CapcomPC98AudioDriver;
537 class SoundPC98_Darkmoon : public Sound {
538 public:
539  SoundPC98_Darkmoon(KyraEngine_v1 *vm, MidiDriver::DeviceHandle dev, Audio::Mixer *mixer);
540  ~SoundPC98_Darkmoon() override;
541 
542  kType getMusicType() const override;
543  kType getSfxType() const override;
544 
545  bool init() override;
546 
547  void initAudioResourceInfo(int set, void *info) override;
548  void selectAudioResourceSet(int set) override;
549  bool hasSoundFile(uint file) const override { return true; }
550  void loadSoundFile(uint file) override;
551  void loadSoundFile(const Common::Path &name) override;
552 
553  void playTrack(uint8 track) override;
554  void haltTrack() override;
555  bool isPlaying() const override;
556 
557  void playSoundEffect(uint16 track, uint8 volume = 0xFF) override;
558  void stopAllSoundEffects() override;
559 
560  void beginFadeOut() override;
561 
562  void pause(bool paused) override;
563 
564  void updateVolumeSettings() override;
565 
566  int checkTrigger() override;
567  void resetTrigger() override {} // This sound class is for EOB II only, this method is not needed there.
568 
569 private:
570  void restartBackgroundMusic();
571  const uint8 *getData(uint16 track) const;
572 
573  KyraEngine_v1 *_vm;
574  CapcomPC98AudioDriver *_driver;
575  uint8 *_soundData, *_fileBuffer;
576 
577  int _lastTrack;
578 
579  const SoundResourceInfo_PC *res() const {return _resInfo[_currentResourceSet]; }
580  SoundResourceInfo_PC *_resInfo[3];
581  int _currentResourceSet;
582 
583  Common::Path _soundFileLoaded;
584 
586  kType _drvType;
587  bool _ready;
588 };
589 
590 class SegaAudioDriver;
591 class SoundSegaCD_EoB : public Sound {
592 public:
593  SoundSegaCD_EoB(KyraEngine_v1 *vm, Audio::Mixer *mixer);
594  ~SoundSegaCD_EoB() override;
595 
596  kType getMusicType() const override;
597 
598  bool init() override;
599  void initAudioResourceInfo(int, void*) override {}
600  void selectAudioResourceSet(int) override {}
601  bool hasSoundFile(uint file) const override { return false; }
602  void loadSoundFile(uint file) override {}
603  void loadSoundFile(const Common::Path &file) override {}
604  void playTrack(uint8 track) override;
605  void haltTrack() override;
606  void playSoundEffect(uint16 track, uint8 volume) override;
607  bool isPlaying() const override;
608  void beginFadeOut() override {}
609  void updateVolumeSettings() override;
610 
611 private:
612  void loadPCMData();
613  void loadFMData();
614 
615  KyraEngine_v1 *_vm;
616  SegaAudioDriver *_driver;
617 
618  uint8 _pcmOffsets[8];
619  uint16 _fmOffsets[140];
620  const uint8 *_fmData;
621  int _lastSoundEffect;
622  bool _ready;
623 
624  static const uint8 _fmTrackMap[140];
625 };
626 
627 #endif
628 
629 } // End of namespace Kyra
630 
631 #endif
Definition: sound_intern.h:208
Definition: halestorm.h:44
void loadSoundFile(const Common::Path &) override
Definition: sound_intern.h:132
Definition: str.h:59
Definition: sound.h:40
Definition: sound.h:68
uint32 DeviceHandle
Definition: mididrv.h:322
void loadSoundFile(const Common::Path &) override
Definition: sound_intern.h:337
void loadSoundFile(uint) override
Definition: sound_intern.h:371
Definition: miles.h:123
Definition: kyra_v1.h:126
bool init() override
Definition: sound_intern.h:366
Definition: path.h:52
Definition: sound_intern.h:324
Definition: pcspk.h:88
Definition: sound.h:78
Definition: sound.h:91
Definition: mididrv.h:313
bool hasSoundFile(uint) const override
Definition: sound_intern.h:370
bool isStereo() const override
Definition: sound_intern.h:265
Definition: towns_audio.h:37
Definition: mixer.h:49
Definition: mixer.h:70
Definition: sound_intern.h:248
Definition: towns_euphony.h:115
Definition: algorithm.h:29
Definition: mutex.h:67
int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, uint8 priority, bool isSfx) override
Definition: sound_intern.h:343
Definition: audiostream.h:50
void close() override
Definition: sound_intern.h:254
Definition: sound_intern.h:173
Definition: mididrv.h:541
Definition: detection.h:27
Definition: towns_pc98_driver.h:34
void loadSoundFile(uint file) override
Definition: sound_intern.h:221
int getRate() const override
Definition: sound_intern.h:266
Definition: emumidi.h:29
Definition: sound_intern.h:359
Definition: sound_intern.h:118
Definition: sound_mac_res.h:41
int32 voicePlay(const char *file, Audio::SoundHandle *handle, uint8 volume, uint8 priority, bool isSfx) override
Definition: sound_intern.h:192
void initAudioResourceInfo(int, void *) override
Definition: sound_intern.h:368
Definition: sound_intern.h:316
Definition: system.h:39
Definition: sound_intern.h:59
void loadSoundFile(const Common::Path &) override
Definition: sound_intern.h:372
Definition: midiparser.h:354
Definition: sound.h:46
Definition: towns_audio.h:31