UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
BufferedListenerBase.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "AudioDevice.h"
6#include "DSP/Dsp.h"
7
9#include "Misc/Optional.h"
11
12// Simple locking circular buffer
13// Uses 32bit wrap around logic explained here:
14// https://www.snellman.net/blog/archive/2016-12-13-ring-buffers/
16{
17public:
22
23 // Allow the caller to lock the CS ahead of calling (if necessary)
25 const FCriticalSection& GetCriticialSection() const { return CS; }
26
27 // This doesn't preserve contents.
29 {
30 check(InCapacity > 0);
31
33 {
34 InCapacity = FMath::RoundUpToPowerOfTwo(InCapacity);
35 }
36
37 FScopeLock Lock(&CS);
39 Mask = InCapacity-1;
40 Read = 0; // Empty.
41 Write = 0;
42
43 check(Mask != 0);
44 }
46 {
47 FScopeLock Lock(&CS);
48 return Buffer.Num();
49 }
50 int32 Num() const
51 {
52 FScopeLock Lock(&CS);
53 return Write-Read;
54 }
55
56 // Get number of samples that can be pushed onto the buffer before it is full.
58 {
59 FScopeLock Lock(&CS);
60 return Buffer.Num() - Num();
61 }
62
64 {
65 FScopeLock Lock(&CS);
66
67 int32 CanPush = FMath::Min(Remainder(), InSize);
68 for (int32 i = 0; i < CanPush ; ++i)
69 {
70 Enqueue(InBuffer[i]);
71 }
72 return CanPush;
73 }
74 int32 Pop(float* OutBuffer, int32 InNumSamples)
75 {
76 FScopeLock Lock(&CS);
77 int32 CanPop = FMath::Min(Num(),InNumSamples);
78 for(int32 i=0; i < CanPop; ++i)
79 {
80 OutBuffer[i] = Dequeue();
81 }
82 return CanPop;
83 }
84
86 {
87 FScopeLock Lock(&CS);
89 for(int32 i = 0; i < CanPush; ++i)
90 {
91 Enqueue(0.f);
92 }
93 return CanPush;
94 }
95private:
96 uint32 Read = 0; // These grow indefinitely until wrap at 2^32,
97 uint32 Write = 0; // this allows us to use full capacity as write >= read.
98 uint32 Mask = 0;
99 TArray<float> Buffer;
100 mutable FCriticalSection CS;
101
102 // NOTE: Not forceinline as compiler does better job without.
103 void Enqueue(const float InFloat)
104 {
105 Buffer[Write++ & Mask] = InFloat;
106 }
107 float Dequeue()
108 {
109 return Buffer[Read++ & Mask];
110 }
111};
112
116{
117protected:
119 virtual ~FBufferedListenerBase() = default;
120
121 //~ Begin IBufferedAudioOutput
127 //~ End IBufferedAudioOutput
128
129 //* Common path to receive a new buffer, call from derived classes */
131
132 //* Reset the format of the buffer */
134
135 //* Set the format of the buffer */
136 AUDIOLINKENGINE_API void SetFormat(const FBufferFormat& InFormat);
137
138 //* Ask if the started flag has been set. Note this is non-atomic, as it could change during the call */
140
141 //* Attempt to set our state to started. Not this can fail if we're already started. */
143
144 //* Attempt to set started to false. This can fail if we're already stopped. */
146
148
149private:
151
153 FLockingCircularSampleBuffer CircularBuffer;
154
156 mutable FRWLock FormatKnownRwLock;
157
159 TOptional<FBufferFormat> KnownFormat;
160
162 FOnFormatKnown OnFormatKnown;
163
165 std::atomic<bool> bStarted;
166
168 std::atomic<bool> bStopping;
169};
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
UE::FPlatformRecursiveMutex FCriticalSection
Definition CriticalSection.h:53
FRWLock Lock
Definition UnversionedPropertySerialization.cpp:921
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition BufferedListenerBase.h:116
AUDIOLINKENGINE_API bool TryUnsetStartedFlag()
Definition BufferedListenerBase.cpp:129
AUDIOLINKENGINE_API bool GetFormat(IBufferedAudioOutput::FBufferFormat &OutFormat) const override
Definition BufferedListenerBase.cpp:25
AUDIOLINKENGINE_API void OnBufferReceived(const FBufferFormat &InFormat, TArrayView< const float > InBuffer)
Definition BufferedListenerBase.cpp:42
void SetBufferStreamEndDelegate(FOnBufferStreamEnd) override
Definition BufferedListenerBase.h:126
AUDIOLINKENGINE_API void SetFormatKnownDelegate(FOnFormatKnown InFormatKnownDelegate) override
Definition BufferedListenerBase.cpp:36
virtual ~FBufferedListenerBase()=default
AUDIOLINKENGINE_API void ResetFormat()
Definition BufferedListenerBase.cpp:104
AUDIOLINKENGINE_API void Reserve(int32 InNumSamplesToReserve, int32 InNumSamplesOfSilence) override
Definition BufferedListenerBase.cpp:149
AUDIOLINKENGINE_API bool IsStartedNonAtomic() const
Definition BufferedListenerBase.cpp:116
AUDIOLINKENGINE_API bool PopBuffer(float *InBuffer, int32 InBufferSizeInSamples, int32 &OutSamplesWritten) override
Definition BufferedListenerBase.cpp:13
AUDIOLINKENGINE_API bool TrySetStartedFlag()
Definition BufferedListenerBase.cpp:121
AUDIOLINKENGINE_API bool TrySetStoppingFlag()
Definition BufferedListenerBase.cpp:137
AUDIOLINKENGINE_API void SetFormat(const FBufferFormat &InFormat)
Definition BufferedListenerBase.cpp:110
Definition BufferedListenerBase.h:16
FCriticalSection & GetCriticialSection()
Definition BufferedListenerBase.h:24
int32 Pop(float *OutBuffer, int32 InNumSamples)
Definition BufferedListenerBase.h:74
int32 PushZeros(int32 InNumSamplesOfSilence)
Definition BufferedListenerBase.h:85
int32 Remainder() const
Definition BufferedListenerBase.h:57
int32 GetCapacity() const
Definition BufferedListenerBase.h:45
int32 Num() const
Definition BufferedListenerBase.h:50
const FCriticalSection & GetCriticialSection() const
Definition BufferedListenerBase.h:25
FLockingCircularSampleBuffer(int32 InInitialCapacity)
Definition BufferedListenerBase.h:18
int32 Push(const float *InBuffer, int32 InSize)
Definition BufferedListenerBase.h:63
void SetCapacity(int32 InCapacity)
Definition BufferedListenerBase.h:28
Definition ScopeLock.h:141
Definition IBufferedAudioOutput.h:31
Definition ArrayView.h:139
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void SetNumZeroed(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2340
Definition CriticalSection.h:14
constexpr uint32 Read
Definition MassProcessorDependencySolver.h:21
@ Mask
Definition SProgressBar.h:54
static constexpr UE_FORCEINLINE_HINT bool IsPowerOfTwo(T Value)
Definition UnrealMathUtility.h:519
Definition IBufferedAudioOutput.h:42
Definition Optional.h:131