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