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