1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
#ifndef AUDIOMANAGER_H
#define AUDIOMANAGER_H
#include "Configuration/UnityConfigure.h"
#include "Runtime/BaseClasses/GameManager.h"
#include "Runtime/Math/Vector3.h"
#include "Runtime/Utilities/LinkedList.h"
#include "Runtime/Profiler/ProfilerStats.h"
#include "Runtime/Misc/Player.h"
#include "Runtime/Audio/AudioTypes.h"
#include "Runtime/Mono/MonoIncludes.h"
#if ENABLE_AUDIO_FMOD
#include "Runtime/Audio/AudioScriptBufferManager.h"
#endif
#if ENABLE_AUDIO
#if UNITY_FLASH || UNITY_WEBGL
#include "PlatformDependent/FlashSupport/cpp/AudioChannel.h"
#endif
#ifndef FMOD_ASSERT
#define FMOD_ASSERT(x) {Assert(x == FMOD_OK);\
if (x != FMOD_OK){ ErrorString(FMOD_ErrorString(x));}}
#endif
#include "Runtime/Audio/correct_fmod_includer.h" // can't forward declare enums (@TODO use ints?)
class AudioSource;
class AudioListener;
class AudioClip;
class WWW;
class AudioFilter;
class AudioReverbZone;
struct MonoDomain;
struct MonoThread;
#if ENABLE_AUDIO_FMOD
namespace FMOD { class System; class Sound; class Channel; class ChannelGroup; }
#endif
namespace Unity { class GameObject; }
enum{
kVelocityUpdateModeAuto = 0,
kVelocityUpdateModeFixed = 1,
kVelocityUpdateModeDynamic = 2,
};
class AudioManager : public GlobalGameManager
{
public:
REGISTER_DERIVED_CLASS (AudioManager, GlobalGameManager)
DECLARE_OBJECT_SERIALIZE (AudioManager)
AudioManager (MemLabelId label, ObjectCreationMode mode);
// virtual ~AudioManager (); declared-by-macro
#if UNITY_WII
void UpdateOnDiskEject();
#endif
void Update ();
void FixedUpdate ();
void AddAudioSource (AudioSource* s, bool paused);
void RemoveAudioSource (AudioSource* s);
void StopSources();
void AddAudioListener (AudioListener* newListener);
void RemoveAudioListener (AudioListener* newListener);
AudioListener* GetAudioListener() const;
void SetVolume (float volume);
float GetVolume () const;
void SetPause (bool pause);
bool GetPause () const { return m_IsPaused; }
int GetAutomaticUpdateMode(Unity::GameObject *go);
// Manager implementation
void AwakeFromLoad (AwakeFromLoadMode awakeMode);
static void InitializeClass ();
static void CleanupClass ();
void UpdateListener(
const Vector3f& position,
const Vector3f& velocity,
const Vector3f& up,
const Vector3f& forward);
struct AudioScheduledSource : public ListElement
{
AudioScheduledSource(AudioSource* src) : source(src), time(0.0) {};
AudioSource* source;
double time;
};
private:
float m_DefaultVolume;
float m_Volume;
float m_Rolloffscale;
bool m_IsPaused;
typedef List< ListNode<AudioSource> > TAudioSources;
typedef List< ListNode<AudioListener> > TAudioListeners;
typedef List<AudioScheduledSource> TScheduledSources;
typedef TAudioSources::iterator TAudioSourcesIterator;
typedef TAudioListeners::iterator TAudioListenersIterator;
typedef TScheduledSources::iterator TScheduledSourcesIterator;
TAudioSources m_Sources;
TAudioSources m_PausedSources;
TAudioListeners m_Listeners;
TScheduledSources m_ScheduledSources;
void ProcessScheduledSources();
#if ENABLE_MICROPHONE
FMOD::Sound* CreateSound (int deviceID, int lengthSec, int frequency);
#endif // ENABLE_MICROPHONE
public:
float GetRolloffScale() const { return m_Rolloffscale; }
bool IsAudioDisabled() const { return m_DisableAudio; }
/// Schedule source to be played in sync. In this frame (if delay==0) or later
inline UInt64 GetAccumulatedPauseTicks() const { return m_accPausedTicks; }
void ScheduleSource(AudioSource* s, double time);
void UnScheduleSource(AudioSource* s);
double GetDSPTime() const;
#if ENABLE_AUDIO_FMOD
void AddAudioReverbZone(AudioReverbZone* z);
void RemoveAudioReverbZone(AudioReverbZone* z);
// FMOD
bool ValidateFMODResult(FMOD_RESULT result, const char* errmsg);
bool InitFMOD();
void InitScriptBufferManager();
void ReloadFMODSounds();
bool InitNormal();
#ifdef SUPPORT_REPRODUCE_LOG
bool InitReproduction();
#endif
void CloseFMOD();
FMOD::System* GetFMODSystem() const { return m_FMODSystem;}
static FMOD_RESULT F_CALLBACK systemCallback(FMOD_SYSTEM* c_system, FMOD_SYSTEM_CALLBACKTYPE type, void* data1, void* data2);
// groups
FMOD::ChannelGroup* GetChannelGroup_FX_IgnoreVolume() const { return m_ChannelGroup_FX_IgnoreVolume; }
FMOD::ChannelGroup* GetChannelGroup_FX_UseVolume() const { return m_ChannelGroup_FX_UseVolume; }
FMOD::ChannelGroup* GetChannelGroup_NoFX_IgnoreVolume() const { return m_ChannelGroup_NoFX_IgnoreVolume; }
FMOD::ChannelGroup* GetChannelGroup_NoFX_UseVolume() const { return m_ChannelGroup_NoFX_UseVolume; }
// FMOD profiling
int GetMemoryAllocated() const;
float GetCPUUsage() const;
#if ENABLE_PROFILER
void GetProfilerData( AudioStats& audioStats );
#endif
FMOD::Sound* CreateFMODSound(const void* buffer, FMOD_CREATESOUNDEXINFO exInfo, FMOD_MODE mode, bool useHardwareDecoder);
#if UNITY_EDITOR
FMOD::Sound* CreateFMODSound(const std::string& path, bool threeD,
bool hardware, bool openOnly = false );
#endif
FMOD::Sound* CreateFMODSoundFromWWW(WWW* webStream,
bool threeD,
FMOD_SOUND_TYPE suggestedtype,
FMOD_SOUND_FORMAT format,
unsigned freq,
unsigned channels,
bool stream);
FMOD::Sound* CreateFMODSoundFromMovie(AudioClip* clip, bool threeD);
FMOD::Channel* GetFreeFMODChannel(FMOD::Sound* sound, bool paused = true);
unsigned GetPlayingChannelsForSound(FMOD::Sound* sound);
const std::string& GetLastError() const { return m_LastErrorString; }
FMOD_SPEAKERMODE GetSpeakerMode() const { return m_speakerMode; }
FMOD_SPEAKERMODE GetSpeakerModeCaps() const { return m_speakerModeCaps; }
void SetSpeakerMode(FMOD_SPEAKERMODE speakerMode);
public:
#if ENABLE_MICROPHONE
// Microphone
const std::vector<std::string> GetRecordDevices() const;
bool EndRecord(int deviceID);
PPtr<AudioClip> StartRecord(int deviceID, bool loop, int lengthSec, int frequency);
bool IsRecording(int deviceID) const;
unsigned GetRecordPosition(int deviceID) const;
int GetMicrophoneDeviceIDFromName(const std::string& name) const;
void GetDeviceCaps(int deviceID, int *minFreq, int *maxFreq) const;
mutable std::map<std::string, int> m_MicrophoneNameToIDMap;
#endif // ENABLE_MICROPHONE
private:
float m_SpeedOfSound;
float m_DopplerFactor;
typedef List< ListNode<AudioReverbZone> > TAudioReverbZones;
typedef TAudioReverbZones::iterator TAudioReverbZonesIterator;
TAudioReverbZones m_ReverbZones;
// FMOD
FMOD::System* m_FMODSystem;
/* +----------------+
* | NoFX_UseVolume |
* /+----------------+
* _+-------------------+/
* / | NoFX_IgnoreVolume |<---EditorChannel plays directly into this group
* +-----------+/ +-------------------+
* |FMOD Master| ...............
* +-----------+\ +------------------+ : AudioSource :
* ^ \_| FX_IgnoreVolume | __:__+-----+ :
* | +------------------+\ +--------------+ / : | Wet | :
* | \| FX_UseVolume |/ : +-----+ :
* | +--------------+\ : :
* Zone reverbs \__:__+-----+ :
* : | Dry | :
* : +-----+ :
* ...............
* The AudioSource's Wet and Dry groups can be attached to the Listener, IgnoreVolume, IgnoreVolNoFX, or ListenerNoFX groups depending on the combinations of the bypassEffects and bypassListenerEffects properties.
* Note that zone reverbs are applied by FMOD after the downmix of the master channel group, so in order to avoid reverb on previews the ignoreVolumeGroupNoFX uses FMOD's overrideReverbProperties to turn off the reverb.
*/
FMOD::ChannelGroup* m_ChannelGroup_FMODMaster;
FMOD::ChannelGroup* m_ChannelGroup_FX_IgnoreVolume;
FMOD::ChannelGroup* m_ChannelGroup_FX_UseVolume;
FMOD::ChannelGroup* m_ChannelGroup_NoFX_IgnoreVolume;
FMOD::ChannelGroup* m_ChannelGroup_NoFX_UseVolume;
FMOD_SPEAKERMODE m_speakerMode; ///< TransferName{Default Speaker Mode} enum { Raw = 0, Mono = 1, Stereo = 2, Quad = 3, Surround = 4, Surround 5.1 = 5, Surround 7.1 = 6, Prologic DTS = 7 }
FMOD_SPEAKERMODE m_activeSpeakerMode;
FMOD_CAPS m_driverCaps;
FMOD_SPEAKERMODE m_speakerModeCaps;
// Phone DSP buffer size
int m_DSPBufferSize; ///< enum { Default = 0, Best latency = 256, Good latency = 512, Best performance = 1024 }
// error handling
std::string m_LastErrorString;
FMOD_RESULT m_LastFMODErrorResult;
private:
AudioScriptBufferManager* m_ScriptBufferManager;
public:
AudioScriptBufferManager& GetScriptBufferManager();
AudioScriptBufferManager* GetScriptBufferManagerPtr();
#if UNITY_EDITOR
public:
void PlayClip(AudioClip& clip, int startSample = 0, bool loop = false, bool twoD = true);
void StopClip(const AudioClip& clip);
void PauseClip(const AudioClip& clip);
void ResumeClip(const AudioClip& clip);
bool IsClipPlaying(const AudioClip& clip);
void StopAllClips();
float GetClipPosition(const AudioClip& clip);
unsigned int GetClipSamplePosition(const AudioClip& clip);
void SetClipSamplePosition(const AudioClip& clip, unsigned int iSamplePosition);
void LoopClip(const AudioClip& clip, bool loop);
void ListenerCheck();
private:
FMOD::Channel* m_EditorChannel;
#endif //UNITY_EDITOR
#endif //ENABLE_AUDIO_FMOD
UInt64 m_accPausedTicks;
UInt64 m_pauseStartTicks;
bool m_DisableAudio; // Completely disable audio (in standalone builds only)
};
AudioManager& GetAudioManager ();
AudioManager* GetAudioManagerPtr ();
#endif // ENABLE_AUDIO
#endif // AUDIOMANAGER_H
|