ScummVM API documentation
qmixer.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 * aint with this program; if not, write to the Free Software
19 *
20 */
21
22#ifndef TITANIC_QMIXER_H
23#define TITANIC_QMIXER_H
24
25#include "audio/mixer.h"
26#include "titanic/sound/wave_file.h"
27
28namespace Titanic {
29
30enum QMixFlag {
31 QMIX_OPENSINGLE = 0, // Open the single channel specified by iChannel
32 QMIX_OPENALL = 1, // Opens all the channels, iChannel ignored
33 QMIX_OPENCOUNT = 2, // Open iChannel Channels (eg. if iChannel = 4 will create channels 0-3)
34 QMIX_OPENAVAILABLE = 3, // Open the first unopened channel, and return channel number
35
36 // Channel function flags
37 QMIX_ALL = 0x01, // apply to all channels
38 QMIX_NOREMIX = 0x02, // don't remix
39 QMIX_CONTROL_NOREMIX = 0x04, // don't remix
40 QMIX_USEONCE = 0x10 // settings are temporary
41};
42
43// qsWaveMixEnableChannel flags: if mode==0, use conventional, high-performance
44// stereo mixer. Non-zero modes imply some form of additional processing.
45enum QMixChannelFlag {
46 QMIX_CHANNEL_STEREO = 0x0000, // Perform stereo mixing
47 QMIX_CHANNEL_QSOUND = 0x0001, // Perform QSound localization (default)
48 QMIX_CHANNEL_DOPPLER = 0x0002, // Calculate velocity using position updates
49 QMIX_CHANNEL_RANGE = 0x0004, // Do range effects
50 QMIX_CHANNEL_ELEVATION = 0x0008, // Do elevation effects
51 QMIX_CHANNEL_NODOPPLERPITCH = 0x0010, // Disable Doppler pitch shift for this channel
52 QMIX_CHANNEL_PITCH_COPY = 0x0000, // Pitch shifting using copying (fastest)
53 QMIX_CHANNEL_PITCH_LINEAR = 0x0100, // Pitch shifting using linear interpolation (better but slower)
54 QMIX_CHANNEL_PITCH_SPLINE = 0x0200, // Pitch shifting using spline interpolation (better yet, but much slower)
55 QMIX_CHANNEL_PITCH_FILTER = 0x0300, // Pitch shifting using FIR filter (best, but slowest)
56 QMIX_CHANNEL_PITCH_MASK = 0x0700 // Bits reserved for pitch types
57};
58
70enum QMixPlayFlag {
71 QMIX_QUEUEWAVE = 0x0000, // Queue on channel
72 QMIX_CLEARQUEUE = 0x0001, // Clear queue on channel
73 QMIX_USELRUCHANNEL = 0x0002, // See notes above
74 QMIX_HIGHPRIORITY = 0x0004,
75 QMIX_WAIT = 0x0008, // Queue to be played with other sounds
76 QMIX_IMMEDIATE = 0x0020, // Apply volume/pan changes without interpolation
77
78 QMIX_PLAY_SETEVENT = 0x0100, // Calls SetEvent in the original library when done
79 QMIX_PLAY_PULSEEVENT = 0x0200, // Calls PulseEvent in the original library when done
80 QMIX_PLAY_NOTIFYSTOP = 0x0400 // Do callback even when stopping or flushing sound
81};
82
86struct QMIXCONFIG {
87 uint32 dwSize;
88 uint32 dwFlags;
89 uint32 dwSamplingRate; // Sampling rate in Hz
90 void *lpIDirectSound;
91 const void *lpGuid;
92 int iChannels; // Number of channels
93 int iOutput; // if 0, uses best output device
94 int iLatency; // (in ms) if 0, uses default for output device
95 int iMath; // style of math
96 uint hwnd;
97
98 QMIXCONFIG() : dwSize(40), dwFlags(0), dwSamplingRate(0), lpIDirectSound(nullptr),
99 lpGuid(nullptr), iChannels(0), iOutput(0), iLatency(0), iMath(0), hwnd(0) {}
100 QMIXCONFIG(uint32 rate, int channels, int latency) : dwSize(40), dwFlags(0),
101 dwSamplingRate(rate), iChannels(channels), iLatency(latency),
102 lpIDirectSound(nullptr), lpGuid(nullptr), iOutput(0), iMath(0), hwnd(0) {}
103};
104
108struct QSVECTOR {
109 double x;
110 double y;
111 double z;
112
113 QSVECTOR() : x(0.0), y(0.0), z(0.0) {}
114 QSVECTOR(double xp, double yp, double zp) : x(xp), y(yp), z(zp) {}
115};
116
120struct QSPOLAR {
121 double azimuth; // degrees
122 double range; // meters
123 double elevation; // degrees
124
125 QSPOLAR() : azimuth(0.0), range(0.0), elevation(0.0) {}
126 QSPOLAR(double azimuth_, double range_, double elevation_) :
127 azimuth(azimuth_), range(range_), elevation(elevation_) {}
128};
129
131 int cbSize; // Structure size
132 double minDistance; // sounds are at full volume if closer than this
133 double maxDistance; // sounds are muted if further away than this
134 double scale; // relative amount to adjust rolloff by
135
136 QMIX_DISTANCES() : cbSize(16), minDistance(0.0), maxDistance(0.0), scale(0.0) {}
137 QMIX_DISTANCES(double minDistance_, double maxDistance_, double scale_) :
138 cbSize(16), minDistance(minDistance_), maxDistance(maxDistance_), scale(scale_) {}
139};
140
141typedef void (*LPQMIXDONECALLBACK)(int iChannel, CWaveFile *lpWave, void *dwUser);
142
144 uint dwSize; // Size of the play structure
145 void *lpImage; // Additional preprocessed audio for high performance
146 uint hwndNotify; // if set, WOM_OPEN and WOM_DONE messages sent to that window
147 LPQMIXDONECALLBACK callback; // Callback function
148 void *dwUser; // User data accompanying callback
149 int lStart;
150 int lStartLoop;
151 int lEndLoop;
152 int lEnd;
153 const void *lpChannelParams; // initialize with these parameters
154 // Properties introduced by ScummVM
155 Audio::Mixer::SoundType _soundType;
156
157 QMIXPLAYPARAMS() : dwSize(36), lpImage(nullptr), hwndNotify(0), callback(nullptr),
158 dwUser(nullptr), lStart(0), lStartLoop(0), lEndLoop(0), lEnd(0),
159 lpChannelParams(nullptr), _soundType(Audio::Mixer::kPlainSoundType) {}
160};
161
173class QMixer {
174 struct SoundEntry {
175 bool _started;
176 CWaveFile *_waveFile;
177 Audio::SoundHandle _soundHandle;
178 LPQMIXDONECALLBACK _callback;
179 int _loops;
180 void *_userData;
181 SoundEntry() : _started(false), _waveFile(nullptr), _callback(nullptr),
182 _loops(0), _userData(nullptr) {}
183
184 SoundEntry(CWaveFile *waveFile, LPQMIXDONECALLBACK callback, int loops, void *userData) :
185 _started(false), _waveFile(waveFile), _callback(callback), _loops(loops), _userData(userData) {}
186 };
187 struct ChannelEntry {
188 // Currently playing and any following queued sounds for the channel
190 // Current channel volume
191 byte _volume;
192 // Current time in milliseconds for paning (volume) changes
193 uint _panRate;
194 // Fields used to transition between volume levels
195 uint _volumeChangeStart;
196 uint _volumeChangeEnd;
197 byte _volumeStart;
198 byte _volumeEnd;
199 // Distance of source
200 double _distance;
201 bool _resetDistance;
202
203 ChannelEntry() : _volume(0), _panRate(0), _volumeChangeStart(0),
204 _volumeChangeEnd(0), _volumeStart(0), _volumeEnd(0),
205 _distance(0.0), _resetDistance(true) {}
206
211 byte getRawVolume() const;
212 };
213private:
215protected:
216 Audio::Mixer *_mixer;
217public:
218 QMixer(Audio::Mixer *mixer);
219 virtual ~QMixer();
220
224 bool qsWaveMixInitEx(const QMIXCONFIG &config);
225
229 void qsWaveMixActivate(bool fActivate);
230
234 int qsWaveMixOpenChannel(int iChannel, QMixFlag mode);
235
239 int qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled);
240
245
250
254 void qsWaveMixFlushChannel(int iChannel, uint flags = 0);
255
264 void qsWaveMixSetPanRate(int iChannel, uint flags, uint rate);
265
269 void qsWaveMixSetVolume(int iChannel, uint flags, uint volume);
270
277 void qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position);
278
285 void qsWaveMixSetPolarPosition(int iChannel, uint flags, const QSPOLAR &position);
286
290 void qsWaveMixSetListenerPosition(const QSVECTOR &position, uint flags = 0);
291
295 void qsWaveMixSetListenerOrientation(const QSVECTOR &direction, const QSVECTOR &up, uint flags = 0);
296
300 void qsWaveMixSetDistanceMapping(int iChannel, uint flags, const QMIX_DISTANCES &distances);
301
305 void qsWaveMixSetFrequency(int iChannel, uint flags, uint frequency);
306
310 void qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR &velocity);
311
320 int qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS &params);
321
325 bool qsWaveMixIsChannelDone(int iChannel) const;
326
331};
332
333} // End of namespace Titanic
334
335#endif /* TITANIC_QMIXER_H */
Definition: mixer.h:70
SoundType
Definition: mixer.h:73
@ kPlainSoundType
Definition: mixer.h:74
Definition: mixer.h:49
Definition: wave_file.h:35
Definition: qmixer.h:173
void qsWaveMixFlushChannel(int iChannel, uint flags=0)
int qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS &params)
void qsWaveMixSetListenerOrientation(const QSVECTOR &direction, const QSVECTOR &up, uint flags=0)
void qsWaveMixSetPanRate(int iChannel, uint flags, uint rate)
void qsWaveMixSetListenerPosition(const QSVECTOR &position, uint flags=0)
void qsWaveMixCloseSession()
void qsWaveMixSetDistanceMapping(int iChannel, uint flags, const QMIX_DISTANCES &distances)
int qsWaveMixOpenChannel(int iChannel, QMixFlag mode)
void qsWaveMixActivate(bool fActivate)
void qsWaveMixSetFrequency(int iChannel, uint flags, uint frequency)
void qsWaveMixSetPolarPosition(int iChannel, uint flags, const QSPOLAR &position)
void qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position)
void qsWaveMixSetVolume(int iChannel, uint flags, uint volume)
void qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR &velocity)
void qsWaveMixPump()
bool qsWaveMixInitEx(const QMIXCONFIG &config)
bool qsWaveMixIsChannelDone(int iChannel) const
void qsWaveMixFreeWave(Audio::SoundHandle &handle)
int qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled)
Definition: qmixer.h:130
Definition: qmixer.h:86
Definition: qmixer.h:143
Definition: qmixer.h:120
Definition: qmixer.h:108