1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2008 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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.
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_SOUND_DRIVER_XAUDIO2_H //todo: support MAKEINTRESOURCE for music files?
18 #define NLSOUND_SOUND_DRIVER_XAUDIO2_H
21 #include "source_xaudio2.h"
22 #include "buffer_xaudio2.h"
23 //#include "music_channel_xaudio2.h"
30 class CListenerXAudio2
;
31 class CSampleVoiceXAudio2
;
32 class CMusicChannelXAudio2
;
36 * \brief CSoundDriverXAudio2
37 * \date 2008-08-20 10:52GMT
38 * \author Jan Boon (Kaetemi)
39 * CSoundDriverXAudio2 is an implementation of the ISoundDriver interface to run on XAudio2.
41 class CSoundDriverXAudio2
: public ISoundDriver
, public NLMISC::CManualSingleton
<CSoundDriverXAudio2
>
45 /// Pointer to XAudio2.
47 /// Pointer to XAudio2 Mastering Voice.
48 IXAudio2MasteringVoice
*_MasteringVoice
;
51 /// If XAudio2 is fully initialized.
53 /// If CoInitializeEx has been called.
55 /// Empty 3D Listener.
56 X3DAUDIO_LISTENER _EmptyListener
;
57 /// Listener created by client code.
58 CListenerXAudio2
*_Listener
;
59 /// Array with the allocated buffers created by client code.
60 std::set
<CBufferXAudio2
*> _Buffers
;
61 /// Array with the allocated sources created by client code.
62 std::set
<CSourceXAudio2
*> _Sources
;
63 /// Array with the allocated effects created by client code.
64 std::set
<CEffectXAudio2
*> _Effects
;
65 /// Initialization Handle of X3DAudio.
66 X3DAUDIO_HANDLE _X3DAudioHandle
; //I
67 /// Operation set counter
68 uint32 _OperationSetCounter
;
71 uint _PerformancePCMBufferSize
;
72 uint _PerformanceADPCMBufferSize
;
73 uint _PerformanceSourcePlayCounter
;
74 uint _PerformanceCommit3DCounter
;
78 TSoundOptions _Options
;
81 /// (Internal) Constructor for CSoundDriverXAudio2.
82 CSoundDriverXAudio2(ISoundDriver::IStringMapperProvider
*stringMapper
);
83 /// (Internal) Destructor for CSoundDriverXAudio2.
84 virtual ~CSoundDriverXAudio2();
85 /// (Internal) Release all resources owned by CSoundDriverXAudio2.
88 /// (Internal) Register a data buffer with the performance counters.
89 inline void performanceRegisterBuffer(IBuffer::TBufferFormat bufferFormat
, uint size
)
93 case IBuffer::FormatPcm
: _PerformancePCMBufferSize
+= size
; break;
94 case IBuffer::FormatDviAdpcm
: _PerformanceADPCMBufferSize
+= size
; break;
97 /// (Internal) Remove a data buffer from the performance counters.
98 inline void performanceUnregisterBuffer(IBuffer::TBufferFormat bufferFormat
, uint size
)
100 switch (bufferFormat
)
102 case IBuffer::FormatPcm
: _PerformancePCMBufferSize
-= size
; break;
103 case IBuffer::FormatDviAdpcm
: _PerformanceADPCMBufferSize
-= size
; break;
106 /// (Internal) Increase the source play counter by one.
107 inline void performanceIncreaseSourcePlayCounter() { ++_PerformanceSourcePlayCounter
; }
108 /// (Internal) Increase the commit 3d counter by one.
109 inline void performanceIncreaseCommit3DCounter() { ++_PerformanceCommit3DCounter
; }
111 /// (Internal) Initialize uninitialized sources with this format (so xaudio2 voices don't need to be created at runtime)
112 void initSourcesFormat(IBuffer::TBufferFormat bufferFormat
, uint8 channels
, uint8 bitsPerSample
);
114 /// (Internal) Returns the listener for this driver.
115 inline CListenerXAudio2
*getListener() { return _Listener
; }
116 /// (Internal) Returns the XAudio2 interface.
117 inline IXAudio2
*getXAudio2() { return _XAudio2
; }
118 /// (Internal) Returns the XAudio2 Mastering Voice interface.
119 inline IXAudio2MasteringVoice
*getMasteringVoice() { return _MasteringVoice
; }
120 /// (Internal) Returns the handle to X3DAudio.
121 inline X3DAUDIO_HANDLE
&getX3DAudio() { return _X3DAudioHandle
; }
122 /// (Internal) Returns an X3DAudio listener at 0 position.
123 inline X3DAUDIO_LISTENER
*getEmptyListener() { return &_EmptyListener
; }
124 /// (Internal) Returns if EAX is enabled.
125 inline bool useEax() { return getOption(OptionEnvironmentEffects
); }
126 /// (Internal) Returns a unique operation set id.
127 inline uint32
getUniqueOperationSet() { return ++_OperationSetCounter
; }
129 /// (Internal) Create an XAudio2 source voice of the specified format.
130 IXAudio2SourceVoice
*createSourceVoice(IBuffer::TBufferFormat bufferFormat
, uint8 channels
, uint8 bitsPerSample
, IXAudio2VoiceCallback
*callback
);
131 /// (Internal) Destroy an XAudio2 source voice.
132 void destroySourceVoice(IXAudio2SourceVoice
*sourceVoice
);
134 /// Return a list of available devices for the user. The value at index 0 is empty, and is used for automatic device selection.
135 virtual void getDevices(std::vector
<std::string
> &devices
);
136 /// Initialize the driver with a user selected device. If device.empty(), the default or most appropriate device is used.
137 virtual void initDevice(const std::string
&device
, TSoundOptions options
);
139 /// (Internal) Get device index and details from string.
140 uint
getDeviceIndex(const std::string
&device
, XAUDIO2_DEVICE_DETAILS
*deviceDetails
);
142 /// Return options that are enabled (including those that cannot be disabled on this driver).
143 virtual TSoundOptions
getOptions();
144 /// Return if an option is enabled (including those that cannot be disabled on this driver).
145 virtual bool getOption(TSoundOptions option
);
147 /// Create the listener instance
148 virtual IListener
*createListener();
149 /// Create a source, destroy with delete
150 virtual ISource
*createSource();
151 /// Create a sound buffer, destroy with delete
152 virtual IBuffer
*createBuffer();
153 /// Create a reverb effect
154 virtual IReverbEffect
*createReverbEffect();
155 /// Return the maximum number of sources that can created
156 virtual uint
countMaxSources();
157 /// Return the maximum number of effects that can be created
158 virtual uint
countMaxEffects();
160 /// Commit all the changes made to 3D settings of listener and sources.
161 virtual void commit3DChanges();
163 /// Write information about the driver to the output stream.
164 virtual void writeProfile(std::string
& out
) ;
166 /// Does not create a sound loader... that's really awesome but what does it do?
167 virtual void startBench();
168 virtual void endBench();
169 virtual void displayBench(NLMISC::CLog
*log
);
171 /// Get audio/container extensions that are supported natively by the driver implementation.
172 virtual void getMusicExtensions(std::vector
<std::string
> & /* extensions */) const { }
173 /// Return if a music extension is supported by the driver's music channel.
174 virtual bool isMusicExtensionSupported(const std::string
& /* extension */) const { return false; }
176 /// (Internal) Remove a buffer (should be called by the destructor of the buffer class).
177 void removeBuffer(CBufferXAudio2
*buffer
);
178 /// (Internal) Remove a source (should be called by the destructor of the source class).
179 void removeSource(CSourceXAudio2
*source
);
180 /// (Internal) Remove the listener (should be called by the destructor of the listener class)
181 inline void removeListener(CListenerXAudio2
*listener
) { nlassert(_Listener
== listener
); _Listener
= NULL
; }
182 /// (Internal) Remove an effect (should be called by the destructor of the effect class)
183 void removeEffect(CEffectXAudio2
*effect
);
185 }; /* class CSoundDriverXAudio2 */
187 } /* namespace NLSOUND */
189 #endif /* #ifndef NLSOUND_SOUND_DRIVER_XAUDIO2_H */