Audacity 3.2.0
Public Member Functions | Private Attributes | List of all members
AudioGraph::Buffers Class Reference

Accumulates (non-interleaved) data during effect processing. More...

#include <AudioGraphBuffers.h>

Collaboration diagram for AudioGraph::Buffers:
[legend]

Public Member Functions

 Buffers (size_t blockSize=512)
 
 Buffers (unsigned nChannels, size_t blockSize, size_t nBlocks, size_t padding=0)
 
unsigned Channels () const
 
size_t BufferSize () const
 
size_t BlockSize () const
 
size_t Position () const
 
size_t Remaining () const
 
bool IsRewound () const
 
void Reinit (unsigned nChannels, size_t blockSize, size_t nBlocks, size_t padding=0)
 
float *const * Positions () const
 Get array of positions in the buffers. More...
 
void Discard (size_t drop, size_t keep)
 Discard some data at the (unchanging) positions. More...
 
void Advance (size_t count)
 Move the positions. More...
 
void Rewind ()
 Reset positions to starts of buffers. More...
 
size_t Rotate ()
 Shift all data at and after the old position to position 0. More...
 
constSamplePtr GetReadPosition (unsigned iChannel) const
 Get accumulated data for one channel. More...
 
float & GetWritePosition (unsigned iChannel)
 Get writable position for one channel. More...
 
void ClearBuffer (unsigned iChannel, size_t n)
 

Private Attributes

std::vector< std::vector< float > > mBuffers
 
std::vector< float * > mPositions
 
size_t mBufferSize { 0 }
 
size_t mBlockSize { 0 }
 

Detailed Description

Accumulates (non-interleaved) data during effect processing.

Invariant
BlockSize() > 0
BufferSize() > 0
BufferSize() % BlockSize() == 0
mBuffers.size() == mPositions.size()
all mBuffers[i].size() are equal to BufferSize()
all (mPositions[i] - mBuffers[i].data()) are equal and in range [0, BufferSize()]

Definition at line 30 of file AudioGraphBuffers.h.

Constructor & Destructor Documentation

◆ Buffers() [1/2]

AudioGraph::Buffers::Buffers ( size_t  blockSize = 512)
explicit
Precondition
blockSize > 0
Postcondition
BlockSize() == blockSize
BufferSize() == blockSize
IsRewound()

Definition at line 16 of file AudioGraphBuffers.cpp.

17 : mBufferSize{ blockSize }, mBlockSize{ blockSize }
18{
19 assert(blockSize > 0);
20 assert(IsRewound());
21}

References IsRewound().

Here is the call graph for this function:

◆ Buffers() [2/2]

AudioGraph::Buffers::Buffers ( unsigned  nChannels,
size_t  blockSize,
size_t  nBlocks,
size_t  padding = 0 
)
Parameters
paddingextra allocation can work around a soxr library bug
Precondition
blockSize > 0
nBlocks > 0
Postcondition
Channels() == nChannels
BlockSize() == blockSize
BufferSize() == blockSize * nBlocks

Definition at line 23 of file AudioGraphBuffers.cpp.

26{
27 Reinit(nChannels, blockSize, nBlocks, padding);
28}
void Reinit(unsigned nChannels, size_t blockSize, size_t nBlocks, size_t padding=0)

Member Function Documentation

◆ Advance()

void AudioGraph::Buffers::Advance ( size_t  count)

Move the positions.

Precondition
count <= Remaining()
Postcondition
Remaining() reduced by count

Definition at line 89 of file AudioGraphBuffers.cpp.

90{
91#ifndef NDEBUG
92 sampleCount oldRemaining = Remaining();
93#endif
94 // Assert the pre
95 assert(count <= Remaining());
96
97#if 1
98 // Bounds checking version not assuming the pre, new in 3.2
99 if (mBuffers.empty())
100 return;
101
102 // First buffer; defend against excessive count
103 auto iterP = mPositions.begin();
104 auto iterB = mBuffers.begin();
105 auto &position = *iterP;
106 auto data = iterB->data();
107 auto end = data + iterB->size();
108 // invariant assumed, and preserved
109 assert(data <= position && position <= end);
110 count = std::min<size_t>(end - position, count);
111 position += count;
112 assert(data <= position && position <= end);
113
114 // other buffers; assuming equal sizes and relative positions (invariants)
115 for (const auto endB = mBuffers.end(); ++iterB != endB;) {
116 auto &position = *++iterP;
117 // invariant assumed, and preserved
118 assert(iterB->data() <= position);
119 assert(position <= iterB->data() + iterB->size());
120
121 position += count;
122
123 assert(iterB->data() <= position);
124 assert(position <= iterB->data() + iterB->size());
125 }
126#else
127 // Version that assumes the precondition,
128 // which pre-3.2 did without known errors
129 for (auto &position : mPositions)
130 position += count;
131#endif
132 // Assert the post
133 assert(Remaining() == oldRemaining - count);
134}
size_t Remaining() const
std::vector< std::vector< float > > mBuffers
std::vector< float * > mPositions
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
const char * end(const char *str) noexcept
Definition: StringUtils.h:106

