UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SpectrumAnalyzer.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "DSP/Dsp.h"
7#include "DSP/AudioFFT.h"
9#include "SampleBuffer.h"
10#include "Async/AsyncWork.h"
11
12namespace Audio
13{
14 class IFFTAlgorithm;
15 class FSpectrumAnalyzer;
16
18 {
19 // Actual FFT size used. For FSpectrumAnalyzer, we never zero pad the input buffer.
20 enum class EFFTSize : uint16
21 {
22 Default = 512,
23 TestingMin_8 = 8,
24 Min_64 = 64,
25 Small_256 = 256,
26 Medium_512 = 512,
27 Large_1024 = 1024,
28 VeryLarge_2048 = 2048,
29 TestLarge_4096 = 4096
30 };
31
34
41 float HopSize;
42
48 };
49
50
53 {
55 enum class EMetric : uint8
56 {
59
61 Power,
62
66 };
67
70
71
73 float DecibelNoiseFloor = -40.f;
74
81 bool bDoNormalize = true;
82
87 bool bDoAutoRange = true;
88
91
94 };
95
98 {
101
104
107
110
117
120 {
121 bool bIsEqual = ((SampleRate == Other.SampleRate)
122 && (FFTSize == Other.FFTSize)
123 && (FFTScaling == Other.FFTScaling)
124 && (WindowType == Other.WindowType));
125 return bIsEqual;
126 }
127
130 {
131 return !(*this == Other);
132 }
133 };
134
143 {
144 public:
145
146 enum class EBandType : uint8
147 {
150
152 Lerp,
153
155 Quadratic,
156
159 };
160
163 {
166
168 float CenterFrequency = 0.f;
169
174 float QFactor = 10.0f;
175 };
176
178
181
184
186 virtual void RemoveAllBands() = 0;
187
189 virtual int32 GetNumBands() const = 0;
190
192 virtual void AddBand(const FBandSettings& InSettings) = 0;
193
201
204 };
205
211 {
212 public:
215
216 void Reset(int32 InNum);
217
218 // Input. Used on analysis thread to lock a buffer to write to.
220
221 // When calling stop work on buffer, also set timestmap associated with buffer.
222 void StopWorkOnBuffer(double InTimestamp);
223
224 // Output. Used to lock the most recent buffer we analyzed.
226
227 // Output. Used to lock the most recent buffer we analyzed.
228 // OutTimestamp is populated with the timestamp associated with the buffer wehn StopWorkOnBuffer is called.
230 void UnlockBuffer();
231
232 private:
233 TArray<FAlignedFloatBuffer> ComplexBuffers;
234 TArray<double> Timestamps;
235
236 // Private functions. Either increments or decrements the respective counter,
237 // based on which index is currently in use. Mutually locked.
238 void IncrementInputIndex();
239 void IncrementOutputIndex();
240
241 volatile int32 OutputIndex;
242 volatile int32 InputIndex;
243
244 // This mutex is locked when we increment either the input or output index.
245 FCriticalSection BufferIndicesCriticalSection;
246 };
247
249 {
250
251 public:
257
262
263 void DoWork();
264
266 {
267 return true;
268 }
269
270 void Abandon();
271
272 private:
274
276 bool bUseLatestAudio;
277 bool bIsAbandoned;
278
279 FCriticalSection NonAbandonableSection;
280 };
281
283
291 {
292
293 public:
294 // Peak interpolation method. If the EFFTSize is small but will be densely sampled,
295 // it's worth using a linear or quadratic interpolation method.
297 {
299 Linear,
301 };
302
303 // If an instance is created using the default constructor, Init() must be called before it is used.
305
306 // If an instance is created using either of these constructors, Init() is not neccessary.
309
310 virtual ~FSpectrumAnalyzer() = default;
311
312 // Initialize sample rate of analyzer if not known at time of construction
315
316 // Update the settings used by this Spectrum Analyzer. Safe to call on any thread, but should not be called every tick.
318
319 // Get the current settings used by this Spectrum Analyzer.
321
322 // Samples magnitude (linearly) for a given frequency, in Hz.
325
326 // Samples phase for a given frequency, in Hz.
328
329 // Return array of bands using spectrum band extractor.
331
332 // You can call this function to ensure that you're sampling the same window of frequency data,
333 // Then call UnlockOutputBuffer when you're done.
334 // Otherwise, GetMagnitudeForFrequency and GetPhaseForFrequency will always use the latest window
335 // of frequency data.
338
339 // Push audio to queue. Returns false if the queue is already full.
341 SIGNALPROCESSING_API bool PushAudio(const float* InBuffer, int32 NumSamples);
342
343 // Thread safe call to perform actual FFT. Returns true if it performed the FFT, false otherwise.
344 // If bUseLatestAudio is set to true, this function will flush the entire input buffer, potentially losing data.
345 // Otherwise it will only consume enough samples necessary to perform a single FFT.
346 SIGNALPROCESSING_API bool PerformAnalysisIfPossible(bool bUseLatestAudio = false);
347
348 // Returns false if this instance of FSpectrumAnalyzer was constructed with the default constructor
349 // and Init() has not been called yet.
351
352 private:
353
354
355 // Called on analysis thread.
356 SIGNALPROCESSING_API void ResetSettings();
357
358 // Called in GetMagnitudeForFrequency and GetPhaseForFrequency.
359 SIGNALPROCESSING_API void PerformInterpolation(const FAlignedFloatBuffer& InComplexBuffer, EPeakInterpolationMethod InMethod, const float InFreq, float& OutReal, float& OutImag);
360
361 // Cached current settings. Only actually used in ResetSettings().
362 FSpectrumAnalyzerSettings CurrentSettings;
363 volatile bool bSettingsWereUpdated;
364
365 volatile bool bIsInitialized;
366
367 float SampleRate;
368
369 // Cached window that is applied prior to running the FFT.
370 FWindow Window;
371 int32 FFTSize;
372 int32 HopInSamples;
373 EFFTScaling FFTScaling;
374
375 FAlignedFloatBuffer AnalysisTimeDomainBuffer;
376 FThreadSafeCounter SampleCounter;
378 FSpectrumAnalyzerBuffer FrequencyBuffer;
379
380 // if non-null, owns pointer to locked frequency vector we're using.
381 double LockedBufferTimestamp;
382 const FAlignedFloatBuffer* LockedFrequencyVector;
383
384
386 };
387
389 {
390 public:
396
398 {
399 Analyzer->UnlockOutputBuffer();
400 }
401
402 private:
403 FSpectrumAnalyzer* Analyzer;
404 };
405
406 // SpectrumAnalyzer for computing spectrum in async task.
408 {
409
412
413 FAsyncSpectrumAnalyzer& operator=(const FSpectrumAnalyzer&) = delete;
414 FAsyncSpectrumAnalyzer& operator=(FSpectrumAnalyzer&&) = delete;
415
416
417 public:
419 // If an instance is created using either of these constructors, Init() is not neccessary.
422
424
425 // Initialize sample rate of analyzer if not known at time of construction
428
429 // Returns false if this instance of FSpectrumAnalyzer was constructed with the default constructor
430 // and Init() has not been called yet.
432
433 // Update the settings used by this Spectrum Analyzer. Safe to call on any thread, but should not be called every tick.
435
436 // Get the current settings used by this Spectrum Analyzer.
438
439 // Samples magnitude (linearly) for a given frequency, in Hz.
442
443 // Samples phase for a given frequency, in Hz.
445
446 // Return array of bands using spectrum band extractor.
448
449 // You can call this function to ensure that you're sampling the same window of frequency data,
450 // Then call UnlockOutputBuffer when you're done.
451 // Otherwise, GetMagnitudeForFrequency and GetPhaseForFrequency will always use the latest window
452 // of frequency data.
455
456 // Push audio to queue. Returns false if the queue is already full.
458 SIGNALPROCESSING_API bool PushAudio(const float* InBuffer, int32 NumSamples);
459
460 // Thread safe call to perform actual FFT. Returns true if it performed the FFT, false otherwise.
461 // If bUseLatestAudio is set to true, this function will flush the entire input buffer, potentially losing data.
462 // Otherwise it will only consume enough samples necessary to perform a single FFT.
463 SIGNALPROCESSING_API bool PerformAnalysisIfPossible(bool bUseLatestAudio = false);
464
465
466 // Thread safe call to perform actual FFT. Returns true if it performed the FFT, false otherwise.
467 // If bUseLatestAudio is set to true, this function will flush the entire input buffer, potentially losing data.
468 // Otherwise it will only consume enough samples necessary to perform a single FFT.
469 SIGNALPROCESSING_API bool PerformAsyncAnalysisIfPossible(bool bUseLatestAudio = false);
470
471
472 private:
473
475
476 // This is used if PerformAsyncAnalysisIfPossible is called
477 TUniquePtr<FSpectrumAnalyzerTask> AsyncAnalysisTask;
478 };
479
481 {
482 public:
488
493
494 private:
495 FAsyncSpectrumAnalyzer* Analyzer;
496 };
497}
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define RETURN_QUICK_DECLARE_CYCLE_STAT(StatId, GroupId)
Definition Stats.h:655
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE::FPlatformRecursiveMutex FCriticalSection
Definition CriticalSection.h:53
void Init()
Definition LockFreeList.h:4
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
Definition SpectrumAnalyzer.h:481
FAsyncSpectrumAnalyzerScopeLock(FAsyncSpectrumAnalyzer *InAnalyzer)
Definition SpectrumAnalyzer.h:483
~FAsyncSpectrumAnalyzerScopeLock()
Definition SpectrumAnalyzer.h:489
Definition SpectrumAnalyzer.h:408
SIGNALPROCESSING_API bool PerformAnalysisIfPossible(bool bUseLatestAudio=false)
Definition SpectrumAnalyzer.cpp:1329
SIGNALPROCESSING_API float GetMagnitudeForFrequency(float InFrequency, FSpectrumAnalyzer::EPeakInterpolationMethod InMethod=FSpectrumAnalyzer::EPeakInterpolationMethod::Linear)
Definition SpectrumAnalyzer.cpp:1289
SIGNALPROCESSING_API float GetPhaseForFrequency(float InFrequency, FSpectrumAnalyzer::EPeakInterpolationMethod InMethod=FSpectrumAnalyzer::EPeakInterpolationMethod::Linear)
Definition SpectrumAnalyzer.cpp:1299
SIGNALPROCESSING_API void UnlockOutputBuffer()
Definition SpectrumAnalyzer.cpp:1314
SIGNALPROCESSING_API bool PushAudio(const TSampleBuffer< float > &InBuffer)
Definition SpectrumAnalyzer.cpp:1319
SIGNALPROCESSING_API bool IsInitialized()
Definition SpectrumAnalyzer.cpp:1274
SIGNALPROCESSING_API float GetNormalizedMagnitudeForFrequency(float InFrequency, FSpectrumAnalyzer::EPeakInterpolationMethod InMethod=FSpectrumAnalyzer::EPeakInterpolationMethod::Linear)
Definition SpectrumAnalyzer.cpp:1294
SIGNALPROCESSING_API bool PerformAsyncAnalysisIfPossible(bool bUseLatestAudio=false)
Definition SpectrumAnalyzer.cpp:1334
virtual SIGNALPROCESSING_API ~FAsyncSpectrumAnalyzer()
Definition SpectrumAnalyzer.cpp:1248
SIGNALPROCESSING_API void LockOutputBuffer()
Definition SpectrumAnalyzer.cpp:1309
SIGNALPROCESSING_API FAsyncSpectrumAnalyzer()
Definition SpectrumAnalyzer.cpp:1234
SIGNALPROCESSING_API void SetSettings(const FSpectrumAnalyzerSettings &InSettings)
Definition SpectrumAnalyzer.cpp:1279
SIGNALPROCESSING_API void GetBands(ISpectrumBandExtractor &InExtractor, TArray< float > &OutValues)
Definition SpectrumAnalyzer.cpp:1304
SIGNALPROCESSING_API void GetSettings(FSpectrumAnalyzerSettings &OutSettings)
Definition SpectrumAnalyzer.cpp:1284
Definition SpectrumAnalyzer.h:249
void Abandon()
Definition SpectrumAnalyzer.cpp:1228
bool CanAbandon()
Definition SpectrumAnalyzer.h:265
FSpectrumAnalysisAsyncWorker(TWeakPtr< FSpectrumAnalyzer, ESPMode::ThreadSafe > InAnalyzer, bool bInUseLatestAudio)
Definition SpectrumAnalyzer.h:252
TStatId GetStatId() const
Definition SpectrumAnalyzer.h:258
void DoWork()
Definition SpectrumAnalyzer.cpp:1214
Definition SpectrumAnalyzer.h:211
FAlignedFloatBuffer & StartWorkOnBuffer()
Definition SpectrumAnalyzer.cpp:1186
const FAlignedFloatBuffer & LockMostRecentBuffer() const
Definition SpectrumAnalyzer.cpp:1203
void StopWorkOnBuffer(double InTimestamp)
Definition SpectrumAnalyzer.cpp:1191
void UnlockBuffer()
Definition SpectrumAnalyzer.cpp:1208
FSpectrumAnalyzerBuffer()
Definition SpectrumAnalyzer.cpp:1124
Definition SpectrumAnalyzer.h:389
~FSpectrumAnalyzerScopeLock()
Definition SpectrumAnalyzer.h:397
FSpectrumAnalyzerScopeLock(FSpectrumAnalyzer *InAnalyzer)
Definition SpectrumAnalyzer.h:391
Definition SpectrumAnalyzer.h:291
SIGNALPROCESSING_API float GetPhaseForFrequency(float InFrequency, EPeakInterpolationMethod InMethod=EPeakInterpolationMethod::Linear)
Definition SpectrumAnalyzer.cpp:911
SIGNALPROCESSING_API float GetNormalizedMagnitudeForFrequency(float InFrequency, EPeakInterpolationMethod InMethod=EPeakInterpolationMethod::Linear)
Definition SpectrumAnalyzer.cpp:899
virtual ~FSpectrumAnalyzer()=default
SIGNALPROCESSING_API void SetSettings(const FSpectrumAnalyzerSettings &InSettings)
Definition SpectrumAnalyzer.cpp:845
SIGNALPROCESSING_API void LockOutputBuffer()
Definition SpectrumAnalyzer.cpp:999
SIGNALPROCESSING_API void GetSettings(FSpectrumAnalyzerSettings &OutSettings)
Definition SpectrumAnalyzer.cpp:851
SIGNALPROCESSING_API FSpectrumAnalyzer()
Definition SpectrumAnalyzer.cpp:632
SIGNALPROCESSING_API bool PerformAnalysisIfPossible(bool bUseLatestAudio=false)
Definition SpectrumAnalyzer.cpp:1043
SIGNALPROCESSING_API bool IsInitialized()
Definition SpectrumAnalyzer.cpp:1117
EPeakInterpolationMethod
Definition SpectrumAnalyzer.h:297
SIGNALPROCESSING_API void GetBands(ISpectrumBandExtractor &InExtractor, TArray< float > &OutValues)
Definition SpectrumAnalyzer.cpp:955
SIGNALPROCESSING_API float GetMagnitudeForFrequency(float InFrequency, EPeakInterpolationMethod InMethod=EPeakInterpolationMethod::Linear)
Definition SpectrumAnalyzer.cpp:856
SIGNALPROCESSING_API void UnlockOutputBuffer()
Definition SpectrumAnalyzer.cpp:1015
SIGNALPROCESSING_API bool PushAudio(const TSampleBuffer< float > &InBuffer)
Definition SpectrumAnalyzer.cpp:1030
Definition AudioFFT.h:46
Definition SpectrumAnalyzer.h:143
virtual void SetSettings(const FSpectrumBandExtractorSettings &InSettings)=0
static SIGNALPROCESSING_API TUniquePtr< ISpectrumBandExtractor > CreateSpectrumBandExtractor(const FSpectrumBandExtractorSettings &InSettings)
Definition SpectrumAnalyzer.cpp:627
virtual int32 GetNumBands() const =0
virtual ~ISpectrumBandExtractor()
Definition SpectrumAnalyzer.h:177
virtual void RemoveAllBands()=0
virtual void ExtractBands(const FAlignedFloatBuffer &InComplexBuffer, double InTimestamp, TArray< float > &OutValues)=0
EBandType
Definition SpectrumAnalyzer.h:147
virtual void AddBand(const FBandSettings &InSettings)=0
virtual void SetSpectrumSettings(const FSpectrumBandExtractorSpectrumSettings &InSettings)=0
Definition Dsp.h:834
Definition SampleBuffer.h:24
Definition AsyncWork.h:585
Definition ThreadSafeCounter.h:14
Definition SharedPointer.h:153
Definition UniquePtr.h:107
Definition SharedPointer.h:1295
NO_LOGGING.
Definition AudioMixerPlatformAndroid.cpp:53
FAsyncTask< FSpectrumAnalysisAsyncWorker > FSpectrumAnalyzerTask
Definition SpectrumAnalyzer.h:282
EWindowType
Definition AudioFFT.h:23
EFFTScaling
Definition FFTAlgorithm.h:18
@ false
Definition radaudio_common.h:23
Definition SpectrumAnalyzer.h:18
float HopSize
Definition SpectrumAnalyzer.h:41
EFFTSize FFTSize
Definition SpectrumAnalyzer.h:33
EWindowType WindowType
Definition SpectrumAnalyzer.h:32
FSpectrumAnalyzerSettings()
Definition SpectrumAnalyzer.h:43
EFFTSize
Definition SpectrumAnalyzer.h:21
Definition SpectrumAnalyzer.h:53
float AutoRangeAttackTimeInSeconds
Definition SpectrumAnalyzer.h:93
bool bDoNormalize
Definition SpectrumAnalyzer.h:81
bool bDoAutoRange
Definition SpectrumAnalyzer.h:87
EMetric Metric
Definition SpectrumAnalyzer.h:69
float DecibelNoiseFloor
Definition SpectrumAnalyzer.h:73
EMetric
Definition SpectrumAnalyzer.h:56
float AutoRangeReleaseTimeInSeconds
Definition SpectrumAnalyzer.h:90
Definition SpectrumAnalyzer.h:98
float SampleRate
Definition SpectrumAnalyzer.h:100
bool operator==(const FSpectrumBandExtractorSpectrumSettings &Other) const
Definition SpectrumAnalyzer.h:119
int32 FFTSize
Definition SpectrumAnalyzer.h:103
EFFTScaling FFTScaling
Definition SpectrumAnalyzer.h:106
FSpectrumBandExtractorSpectrumSettings()
Definition SpectrumAnalyzer.h:111
bool operator!=(const FSpectrumBandExtractorSpectrumSettings &Other) const
Definition SpectrumAnalyzer.h:129
EWindowType WindowType
Definition SpectrumAnalyzer.h:109
Definition SpectrumAnalyzer.h:163
EBandType Type
Definition SpectrumAnalyzer.h:165
float CenterFrequency
Definition SpectrumAnalyzer.h:168
float QFactor
Definition SpectrumAnalyzer.h:174
Definition LightweightStats.h:416