ScummVM API documentation
sound.h
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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (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, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef NANCY_SOUND_H
23#define NANCY_SOUND_H
24
25#include "engines/nancy/commontypes.h"
26
27#include "audio/mixer.h"
28
29namespace Common {
30class SeekableReadStream;
31}
32
33namespace Audio {
34class SeekableAudioStream;
35class QueuingAudioStream;
36}
37
38namespace Nancy {
39
40class IFF;
41class NancyConsole;
42class NancyEngine;
43
45public:
46 // Settings for playing a sound, used in nancy3 and up
47 // Older versions had a different, non-bitflag enum, but testing
48 // indicates those were never actually implemented
49 enum PlayCommandFlags {
50 kPlaySequential = 0x0001, // Play normally
51 kPlaySequentialPosition = 0x0003, // Play at fixed position in 3D space
52 kPlaySequentialFrameAnchor = 0x0007, // Position in 3D space is tied to a background frame, ignoring 3D coordinates
53
54 kPlayRandomTime = 0x0010, // Play at random time intervals
55 kPlayRandomPosition = 0x0020, // Play at random 3D positions
56
57 kPlayMoveLinear = 0x0100, // Move sound position in 3D space. The movement is linear unless kPlayMoveCircular is also set
58 kPlayMoveCircular = 0x0300, // Move sound position in a circular direction (see SoundRotationAxis)
59 kPlayRandomMove = 0x0500 // Move along random vector. Does not combine with kPlayMoveCircular
60 };
61
64
65 void loadCommonSounds(IFF *boot);
66 void initSoundChannels();
67
68 // Load a sound into a channel without starting it
69 void loadSound(const SoundDescription &description, SoundEffectDescription **effectData = nullptr, bool forceReload = false);
70
71 void playSound(uint16 channelID);
72 void playSound(const SoundDescription &description);
73 void playSound(const Common::String &chunkName);
74
75 void pauseSound(uint16 channelID, bool pause);
76 void pauseSound(const SoundDescription &description, bool pause);
77 void pauseSound(const Common::String &chunkName, bool pause);
78 void pauseAllSounds(bool pause);
79
80 bool isSoundPlaying(uint16 channelID) const;
81 bool isSoundPlaying(const SoundDescription &description) const;
82 bool isSoundPlaying(const Common::String &chunkName) const;
83
84 void stopSound(uint16 channelID);
85 void stopSound(const SoundDescription &description);
86 void stopSound(const Common::String &chunkName);
87 void stopAllSounds();
88
89 byte getVolume(uint16 channelID);
90 byte getVolume(const SoundDescription &description);
91 byte getVolume(const Common::String &chunkName);
92
93 void setVolume(uint16 channelID, uint16 volume);
94 void setVolume(const SoundDescription &description, uint16 volume);
95 void setVolume(const Common::String &chunkName, uint16 volume);
96
97 // The volume a channel was last given, by the sound loaded into it or by
98 // setVolume(), from 0 to 100. Nancy20 scripts read it back.
99 uint16 getRequestedVolume(uint16 channelID) const;
100
101 // Nancy 11+ Update3DSound (AR 156). Adjusts a playing fixed-position
102 // 3D sound's position and/or its min/max audible distance.
103 void update3DSoundPosition(uint16 channelID, int32 x, int32 y, int32 z);
104 void update3DSoundMinDistance(uint16 channelID, uint32 minDistance);
105 void update3DSoundMaxDistance(uint16 channelID, uint32 maxDistance);
106
107 // Nancy12 Set3DSoundListenerPosition (AR 168). Overrides the 3D listener
108 // position, which is otherwise taken from the scene summary. The override
109 // is cleared when a new scene is loaded.
110 void setListenerPosition(const Math::Vector3d &position);
111 void clearListenerPositionOverride();
112
113 uint32 getRate(uint16 channelID);
114 uint32 getRate(const SoundDescription &description);
115 uint32 getRate(const Common::String &chunkName);
116
117 uint32 getBaseRate(uint16 channelID);
118 uint32 getBaseRate(const SoundDescription &description);
119 uint32 getBaseRate(const Common::String &chunkName);
120
121 void setRate(uint16 channelID, uint32 rate);
122 void setRate(const SoundDescription &description, uint32 rate);
123 void setRate(const Common::String &chunkName, uint32 rate);
124
125 Audio::Timestamp getLength(uint16 channelID);
126 Audio::Timestamp getLength(const SoundDescription &description);
127 Audio::Timestamp getLength(const Common::String &chunkName);
128
129 bool isCommonSound(const Common::String &soundName) const { return _commonSounds.contains(soundName); }
130
131 void soundEffectMaintenance();
132 void recalculateSoundEffects();
133
134 Math::Vector3d &getOrientation() { return _orientation; }
135 Common::String getChannelInfo(uint16 channelID);
136
137 // Used when changing scenes
138 void stopAndUnloadSceneSpecificSounds();
139 void pauseSceneSpecificSounds(bool pause);
140
141 static Audio::SeekableAudioStream *makeHISStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 overrideSamplesPerSec = 0);
142
143protected:
144 struct Channel {
145 ~Channel();
146 Common::String name;
147 Audio::Mixer::SoundType type = Audio::Mixer::SoundType::kPlainSoundType;
148 uint16 playCommands = 1;
149 uint16 numLoops = 0;
150 uint volume = 0;
151 uint16 requestedVolume = 0;
152 uint16 panAnchorFrame = 0;
153 bool isPanning = false;
154 Audio::SeekableAudioStream *stream = nullptr;
155 Audio::AudioStream *streamForMixer = nullptr;
156 Audio::SoundHandle handle;
157 bool isPersistent = false;
158
159 // Sound effect data, not applicable to nancy2 and below
160 SoundEffectDescription *effectData = nullptr;
161 Math::Vector3d position;
162 Math::Vector3d positionDelta;
163 uint32 nextStepTime = 0;
164 uint16 stepsLeft = 0;
165 uint32 nextRepeatTime = 0;
166 };
167
168 void soundEffectMaintenance(uint16 channelID, bool force = false);
169
170 // Nancy 13 introduced the MMIX ("music mix") boot chunk, a table mapping a
171 // short location code (e.g. "CAM", "BRI") to a set of interchangeable music /
172 // ambience tracks. When a sound is loaded by such a code, the engine picks one
173 // of the mapped tracks at random and plays that instead. Returns the resolved
174 // filename, or the input name unchanged when it doesn't match any mix record.
175 Common::String resolveMusicMix(const Common::String &name) const;
176
177 // Returns the listener position override if one is active, otherwise
178 // the scene summary's listener position
179 Math::Vector3d getListenerPosition() const;
180
181 Audio::Mixer *_mixer;
182
183 Common::Array<Channel> _channels;
185
186 bool _shouldRecalculate;
187
188 Math::Vector3d _orientation;
189 Math::Vector3d _position;
190 uint _positionLerp = 0;
191
192 Math::Vector3d _listenerPositionOverride;
193 bool _hasListenerPositionOverride = false;
194};
195
196} // End of namespace Nancy
197
198#endif // NANCY_SOUND_H
Definition: audiostream.h:50
Definition: mixer.h:70
SoundType
Definition: mixer.h:73
Definition: audiostream.h:212
Definition: mixer.h:49
Definition: timestamp.h:83
Definition: array.h:52
Definition: hashmap.h:85
Definition: stream.h:745
Definition: str.h:59
Definition: iff.h:35
Definition: sound.h:44
Definition: system.h:39
Definition: algorithm.h:29
Definition: actionmanager.h:32
Definition: commontypes.h:306
Definition: commontypes.h:269
Definition: sound.h:144