Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / sound / driver / xaudio2 / source_xaudio2.h
blob22e5bd4dcf3867c6c139e657bb2320927a16e862
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2008-2015 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #ifndef NLSOUND_SOURCE_XAUDIO2_H
18 #define NLSOUND_SOURCE_XAUDIO2_H
20 #include "nel/sound/driver/source.h"
21 #include "nel/sound/driver/sound_driver.h"
22 #include "nel/sound/driver/buffer.h"
24 namespace NLSOUND {
25 class CSoundDriverXAudio2;
26 class CBufferXAudio2;
27 class CAdpcmXAudio2;
28 class CEffectXAudio2;
30 /**
31 * \brief CSourceXAudio2
32 * \date 2008-08-20 15:53GMT
33 * \author Jan Boon (Kaetemi)
34 * CSourceXAudio2 is an implementation of the ISource interface to run on XAudio2.
36 class CSourceXAudio2 : public ISource
38 private:
39 // -- outside pointers --
40 /// The sound driver, cannot change at runtime.
41 CSoundDriverXAudio2 *_SoundDriver;
42 /// Buffer that should be playing.
43 CBufferXAudio2 *_StaticBuffer;
44 /// Last buffer that was prepared for playing.
45 CBufferXAudio2 *_LastPreparedBuffer;
47 // -- Pointers --
48 /// Source voice, can be NULL!
49 IXAudio2SourceVoice *_SourceVoice;
50 /// Adpcm helper, can be NULL!
51 CAdpcmXAudio2 *_AdpcmUtility;
53 // -- System vars 2d --
54 /// Unique operation set
55 uint32 _OperationSet;
56 /// Format of the current source voice.
57 IBuffer::TBufferFormat _Format;
58 /// Number of channels in the current format
59 uint8 _Channels;
60 /// Bits per sample in the current format
61 uint8 _BitsPerSample;
62 /// Frequency of the current sample format
63 uint32 _Frequency;
64 /// Time when source started playing.
65 NLMISC::TTime _PlayStart;
66 /// Buffer loading system
67 bool _BufferStreaming;
69 // -- System vars 3d --
70 float _Doppler;
72 // -- User vars 3d --
73 X3DAUDIO_EMITTER _Emitter;
74 X3DAUDIO_CONE _Cone;
75 /// Minimum distance of sound at max volume.
76 float _MinDistance;
77 /// Maximum distance of sound.
78 float _MaxDistance;
79 /// Position of the source.
80 NLMISC::CVector _Pos;
81 /// Source relative to listener position (listener + source = actual source location).
82 bool _Relative;
83 /// Alpha for manual rolloff.
84 double _Alpha;
86 // -- Output path vars --
87 /// Voices
88 IXAudio2Voice *_DirectDryVoice, *_DirectFilterVoice, *_EffectDryVoice, *_EffectFilterVoice;
89 /// Path enabled settings
90 bool _DirectDryEnabled, _DirectFilterEnabled, _EffectDryEnabled, _EffectFilterEnabled;
91 /// Gain settings
92 float _DirectGain, _EffectGain;
93 float _DirectFilterPassGain, _EffectFilterPassGain;
94 /// Filter cutoff frequencies
95 float _DirectFilterLowFrequency, _DirectFilterHighFrequency;
96 /// Filter cutoff frequencies
97 float _EffectFilterLowFrequency, _EffectFilterHighFrequency;
98 /// Filter settings
99 XAUDIO2_FILTER_PARAMETERS _DirectFilter, _EffectFilter;
101 // -- User vars 2d --
102 /// True if play() or pause(), false if stop().
103 bool _IsPlaying;
104 /// True if pause(), false if play() or stop().
105 bool _IsPaused;
106 /// True if setLooping(true).
107 bool _IsLooping;
108 /// Pitch set by user.
109 float _Pitch;
110 /// Volume set by user.
111 float _Gain;
113 // -- Combined vars --
114 // _FreqRatio = (float)_StaticBuffer->getFreq() / _FreqVoice;
115 // 3D PITCH = (_FreqRatio * _Pitch * _Doppler)
116 // 2D PITCH = (_FreqRatio * _Pitch)
117 public:
118 // Internal functions
119 CSourceXAudio2(CSoundDriverXAudio2 *soundDriver);
120 virtual ~CSourceXAudio2();
121 void release();
123 void commit3DChanges();
124 void update3DChanges();
125 void updateState();
127 /// (Internal) Initialize voice with this format, if no voice has been created yet.
128 bool initFormat(IBuffer::TBufferFormat bufferFormat, uint8 channels, uint8 bitsPerSample);
129 /// (Internal) Returns the XAudio2 source voice.
130 inline IXAudio2SourceVoice * getSourceVoice() { return _SourceVoice; }
131 /// (Internal) Submit a buffer to the XAudio2 source voice.
132 void submitBuffer(CBufferXAudio2 *ibuffer);
133 /// (Internal) Prepare to play. Stop the currently playing buffers, and set the correct voice settings.
134 bool preparePlay(IBuffer::TBufferFormat bufferFormat, uint8 channels, uint8 bitsPerSample, uint32 frequency);
135 /// (Internal) Set the effect send for this source, NULL to disable.
136 void setEffect(CEffectXAudio2 *effect);
137 /// (Internal) Update the send descriptor
138 void setupVoiceSends();
139 /// (Internal) Setup the direct send filter.
140 void setupDirectFilter();
141 /// (Internal) Setup the effect send filter.
142 void setupEffectFilter();
144 /// \name Initialization
145 //@{
146 /// Enable or disable streaming mode. Source must be stopped to call this.
147 virtual void setStreaming(bool streaming);
148 /** Set the buffer that will be played (no streaming)
149 * If the buffer is stereo, the source mode becomes stereo and the source relative mode is on,
150 * otherwise the source is considered as a 3D source. Use submitStreamingBuffer for streaming.
152 virtual void setStaticBuffer(IBuffer *buffer);
153 /// Return the buffer, or NULL if streaming is used. Not available for streaming.
154 virtual IBuffer *getStaticBuffer();
155 /// Add a buffer to the streaming queue. A buffer of 100ms length is optimal for streaming.
156 /// Should be called by a thread which checks countStreamingBuffers every 100ms.
157 virtual void submitStreamingBuffer(IBuffer *buffer);
158 /// Return the amount of buffers in the queue (playing and waiting). 3 buffers is optimal.
159 virtual uint countStreamingBuffers() const;
160 //@}
162 /// \name Playback control
163 //@{
164 /// Set looping on/off for future playbacks (default: off), not available for streaming
165 virtual void setLooping(bool l);
166 /// Return the looping state
167 virtual bool getLooping() const;
169 /** Play the static buffer (or stream in and play).
170 * This method can return false if the sample for this sound is unloaded.
172 virtual bool play();
173 /// Stop playing
174 virtual void stop();
175 /// Pause. Call play() to resume.
176 virtual void pause();
177 /// Return true if play() or pause(), false if stop().
178 virtual bool isPlaying() const;
179 /// Return true if playing is finished or stop() has been called.
180 virtual bool isStopped() const;
181 /// Return true if the playing source is paused
182 virtual bool isPaused() const;
183 /// Returns the number of milliseconds the source has been playing
184 virtual uint32 getTime();
185 //@}
187 /// \name Source properties
188 //@{
189 /** Set the position vector (default: (0,0,0)).
190 * 3D mode -> 3D position
191 * st mode -> x is the pan value (from left (-1) to right (1)), set y and z to 0
193 virtual void setPos(const NLMISC::CVector& pos, bool deffered = true);
194 /** Get the position vector.
195 * See setPos() for details.
197 virtual const NLMISC::CVector &getPos() const;
198 /// Set the velocity vector (3D mode only, ignored in stereo mode) (default: (0,0,0))
199 virtual void setVelocity(const NLMISC::CVector& vel, bool deferred = true);
200 /// Get the velocity vector
201 virtual void getVelocity(NLMISC::CVector& vel) const;
202 /// Set the direction vector (3D mode only, ignored in stereo mode) (default: (0,0,0) as non-directional)
203 virtual void setDirection(const NLMISC::CVector& dir);
204 /// Get the direction vector
205 virtual void getDirection(NLMISC::CVector& dir) const;
206 /** Set the gain (volume value inside [0 , 1]). (default: 1)
207 * 0.0 -> silence
208 * 0.5 -> -6dB
209 * 1.0 -> no attenuation
210 * values > 1 (amplification) not supported by most drivers
212 virtual void setGain(float gain);
213 /// Get the gain
214 virtual float getGain() const;
215 /** Shift the frequency. 1.0f equals identity, each reduction of 50% equals a pitch shift
216 * of one octave. 0 is not a legal value.
218 virtual void setPitch(float pitch);
219 /// Get the pitch
220 virtual float getPitch() const;
221 /// Set the source relative mode. If true, positions are interpreted relative to the listener position
222 virtual void setSourceRelativeMode(bool mode);
223 /// Get the source relative mode
224 virtual bool getSourceRelativeMode() const;
225 /// Set the min and max distances (default: 1, MAX_FLOAT) (3D mode only)
226 virtual void setMinMaxDistances(float mindist, float maxdist, bool deferred = true);
227 /// Get the min and max distances
228 virtual void getMinMaxDistances(float& mindist, float& maxdist) const;
229 /// Set the cone angles (in radian) and gain (in [0 , 1]) (default: 2PI, 2PI, 0)
230 virtual void setCone(float innerAngle, float outerAngle, float outerGain);
231 /// Get the cone angles (in radian)
232 virtual void getCone(float& innerAngle, float& outerAngle, float& outerGain) const;
233 /** Set the alpha value for the volume-distance curve
235 * Useful only with OptionManualRolloff. value from -1 to 1 (default 0)
237 * alpha.0: the volume will decrease linearly between 0dB and -100 dB
238 * alpha = 1.0: the volume will decrease linearly between 1.0 and 0.0 (linear scale)
239 * alpha = -1.0: the volume will decrease inversely with the distance (1/dist). This
240 * is the default used by DirectSound/OpenAL
242 * For any other value of alpha, an interpolation is be done between the two
243 * adjacent curves. For example, if alpha equals 0.5, the volume will be halfway between
244 * the linear dB curve and the linear amplitude curve.
246 virtual void setAlpha(double a);
247 //@}
249 /// \name Direct output
250 //@{
251 /// Enable or disable direct output [true/false], default: true
252 virtual void setDirect(bool enable = true);
253 /// Return if the direct output is enabled
254 virtual bool getDirect() const;
255 /// Set the gain for the direct path
256 virtual void setDirectGain(float gain);
257 /// Get the gain for the direct path
258 virtual float getDirectGain() const;
260 /// Enable or disable the filter for the direct channel
261 virtual void enableDirectFilter(bool enable = true);
262 /// Check if the filter on the direct channel is enabled
263 virtual bool isDirectFilterEnabled() const;
264 /// Set the filter parameters for the direct channel
265 virtual void setDirectFilter(TFilter filter, float lowFrequency, float highFrequency, float passGain);
266 /// Get the filter parameters for the direct channel
267 virtual void getDirectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const;
268 /// Set the direct filter gain
269 virtual void setDirectFilterPassGain(float passGain);
270 /// Get the direct filter gain
271 virtual float getDirectFilterPassGain() const;
272 //@}
274 /// \name Effect output
275 //@{
276 /// Set the effect send for this source, NULL to disable. [IEffect], default: NULL
277 virtual void setEffect(IReverbEffect *reverbEffect);
278 /// Get the effect send for this source
279 virtual IEffect *getEffect() const;
280 /// Set the gain for the effect path
281 virtual void setEffectGain(float gain);
282 /// Get the gain for the effect path
283 virtual float getEffectGain() const;
285 /// Enable or disable the filter for the effect channel
286 virtual void enableEffectFilter(bool enable = true);
287 /// Check if the filter on the effect channel is enabled
288 virtual bool isEffectFilterEnabled() const;
289 /// Set the filter parameters for the effect channel
290 virtual void setEffectFilter(TFilter filter, float lowFrequency, float highFrequency, float passGain);
291 /// Get the filter parameters for the effect channel
292 virtual void getEffectFilter(TFilter &filterType, float &lowFrequency, float &highFrequency, float &passGain) const;
293 /// Set the effect filter gain
294 virtual void setEffectFilterPassGain(float passGain);
295 /// Get the effect filter gain
296 virtual float getEffectFilterPassGain() const;
297 //@}
299 }; /* class CSourceXAudio2 */
301 } /* namespace NLSOUND */
303 #endif /* #ifndef NLSOUND_SOURCE_XAUDIO2_H */
305 /* end of file */