VJ Master 1.5
Real-time audio analysis and visualisation.
Loading...
Searching...
No Matches
ST_AudioIOBase.h
1// Copyright (c) 2025 Aaron Trotter (ShaderTech). All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "Subsystems/EngineSubsystem.h"
7#include "Main/ST_AudioProcessingSettings.h"
8#include "miniaudio.h"
9#if WITH_KISSFFT
10#include "kiss_fft.h"
11#endif
12#include "FFT/ST_FFTThread.h"
13
14#include "ST_AudioIOBase.generated.h"
15
16//disabling warning C4996: 'UE::Math::TIntPoint<int32>::XY': was declared deprecated
17PRAGMA_DISABLE_DEPRECATION_WARNINGS
18// Define the delegates to pass the buffer
20DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnAudioIOStatusChanged, const bool, bIsActive, const FIntPoint, IOId);
22DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnRawMagnitudesReady, const TArray<float>&, RawMagnitudes, const FIntPoint, IOId);
24DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnFrequencyBandsReady, const TArray<float>&, FrequencyBands, const int32, NumFrequencyBands, const FIntPoint, IOId);
26DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnAmplitudesReady, const TArray<float>&, Amplitudes, const FIntPoint, IOId);
28DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnPitchesReady, const TArray<float>&, Pitches, const FIntPoint, IOId);
30DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnBeatDetected, const TArray<float>&, Beats, const TArray<FChannelBeatDetection>&, BeatDetectionForChannel, const FIntPoint, IOId);
31PRAGMA_ENABLE_DEPRECATION_WARNINGS
32
38UCLASS(BlueprintType, Abstract)
39class ST_AUDIOPROCESSING_API UST_AudioIOBase : public UEngineSubsystem
40{
41 GENERATED_BODY()
42
43public:
46
49
50protected:
51 //~ Begin USubsystem Interface
52 virtual void Initialize(FSubsystemCollectionBase& Collection) override;
53 virtual void Deinitialize() override;
54 //~ End USubsystem Interface
55
56public:
58 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
59 bool Activate();
60
62 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
63 void Deactivate();
64
66 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
67 virtual EAudioIOType GetAudioIOType() const;
68
70 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
72
74 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
76
82 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
83 bool RegisterSampler(UObject* Sampler, bool bSamplerActivates = false);
84
90 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
91 void DeregisterSampler(UObject* Sampler, bool bZeroSamplersDeactivates = false);
92
97 bool MA_IsDataAvailable(uint64 PeriodSizeInFrames);
98
105 void MA_ReadRealtimePcmRB(uint64 PeriodSizeInFrames, ma_format Format, uint32 Channels);
106
111 static void MA_DataAvailable(ma_device* pDevice);
112
120 void MA_DataOrganiser(void* pSamples, uint64 PeriodSizeInFrames, ma_format Format, uint32 Channels);
121
123 FCriticalSection AudioBufferLock;
124
126 static constexpr uint32 BufferCount = 2;
127
129 void* SampledAudioBuffers[BufferCount] = { nullptr, nullptr };
130
132 void* CurrentAudioBuffer = nullptr;
133
138 template<typename InterfaceType>
139 bool ContainsInterface() const;
140
142 std::atomic<uint32> ReadIndex;
143
145 std::atomic<uint32> WriteIndex;
146
148 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
149 FOnAudioIOStatusChanged OnAudioIOStatusChanged;
150
152 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
153 FOnRawMagnitudesReady OnRawMagnitudesReady;
154
156 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
157 FOnFrequencyBandsReady OnFrequencyBandsReady;
158
160 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
161 FOnAmplitudesReady OnAmplitudesReady;
162
164 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
165 FOnPitchesReady OnPitchesReady;
166
168 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
169 FOnBeatDetected OnBeatDetected;
170
172 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
173 FIntPoint GetIOId() const;
174
179 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
180 virtual EST_SampleFormat GetAudioFormat() const;
181
182protected:
184 bool bActivated = false;
185
187 bool bIsProcessingFFT = false;
188
193 virtual bool InitializeAudioIO();
194
196 virtual void DeinitializeAudioIO();
197
205 void BuildFFTIOData(uint32 PeriodSizeInFrames, ma_format Format, uint32 SampleRate, uint32 Channels);
206
208 void DeinitializeFFT();
209
211 virtual ma_decoder* GetPlaybackDecoder() const;
212
214 virtual ma_encoder* GetCaptureEncoder() const;
215
217 FCriticalSection SamplerRegistrationMutex;
219 TArray<UObject*> RegisteredSamplers;
220
226 void GetDeviceInfo(EAudioIOType AudioIOType, FString FindDeviceName);
227
230
233
236
238 ma_uint32 playbackDeviceCount = 0;
239
241 ma_uint32 captureDeviceCount = 0;
242
245
248
251
254
257
258private:
260 FST_FFTThread* FFTThreadHandle = nullptr;
261
263 FIntPoint mIOId = FIntPoint::ZeroValue;
264
266 void SwapBuffers();
267
269 UFUNCTION()
270 void LOCAL_OnAudioIOStatusChanged(const bool bIsActive, const FIntPoint IOId);
271
273 UFUNCTION()
274 void LOCAL_OnRawMagnitudesReady(const TArray<float>& RawMagnitudes, const FIntPoint IOId);
275
277 UFUNCTION()
278 void LOCAL_OnFrequencyBandsReady(const TArray<float>& FrequencyBands, const int32 NumFrequencyBands, const FIntPoint IOId);
279
281 UFUNCTION()
282 void LOCAL_OnAmplitudesReady(const TArray<float>& Amplitudes, const FIntPoint IOId);
283
285 UFUNCTION()
286 void LOCAL_OnPitchesReady(const TArray<float>& Pitches, const FIntPoint IOId);
287
289 UFUNCTION()
290 void LOCAL_OnBeatDetected(const TArray<float>& Beats, const TArray<FChannelBeatDetection>& BeatDetectionForChannel, const FIntPoint IOId);
291};
292
293inline EAudioIOType UST_AudioIOBase::GetAudioIOType() const
294{
295 return EAudioIOType::None;
296}
297
302
304{
305 return CachedFFTIOData;
306}
307
309{
310 return nullptr;
311}
312
314{
315 return nullptr;
316}
317
318template<typename InterfaceType>
320{
321 for (UObject* Sampler : RegisteredSamplers)
322 {
323 if (Sampler && Sampler->Implements<InterfaceType>())
324 {
325 return true; // Found an object implementing the interface
326 }
327 }
328 return false; // No matching objects found
329}
330
331inline FIntPoint UST_AudioIOBase::GetIOId() const
332{
333 return mIOId;
334}
335
336inline EST_SampleFormat UST_AudioIOBase::GetAudioFormat() const
337{
338 return EST_SampleFormat::Unknown;
339}
FFT processing thread class that runs audio analysis in a background thread.
Definition ST_FFTThread.h:20
FFFTIOData CachedFFTIOData
Cached FFT IO data.
Definition ST_AudioIOBase.h:244
virtual void DeinitializeAudioIO()
Definition ST_AudioIOBase.cpp:98
TArray< UObject * > RegisteredSamplers
Definition ST_AudioIOBase.h:219
FCriticalSection AudioBufferLock
Definition ST_AudioIOBase.h:123
FFFTIOData GetFFTIOData() const
Definition ST_AudioIOBase.h:303
TArray< uint8 > RealtimePcmRBBackingMemory
Preallocated backing memory used by the ring buffer (no runtime allocations).
Definition ST_AudioIOBase.h:256
void MA_ReadRealtimePcmRB(uint64 PeriodSizeInFrames, ma_format Format, uint32 Channels)
Definition ST_AudioIOBase.cpp:313
FIntPoint GetIOId() const
Definition ST_AudioIOBase.h:331
ma_pcm_rb RealtimePcmRingBuffer
Lock-free PCM ring buffer for passing audio from the realtime callback to the FFT worker thread.
Definition ST_AudioIOBase.h:250
void MA_DataOrganiser(void *pSamples, uint64 PeriodSizeInFrames, ma_format Format, uint32 Channels)
Definition ST_AudioIOBase.cpp:360
bool ContainsInterface() const
Definition ST_AudioIOBase.h:319
FOnAudioIOStatusChanged OnAudioIOStatusChanged
Definition ST_AudioIOBase.h:149
FOnAmplitudesReady OnAmplitudesReady
Definition ST_AudioIOBase.h:161
std::atomic< uint32 > WriteIndex
Definition ST_AudioIOBase.h:145
void BuildFFTIOData(uint32 PeriodSizeInFrames, ma_format Format, uint32 SampleRate, uint32 Channels)
Definition ST_AudioIOBase.cpp:110
void Deactivate()
Definition ST_AudioIOBase.cpp:71
void GetDeviceInfo(EAudioIOType AudioIOType, FString FindDeviceName)
Definition ST_AudioIOBase.cpp:511
bool bActivated
Definition ST_AudioIOBase.h:184
FOnPitchesReady OnPitchesReady
Definition ST_AudioIOBase.h:165
void DeregisterSampler(UObject *Sampler, bool bZeroSamplersDeactivates=false)
Definition ST_AudioIOBase.cpp:228
ma_uint32 captureDeviceCount
Number of capture devices found.
Definition ST_AudioIOBase.h:241
ma_uint32 RealtimePcmRBFrameCapacity
Fixed maximum number of audio frames the ring buffer can hold.
Definition ST_AudioIOBase.h:253
bool RegisterSampler(UObject *Sampler, bool bSamplerActivates=false)
Definition ST_AudioIOBase.cpp:185
virtual ma_encoder * GetCaptureEncoder() const
Definition ST_AudioIOBase.h:313
FAudioIOConfig GetAudioIOConfig() const
Definition ST_AudioIOBase.h:298
void * SampledAudioBuffers[BufferCount]
Definition ST_AudioIOBase.h:129
ma_device_id * pDeviceID
Pointer to the selected device ID.
Definition ST_AudioIOBase.h:229
static constexpr uint32 BufferCount
Definition ST_AudioIOBase.h:126
ma_uint32 playbackDeviceCount
Number of playback devices found.
Definition ST_AudioIOBase.h:238
virtual EAudioIOType GetAudioIOType() const
Definition ST_AudioIOBase.h:293
virtual bool InitializeAudioIO()
Definition ST_AudioIOBase.cpp:85
virtual EST_SampleFormat GetAudioFormat() const
Returns the current audio format.
Definition ST_AudioIOBase.h:336
static void MA_DataAvailable(ma_device *pDevice)
Definition ST_AudioIOBase.cpp:344
FOnBeatDetected OnBeatDetected
Definition ST_AudioIOBase.h:169
void * CurrentAudioBuffer
Definition ST_AudioIOBase.h:132
ma_device_info * pCaptureDeviceInfos
Capture device information.
Definition ST_AudioIOBase.h:235
void DeinitializeFFT()
Definition ST_AudioIOBase.cpp:150
virtual ma_decoder * GetPlaybackDecoder() const
Definition ST_AudioIOBase.h:308
ma_device_info * pPlaybackDeviceInfos
Playback device information.
Definition ST_AudioIOBase.h:232
bool MA_IsDataAvailable(uint64 PeriodSizeInFrames)
Definition ST_AudioIOBase.cpp:308
FCriticalSection SamplerRegistrationMutex
Definition ST_AudioIOBase.h:217
UST_AudioIOBase()
Definition ST_AudioIOBase.cpp:18
FAudioIOConfig CachedAudioIOConfig
Cached audio IO configuration.
Definition ST_AudioIOBase.h:247
FOnFrequencyBandsReady OnFrequencyBandsReady
Definition ST_AudioIOBase.h:157
bool Activate()
Definition ST_AudioIOBase.cpp:35
bool bIsProcessingFFT
Definition ST_AudioIOBase.h:187
std::atomic< uint32 > ReadIndex
Definition ST_AudioIOBase.h:142
FOnRawMagnitudesReady OnRawMagnitudesReady
Definition ST_AudioIOBase.h:153
Structure that holds the configuration for audio input/output.
Definition ST_AudioProcessingSettings.h:1126
Structure that holds configuration settings for the FFT (Fast Fourier Transform) Beat detection.
Definition ST_AudioProcessingSettings.h:666
Structure that holds the miniaudio playback and capture settings.
Definition ST_AudioProcessingSettings.h:835
Definition miniaudio.h:9918
Definition miniaudio.h:7022
Definition miniaudio.h:7710
Definition miniaudio.h:10059
Definition miniaudio.h:6002
Definition miniaudio.h:6987