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 
27 namespace Audio {
28  class AudioStream;
29  class SoundHandle;
30  class PCSpeaker;
31  class RewindableAudioStream;
32  class LoopableAudioStream;
33 }
34 
35 namespace Common {
36  class MacResManager;
37 }
38 
39 namespace Director {
40 
41 class AudioDecoder;
42 
43 struct FadeParams {
44  int startVol;
45  int targetVol;
46  int totalTicks;
47  int startTicks;
48  int lapsedTicks;
49  bool fadeIn;
50 
51  FadeParams(int sv, int tv, int tt, int st, bool f) :
52  startVol(sv), targetVol(tv), totalTicks(tt), startTicks(st), lapsedTicks(0), fadeIn(f) {}
53 };
54 
55 const uint16 kMinSampledMenu = 10;
56 const uint16 kMaxSampledMenu = 15;
57 const uint16 kNumSampledMenus = kMaxSampledMenu - kMinSampledMenu + 1;
58 
60  uint16 menu;
61  uint16 submenu;
62 
63  ExternalSoundID() : menu(0), submenu(0) {}
64  ExternalSoundID(uint16 menuID, uint16 submenuID)
65  : menu(menuID), submenu(submenuID) {}
66 
67  bool operator==(const ExternalSoundID &b) {
68  return menu == b.menu && submenu == b.submenu;
69  }
70  bool operator!=(const ExternalSoundID &b) {
71  return !(*this == b);
72  }
73 };
74 
75 enum SoundIDType {
76  kSoundCast,
77  kSoundExternal
78 };
79 
80 struct SoundID {
81  SoundIDType type;
82  union {
83  struct {
84  int member;
85  int castLib;
86  } cast;
87  struct {
88  uint16 menu;
89  uint16 submenu;
90  } external;
91  } u;
92 
93  SoundID() {
94  type = kSoundCast;
95  u.cast.member = 0;
96  u.cast.castLib = 0;
97  }
98  SoundID(SoundIDType type_, int a, int b) {
99  type = type_;
100  switch (type) {
101  case kSoundCast:
102  u.cast.member = a;
103  u.cast.castLib = b;
104  break;
105  case kSoundExternal:
106  u.external.menu = a;
107  u.external.submenu = b;
108  }
109  }
110  SoundID(CastMemberID memberID) {
111  type = kSoundCast;
112  u.cast.member = memberID.member;
113  u.cast.castLib = memberID.castLib;
114  }
115 
116  bool operator==(const SoundID &b) {
117  if (type != b.type)
118  return false;
119 
120  switch (type) {
121  case kSoundCast:
122  return u.cast.member == b.u.cast.member && u.cast.castLib == b.u.cast.castLib;
123  case kSoundExternal:
124  return u.external.menu == b.u.external.menu && u.external.submenu == b.u.external.submenu;
125  }
126 
127  return false;
128  }
129  bool operator!=(const SoundID &b) {
130  return !(*this == b);
131  }
132 };
133 
134 struct SoundChannel {
135  Audio::SoundHandle handle;
136  SoundID lastPlayedSound;
137  bool stopOnZero; // Should the sound be stopped when the channel contains cast member 0?
138  byte volume;
139  FadeParams *fade;
140 
141  // a non-zero sound ID if the channel is a puppet. i.e. it's controlled by lingo
142  SoundID puppet;
143  bool newPuppet;
144 
145  // this indicate whether the sound is playing across the movie. Because the cast name may be the same while the actual sounds are changing.
146  // And we will override the sound when ever the sound is changing. thus we use a flag to indicate whether the movie is changed.
147  bool movieChanged;
148 
149  // Pointer for keeping track of a looping sound, used to signal
150  // a stop at the end of a loop.
152 
153  SoundChannel(): handle(), lastPlayedSound(SoundID()), stopOnZero(true), volume(255), fade(nullptr), puppet(SoundID()), newPuppet(false), movieChanged(false), loopPtr(nullptr) {}
154 };
155 
157 
158 private:
159  Window *_window;
161  Common::HashMap<int, int> _volumes;
162  Audio::SoundHandle _scriptSound;
163  Audio::Mixer *_mixer;
164  Audio::PCSpeaker *_speaker;
165  Audio::SoundHandle _pcSpeakerHandle;
166 
167  // these two were used in fplay xobj
168  Common::Queue<Common::String> _fplayQueue;
169  Common::String _currentSoundName;
170 
171  bool _enable;
172 
173  Common::Array<AudioDecoder *> _sampleSounds[kNumSampledMenus];
174 
175 public:
176  DirectorSound(Window *window);
177  ~DirectorSound();
178 
179  SoundChannel *getChannel(uint8 soundChannel);
180  void playFile(Common::String filename, uint8 soundChannel);
181  void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
182  void playStream(Audio::AudioStream &stream, uint8 soundChannel);
183  void playSound(SoundID soundId, uint8 soundChannel, bool forPuppet = false);
184  void playCastMember(CastMemberID memberID, uint8 soundChannel, bool forPuppet = false);
185  void playExternalSound(uint16 menu, uint16 submenu, uint8 soundChannel);
186  void playFPlaySound(const Common::Array<Common::String> &fplayList);
187  void playFPlaySound();
188  void setSoundEnabled(bool enabled);
189  void systemBeep();
190  void changingMovie();
191 
192  void loadSampleSounds(uint type);
193  void unloadSampleSounds();
194 
195  bool isChannelPuppet(uint8 soundChannel);
196  void setPuppetSound(SoundID soundId, uint8 soundChannel);
197  void playPuppetSound(uint8 soundChannel);
198 
199  bool getSoundEnabled() { return _enable; }
200 
201  Common::String getCurrentSound() { return _currentSoundName; }
202 
203  void registerFade(uint8 soundChannel, bool fadeIn, int ticks);
204  bool fadeChannels();
205 
206  bool isChannelActive(uint8 soundChannel);
207  uint8 getChannelVolume(uint8 soundChannel);
208  void setChannelVolume(int channel, uint8 volume);
209  void stopSound(uint8 soundChannel);
210  void stopSound();
211  void setChannelDefaultVolume(int soundChannel);
212 
213 private:
214  void setLastPlayedSound(uint8 soundChannel, SoundID soundId, bool stopOnZero = true);
215  bool isLastPlayedSound(uint8 soundChannel, const SoundID &soundId);
216  bool shouldStopOnZero(uint8 soundChannel);
217 
218  void setChannelVolumeInternal(uint8 soundChannel, uint8 volume);
219  bool assertChannel(int soundChannel);
220  void cancelFade(uint8 soundChannel);
221 };
222 
224 public:
225  AudioDecoder() {};
226  virtual ~AudioDecoder() {};
227 public:
228  virtual Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) { return nullptr; }
229 };
230 
231 class SNDDecoder : public AudioDecoder {
232 public:
233  SNDDecoder();
234  ~SNDDecoder();
235 
236  bool loadStream(Common::SeekableReadStreamEndian &stream);
237  void loadExternalSoundStream(Common::SeekableReadStreamEndian &stream);
238  bool processCommands(Common::SeekableReadStreamEndian &stream);
239  bool processBufferCommand(Common::SeekableReadStreamEndian &stream);
240  Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
241  bool hasLoopBounds();
242  void resetLoopBounds();
243  bool hasValidLoopBounds();
244 
245 private:
246  byte *_data;
247  uint16 _channels;
248  uint32 _size;
249  uint16 _rate;
250  byte _flags;
251  uint32 _loopStart;
252  uint32 _loopEnd;
253 };
254 
256 public:
258  ~AudioFileDecoder();
259 
260  void setPath(Common::String &path);
261 
262  Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) override;
263 
264 private:
265  Common::String _path;
266  Common::MacResManager *_macresman;
267 };
268 
269 } // End of namespace Director
270 
271 #endif
Definition: audiostream.h:123
Definition: sound.h:231
Definition: macresman.h:125
Definition: str.h:59
Definition: array.h:52
Definition: sound.h:80
Definition: sound.h:223
Definition: sound.h:255
Definition: window.h:103
Definition: archive.h:35
Definition: mixer.h:49
Definition: mixer.h:59
Definition: sound.h:156
Definition: hashmap.h:85
Definition: algorithm.h:29
Definition: audiostream.h:50
Definition: sound.h:59
Definition: stream.h:944
Definition: sound.h:134
Definition: sound.h:43
Definition: types.h:413
Definition: pcspk.h:31
Definition: system.h:38