Audacity 3.2.0
WideSampleSource.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 @file WideSampleSource.cpp
6
7 Dominic Mazzoni
8 Vaughan Johnson
9 Martyn Shaw
10
11 Paul Licameli split from PerTrackEffect.cpp
12
13*******************************************************************//*******************************************************************/
19#include "WideSampleSource.h"
20
21#include "AudioGraphBuffers.h"
22#include "WideSampleSequence.h"
23#include <cassert>
24
26 size_t nChannels, sampleCount start, sampleCount len, Poller pollUser
27) : mSequence{ sequence }, mnChannels{ nChannels }, mPollUser{ move(pollUser) }
28 , mPos{ start }, mOutputRemaining{ len }
29{
30 assert(nChannels <= sequence.NChannels());
31}
32
34
35bool WideSampleSource::AcceptsBuffers(const Buffers &buffers) const
36{
37 return mOutputRemaining == 0 || buffers.Channels() > 0;
38}
39
41{
42 return true;
43}
44
46{
47 return std::max<sampleCount>(0, mOutputRemaining);
48}
49
50#define stackAllocate(T, count) static_cast<T*>(alloca(count * sizeof(T)))
51
52std::optional<size_t> WideSampleSource::Acquire(Buffers &data, size_t bound)
53{
54 assert(bound <= data.BlockSize());
55 assert(data.BlockSize() <= data.Remaining());
56 assert(AcceptsBuffers(data));
57 assert(AcceptsBlockSize(data.BlockSize()));
58
59 if (!mInitialized || mFetched < bound) {
60 // Need to fill sufficent data in the buffers
61 // Calculate the number of samples to get
62 const auto fetch =
64 // guarantees write won't overflow
65 assert(mFetched + fetch <= data.Remaining());
66 // Fill the buffers
67 auto buffers = stackAllocate(float *, mnChannels);
68 if (mnChannels > 0)
69 buffers[0] = &data.GetWritePosition(0) + mFetched;
70 if (mnChannels > 1)
71 buffers[1] = &data.GetWritePosition(1) + mFetched;
72 mSequence.GetFloats(0, mnChannels, buffers, mPos, fetch);
73 mPos += fetch;
74 mFetched += fetch;
75 mInitialized = true;
76 }
77 assert(data.Remaining() > 0);
78 auto result = mLastProduced = std::min(bound,
80 // assert post
81 assert(result <= bound);
82 assert(result <= data.Remaining());
83 assert(result <= Remaining());
84 // true because the three terms of the min would be positive
85 assert(bound == 0 || Remaining() == 0 || result > 0);
86 return { result };
87}
88
90{
93 mLastProduced = 0;
94 assert(mOutputRemaining >= 0);
95 return !mPollUser || mPollUser(mPos);
96}
int min(int a, int b)
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
#define stackAllocate(T, count)
Accumulates (non-interleaved) data during effect processing.
size_t BlockSize() const
float & GetWritePosition(unsigned iChannel)
Get writable position for one channel.
size_t Remaining() const
unsigned Channels() const
bool GetFloats(size_t iChannel, size_t nBuffers, float *const buffers[], sampleCount start, size_t len, bool backwards=false, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
virtual size_t NChannels() const =0
A constant property.
const WideSampleSequence & mSequence
bool AcceptsBlockSize(size_t blockSize) const override
Always true.
~WideSampleSource() override
std::optional< size_t > Acquire(Buffers &data, size_t bound) override
Occupy vacant space in Buffers with some data.
const Poller mPollUser
bool AcceptsBuffers(const Buffers &buffers) const override
sampleCount mOutputRemaining
std::function< bool(sampleCount blockSize)> Poller
Type of function returning false if user cancels progress.
bool Release() override
Can test for user cancellation.
sampleCount Remaining() const override
Result includes any amount Acquired and not yet Released.
const size_t mnChannels
WideSampleSource(const WideSampleSequence &sequence, size_t nChannels, sampleCount start, sampleCount len, Poller pollUser)
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19