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 LURE_SOUND_H 24 #define LURE_SOUND_H 25 26 #include "lure/luredefs.h" 27 #include "lure/disk.h" 28 #include "lure/memory.h" 29 30 #include "common/mutex.h" 31 #include "common/singleton.h" 32 #include "common/ptr.h" 33 34 #include "audio/adlib_ms.h" 35 #include "audio/mididrv.h" 36 #include "audio/mt32gm.h" 37 38 class MidiParser; 39 class MidiChannel; 40 41 namespace Lure { 42 43 #define NUM_CHANNELS 16 44 #define LURE_MAX_SOURCES 10 45 46 class MidiMusic: public MidiDriver_BASE { 47 private: 48 uint8 _soundNumber; 49 uint8 _numChannels; 50 byte _volume; 51 MemoryBlock *_decompressedSound; 52 uint8 *_soundData; 53 uint8 _soundSize; 54 MidiDriver_Multisource *_driver; 55 MidiDriver_MT32GM *_mt32Driver; 56 int8 _source; 57 MidiParser *_parser; 58 bool _isMusic; 59 bool _loop; 60 bool _isPlaying; 61 62 void queueUpdatePos(); 63 uint8 randomQueuePos(); 64 uint32 songOffset(uint16 songNum) const; 65 uint32 songLength(uint16 songNum) const; 66 67 public: 68 MidiMusic(MidiDriver_Multisource *driver, uint8 soundNum, bool isMus, bool loop, 69 int8 source, uint8 numChannels, void *soundData, uint32 size, uint8 volume); 70 ~MidiMusic() override; 71 void setVolume(int volume); getVolume()72 int getVolume() const { return _volume; } 73 74 void playSong(uint16 songNum); stopSong()75 void stopSong() { stopMusic(); } 76 void playMusic(); 77 void stopMusic(); 78 void pauseMusic(); 79 void resumeMusic(); 80 void queueTuneList(int16 tuneList); 81 bool queueSong(uint16 songNum); 82 void toggleVChange(); 83 84 // MidiDriver_BASE interface implementation 85 void send(uint32 b) override; 86 void send(int8 source, uint32 b) override; 87 void metaEvent(byte type, byte *data, uint16 length) override; 88 void metaEvent(int8 source, byte type, byte *data, uint16 length) override; 89 90 void onTimer(); 91 soundNumber()92 uint8 soundNumber() const { return _soundNumber; } getSource()93 int8 getSource() const { return _source; } isPlaying()94 bool isPlaying() const { return _isPlaying; } isMusic()95 bool isMusic() const { return _isMusic; } 96 }; 97 98 class SoundManager : public Common::Singleton<SoundManager> { 99 private: 100 // Outer sound interface properties 101 MemoryBlock *_descs; 102 MemoryBlock *_soundData; 103 uint8 _soundsTotal; 104 int _numDescs; soundDescs()105 SoundDescResource *soundDescs() { return (SoundDescResource *) _descs->data(); } 106 MidiDriver_Multisource *_driver; 107 MidiDriver_MT32GM *_mt32Driver; 108 typedef Common::List<Common::SharedPtr<SoundDescResource> > SoundList; 109 typedef SoundList::iterator SoundListIterator; 110 SoundList _activeSounds; 111 typedef Common::List<Common::SharedPtr<MidiMusic> > MusicList; 112 typedef MusicList::iterator MusicListIterator; 113 MusicList _playingSounds; 114 bool _sourcesInUse[LURE_MAX_SOURCES]; 115 bool _nativeMT32; 116 bool _isRoland; 117 Common::Mutex _soundMutex; 118 bool _paused; 119 120 // Internal support methods 121 void bellsBodge(); 122 void musicInterface_TidySounds(); 123 static void onTimer(void *data); 124 void doTimer(); 125 126 public: 127 SoundManager(); 128 ~SoundManager() override; 129 130 void saveToStream(Common::WriteStream *stream); 131 void loadFromStream(Common::ReadStream *stream); 132 133 void loadSection(uint16 sectionId); 134 bool initCustomTimbres(bool canAbort = false); 135 void killSounds(); 136 void addSound(uint8 soundIndex, bool tidyFlag = true); 137 void addSound2(uint8 soundIndex); 138 void stopSound(uint8 soundIndex); 139 void killSound(uint8 soundNumber); 140 void setVolume(uint8 soundNumber, uint8 volume); 141 void syncSounds(); 142 void tidySounds(); 143 uint8 descIndexOf(uint8 soundNumber); 144 SoundDescResource *findSound(uint8 soundNumber); 145 void removeSounds(); 146 void restoreSounds(); 147 bool fadeOut(); 148 void pause(); 149 void resume(); getPaused()150 bool getPaused() const { return _paused; } hasNativeMT32()151 bool hasNativeMT32() const { return _nativeMT32; } isRoland()152 bool isRoland() const { return _isRoland; } 153 154 // The following methods implement the external sound player module 155 //void musicInterface_Initialize(); 156 void musicInterface_Play(uint8 soundNumber, bool isMusic = false, uint8 numChannels = 4, uint8 volume = 0x80); 157 void musicInterface_Stop(uint8 soundNumber); 158 bool musicInterface_CheckPlaying(uint8 soundNumber); 159 void musicInterface_SetVolume(uint8 soundNumber, uint8 volume); 160 void musicInterface_KillAll(); 161 void musicInterface_ContinuePlaying(); 162 void musicInterface_TrashReverb(); 163 }; 164 165 // AdLib MidiDriver subclass implementing the behavior specific to Lure of the 166 // Temptress. 167 class MidiDriver_ADLIB_Lure : public MidiDriver_ADLIB_Multisource { 168 protected: 169 // Lookup array for OPL frequency (F-num) values. 170 static const uint16 OPL_FREQUENCY_LOOKUP[]; 171 172 public: 173 MidiDriver_ADLIB_Lure(); 174 175 // Channel aftertouch is used to adjust a note's volume. This is done by 176 // overriding the velocity of the active note and recalculating the volume. 177 void channelAftertouch(uint8 channel, uint8 pressure, uint8 source) override; 178 // The MIDI data uses three custom sequencer meta events; the most important 179 // one sets the instrument definition for a channel. 180 void metaEvent(int8 source, byte type, byte *data, uint16 length) override; 181 182 protected: 183 InstrumentInfo determineInstrument(uint8 channel, uint8 source, uint8 note) override; 184 uint16 calculateFrequency(uint8 channel, uint8 source, uint8 note) override; 185 // Returns the number of semitones in bits 8+ and an 8 bit fraction of a 186 // semitone. 187 int32 calculatePitchBend(uint8 channel, uint8 source, uint16 oplFrequency) override; 188 uint8 calculateUnscaledVolume(uint8 channel, uint8 source, uint8 velocity, OplInstrumentDefinition &instrumentDef, uint8 operatorNum) override; 189 190 // Stores the instrument definitions set by sequencer meta events. 191 OplInstrumentDefinition _instrumentDefs[LURE_MAX_SOURCES][MIDI_CHANNEL_COUNT]; 192 // Pitch bend sensitivity in semi-tones. This is a global setting; 193 // it cannot be specified for a specific MIDI channel. 194 uint8 _pitchBendSensitivity; 195 }; 196 197 } // End of namespace Lure 198 199 #define Sound (::Lure::SoundManager::instance()) 200 201 #endif 202