tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_AudioFifo.h
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11namespace tracktion { inline namespace engine
12{
13
14//==============================================================================
18{
19public:
20 AudioFifo (int channels, int numSamples)
21 : fifo (numSamples), buffer (channels, numSamples)
22 {
23 }
24
25 void setSize (int numChannels, int numSamples)
26 {
27 fifo.setTotalSize (numSamples);
28 buffer.setSize (numChannels, numSamples);
29 }
30
31 int getFreeSpace() const noexcept { return fifo.getFreeSpace(); }
32 int getNumReady() const noexcept { return fifo.getNumReady(); }
33 int getNumChannels() const noexcept { return buffer.getNumChannels(); }
34 void reset() noexcept { fifo.reset(); }
35
36 void ensureFreeSpace (int numSamples)
37 {
38 const int freeSpace = getFreeSpace();
39
40 if (numSamples > freeSpace)
41 {
42 const int samplesRequired = numSamples - freeSpace;
43 jassert (samplesRequired <= getNumReady());
44 fifo.finishedRead (samplesRequired);
45 }
46 }
47
48 bool write (const juce::AudioBuffer<float>& src)
49 {
50 return write (src.getArrayOfReadPointers(), src.getNumSamples());
51 }
52
53 bool write (const juce::AudioBuffer<float>& src, int startSample, int numSamples)
54 {
55 if (numSamples <= 0)
56 return true;
57
58 int start1, size1, start2, size2;
59 fifo.prepareToWrite (numSamples, start1, size1, start2, size2);
60
61 if (size1 + size2 < numSamples)
62 return false;
63
64 for (int i = juce::jmin (buffer.getNumChannels(), src.getNumChannels()); --i >= 0;)
65 {
66 buffer.copyFrom (i, start1, src.getReadPointer (i, startSample), size1);
67 buffer.copyFrom (i, start2, src.getReadPointer (i, startSample) + size1, size2);
68 }
69
70 for (int i = buffer.getNumChannels(); --i >= src.getNumChannels();)
71 {
72 buffer.clear (i, start1, size1);
73 buffer.clear (i, start2, size1 + size2);
74 }
75
76 fifo.finishedWrite (size1 + size2);
77 return true;
78 }
79
80 bool write (const float* const* data, int numSamples)
81 {
82 if (numSamples <= 0)
83 return true;
84
85 int start1, size1, start2, size2;
86 fifo.prepareToWrite (numSamples, start1, size1, start2, size2);
87
88 if (size1 + size2 < numSamples)
89 return false;
90
91 for (int i = buffer.getNumChannels(); --i >= 0;)
92 {
93 buffer.copyFrom (i, start1, data[i], size1);
94 buffer.copyFrom (i, start2, data[i] + size1, size2);
95 }
96
97 fifo.finishedWrite (size1 + size2);
98 return true;
99 }
100
101 bool writeSilence (int numSamples)
102 {
103 if (numSamples <= 0)
104 return true;
105
106 int start1, size1, start2, size2;
107 fifo.prepareToWrite (numSamples, start1, size1, start2, size2);
108
109 if (size1 + size2 < numSamples)
110 return false;
111
112 buffer.clear (start1, size1);
113 buffer.clear (start2, size2);
114
115 fifo.finishedWrite (size1 + size2);
116
117 return true;
118 }
119
120 bool read (juce::AudioBuffer<float>& dest, int startSampleInDestBuffer)
121 {
122 return read (dest, startSampleInDestBuffer, dest.getNumSamples());
123 }
124
125 bool read (juce::AudioBuffer<float>& dest, int startSampleInDestBuffer, int numSamples)
126 {
127 int start1, size1, start2, size2;
128 fifo.prepareToRead (numSamples, start1, size1, start2, size2);
129
130 if (size1 + size2 < numSamples)
131 return false;
132
133 for (int i = juce::jmin (buffer.getNumChannels(), dest.getNumChannels()); --i >= 0;)
134 {
135 dest.copyFrom (i, startSampleInDestBuffer, buffer, i, start1, size1);
136 dest.copyFrom (i, startSampleInDestBuffer + size1, buffer, i, start2, size2);
137 }
138 for (int i = dest.getNumChannels(); --i >= buffer.getNumChannels();)
139 {
140 dest.copyFrom (i, startSampleInDestBuffer, buffer, buffer.getNumChannels() - 1, start1, size1);
141 dest.copyFrom (i, startSampleInDestBuffer + size1, buffer, buffer.getNumChannels() - 1, start2, size2);
142 }
143
144 fifo.finishedRead (size1 + size2);
145 return true;
146 }
147
148 bool readAdding (juce::AudioBuffer<float>& dest, int startSampleInDestBuffer)
149 {
150 return readAdding (dest, startSampleInDestBuffer, dest.getNumSamples());
151 }
152
153 bool readAdding (juce::AudioBuffer<float>& dest, int startSampleInDestBuffer, int numSamples)
154 {
155 int start1, size1, start2, size2;
156 fifo.prepareToRead (numSamples, start1, size1, start2, size2);
157
158 if ((size1 + size2) < numSamples)
159 return false;
160
161 for (int i = buffer.getNumChannels(); --i >= 0;)
162 {
163 dest.addFrom (i, startSampleInDestBuffer, buffer, i, start1, size1);
164 dest.addFrom (i, startSampleInDestBuffer + size1, buffer, i, start2, size2);
165 }
166
167 for (int i = dest.getNumChannels(); --i >= buffer.getNumChannels();)
168 {
169 dest.addFrom (i, startSampleInDestBuffer, buffer, buffer.getNumChannels() - 1, start1, size1);
170 dest.addFrom (i, startSampleInDestBuffer + size1, buffer, buffer.getNumChannels() - 1, start2, size2);
171 }
172
173 fifo.finishedRead (size1 + size2);
174 return true;
175 }
176
177private:
180
182};
183
184}} // namespace tracktion { inline namespace engine
void reset() noexcept
void prepareToWrite(int numToWrite, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
void prepareToRead(int numWanted, int &startIndex1, int &blockSize1, int &startIndex2, int &blockSize2) const noexcept
void finishedRead(int numRead) noexcept
int getFreeSpace() const noexcept
void finishedWrite(int numWritten) noexcept
int getNumReady() const noexcept
void setTotalSize(int newSize) noexcept
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
int getNumChannels() const noexcept
int getNumSamples() const noexcept
void clear() noexcept
void copyFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples) noexcept
void addFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples, Type gainToApplyToSource=Type(1)) noexcept
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE(className)
constexpr Type jmin(Type a, Type b)