References details::end().

Referenced by DownmixStage::Acquire(), and EffectStage::FetchProcessAndAdvance().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ BlockSize()

size_t AudioGraph::Buffers::BlockSize ( ) const
inline

◆ BufferSize()

size_t AudioGraph::Buffers::BufferSize ( ) const
inline

Definition at line 51 of file AudioGraphBuffers.h.

51{ return mBufferSize; }

Referenced by DownmixStage::AcceptsBlockSize(), and MixerSource::AcceptsBuffers().

Here is the caller graph for this function:

◆ Channels()

unsigned AudioGraph::Buffers::Channels ( ) const
inline

Definition at line 50 of file AudioGraphBuffers.h.

50{ return mBuffers.size(); }

Referenced by DownmixStage::AcceptsBuffers(), WideSampleSource::AcceptsBuffers(), WaveTrackSink::AcceptsBuffers(), MixerSource::Acquire(), DownmixStage::Acquire(), Mixer::Clear(), WaveTrackSink::DoConsume(), EffectStage::FetchProcessAndAdvance(), EffectStage::Process(), and PerTrackEffect::ProcessPass().

Here is the caller graph for this function:

◆ ClearBuffer()

void AudioGraph::Buffers::ClearBuffer ( unsigned  iChannel,
size_t  n 
)

Zero-fill n places in one of the buffers, starting from its position

Definition at line 168 of file AudioGraphBuffers.cpp.

169{
170 if (iChannel < mPositions.size()) {
171 auto p = mPositions[iChannel];
172 auto &buffer = mBuffers[iChannel];
173 auto end = buffer.data() + buffer.size();
174 p = std::min(end, p);
175 n = std::min<size_t>(end - p, n);
176 std::fill(p, p + n, 0);
177 }
178}
int min(int a, int b)

References details::end(), anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, and min().

Referenced by DownmixStage::Acquire(), Mixer::Clear(), and PerTrackEffect::ProcessPass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Discard()

void AudioGraph::Buffers::Discard ( size_t  drop,
size_t  keep 
)

Discard some data at the (unchanging) positions.

Parameters
drophow many values to discard
keephow many following values are defined
Precondition
drop + keep <= Remaining()
Postcondition
Remaining() is unchanged

Definition at line 46 of file AudioGraphBuffers.cpp.

47{
48#ifndef NDEBUG
49 sampleCount oldRemaining = Remaining();
50#endif
51 // Assert the pre
52 assert(drop + keep <= Remaining());
53
54#if 1
55 // Bounds checking version not assuming the pre, new in 3.2
56 if (mBuffers.empty())
57 return;
58
59 // First buffer
60 auto iterP = mPositions.begin();
61 auto iterB = mBuffers.begin();
62 auto position = *iterP;
63 auto data = iterB->data();
64 auto end = data + iterB->size();
65
66 // Defend against excessive input values
67 end = std::max(data, std::min(end, position + drop + keep));
68 position = std::min(end, position);
69 drop = std::min<size_t>(end - position, drop);
70 // i.e. usually keep * sizeof(float) :
71 const size_t size = ((end - position) - drop) * sizeof(float);
72 memmove(position, position + drop, size);
73
74 // other buffers; assuming equal sizes and relative positions (invariants)
75 for (const auto endB = mBuffers.end(); ++iterB != endB;) {
76 position = *++iterP;
77 memmove(position, position + drop, size);
78 }
79#else
80 // Version that assumes the precondition,
81 // which pre-3.2 did without known errors
82 for (auto position : mPositions)
83 memmove(position, position + drop, keep * sizeof(float));
84#endif
85 // Assert the post
86 assert(oldRemaining == Remaining());
87}

References details::end(), min(), and size.

Referenced by EffectStage::Acquire().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetReadPosition()

constSamplePtr AudioGraph::Buffers::GetReadPosition ( unsigned  iChannel) const

Get accumulated data for one channel.

Last channel is replicated for all greater indices

Precondition
Channels() > 0
BufferSize() > 0
Postcondition
result: result != nullptr

Definition at line 155 of file AudioGraphBuffers.cpp.

156{
158 auto buffer = mBuffers[iChannel].data();
159 return reinterpret_cast<constSamplePtr>(buffer);
160}
const char * constSamplePtr
Definition: SampleFormat.h:58
unsigned Channels() const

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel, and min().

Referenced by DownmixStage::Acquire(), WaveTrackSink::DoConsume(), and Mixer::Process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetWritePosition()

float & AudioGraph::Buffers::GetWritePosition ( unsigned  iChannel)

Get writable position for one channel.

Precondition
iChannel < Channels()
BufferSize() > 0

Definition at line 162 of file AudioGraphBuffers.cpp.

163{
164 assert(iChannel < Channels());
165 return mBuffers[iChannel].data()[ Position() ];
166}
size_t Position() const

References anonymous_namespace{StretchingSequenceIntegrationTest.cpp}::iChannel.

