-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAudioMiddleware.h
More file actions
433 lines (366 loc) · 18.1 KB
/
Copy pathAudioMiddleware.h
File metadata and controls
433 lines (366 loc) · 18.1 KB
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
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
// Copyright (c) 2026-present Sparky Studios. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <Engine/Core/Types/StringView.h>
#include "AudioSystemData.h"
// ============================================================================
// AudioMiddleware
//
// Pure-virtual contract that every audio backend plugin must implement.
// Middleware implementations are loaded at runtime as native plugins and
// are never exposed to Flax reflection — do NOT add API_CLASS here.
//
// Configuration is loaded from a Flax JSON asset; pass its virtual path
// (or absolute path) as a StringView to LoadConfiguration().
// ============================================================================
/// <summary>
/// Abstract backend interface that decouples the AudioSystem from any
/// specific audio middleware (Wwise, FMOD, OpenAL, …).
///
/// A concrete middleware plugin subclasses this, overrides every pure-virtual
/// method, and registers an instance with the AudioSystem at startup.
/// The AudioSystem calls methods on this interface exclusively — it never
/// touches middleware-specific APIs directly.
/// </summary>
class AUDIOSYSTEM_API AudioMiddleware
{
public:
virtual ~AudioMiddleware() = default;
// ========================================================================
// Lifecycle
//
// Ordered sequence: LoadConfiguration → Startup → (Update loop) →
// Shutdown → Release. StopAllSounds can be called at any point while
// the middleware is running.
// ========================================================================
/// <summary>
/// Load the middleware configuration from a Flax JSON asset.
/// </summary>
/// <param name="configFile">Virtual or absolute path to the JSON configuration asset.</param>
/// <returns>true on success; false if the asset is missing or malformed.</returns>
virtual bool LoadConfiguration(StringView configFile) = 0;
/// <summary>
/// Initialise the middleware engine. Call after LoadConfiguration succeeds.
/// </summary>
/// <returns>true if the backend started successfully.</returns>
virtual bool Startup() = 0;
/// <summary>
/// Advance the middleware audio engine by one frame.
/// </summary>
/// <param name="dt">Elapsed time in seconds since the last Update call.</param>
virtual void Update(float dt) = 0;
/// <summary>
/// Pause all middleware processing and release runtime audio resources.
/// Pair with Release() to fully tear down the backend.
/// </summary>
virtual void Shutdown() = 0;
/// <summary>
/// Fully release all middleware resources. Call after Shutdown().
/// </summary>
virtual void Release() = 0;
/// <summary>
/// Immediately stop every currently-playing sound without unloading data.
/// </summary>
virtual void StopAllSounds() = 0;
#if USE_EDITOR
/// <summary>
/// Deploy middleware-specific files (sound banks, config, etc.) to the
/// cooked build output directory. Called by the editor build hook during
/// the GameCooker deploy phase.
///
/// The middleware implementation is responsible for knowing which files
/// to copy and where they should go within the output tree.
/// </summary>
/// <param name="outputPath">Absolute path to the cooked output root folder.</param>
/// <returns>true if deployment succeeded; false on error.</returns>
virtual bool DeployFiles(const StringView& outputPath) = 0;
#endif
// ========================================================================
// Entity
//
// Audio entities map 1-to-1 to game objects in the middleware.
// The "world entity" is a special global entity used for non-spatial
// (2-D) sounds that are not attached to any scene object.
// ========================================================================
/// <summary>
/// Create the global "world" entity used for non-spatial sounds.
/// </summary>
/// <param name="id">Unique identifier to assign to the world entity.</param>
/// <returns>Newly allocated entity data, or nullptr on failure. Caller owns the pointer and must eventually pass it to DestroyEntityData().</returns>
virtual AudioSystemEntityData* CreateWorldEntity(AudioSystemDataID id) = 0;
/// <summary>
/// Create middleware data for a new spatial audio entity.
/// </summary>
/// <param name="id">Unique identifier for the entity.</param>
/// <returns>Newly allocated entity data, or nullptr on failure.</returns>
virtual AudioSystemEntityData* CreateEntityData(AudioSystemDataID id) = 0;
/// <summary>
/// Release middleware data previously created by CreateEntityData or
/// CreateWorldEntity.
/// </summary>
virtual void DestroyEntityData(AudioSystemEntityData* data) = 0;
/// <summary>
/// Register an entity with the middleware so it can receive audio requests.
/// </summary>
/// <returns>true if the entity was registered successfully.</returns>
virtual bool AddEntity(AudioSystemDataID id, AudioSystemEntityData* data) = 0;
/// <summary>
/// Reset an entity to its default state without unregistering it.
/// </summary>
/// <returns>true on success.</returns>
virtual bool ResetEntity(AudioSystemDataID id, AudioSystemEntityData* data) = 0;
/// <summary>
/// Notify the middleware that an entity's properties (other than transform)
/// may have changed and should be re-evaluated.
/// </summary>
/// <returns>true on success.</returns>
virtual bool UpdateEntity(AudioSystemDataID id, AudioSystemEntityData* data) = 0;
/// <summary>
/// Unregister an entity from the middleware. Does not free data.
/// </summary>
/// <returns>true on success.</returns>
virtual bool RemoveEntity(AudioSystemDataID id, AudioSystemEntityData* data) = 0;
/// <summary>
/// Push an updated world-space transform to the middleware for an entity.
/// </summary>
/// <param name="transform">Position, velocity, forward, and up vectors.</param>
/// <returns>true on success.</returns>
virtual bool SetEntityTransform(AudioSystemDataID id, AudioSystemEntityData* data, const AudioSystemTransform& transform) = 0;
// ========================================================================
// Listener
//
// Listeners represent the "ears" in the scene (typically the camera or
// the player character). Most middleware supports multiple simultaneous
// listeners.
// ========================================================================
/// <summary>
/// Create middleware data for a new audio listener.
/// </summary>
/// <param name="id">Unique identifier for the listener.</param>
/// <param name="isDefault">Whether the listener is the default listener.</param>
/// <returns>Newly allocated listener data, or nullptr on failure.</returns>
virtual AudioSystemListenerData* CreateListenerData(AudioSystemDataID id, bool isDefault) = 0;
/// <summary>
/// Release middleware data previously created by CreateListenerData.
/// </summary>
virtual void DestroyListenerData(AudioSystemListenerData* data) = 0;
/// <summary>
/// Register a listener with the middleware.
/// </summary>
/// <returns>true if the listener was registered successfully.</returns>
virtual bool AddListener(AudioSystemDataID id, AudioSystemListenerData* data) = 0;
/// <summary>
/// Reset a listener to its default state without unregistering it.
/// </summary>
/// <returns>true on success.</returns>
virtual bool ResetListener(AudioSystemDataID id, AudioSystemListenerData* data) = 0;
/// <summary>
/// Unregister a listener from the middleware. Does not free data.
/// </summary>
/// <returns>true on success.</returns>
virtual bool RemoveListener(AudioSystemDataID id, AudioSystemListenerData* data) = 0;
/// <summary>
/// Push an updated world-space transform to the middleware for a listener.
/// </summary>
/// <param name="transform">Position, velocity, forward, and up vectors.</param>
/// <returns>true on success.</returns>
virtual bool SetListenerTransform(AudioSystemDataID id, AudioSystemListenerData* data, const AudioSystemTransform& transform) = 0;
// ========================================================================
// Event
//
// Event data objects represent a single running instance of a trigger
// inside the middleware (e.g. a playing Wwise event or FMOD instance).
// ========================================================================
/// <summary>
/// Allocate a new event instance for the given logical ID.
/// </summary>
/// <returns>Newly allocated event data, or nullptr on failure.</returns>
virtual AudioSystemEventData* CreateEventData(AudioSystemDataID id) = 0;
/// <summary>
/// Reset an event instance back to its initial state (e.g. after stopping).
/// </summary>
virtual void ResetEventData(AudioSystemEventData* data) = 0;
/// <summary>
/// Release event instance data previously created by CreateEventData.
/// </summary>
virtual void DestroyEventData(AudioSystemEventData* data) = 0;
// ========================================================================
// Trigger
//
// Triggers map to middleware events / cues. Loading prepares the data;
// activating starts playback; unloading releases resources.
// ========================================================================
/// <summary>
/// Prepare the trigger's audio data for playback (pre-load / bank prime).
/// </summary>
/// <returns>true if the load request was accepted.</returns>
virtual bool LoadTrigger(AudioSystemDataID entityId, AudioSystemTriggerData* triggerData, AudioSystemEventData* eventData) = 0;
/// <summary>
/// Start playing the trigger on the specified entity.
/// </summary>
/// <returns>true if the activation request was accepted.</returns>
virtual bool ActivateTrigger(AudioSystemDataID entityId, AudioSystemTriggerData* triggerData, AudioSystemEventData* eventData) = 0;
/// <summary>
/// Release audio data loaded by LoadTrigger.
/// </summary>
/// <returns>true if the unload request was accepted.</returns>
virtual bool UnloadTrigger(AudioSystemDataID entityId, AudioSystemTriggerData* triggerData, AudioSystemEventData* eventData) = 0;
/// <summary>
/// Stop a specific running event instance on the given entity.
/// </summary>
/// <returns>true on success.</returns>
virtual bool StopEvent(AudioSystemDataID entityId, AudioSystemEventData* eventData) = 0;
/// <summary>
/// Stop all running events on the given entity.
/// </summary>
/// <returns>true on success.</returns>
virtual bool StopAllEvents(AudioSystemDataID entityId) = 0;
// ========================================================================
// RTPC (Real-Time Parameter Control)
//
// RTPCs are named floating-point parameters that drive middleware
// behaviours (e.g. music intensity, character speed).
// ========================================================================
/// <summary>
/// Set an RTPC to a specific value on the given entity.
/// </summary>
/// <param name="value">New parameter value (range is middleware-defined).</param>
/// <returns>true on success.</returns>
virtual bool SetRtpc(AudioSystemDataID entityId, AudioSystemRtpcData* data, float value) = 0;
/// <summary>
/// Reset an RTPC to its default (middleware-defined) value on the entity.
/// </summary>
/// <returns>true on success.</returns>
virtual bool ResetRtpc(AudioSystemDataID entityId, AudioSystemRtpcData* data) = 0;
// ========================================================================
// Switch / State
//
// Switches (or "states" in some middleware) are named discrete values
// that select between different audio behaviours or variations.
// ========================================================================
/// <summary>
/// Apply a switch-state value to the given entity.
/// </summary>
/// <returns>true on success.</returns>
virtual bool SetSwitchState(AudioSystemDataID entityId, AudioSystemSwitchStateData* data) = 0;
// ========================================================================
// Obstruction & Occlusion
//
// Provides pre-computed obstruction (partial line-of-sight blockage) and
// occlusion (full blockage through geometry) values to the middleware so
// it can attenuate or filter sounds accordingly.
// ========================================================================
/// <summary>
/// Supply obstruction and occlusion coefficients for an entity.
/// </summary>
/// <param name="obstruction">Partial-blockage factor [0.0, 1.0].</param>
/// <param name="occlusion">Full-blockage factor [0.0, 1.0].</param>
/// <returns>true on success.</returns>
virtual bool SetObstructionAndOcclusion(AudioSystemDataID entityId, AudioSystemEntityData* entityData, float obstruction, float occlusion) = 0;
// ========================================================================
// Environment
//
// Environments (aux buses, reverb sends) model acoustic spaces.
// An entity can contribute to multiple environments simultaneously,
// each with its own send amount.
// ========================================================================
/// <summary>
/// Set how strongly an entity contributes to a given environment.
/// </summary>
/// <param name="amount">Contribution factor [0.0, 1.0].</param>
/// <returns>true on success.</returns>
virtual bool SetEnvironmentAmount(AudioSystemDataID entityId, AudioSystemEnvironmentData* envData, float amount) = 0;
// ========================================================================
// Bank
//
// Sound banks bundle compressed audio assets. They must be loaded before
// any triggers or RTPCs that reference their assets can be used.
// ========================================================================
/// <summary>
/// Load a sound bank into middleware memory.
/// </summary>
/// <returns>true if the bank was loaded successfully.</returns>
virtual bool LoadBank(AudioSystemBankData* data) = 0;
/// <summary>
/// Unload a previously loaded sound bank from middleware memory.
/// </summary>
/// <returns>true if the bank was unloaded successfully.</returns>
virtual bool UnloadBank(AudioSystemBankData* data) = 0;
/// <summary>
/// Release bank descriptor data previously created by the middleware.
/// </summary>
virtual void DestroyBank(AudioSystemBankData* data) = 0;
// ========================================================================
// Control Data Destroy
//
// Paired destroy calls for each control-descriptor type. Must be called
// after the control has been deregistered from all entities.
// ========================================================================
/// <summary>
/// Release trigger descriptor data.
/// </summary>
virtual void DestroyTriggerData(AudioSystemTriggerData* data) = 0;
/// <summary>
/// Release RTPC descriptor data.
/// </summary>
virtual void DestroyRtpcData(AudioSystemRtpcData* data) = 0;
/// <summary>
/// Release switch-state descriptor data.
/// </summary>
virtual void DestroySwitchStateData(AudioSystemSwitchStateData* data) = 0;
/// <summary>
/// Release environment descriptor data.
/// </summary>
virtual void DestroyEnvironmentData(AudioSystemEnvironmentData* data) = 0;
// ========================================================================
// Global
//
// Session-wide settings that affect the entire middleware instance.
// ========================================================================
/// <summary>
/// Set the active voice/localisation language for middleware assets.
/// </summary>
virtual void SetLanguage(StringView language) = 0;
/// <summary>
/// Respond to a master-gain change issued by the AudioSystem.
/// </summary>
/// <param name="gain">New master gain value (range is implementation-defined).</param>
virtual void OnMasterGainChange(float gain) = 0;
/// <summary>
/// Respond to a mute-state change issued by the AudioSystem.
/// </summary>
/// <param name="muted">true to mute all output; false to unmute.</param>
virtual void OnMuteChange(bool muted) = 0;
/// <summary>
/// Called when the application loses focus (e.g. Alt-Tab on PC).
/// Implementations should pause or duck audio as appropriate.
/// </summary>
virtual void OnLoseFocus() = 0;
/// <summary>
/// Called when the application regains focus.
/// Implementations should restore the audio state set before OnLoseFocus.
/// </summary>
virtual void OnGainFocus() = 0;
// ========================================================================
// Query
//
// Read-only accessors for middleware state inspected by the AudioSystem.
// ========================================================================
/// <returns>The human-readable name of this middleware (e.g. "Amplitude", "Wwise", "FMOD").</returns>
virtual StringView GetMiddlewareName() const = 0;
/// <returns>The current master gain value.</returns>
virtual float GetMasterGain() const = 0;
/// <returns>true if the middleware output is currently muted.</returns>
virtual bool GetMute() const = 0;
};