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
36namespace Sci {
37class Console;
38
39bool detectSolAudio(Common::SeekableReadStream &stream);
40bool detectWaveAudio(Common::SeekableReadStream &stream);
41
42#pragma mark AudioChannel
43
52
58
65
71
75 uint32 duration;
76
81
86
92
97
102
107
113
117 bool robot;
118
124
129
134 int pan;
135
136 AudioChannel &operator=(AudioChannel &other) {
137 id = other.id;
138 resource = other.resource;
139 stream.reset(other.stream.release());
141 duration = other.duration;
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
175public:
176 Audio32(ResourceManager *resMan);
177 ~Audio32() override;
178
179 void saveLoadWithSerializer(Common::Serializer &s) override;
180
181 enum {
186
187 kMonitorAudioFlagSci3 = 0x80
188 };
189
190private:
191 ResourceManager *_resMan;
192 Audio::Mixer *_mixer;
193 Audio::SoundHandle _handle;
194 Common::Mutex _mutex;
195
196#pragma mark -
197#pragma mark AudioStream implementation
198public:
199 int readBuffer(int16 *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
205private:
210 int16 getNumChannelsToMix() const;
211
216 bool channelShouldMix(const AudioChannel &channel) const;
217
222 int writeAudioInternal(Audio::AudioStream &sourceStream, Audio::RateConverter &converter, int16 *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
226public:
230 inline uint8 getNumActiveChannels() const {
231 Common::StackLock lock(_mutex);
232 return _numActiveChannels;
233 }
234
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
266private:
269
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
337public:
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
396private:
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
440public:
441 bool playRobotAudio(const RobotAudioStream::RobotAudioPacket &packet);
442 bool queryRobotAudio(RobotAudioStream::StreamState &outStatus) const;
443 bool finishRobotAudio();
444 bool stopRobotAudio();
445
446private:
450 int16 findRobotChannel() const;
451
455 bool _robotAudioPaused;
456
457#pragma mark -
458#pragma mark Playback
459public:
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
524private:
528 uint32 _pausedAtTick;
529
533 uint32 _startedAtTick;
534
535#pragma mark -
536#pragma mark Effects
537public:
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
589private:
594 bool _attenuatedMixing;
595
600 bool _useModifiedAttenuation;
601
607 bool processFade(const int16 channelIndex);
608
609#pragma mark -
610#pragma mark Signal monitoring
611public:
616 bool hasSignal() const;
617
618private:
624 int16 _monitoredChannelIndex;
625
630 Common::Array<int16> _monitoredBuffer;
631
635 int _numMonitoredSamples;
636
637#pragma mark -
638#pragma mark Kernel
639public:
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
654public:
655 void printAudioList(Console *con) const;
656};
657
658} // End of namespace Sci
659
660#endif // SCI_SOUND_AUDIO32_H
Definition: audiostream.h:50
Definition: mixer.h:70
virtual uint getOutputRate() const =0
@ kMaxChannelVolume
Definition: mixer.h:82
@ kSFXSoundType
Definition: mixer.h:77
virtual void setVolumeForSoundType(SoundType type, int volume)=0
Definition: rate.h:93
Definition: mixer.h:49
Definition: mutex.h:67
void reset(PointerType o=nullptr)
Definition: ptr.h:607
PointerType release()
Definition: ptr.h:645
Definition: stream.h:745
Definition: serializer.h:352
Definition: serializer.h:80
Definition: mutex.h:51
Definition: audio32.h:174
int getRate() const override
Definition: audio32.h:201
int16 getVolume(const int16 channelIndex) const
void setMasterVolume(const int16 volume)
Definition: audio32.h:561
uint8 getNumActiveChannels() const
Definition: audio32.h:230
int16 getPosition(const int16 channelIndex) const
bool endOfStream() const override
Definition: audio32.h:203
void setVolume(const int16 channelIndex, int16 volume)
uint8 getNumOutputChannels() const
Definition: audio32.h:370
int16 findChannelByArgs(EngineState *s, int argc, const reg_t *argv, const int startIndex, const reg_t soundNode) const
void setSampleRate(uint16 rate)
uint8 getNumUnlockedChannels() const
int readBuffer(int16 *buffer, const int numSamples) override
uint8 getBitDepth() const
Definition: audio32.h:356
bool hasSignal() const
void setNumOutputChannels(int16 numChannels)
void setPreload(uint8 preload)
Definition: audio32.h:392
bool fadeChannel(const int16 channelIndex, const int16 targetVolume, const int16 speed, const int16 steps, const bool stopAfterFade)
int16 stop(const int16 channelIndex)
void setLoop(const int16 channelIndex, const bool loop)
bool isStereo() const override
Definition: audio32.h:200
void lockResource(const ResourceId resourceId, const bool lock)
uint16 play(int16 channelIndex, const ResourceId resourceId, const bool autoPlay, const bool loop, const int16 volume, const reg_t soundNode, const bool monitor)
uint16 getSampleRate() const
Definition: audio32.h:342
bool getAttenuatedMixing() const
Definition: audio32.h:577
bool resume(const int16 channelIndex)
bool endOfData() const override
Definition: audio32.h:202
uint8 getPreload() const
Definition: audio32.h:384
@ kMaxVolume
Definition: audio32.h:185
void setBitDepth(uint8 depth)
uint16 restart(const ResourceId resourceId, const bool autoPlay, const bool loop, const int16 volume, const reg_t soundNode, const bool monitor)
bool pause(const int16 channelIndex)
int16 findChannelById(const ResourceId resourceId, const reg_t soundNode=NULL_REG) const
void setAttenuatedMixing(bool attenuated)
Definition: audio32.h:584
void setPan(const int16 channelIndex, const int16 pan)
Definition: audio32.h:519
Definition: console.h:36
Definition: resource.h:256
Definition: resource.h:161
Definition: resource.h:327
Definition: console.h:28
AudioChannelIndex
Definition: audio32.h:163
Definition: audio32.h:47
ResourceId id
Definition: audio32.h:51
uint32 startedAtTick
Definition: audio32.h:80
int pan
Definition: audio32.h:134
Resource * resource
Definition: audio32.h:57
uint32 fadeDuration
Definition: audio32.h:101
uint32 pausedAtTick
Definition: audio32.h:85
uint32 fadeStartTick
Definition: audio32.h:91
uint32 duration
Definition: audio32.h:75
Common::ScopedPtr< Audio::AudioStream > stream
Definition: audio32.h:64
bool robot
Definition: audio32.h:117
bool stopChannelOnFade
Definition: audio32.h:112
int fadeStartVolume
Definition: audio32.h:96
int volume
Definition: audio32.h:128
int fadeTargetVolume
Definition: audio32.h:106
Common::ScopedPtr< Audio::RateConverter > converter
Definition: audio32.h:70
reg_t soundNode
Definition: audio32.h:123
Definition: state.h:100
Definition: robot_decoder.h:300
Definition: robot_decoder.h:280
Definition: vm_types.h:39