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 DIRECTOR_SOUND_H
23#define DIRECTOR_SOUND_H
24
25#include "audio/mixer.h"
26
27namespace Audio {
28 class AudioStream;
29 class SoundHandle;
30 class PCSpeaker;
31 class RewindableAudioStream;
32 class LoopableAudioStream;
33}
34
35namespace Common {
36 class MacResManager;
37}
38
39namespace Director {
40
41class AudioDecoder;
42
43struct FadeParams {
44 int startVol;
45 int targetVol;
46 int totalTicks;
47 int startTicks;
48 int lapsedTicks;
49 bool fadeIn;
50 bool autoStop;
51
52 FadeParams(int sv, int tv, int tt, int st, bool f, bool as) :
53 startVol(sv), targetVol(tv), totalTicks(tt), startTicks(st), lapsedTicks(0), fadeIn(f), autoStop(as) {}
54};
55
56const uint16 kMinSampledMenu = 10;
57const uint16 kMaxSampledMenu = 15;
58const uint16 kNumSampledMenus = kMaxSampledMenu - kMinSampledMenu + 1;
59
61 uint16 menu;
62 uint16 submenu;
63
64 ExternalSoundID() : menu(0), submenu(0) {}
65 ExternalSoundID(uint16 menuID, uint16 submenuID)
66 : menu(menuID), submenu(submenuID) {}
67
68 bool operator==(const ExternalSoundID &b) {
69 return menu == b.menu && submenu == b.submenu;
70 }
71 bool operator!=(const ExternalSoundID &b) {
72 return !(*this == b);
73 }
74};
75
76enum SoundIDType {
77 kSoundCast,
78 kSoundExternal
79};
80
81struct SoundID {
82 SoundIDType type;
83 union {
84 struct {
85 int member;
86 int castLib;
87 } cast;
88 struct {
89 uint16 menu;
90 uint16 submenu;
91 } external;
92 } u;
93
94 SoundID() {
95 type = kSoundCast;
96 u.cast.member = 0;
97 u.cast.castLib = 0;
98 }
99 SoundID(SoundIDType type_, int a, int b) {
100 type = type_;
101 switch (type) {
102 case kSoundCast:
103 u.cast.member = a;
104 u.cast.castLib = b;
105 break;
106 case kSoundExternal:
107 u.external.menu = a;
108 u.external.submenu = b;
109 }
110 }
111 SoundID(CastMemberID memberID) {
112 type = kSoundCast;
113 u.cast.member = memberID.member;
114 u.cast.castLib = memberID.castLib;
115 }
116
117 bool operator==(const SoundID &b) {
118 if (type != b.type)
119 return false;
120
121 switch (type) {
122 case kSoundCast:
123 return u.cast.member == b.u.cast.member && u.cast.castLib == b.u.cast.castLib;
124 case kSoundExternal:
125 return u.external.menu == b.u.external.menu && u.external.submenu == b.u.external.submenu;
126 }
127
128 return false;
129 }
130 bool operator!=(const SoundID &b) {
131 return !(*this == b);
132 }
133 bool isZero() {
134 if (type == kSoundCast)
135 return u.cast.member == 0;
136 return false;
137 }
138};
139
141 Audio::SoundHandle handle;
142 SoundID lastPlayedSound;
143 bool stopOnZero; // Should the sound be stopped when the channel contains cast member 0?
144 bool fromLastMovie; // Was this sound carried over from a movie switch?
145 byte volume;
146 int pitchShiftPercent;
147 int originalRate;
148 FadeParams *fade;
149 int lastCuePointIndex;
150
151 // a non-zero sound ID if the channel is a puppet. i.e. it's controlled by lingo
152 SoundID puppet;
153 bool newPuppet;
154
155 // this indicate whether the sound is playing across the movie. Because the cast name may be the same while the actual sounds are changing.
156 // And we will override the sound when ever the sound is changing. thus we use a flag to indicate whether the movie is changed.
157 bool movieChanged;
158
159 // Pointer for keeping track of a looping sound, used to signal
160 // a stop at the end of a loop.
162
163 SoundChannel(): handle(), lastPlayedSound(SoundID()), stopOnZero(true), fromLastMovie(false), volume(255), originalRate(-1),
164 pitchShiftPercent(100), fade(nullptr), puppet(SoundID()), newPuppet(false), movieChanged(false), loopPtr(nullptr),
165 lastCuePointIndex(-1) {}
166};
167
169
170private:
171 Window *_window;
174 Audio::SoundHandle _scriptSound;
175 Audio::Mixer *_mixer;
176 Audio::PCSpeaker *_speaker;
177
178 // these two were used in fplay xobj
180 Common::String _currentSoundName;
181
182 bool _enable;
183
184 Common::Array<AudioDecoder *> _sampleSounds[kNumSampledMenus];
185
186public:
187 DirectorSound(Window *window);
189
190 SoundChannel *getChannel(int soundChannel);
191 void playFile(Common::String filename, int soundChannel);
192 void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
193 void playStream(Audio::AudioStream &stream, int soundChannel);
194 void playSound(SoundID soundId, int soundChannel, bool forPuppet = false);
195 void playCastMember(CastMemberID memberID, int soundChannel, bool forPuppet = false);
196 void playExternalSound(uint16 menu, uint16 submenu, int soundChannel);
197 void playFPlaySound(const Common::Array<Common::String> &fplayList);
198 void playFPlaySound();
199 void setSoundEnabled(bool enabled);
200 void systemBeep();
201 void changingMovie();
202
203 void loadSampleSounds(uint type);
204 void unloadSampleSounds();
205
206 bool isChannelPuppet(int soundChannel);
207 void setPuppetSound(SoundID soundId, int soundChannel);
208 void disablePuppetSound(int soundChannel);
209 void playPuppetSound(int soundChannel);
210
211 bool getSoundEnabled() { return _enable; }
212
213 Common::String getCurrentSound() { return _currentSoundName; }
214
215 void registerFade(int soundChannel, int startVol, int targetVol, int ticks, bool autoStop = false);
216 void registerFade(int soundChannel, bool fadeIn, int ticks, bool autoStop = false);
217 bool fadeChannels();
218
219 bool isChannelActive(int soundChannel);
220 uint8 getChannelVolume(int soundChannel);
221 void setChannelVolume(int channel, uint8 volume);
222 int8 getChannelBalance(int soundChannel);
223 void setChannelBalance(int soundChannel, int8 balance);
224 uint8 getChannelFaderL(int soundChannel);
225 void setChannelFaderL(int soundChannel, uint8 faderL);
226 uint8 getChannelFaderR(int soundChannel);
227 void setChannelFaderR(int soundChannel, uint8 faderR);
228 void stopSound(int soundChannel);
229 void stopSound();
230 void setChannelDefaultVolume(int soundChannel);
231 void setChannelPitchShift(int soundChannel, int pitchShiftPercent);
232
233 void processCuePoints();
234
235private:
236 void setLastPlayedSound(int soundChannel, SoundID soundId, bool stopOnZero = true);
237 bool isLastPlayedSound(int soundChannel, const SoundID &soundId);
238 bool shouldStopOnZero(int soundChannel);
239
240 void setChannelVolumeInternal(int soundChannel, uint8 volume);
241 bool assertChannel(int soundChannel);
242 void cancelFade(int soundChannel);
243};
244
246public:
247 AudioDecoder() {};
248 virtual ~AudioDecoder() {};
249public:
250 virtual Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) { return nullptr; }
251 virtual int getChannelCount() { return 0; }
252 virtual int getSampleRate() { return 0; }
253 virtual int getSampleSize() { return 0; }
254};
255
256class SNDDecoder : public AudioDecoder {
257public:
258 SNDDecoder();
259 ~SNDDecoder();
260
261 bool loadStream(Common::SeekableReadStreamEndian &stream);
262 void loadExternalSoundStream(Common::SeekableReadStreamEndian &stream);
263 bool processCommands(Common::SeekableReadStreamEndian &stream);
264 bool processBufferCommand(Common::SeekableReadStreamEndian &stream);
265 Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
266 bool hasLoopBounds();
267 void resetLoopBounds();
268 bool hasValidLoopBounds();
269 int getChannelCount() override { return _channels; }
270 int getSampleRate() override { return _rate; }
271 int getSampleSize() override { return _bits; }
272
273private:
274 byte *_data;
275 uint16 _channels;
276 uint32 _size;
277 uint16 _rate;
278 uint16 _bits;
279 byte _flags;
280 uint32 _loopStart;
281 uint32 _loopEnd;
282};
283
285public:
288
289 void setPath(Common::String &path);
290
291 Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
292
293private:
294 Common::String _path;
295 Common::MacResManager *_macresman;
296};
297
299public:
302
303 Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
304
305private:
306 Common::String _format;
308};
309
310// Source: mixsnd.h in the Director 7 XDK
312 int32 offset;
313 int32 size;
314 int32 playbackStart;
315 int32 playbackStartFrame;
316 int32 loopStart;
317 int32 loopStartFrame;
318 int32 loopEnd;
319 int32 loopEndFrame;
320 int32 playbackEnd;
321 int32 playbackEndFrame;
322 int32 numFrames;
323 int32 frameRate;
324 int32 byteRate;
325 byte compressionType[16];
326 int32 bitsPerSample;
327 int32 bytesPerSample;
328 int32 numChannels;
329 int32 bytesPerFrame;
330 byte soundHeaderType[16];
331 uint32 platformData[63];
332 int32 bytesPerBlock;
333};
334
336public:
339
340 bool loadHeaderStream(Common::SeekableReadStreamEndian &stream);
341 bool loadSampleStream(Common::SeekableReadStreamEndian &stream);
342
343 MoaSoundFormat _format;
344 byte *_data = nullptr;
345 uint32 _size = 0;
346
347 Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
348};
349
350} // End of namespace Director
351
352#endif
Definition: audiostream.h:50
Definition: audiostream.h:123
Definition: mixer.h:70
Definition: pcspk.h:36
Definition: mixer.h:49
Definition: array.h:52
Definition: hashmap.h:85
Definition: macresman.h:126
Definition: stream.h:944
Definition: str.h:59
Definition: sound.h:245
Definition: sound.h:284
Definition: sound.h:168
Definition: sound.h:335
Definition: sound.h:298
Definition: sound.h:256
Definition: window.h:106
Definition: system.h:39
Definition: algorithm.h:29
Definition: types.h:424
Definition: sound.h:60
Definition: sound.h:43
Definition: sound.h:311
Definition: sound.h:140
Definition: sound.h:81