1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef NANCY_SOUND_H
#define NANCY_SOUND_H
#include "engines/nancy/commontypes.h"
#include "audio/mixer.h"
namespace Common {
class SeekableReadStream;
}
namespace Audio {
class SeekableAudioStream;
class QueuingAudioStream;
}
namespace Nancy {
class IFF;
class NancyConsole;
class NancyEngine;
class SoundManager {
friend class NancyConsole;
public:
// Settings for playing a sound, used in nancy3 and up
// Older versions had a different, non-bitflag enum, but testing
// indicates those were never actually implemented
enum PlayCommandFlags {
kPlaySequential = 0x0001, // Play normally
kPlaySequentialPosition = 0x0003, // Play at fixed position in 3D space
kPlaySequentialFrameAnchor = 0x0007, // Position in 3D space is tied to a background frame, ignoring 3D coordinates
kPlayRandomTime = 0x0010, // Play at random time intervals
kPlayRandomPosition = 0x0020, // Play at random 3D positions
kPlayMoveLinear = 0x0100, // Move sound position in 3D space. The movement is linear unless kPlayMoveCircular is also set
kPlayMoveCircular = 0x0300, // Move sound position in a circular direction (see SoundRotationAxis)
kPlayRandomMove = 0x0500 // Move along random vector. Does not combine with kPlayMoveCircular
};
SoundManager();
~SoundManager();
void loadCommonSounds(IFF *boot);
void initSoundChannels();
// Load a sound into a channel without starting it
void loadSound(const SoundDescription &description, SoundEffectDescription **effectData = nullptr, bool forceReload = false);
void playSound(uint16 channelID);
void playSound(const SoundDescription &description);
void playSound(const Common::String &chunkName);
void pauseSound(uint16 channelID, bool pause);
void pauseSound(const SoundDescription &description, bool pause);
void pauseSound(const Common::String &chunkName, bool pause);
void pauseAllSounds(bool pause);
bool isSoundPlaying(uint16 channelID) const;
bool isSoundPlaying(const SoundDescription &description) const;
bool isSoundPlaying(const Common::String &chunkName) const;
void stopSound(uint16 channelID);
void stopSound(const SoundDescription &description);
void stopSound(const Common::String &chunkName);
void stopAllSounds();
byte getVolume(uint16 channelID);
byte getVolume(const SoundDescription &description);
byte getVolume(const Common::String &chunkName);
void setVolume(uint16 channelID, uint16 volume);
void setVolume(const SoundDescription &description, uint16 volume);
void setVolume(const Common::String &chunkName, uint16 volume);
uint32 getRate(uint16 channelID);
uint32 getRate(const SoundDescription &description);
uint32 getRate(const Common::String &chunkName);
uint32 getBaseRate(uint16 channelID);
uint32 getBaseRate(const SoundDescription &description);
uint32 getBaseRate(const Common::String &chunkName);
void setRate(uint16 channelID, uint32 rate);
void setRate(const SoundDescription &description, uint32 rate);
void setRate(const Common::String &chunkName, uint32 rate);
Audio::Timestamp getLength(uint16 channelID);
Audio::Timestamp getLength(const SoundDescription &description);
Audio::Timestamp getLength(const Common::String &chunkName);
void soundEffectMaintenance();
void recalculateSoundEffects();
// Used when changing scenes
void stopAndUnloadSceneSpecificSounds();
void pauseSceneSpecificSounds(bool pause);
static Audio::SeekableAudioStream *makeHISStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 overrideSamplesPerSec = 0);
protected:
struct Channel {
~Channel();
Common::String name;
Audio::Mixer::SoundType type = Audio::Mixer::SoundType::kPlainSoundType;
uint16 playCommands = 1;
uint16 numLoops = 0;
uint volume = 0;
uint16 panAnchorFrame = 0;
bool isPanning = false;
Audio::SeekableAudioStream *stream = nullptr;
Audio::AudioStream *streamForMixer = nullptr;
Audio::SoundHandle handle;
bool isPersistent = false;
// Sound effect data, not applicable to nancy2 and below
SoundEffectDescription *effectData = nullptr;
Math::Vector3d position;
Math::Vector3d positionDelta;
uint32 nextStepTime = 0;
uint16 stepsLeft = 0;
uint32 nextRepeatTime = 0;
};
void soundEffectMaintenance(uint16 channelID, bool force = false);
Audio::Mixer *_mixer;
Common::Array<Channel> _channels;
Common::HashMap<Common::String, SoundDescription> _commonSounds;
bool _shouldRecalculate;
Math::Vector3d _orientation;
Math::Vector3d _position;
uint _positionLerp = 0;
};
} // End of namespace Nancy
#endif // NANCY_SOUND_H
|