Referenced by MixerSource::Acquire(), WideSampleSource::Acquire(), EffectStage::FetchProcessAndAdvance(), and anonymous_namespace{DownmixStage.cpp}::MixBuffers().

Here is the caller graph for this function:

◆ IsRewound()

bool AudioGraph::Buffers::IsRewound ( ) const
inline

Definition at line 59 of file AudioGraphBuffers.h.

59{ return BufferSize() == Remaining(); }
size_t BufferSize() const

References BufferSize.

Referenced by Buffers().

Here is the caller graph for this function:

◆ Position()

size_t AudioGraph::Buffers::Position ( ) const
inline

Definition at line 53 of file AudioGraphBuffers.h.

53 {
54 return mBuffers.empty() ? 0
55 : Positions()[0]
56 - reinterpret_cast<const float*>(GetReadPosition(0));
57 }
constSamplePtr GetReadPosition(unsigned iChannel) const
Get accumulated data for one channel.
float *const * Positions() const
Get array of positions in the buffers.

Referenced by WaveTrackSink::DoConsume().

Here is the caller graph for this function:

◆ Positions()

float *const * AudioGraph::Buffers::Positions ( ) const
inline

Get array of positions in the buffers.

Definition at line 72 of file AudioGraphBuffers.h.

72{ return mPositions.data(); }

Referenced by EffectStage::Process().

Here is the caller graph for this function:

◆ Reinit()

void AudioGraph::Buffers::Reinit ( unsigned  nChannels,
size_t  blockSize,
size_t  nBlocks,
size_t  padding = 0 
)
Parameters
paddingextra allocation can work around a soxr library bug
Precondition
blockSize > 0
nBlocks > 0
Postcondition
Channels() == nChannels
BlockSize() == blockSize
BufferSize() == blockSize * nBlocks

Definition at line 30 of file AudioGraphBuffers.cpp.

32{
33 assert(blockSize > 0);
34 assert(nBlocks > 0);
35 mBuffers.resize(nChannels);
36 mPositions.resize(nChannels);
37 const auto bufferSize = blockSize * nBlocks;
38 for (auto &buffer : mBuffers)
39 // Guarantee initial zeroes (needed at least in last buffer sometimes)
40 buffer.resize(bufferSize + padding, 0.0f);
41 mBufferSize = bufferSize;
42 mBlockSize = blockSize;
43 Rewind();
44}
void Rewind()
Reset positions to starts of buffers.

Referenced by PerTrackEffect::ProcessPass().

Here is the caller graph for this function:

◆ Remaining()

size_t AudioGraph::Buffers::Remaining ( ) const
inline

Definition at line 58 of file AudioGraphBuffers.h.

58{ return BufferSize() - Position(); }

References BufferSize.

Referenced by WaveTrackSink::Acquire(), EffectStage::Acquire(), MixerSource::Acquire(), WideSampleSource::Acquire(), WaveTrackSink::DoConsume(), and EffectStage::FetchProcessAndAdvance().

Here is the caller graph for this function:

◆ Rewind()

void AudioGraph::Buffers::Rewind ( )

Reset positions to starts of buffers.

Postcondition
IsRewound()

Definition at line 136 of file AudioGraphBuffers.cpp.

137{
138 auto iterP = mPositions.begin();
139 for (auto &buffer : mBuffers)
140 *iterP++ = buffer.data();
141 assert(IsRewound());
142}

Referenced by WaveTrackSink::DoConsume(), EffectStage::EffectStage(), EffectStage::FetchProcessAndAdvance(), and PerTrackEffect::ProcessPass().

Here is the caller graph for this function:

◆ Rotate()

size_t AudioGraph::Buffers::Rotate ( )

Shift all data at and after the old position to position 0.

Returns
how many positions were shifted; other contents are unspecified
Postcondition
IsRewound()

Definition at line 144 of file AudioGraphBuffers.cpp.

145{
146 auto oldRemaining = Remaining();
147 Rewind();
148 const auto free = BufferSize() - oldRemaining;
149 // Shift any partial block of unread data leftward
150 Discard(free, oldRemaining);
151 assert(IsRewound());
152 return oldRemaining;
153}
void Discard(size_t drop, size_t keep)
Discard some data at the (unchanging) positions.
void free(void *ptr)
Definition: VectorOps.h:34

References BufferSize, and staffpad::vo::free().

Referenced by DownmixStage::Acquire(), and EffectStage::FetchProcessAndAdvance().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ mBlockSize

size_t AudioGraph::Buffers::mBlockSize { 0 }
private

Definition at line 122 of file AudioGraphBuffers.h.

◆ mBuffers

std::vector<std::vector<float> > AudioGraph::Buffers::mBuffers
private

Definition at line 119 of file AudioGraphBuffers.h.

◆ mBufferSize

size_t AudioGraph::Buffers::mBufferSize { 0 }
private

Definition at line 121 of file AudioGraphBuffers.h.

◆ mPositions

std::vector<float *> AudioGraph::Buffers::mPositions
private

Definition at line 120 of file AudioGraphBuffers.h.


The documentation for this class was generated from the following files: