VJ Master 1.0
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// Define the delegates to pass the buffer
17
19DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnAudioIOStatusChanged, bool, bIsActive, FIntPoint, IOId);
21DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnRawMagnitudesReady, const TArray<float>&, RawMagnitudes, FIntPoint, IOId);
23DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnFrequencyBandsReady, const TArray<float>&, FrequencyBands, int32, NumFrequencyBands, FIntPoint, IOId);
25DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnAmplitudesReady, const TArray<float>&, Amplitudes, FIntPoint, IOId);
27DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnPitchesReady, const TArray<float>&, Pitches, FIntPoint, IOId);
29DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnBeatDetected, const TArray<float>&, Beats, const TArray<bool>&, BeatDetectedForChannel, FIntPoint, IOId);
30
36UCLASS(BlueprintType, Abstract)
37class ST_AUDIOPROCESSING_API UST_AudioIOBase : public UEngineSubsystem
38{
39 GENERATED_BODY()
40
41public:
44
47
48protected:
49 //~ Begin USubsystem Interface
50 virtual void Initialize(FSubsystemCollectionBase& Collection) override;
51 virtual void Deinitialize() override;
52 //~ End USubsystem Interface
53
54public:
56 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
57 bool Activate();
58
60 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
61 void Deactivate();
62
64 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
65 virtual EAudioIOType GetAudioIOType() const;
66
68 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
70
72 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
74
80 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
81 bool RegisterSampler(UObject* Sampler, bool bSamplerActivates = false);
82
88 UFUNCTION(BlueprintCallable, Category = "ShaderTech|AudioProcessing|IO")
89 void DeregisterSampler(UObject* Sampler, bool bZeroSamplersDeactivates = false);
90
99 static void MA_DataOrganiser(ma_device* pDevice, void* pSamples, uint64 PeriodSizeInFrames, ma_format Format, uint32 Channels);
100
102 FCriticalSection AudioBufferLock;
103
105 static constexpr uint32 BufferCount = 2;
106
108 void* SampledAudioBuffers[BufferCount] = { nullptr, nullptr };
109
111 void* CurrentAudioBuffer = nullptr;
112
117 template<typename InterfaceType>
118 bool ContainsInterface() const;
119
121 std::atomic<uint32> ReadIndex;
122
124 std::atomic<uint32> WriteIndex;
125
127 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
128 FOnAudioIOStatusChanged OnAudioIOStatusChanged;
129
131 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
132 FOnRawMagnitudesReady OnRawMagnitudesReady;
133
135 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
136 FOnFrequencyBandsReady OnFrequencyBandsReady;
137
139 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
140 FOnAmplitudesReady OnAmplitudesReady;
141
143 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
144 FOnPitchesReady OnPitchesReady;
145
147 UPROPERTY(BlueprintAssignable, Category = "ShaderTech|AudioProcessing|IO")
148 FOnBeatDetected OnBeatDetected;
149
151 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
152 FIntPoint GetIOId() const;
153
158 UFUNCTION(BlueprintPure, Category = "ShaderTech|AudioProcessing|IO")
159 virtual EST_SampleFormat GetAudioFormat() const;
160
161protected:
163 bool bActivated = false;
164
166 bool bIsProcessingFFT = false;
167
172 virtual bool InitializeAudioIO();
173
175 virtual void DeinitializeAudioIO();
176
184 void BuildFFTIOData(uint32 PeriodSizeInFrames, ma_format Format, uint32 SampleRate, uint32 Channels);
185
187 void DeinitializeFFT();
188
190 virtual ma_decoder* GetPlaybackDecoder() const;
191
193 virtual ma_encoder* GetCaptureEncoder() const;
194
196 FCriticalSection SamplerRegistrationMutex;
198 TArray<UObject*> RegisteredSamplers;
199
205 void GetDeviceInfo(EAudioIOType AudioIOType, FString FindDeviceName);
206
209
212
215
217 ma_uint32 playbackDeviceCount = 0;
218
220 ma_uint32 captureDeviceCount = 0;
221
224
227
228private:
230 FST_FFTThread* FFTThreadHandle = nullptr;
231
233 FIntPoint mIOId = FIntPoint::ZeroValue;
234
236 void SwapBuffers();
237
239 UFUNCTION()
240 void LOCAL_OnAudioIOStatusChanged(bool bIsActive, FIntPoint IOId);
241
243 UFUNCTION()
244 void LOCAL_OnRawMagnitudesReady(const TArray<float>& RawMagnitudes, FIntPoint IOId);
245
247 UFUNCTION()
248 void LOCAL_OnFrequencyBandsReady(const TArray<float>& FrequencyBands, int32 NumFrequencyBands, FIntPoint IOId);
249
251 UFUNCTION()
252 void LOCAL_OnAmplitudesReady(const TArray<float>& Amplitudes, FIntPoint IOId);
253
255 UFUNCTION()
256 void LOCAL_OnPitchesReady(const TArray<float>& Pitches, FIntPoint IOId);
257
259 UFUNCTION()
260 void LOCAL_OnBeatDetected(const TArray<float>& Beats, const TArray<bool>& BeatDetectedForChannel, FIntPoint IOId);
261};
262
263inline EAudioIOType UST_AudioIOBase::GetAudioIOType() const
264{
265 return EAudioIOType::None;
266}
267
272
274{
275 return CachedFFTIOData;
276}
277
279{
280 return nullptr;
281}
282
284{
285 return nullptr;
286}
287
288template<typename InterfaceType>
290{
291 for (UObject* Sampler : RegisteredSamplers)
292 {
293 if (Sampler && Sampler->Implements<InterfaceType>())
294 {
295 return true; // Found an object implementing the interface
296 }
297 }
298 return false; // No matching objects found
299}
300
301inline FIntPoint UST_AudioIOBase::GetIOId() const
302{
303 return mIOId;
304}
305
306inline EST_SampleFormat UST_AudioIOBase::GetAudioFormat() const
307{
308 return EST_SampleFormat::Unknown;
309}
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:223
virtual void DeinitializeAudioIO()
Definition ST_AudioIOBase.cpp:92
TArray< UObject * > RegisteredSamplers
Definition ST_AudioIOBase.h:198
static void MA_DataOrganiser(ma_device *pDevice, void *pSamples, uint64 PeriodSizeInFrames, ma_format Format, uint32 Channels)
Definition ST_AudioIOBase.cpp:295
FCriticalSection AudioBufferLock
Definition ST_AudioIOBase.h:102
FFFTIOData GetFFTIOData() const
Definition ST_AudioIOBase.h:273
FIntPoint GetIOId() const
Definition ST_AudioIOBase.h:301
bool ContainsInterface() const
Definition ST_AudioIOBase.h:289
FOnAudioIOStatusChanged OnAudioIOStatusChanged
Definition ST_AudioIOBase.h:128
FOnAmplitudesReady OnAmplitudesReady
Definition ST_AudioIOBase.h:140
std::atomic< uint32 > WriteIndex
Definition ST_AudioIOBase.h:124
void BuildFFTIOData(uint32 PeriodSizeInFrames, ma_format Format, uint32 SampleRate, uint32 Channels)
Definition ST_AudioIOBase.cpp:97
void Deactivate()
Definition ST_AudioIOBase.cpp:71
void GetDeviceInfo(EAudioIOType AudioIOType, FString FindDeviceName)
Definition ST_AudioIOBase.cpp:446
bool bActivated
Definition ST_AudioIOBase.h:163
FOnPitchesReady OnPitchesReady
Definition ST_AudioIOBase.h:144
void DeregisterSampler(UObject *Sampler, bool bZeroSamplersDeactivates=false)
Definition ST_AudioIOBase.cpp:215
ma_uint32 captureDeviceCount
Number of capture devices found.
Definition ST_AudioIOBase.h:220
bool RegisterSampler(UObject *Sampler, bool bSamplerActivates=false)
Definition ST_AudioIOBase.cpp:172
virtual ma_encoder * GetCaptureEncoder() const
Definition ST_AudioIOBase.h:283
FAudioIOConfig GetAudioIOConfig() const
Definition ST_AudioIOBase.h:268
void * SampledAudioBuffers[BufferCount]
Definition ST_AudioIOBase.h:108
ma_device_id * pDeviceID
Pointer to the selected device ID.
Definition ST_AudioIOBase.h:208
static constexpr uint32 BufferCount
Definition ST_AudioIOBase.h:105
ma_uint32 playbackDeviceCount
Number of playback devices found.
Definition ST_AudioIOBase.h:217
virtual EAudioIOType GetAudioIOType() const
Definition ST_AudioIOBase.h:263
virtual bool InitializeAudioIO()
Definition ST_AudioIOBase.cpp:85
virtual EST_SampleFormat GetAudioFormat() const
Returns the current audio format.
Definition ST_AudioIOBase.h:306
FOnBeatDetected OnBeatDetected
Definition ST_AudioIOBase.h:148
void * CurrentAudioBuffer
Definition ST_AudioIOBase.h:111
ma_device_info * pCaptureDeviceInfos
Capture device information.
Definition ST_AudioIOBase.h:214
void DeinitializeFFT()
Definition ST_AudioIOBase.cpp:137
virtual ma_decoder * GetPlaybackDecoder() const
Definition ST_AudioIOBase.h:278
ma_device_info * pPlaybackDeviceInfos
Playback device information.
Definition ST_AudioIOBase.h:211
FCriticalSection SamplerRegistrationMutex
Definition ST_AudioIOBase.h:196
UST_AudioIOBase()
Definition ST_AudioIOBase.cpp:18
FAudioIOConfig CachedAudioIOConfig
Cached audio IO configuration.
Definition ST_AudioIOBase.h:226
FOnFrequencyBandsReady OnFrequencyBandsReady
Definition ST_AudioIOBase.h:136
bool Activate()
Definition ST_AudioIOBase.cpp:35
bool bIsProcessingFFT
Definition ST_AudioIOBase.h:166
std::atomic< uint32 > ReadIndex
Definition ST_AudioIOBase.h:121
FOnRawMagnitudesReady OnRawMagnitudesReady
Definition ST_AudioIOBase.h:132
Structure that holds the configuration for audio input/output.
Definition ST_AudioProcessingSettings.h:984
Structure that holds the miniaudio playback and capture settings.
Definition ST_AudioProcessingSettings.h:714
Definition miniaudio.h:9918
Definition miniaudio.h:7022
Definition miniaudio.h:7710
Definition miniaudio.h:10059
Definition miniaudio.h:6987