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 NEVERHOOD_SOUND_H 24 #define NEVERHOOD_SOUND_H 25 26 #include "audio/audiostream.h" 27 #include "common/array.h" 28 #include "neverhood/resourceman.h" 29 30 namespace Common { 31 class SeekableReadStream; 32 } 33 34 namespace Audio { 35 class SoundHandle; 36 } 37 38 namespace Neverhood { 39 40 class NeverhoodEngine; 41 class AudioResourceManSoundItem; 42 class AudioResourceManMusicItem; 43 44 class SoundResource { 45 public: 46 SoundResource(NeverhoodEngine *vm); 47 ~SoundResource(); 48 bool isPlaying(); 49 void load(uint32 fileHash); 50 void unload(); 51 void play(uint32 fileHash); 52 void play(); 53 void playLooping(); 54 void stop(); 55 void setVolume(int16 volume); 56 void setPan(int16 pan); 57 protected: 58 NeverhoodEngine *_vm; 59 int16 _soundIndex; 60 AudioResourceManSoundItem *getSoundItem(); 61 }; 62 63 class MusicResource { 64 public: 65 MusicResource(NeverhoodEngine *vm); 66 bool isPlaying(); 67 void load(uint32 fileHash); 68 void unload(); 69 void play(int16 fadeVolumeStep); 70 void stop(int16 fadeVolumeStep); 71 void setVolume(int16 volume); 72 protected: 73 NeverhoodEngine *_vm; 74 int16 _musicIndex; 75 AudioResourceManMusicItem *getMusicItem(); 76 }; 77 78 class MusicItem { 79 public: 80 MusicItem(NeverhoodEngine *vm, uint32 groupNameHash, uint32 musicFileHash); 81 ~MusicItem(); 82 void startMusic(int16 countdown, int16 fadeVolumeStep); 83 void stopMusic(int16 countdown, int16 fadeVolumeStep); 84 void update(); getGroupNameHash()85 uint32 getGroupNameHash() const { return _groupNameHash; } getFileHash()86 uint32 getFileHash() const { return _fileHash; } 87 protected: 88 NeverhoodEngine *_vm; 89 uint32 _groupNameHash; 90 uint32 _fileHash; 91 bool _play; 92 bool _stop; 93 int16 _fadeVolumeStep; 94 int16 _countdown; 95 MusicResource *_musicResource; 96 }; 97 98 class SoundItem { 99 public: 100 SoundItem(NeverhoodEngine *vm, uint32 groupNameHash, uint32 soundFileHash, 101 bool playOnceAfterRandomCountdown, int16 minCountdown, int16 maxCountdown, 102 bool playOnceAfterCountdown, int16 initialCountdown, bool playLooping, int16 currCountdown); 103 ~SoundItem(); 104 void setSoundParams(bool playOnceAfterRandomCountdown, int16 minCountdown, int16 maxCountdown, 105 int16 firstMinCountdown, int16 firstMaxCountdown); 106 void playSoundLooping(); 107 void stopSound(); 108 void setVolume(int volume); 109 void update(); setPlayOnceAfterCountdown(bool playOnceAfterCountdown)110 void setPlayOnceAfterCountdown(bool playOnceAfterCountdown) { _playOnceAfterCountdown = playOnceAfterCountdown; } getGroupNameHash()111 uint32 getGroupNameHash() const { return _groupNameHash; } getFileHash()112 uint32 getFileHash() const { return _fileHash; } getCurrCountdown()113 int16 getCurrCountdown() const { return _currCountdown; } 114 protected: 115 NeverhoodEngine *_vm; 116 uint32 _groupNameHash; 117 uint32 _fileHash; 118 bool _playOnceAfterRandomCountdown; 119 int16 _minCountdown; 120 int16 _maxCountdown; 121 bool _playOnceAfterCountdown; 122 int16 _initialCountdown; 123 bool _playLooping; 124 int16 _currCountdown; 125 SoundResource *_soundResource; 126 }; 127 128 class SoundMan { 129 public: 130 SoundMan(NeverhoodEngine *vm); 131 ~SoundMan(); 132 133 void stopAllMusic(); 134 void stopAllSounds(); 135 136 // Music 137 void addMusic(uint32 groupNameHash, uint32 musicFileHash); 138 void deleteMusic(uint32 musicFileHash); 139 void startMusic(uint32 musicFileHash, int16 countdown, int16 fadeVolumeStep); 140 void stopMusic(uint32 musicFileHash, int16 countdown, int16 fadeVolumeStep); 141 142 // Sound 143 void addSound(uint32 groupNameHash, uint32 soundFileHash); 144 void addSoundList(uint32 groupNameHash, const uint32 *soundFileHashList); 145 void deleteSound(uint32 soundFileHash); 146 void setSoundParams(uint32 soundFileHash, bool playOnceAfterRandomCountdown, 147 int16 minCountdown, int16 maxCountdown, int16 firstMinCountdown, int16 firstMaxCountdown); 148 void setSoundListParams(const uint32 *soundFileHashList, bool playOnceAfterRandomCountdown, 149 int16 minCountdown, int16 maxCountdown, int16 firstMinCountdown, int16 firstMaxCountdown); 150 void playSoundLooping(uint32 soundFileHash); 151 void stopSound(uint32 soundFileHash); 152 void setSoundVolume(uint32 soundFileHash, int volume); 153 154 // Misc 155 void update(); 156 void deleteGroup(uint32 groupNameHash); 157 void deleteMusicGroup(uint32 groupNameHash); 158 void deleteSoundGroup(uint32 groupNameHash); 159 void playTwoSounds(uint32 groupNameHash, uint32 soundFileHash1, uint32 soundFileHash2, int16 initialCountdown); 160 void playSoundThree(uint32 groupNameHash, uint32 soundFileHash); 161 void setTwoSoundsPlayFlag(bool playOnceAfterCountdown); 162 void setSoundThreePlayFlag(bool playOnceAfterCountdown); 163 164 protected: 165 NeverhoodEngine *_vm; 166 167 // TODO Find out what these special sounds are used for (door sounds?) 168 int _soundIndex1, _soundIndex2; 169 int16 _initialCountdown; 170 bool _playOnceAfterCountdown; 171 172 int _soundIndex3; 173 int16 _initialCountdown3; 174 bool _playOnceAfterCountdown3; 175 176 Common::Array<MusicItem*> _musicItems; 177 Common::Array<SoundItem*> _soundItems; 178 179 MusicItem *getMusicItemByHash(uint32 musicFileHash); 180 SoundItem *getSoundItemByHash(uint32 soundFileHash); 181 int16 addMusicItem(MusicItem *musicItem); 182 int16 addSoundItem(SoundItem *soundItem); 183 void deleteSoundByIndex(int index); 184 185 }; 186 187 class NeverhoodAudioStream : public Audio::AudioStream { 188 public: 189 NeverhoodAudioStream(int rate, byte shiftValue, bool isLooping, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream); 190 ~NeverhoodAudioStream() override; 191 int readBuffer(int16 *buffer, const int numSamples) override; isStereo()192 bool isStereo() const override { return _isStereo; } endOfData()193 bool endOfData() const override { return _endOfData; } getRate()194 int getRate() const override { return _rate; } 195 private: 196 const int _rate; 197 const bool _isLooping; 198 const bool _isStereo; 199 const byte _shiftValue; 200 const bool _isCompressed; 201 int16 _prevValue; 202 Common::DisposablePtr<Common::SeekableReadStream> _stream; 203 bool _endOfData; 204 byte *_buffer; 205 enum { 206 kSampleBufferLength = 2048 207 }; 208 int fillBuffer(int maxSamples); 209 }; 210 211 // TODO Rename these 212 213 class AudioResourceManSoundItem { 214 public: 215 AudioResourceManSoundItem(NeverhoodEngine *vm, uint32 fileHash); 216 ~AudioResourceManSoundItem(); 217 void loadSound(); 218 void unloadSound(); 219 void setVolume(int16 volume); 220 void setPan(int16 pan); 221 void playSound(bool looping); 222 void stopSound(); 223 bool isPlaying(); 224 protected: 225 NeverhoodEngine *_vm; 226 uint32 _fileHash; 227 ResourceHandle _resourceHandle; 228 const byte *_data; 229 bool _isLoaded; 230 bool _isPlaying; 231 int16 _volume; 232 int16 _panning; 233 Audio::SoundHandle *_soundHandle; 234 }; 235 236 class AudioResourceManMusicItem { 237 public: 238 AudioResourceManMusicItem(NeverhoodEngine *vm, uint32 fileHash); 239 ~AudioResourceManMusicItem(); 240 void playMusic(int16 fadeVolumeStep); 241 void stopMusic(int16 fadeVolumeStep); 242 void unloadMusic(); 243 void setVolume(int16 volume); 244 void restart(); 245 void update(); isPlaying()246 bool isPlaying() const { return _isPlaying; } canRestart()247 bool canRestart() const { return _canRestart; } isTerminated()248 bool isTerminated() const { return _terminate; } getFileHash()249 uint32 getFileHash() const { return _fileHash; } 250 protected: 251 NeverhoodEngine *_vm; 252 uint32 _fileHash; 253 bool _isPlaying; 254 bool _canRestart; 255 bool _terminate; 256 int16 _volume; 257 int16 _panning; 258 bool _start; 259 bool _isFadingIn; 260 bool _isFadingOut; 261 int16 _fadeVolume; 262 int16 _fadeVolumeStep; 263 Audio::SoundHandle *_soundHandle; 264 }; 265 266 class AudioResourceMan { 267 public: 268 AudioResourceMan(NeverhoodEngine *vm); 269 ~AudioResourceMan(); 270 271 void stopAllMusic(); 272 void stopAllSounds(); 273 274 int16 addSound(uint32 fileHash); 275 void removeSound(int16 soundIndex); 276 277 int16 loadMusic(uint32 fileHash); 278 void updateMusic(); 279 280 AudioResourceManSoundItem *getSoundItem(int16 index); 281 AudioResourceManMusicItem *getMusicItem(int16 index); 282 283 protected: 284 NeverhoodEngine *_vm; 285 286 Common::Array<AudioResourceManMusicItem*> _musicItems; 287 Common::Array<AudioResourceManSoundItem*> _soundItems; 288 289 int16 addSoundItem(AudioResourceManSoundItem *soundItem); 290 291 }; 292 293 } // End of namespace Neverhood 294 295 #endif /* NEVERHOOD_SOUND_H */ 296