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 graph
12{
13
14//==============================================================================
18{
19public:
20 AudioFifo (choc::buffer::ChannelCount numChannels,
21 choc::buffer::FrameCount numFrames)
22 : fifo ((int) numFrames)
23 {
24 setSize (numChannels, numFrames);
25 }
26
27 void setSize (choc::buffer::ChannelCount numChannels,
28 choc::buffer::FrameCount numFrames)
29 {
30 fifo.setTotalSize ((int) numFrames);
31 buffer.resize ({ numChannels, numFrames });
32 }
33
34 int getFreeSpace() const noexcept { return fifo.getFreeSpace(); }
35 int getNumReady() const noexcept { return fifo.getNumReady(); }
36
37 choc::buffer::ChannelCount getNumChannels() const noexcept { return buffer.getNumChannels(); }
38 void reset() noexcept { fifo.reset(); }
39
40 void ensureFreeSpace (int numFrames)
41 {
42 auto freeSpace = getFreeSpace();
43
44 if (numFrames > freeSpace)
45 {
46 auto required = numFrames - freeSpace;
47 jassert (required <= getNumReady());
48 fifo.finishedRead (required);
49 }
50 }
51
52 bool write (choc::buffer::ChannelArrayView<float> block)
53 {
54 jassert (block.getNumChannels() <= buffer.getNumChannels());
55
56 int numSamples = (int) block.getNumFrames();
57 int start1, size1, start2, size2;
58 fifo.prepareToWrite (numSamples, start1, size1, start2, size2);
59
60 if (size1 + size2 < numSamples)
61 return false;
62
63 auto fifo1 = buffer.getFrameRange ({ (choc::buffer::FrameCount) start1, (choc::buffer::FrameCount) (start1 + size1) });
64 auto block1 = block.getStart ((choc::buffer::FrameCount) size1);
65 copyIntersectionAndClearOutside (fifo1, block1);
66
67 if (size2 != 0)
68 {
69 auto fifo2 = buffer.getFrameRange ({ (choc::buffer::FrameCount) start2, (choc::buffer::FrameCount) (start2 + size2) });
70 auto block2 = block.getFrameRange ({ (choc::buffer::FrameCount) size1, (choc::buffer::FrameCount) (size1 + size2) });
71 copyIntersectionAndClearOutside (fifo2, block2);
72 }
73
74 fifo.finishedWrite (size1 + size2);
75 return true;
76 }
77
78 bool writeSilence (choc::buffer::FrameCount numFrames)
79 {
80 if (numFrames == 0)
81 return true;
82
83 int start1, size1, start2, size2;
84 fifo.prepareToWrite ((int) numFrames, start1, size1, start2, size2);
85
86 if (size1 + size2 < (int) numFrames)
87 return false;
88
89 choc::buffer::FrameRange fifo1 { (choc::buffer::FrameCount) start1, (choc::buffer::FrameCount) (start1 + size1) };
90 buffer.getFrameRange (fifo1).clear();
91
92 if (size2 != 0)
93 {
94 choc::buffer::FrameRange fifo2 { (choc::buffer::FrameCount) start2, (choc::buffer::FrameCount) (start2 + size2) };
95 buffer.getFrameRange (fifo2).clear();
96 }
97
98 fifo.finishedWrite (size1 + size2);
99 return true;
100 }
101
102 bool readAdding (choc::buffer::ChannelArrayView<float> dest)
103 {
104 jassert (dest.getNumChannels() <= buffer.getNumChannels());
105
106 auto numFrames = (int) dest.getNumFrames();
107 int start1, size1, start2, size2;
108 fifo.prepareToRead (numFrames, start1, size1, start2, size2);
109
110 if (size1 + size2 < numFrames)
111 return false;
112
113 auto fifo1 = buffer.getFrameRange ({ (choc::buffer::FrameCount) start1, (choc::buffer::FrameCount) (start1 + size1) });
114 auto block1 = dest.getStart ((choc::buffer::FrameCount) size1);
115 add (block1, fifo1);
116
117 if (size2 != 0)
118 {
119 auto fifo2 = buffer.getFrameRange ({ (choc::buffer::FrameCount) start2, (choc::buffer::FrameCount) (start2 + size2) });
120 auto block2 = dest.getFrameRange ({ (choc::buffer::FrameCount) size1, (choc::buffer::FrameCount) (size1 + size2) });
121 add (block2, fifo2);
122 }
123
124 fifo.finishedRead (size1 + size2);
125 return true;
126 }
127
128 bool readOverwriting (choc::buffer::ChannelArrayView<float> dest)
129 {
130 jassert (dest.getNumChannels() <= buffer.getNumChannels());
131
132 auto numFrames = (int) dest.getNumFrames();
133 int start1, size1, start2, size2;
134 fifo.prepareToRead (numFrames, start1, size1, start2, size2);
135
136 if (size1 + size2 < numFrames)
137 return false;
138
139 auto fifo1 = buffer.getFrameRange ({ (choc::buffer::FrameCount) start1, (choc::buffer::FrameCount) (start1 + size1) });
140 auto block1 = dest.getStart ((choc::buffer::FrameCount) size1);
141 copy (block1, fifo1);
142
143 if (size2 != 0)
144 {
145 auto fifo2 = buffer.getFrameRange ({ (choc::buffer::FrameCount) start2, (choc::buffer::FrameCount) (start2 + size2) });
146 auto block2 = dest.getFrameRange ({ (choc::buffer::FrameCount) size1, (choc::buffer::FrameCount) (size1 + size2) });
147 copy (block2, fifo2);
148 }
149
150 fifo.finishedRead (size1 + size2);
151 return true;
152 }
153
154 void removeSamples (int numSamples)
155 {
156 fifo.finishedRead (numSamples);
157 }
158
159private:
161 choc::buffer::ChannelArrayBuffer<float> buffer;
162
164};
165
166}} // namespace tracktion
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
#define jassert(expression)
#define JUCE_DECLARE_NON_COPYABLE(className)
typedef int