ScummVM API documentation
audio32.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 SCI_SOUND_AUDIO32_H
23 #define SCI_SOUND_AUDIO32_H
24 
25 #include "audio/audiostream.h" // for AudioStream, SeekableAudioStream (...
26 #include "audio/mixer.h" // for Mixer, SoundHandle
27 #include "audio/rate.h" // for Audio::st_volume_t, RateConverter
28 #include "common/array.h" // for Array
29 #include "common/mutex.h" // for StackLock, Mutex
30 #include "common/scummsys.h" // for int16, uint8, uint32, uint16
31 #include "sci/resource/resource.h" // for ResourceId
32 #include "sci/engine/state.h" // for EngineState
33 #include "sci/engine/vm_types.h" // for reg_t, NULL_REG
34 #include "sci/video/robot_decoder.h" // for RobotAudioStream
35 
36 namespace Sci {
37 class Console;
38 
39 bool detectSolAudio(Common::SeekableReadStream &stream);
40 bool detectWaveAudio(Common::SeekableReadStream &stream);
41 
42 #pragma mark AudioChannel
43 
47 struct AudioChannel {
52 
58 
65 
71 
75  uint32 duration;
76 
80  uint32 startedAtTick;
81 
85  uint32 pausedAtTick;
86 
91  uint32 fadeStartTick;
92 
97 
101  uint32 fadeDuration;
102 
107 
113 
117  bool robot;
118 
124 
128  int volume;
129 
134  int pan;
135 
136  AudioChannel &operator=(AudioChannel &other) {
137  id = other.id;
138  resource = other.resource;
139  stream.reset(other.stream.release());
140  converter.reset(other.converter.release());
141  duration = other.duration;
142  startedAtTick = other.startedAtTick;
143  pausedAtTick = other.pausedAtTick;
144  fadeStartTick = other.fadeStartTick;
145  fadeStartVolume = other.fadeStartVolume;
146  fadeDuration = other.fadeDuration;
147  fadeTargetVolume = other.fadeTargetVolume;
148  stopChannelOnFade = other.stopChannelOnFade;
149  robot = other.robot;
150  soundNode = other.soundNode;
151  volume = other.volume;
152  pan = other.pan;
153  return *this;
154  }
155 };
156 
157 #pragma mark -
158 
164  kRobotChannel = -3,
165  kNoExistingChannel = -2,
166  kAllChannels = -1
167 };
168 
175 public:
176  Audio32(ResourceManager *resMan);
177  ~Audio32() override;
178 
179  void saveLoadWithSerializer(Common::Serializer &s) override;
180 
181  enum {
185  kMaxVolume = 127,
186 
187  kMonitorAudioFlagSci3 = 0x80
188  };
189 
190 private:
191  ResourceManager *_resMan;
192  Audio::Mixer *_mixer;
193  Audio::SoundHandle _handle;
194  Common::Mutex _mutex;
195 
196 #pragma mark -
197 #pragma mark AudioStream implementation
198 public:
199  int readBuffer(Audio::st_sample_t *buffer, const int numSamples) override;
200  bool isStereo() const override { return true; }
201  int getRate() const override { return _mixer->getOutputRate(); }
202  bool endOfData() const override { return _numActiveChannels == 0; }
203  bool endOfStream() const override { return false; }
204 
205 private:
210  int16 getNumChannelsToMix() const;
211 
216  bool channelShouldMix(const AudioChannel &channel) const;
217 
222  int writeAudioInternal(Audio::AudioStream &sourceStream, Audio::RateConverter &converter, Audio::st_sample_t *targetBuffer, const int numSamples, const Audio::st_volume_t leftVolume, const Audio::st_volume_t rightVolume);
223 
224 #pragma mark -
225 #pragma mark Channel management
226 public:
230  inline uint8 getNumActiveChannels() const {
231  Common::StackLock lock(_mutex);
232  return _numActiveChannels;
233  }
234 
246  uint8 getNumUnlockedChannels() const;
247 
254  int16 findChannelByArgs(EngineState *s, int argc, const reg_t *argv, const int startIndex, const reg_t soundNode) const;
255 
259  int16 findChannelById(const ResourceId resourceId, const reg_t soundNode = NULL_REG) const;
260 
264  void lockResource(const ResourceId resourceId, const bool lock);
265 
266 private:
269 
273  Common::Array<AudioChannel> _channels;
274 
279  uint8 _numActiveChannels;
280 
289  bool _inAudioThread;
290 
295  UnlockList _resourcesToUnlock;
296 
300  LockList _lockedResourceIds;
301 
305  inline AudioChannel &getChannel(const int16 channelIndex) {
306  Common::StackLock lock(_mutex);
307  assert(channelIndex >= 0 && channelIndex < _numActiveChannels);
308  return _channels[channelIndex];
309  }
310 
314  inline const AudioChannel &getChannel(const int16 channelIndex) const {
315  Common::StackLock lock(_mutex);
316  assert(channelIndex >= 0 && channelIndex < _numActiveChannels);
317  return _channels[channelIndex];
318  }
319 
323  void freeUnusedChannels();
324 
328  void freeChannel(const int16 channelIndex);
329 
333  void unlockResources();
334 
335 #pragma mark -
336 #pragma mark Script compatibility
337 public:
342  inline uint16 getSampleRate() const {
343  return _globalSampleRate;
344  }
345 
350  void setSampleRate(uint16 rate);
351 
356  inline uint8 getBitDepth() const {
357  return _globalBitDepth;
358  }
359 
364  void setBitDepth(uint8 depth);
365 
370  inline uint8 getNumOutputChannels() const {
371  return _globalNumOutputChannels;
372  }
373 
378  void setNumOutputChannels(int16 numChannels);
379 
384  inline uint8 getPreload() const {
385  return _preload;
386  }
387 
392  inline void setPreload(uint8 preload) {
393  _preload = preload;
394  }
395 
396 private:
400  uint16 _globalSampleRate;
401 
406  uint16 _maxAllowedSampleRate;
407 
411  uint8 _globalBitDepth;
412 
417  uint8 _maxAllowedBitDepth;
418 
423  uint8 _globalNumOutputChannels;
424 
429  uint8 _maxAllowedOutputChannels;
430 
436  uint8 _preload;
437 
438 #pragma mark -
439 #pragma mark Robot
440 public:
441  bool playRobotAudio(const RobotAudioStream::RobotAudioPacket &packet);
442  bool queryRobotAudio(RobotAudioStream::StreamState &outStatus) const;
443  bool finishRobotAudio();
444  bool stopRobotAudio();
445 
446 private:
450  int16 findRobotChannel() const;
451 
455  bool _robotAudioPaused;
456 
457 #pragma mark -
458 #pragma mark Playback
459 public:
463  uint16 play(int16 channelIndex, const ResourceId resourceId, const bool autoPlay, const bool loop, const int16 volume, const reg_t soundNode, const bool monitor);
464 
469  bool resume(const int16 channelIndex);
470  bool resume(const ResourceId resourceId, const reg_t soundNode = NULL_REG) {
471  Common::StackLock lock(_mutex);
472  return resume(findChannelById(resourceId, soundNode));
473  }
474 
478  bool pause(const int16 channelIndex);
479  bool pause(const ResourceId resourceId, const reg_t soundNode = NULL_REG) {
480  Common::StackLock lock(_mutex);
481  return pause(findChannelById(resourceId, soundNode));
482  }
483 
487  int16 stop(const int16 channelIndex);
488  int16 stop(const ResourceId resourceId, const reg_t soundNode = NULL_REG) {
489  Common::StackLock lock(_mutex);
490  return stop(findChannelById(resourceId, soundNode));
491  }
492 
496  uint16 restart(const ResourceId resourceId, const bool autoPlay, const bool loop, const int16 volume, const reg_t soundNode, const bool monitor);
497 
501  int16 getPosition(const int16 channelIndex) const;
502  int16 getPosition(const ResourceId resourceId, const reg_t soundNode = NULL_REG) {
503  Common::StackLock lock(_mutex);
504  return getPosition(findChannelById(resourceId, soundNode));
505  }
506 
510  void setLoop(const int16 channelIndex, const bool loop);
511  void setLoop(const ResourceId resourceId, const reg_t soundNode, const bool loop) {
512  Common::StackLock lock(_mutex);
513  setLoop(findChannelById(resourceId, soundNode), loop);
514  }
515 
519  void setPan(const int16 channelIndex, const int16 pan) {
520  Common::StackLock lock(_mutex);
521  getChannel(channelIndex).pan = pan;
522  }
523 
524 private:
528  uint32 _pausedAtTick;
529 
533  uint32 _startedAtTick;
534 
535 #pragma mark -
536 #pragma mark Effects
537 public:
542  int16 getVolume(const int16 channelIndex) const;
543  int16 getVolume(const ResourceId resourceId, const reg_t soundNode) const {
544  Common::StackLock lock(_mutex);
545  return getVolume(findChannelById(resourceId, soundNode));
546  }
547 
552  void setVolume(const int16 channelIndex, int16 volume);
553  void setVolume(const ResourceId resourceId, const reg_t soundNode, const int16 volume) {
554  Common::StackLock lock(_mutex);
555  setVolume(findChannelById(resourceId, soundNode), volume);
556  }
557 
561  void setMasterVolume(const int16 volume) {
563  }
564 
568  bool fadeChannel(const int16 channelIndex, const int16 targetVolume, const int16 speed, const int16 steps, const bool stopAfterFade);
569  bool fadeChannel(const ResourceId resourceId, const reg_t soundNode, const int16 targetVolume, const int16 speed, const int16 steps, const bool stopAfterFade) {
570  Common::StackLock lock(_mutex);
571  return fadeChannel(findChannelById(resourceId, soundNode), targetVolume, speed, steps, stopAfterFade);
572  }
573 
577  inline bool getAttenuatedMixing() const {
578  return _attenuatedMixing;
579  }
580 
584  void setAttenuatedMixing(bool attenuated) {
585  Common::StackLock lock(_mutex);
586  _attenuatedMixing = attenuated;
587  }
588 
589 private:
594  bool _attenuatedMixing;
595 
600  bool _useModifiedAttenuation;
601 
607  bool processFade(const int16 channelIndex);
608 
609 #pragma mark -
610 #pragma mark Signal monitoring
611 public:
616  bool hasSignal() const;
617 
618 private:
624  int16 _monitoredChannelIndex;
625 
630  Common::Array<Audio::st_sample_t> _monitoredBuffer;
631 
635  int _numMonitoredSamples;
636 
637 #pragma mark -
638 #pragma mark Kernel
639 public:
640  reg_t kernelPlay(const bool autoPlay, EngineState *s, const int argc, const reg_t *const argv);
641  reg_t kernelStop(EngineState *s, const int argc, const reg_t *const argv);
642  reg_t kernelPause(EngineState *s, const int argc, const reg_t *const argv);
643  reg_t kernelResume(EngineState *s, const int argc, const reg_t *const argv);
644  reg_t kernelPosition(EngineState *s, const int argc, const reg_t *const argv);
645  reg_t kernelVolume(EngineState *s, const int argc, const reg_t *const argv);
646  reg_t kernelMixing(const int argc, const reg_t *const argv);
647  reg_t kernelFade(EngineState *s, const int argc, const reg_t *const argv);
648  void kernelLoop(EngineState *s, const int argc, const reg_t *const argv);
649  void kernelPan(EngineState *s, const int argc, const reg_t *const argv);
650  void kernelPanOff(EngineState *s, const int argc, const reg_t *const argv);
651 
652 #pragma mark -
653 #pragma mark Debugging
654 public:
655  void printAudioList(Console *con) const;
656 };
657 
658 } // End of namespace Sci
659 
660 #endif // SCI_SOUND_AUDIO32_H
Definition: robot_decoder.h:280
Definition: state.h:100
ResourceId id
Definition: audio32.h:51
uint32 fadeStartTick
Definition: audio32.h:91
virtual uint getOutputRate() const =0
int fadeStartVolume
Definition: audio32.h:96
Definition: mixer.h:66
uint32 duration
Definition: audio32.h:75
Definition: mutex.h:51
uint8 getNumOutputChannels() const
Definition: audio32.h:370
bool robot
Definition: audio32.h:117
uint8 getBitDepth() const
Definition: audio32.h:356
uint16 getSampleRate() const
Definition: audio32.h:342
Definition: stream.h:745
int volume
Definition: audio32.h:128
uint32 startedAtTick
Definition: audio32.h:80
bool endOfData() const override
Definition: audio32.h:202
bool stopChannelOnFade
Definition: audio32.h:112
Definition: serializer.h:79
void setPan(const int16 channelIndex, const int16 pan)
Definition: audio32.h:519
PointerType release()
Definition: ptr.h:644
uint8 getNumActiveChannels() const
Definition: audio32.h:230
Definition: mixer.h:49
Definition: resource.h:327
uint32 fadeDuration
Definition: audio32.h:101
Definition: mixer.h:59
Definition: audio32.h:174
void setAttenuatedMixing(bool attenuated)
Definition: audio32.h:584
Definition: mutex.h:67
Definition: rate.h:75
void setMasterVolume(const int16 volume)
Definition: audio32.h:561
Definition: resource.h:256
Definition: audiostream.h:50
Definition: console.h:28
void reset(PointerType o=nullptr)
Definition: ptr.h:607
Definition: serializer.h:308
bool getAttenuatedMixing() const
Definition: audio32.h:577
uint8 getPreload() const
Definition: audio32.h:384
Definition: audio32.h:47
Definition: mixer.h:71
virtual void setVolumeForSoundType(SoundType type, int volume)=0
int fadeTargetVolume
Definition: audio32.h:106
Common::ScopedPtr< Audio::RateConverter > converter
Definition: audio32.h:70
Definition: resource.h:161
Resource * resource
Definition: audio32.h:57
uint32 pausedAtTick
Definition: audio32.h:85
AudioChannelIndex
Definition: audio32.h:163
int getRate() const override
Definition: audio32.h:201
Definition: robot_decoder.h:300
void setPreload(uint8 preload)
Definition: audio32.h:392
reg_t soundNode
Definition: audio32.h:123
int pan
Definition: audio32.h:134
bool endOfStream() const override
Definition: audio32.h:203
Definition: vm_types.h:39
Common::ScopedPtr< Audio::AudioStream > stream
Definition: audio32.h:64
Definition: console.h:36
bool isStereo() const override
Definition: audio32.h:200