72 std::optional<EffectOutputTracks> outputs;
77 bool bGoodResult =
true;
80 auto &myInstance =
dynamic_cast<Instance&
>(instance);
81 bGoodResult = pThis->ProcessPass(pOutputs->Get(), myInstance,
settings);
84 bGoodResult = pThis->ProcessPass(pOutputs->Get(), myInstance,
settings);
95 const auto duration =
settings.extra.GetDuration();
96 bool bGoodResult =
true;
102 size_t prevBufferSize = 0;
114 std::vector<std::shared_ptr<EffectInstance>> recycledInstances{
117 std::dynamic_pointer_cast<EffectInstanceEx>(instance.shared_from_this())
120 const bool multichannel = numAudioIn > 1;
123 const auto waveTrackVisitor =
132 const int channel = (multichannel ? -1 :
iChannel++);
135 assert(numAudioIn > 1);
136 if (numChannels == 2) {
138 pRight = (*wt.
Channels().rbegin()).get();
146 if (len > 0 && numAudioIn < 1) {
159 if (blockSize == 0) {
166 const auto bufferSize =
167 ((max + (blockSize - 1)) / blockSize) * blockSize;
168 if (bufferSize == 0) {
179 assert(numAudioIn > 0);
184 std::max(1u, numAudioIn),
186 std::max<size_t>(1, bufferSize / blockSize));
191 if (prevBufferSize != bufferSize) {
195 for (
size_t i = 2; i < numAudioIn; i++)
198 prevBufferSize = bufferSize;
205 assert(numAudioOut > 0);
206 outBuffers.
Reinit(numAudioOut, blockSize,
207 (bufferSize / blockSize) + 1);
215 if (!pRight && !clear && numAudioIn > 1) {
220 const auto genLength = [
this, &
settings, &wt, isGenerator](
221 ) -> std::optional<sampleCount> {
224 const auto duration =
settings.extra.GetDuration();
226 gPrefs->
Read(
wxT(
"/AudioIO/EffectsPreviewLen"), &genDur, 6.0);
232 return sampleCount{ (wt.GetRate() * genDur) + 0.5 };
238 const auto pollUser = [
this, numChannels, count, start,
239 length = (genLength ? *genLength : len).as_double()
241 if (numChannels > 1) {
243 count, (inPos - start).as_double() / length)
248 if (
TrackProgress(count, (inPos - start).as_double() / length))
255 assert(len == 0 || inBuffers.
Channels() > 0);
258 if (len == 0 && genLength)
264 *pSeq, size_t(pRight ? 2 : 1), start, len, pollUser };
266 assert(source.AcceptsBuffers(inBuffers));
267 assert(source.AcceptsBlockSize(inBuffers.
BlockSize()));
273 (pRight && isGenerator) ? wt.EmptyCopy() :
nullptr;
275 (!pRight && isGenerator) ? wt.EmptyCopy(1) :
nullptr;
276 const auto pGenerated = wideTrack
280 WaveTrackSink sink{ chan, pRight, pGenerated.get(), start, isProcessor,
283 assert(sink.AcceptsBuffers(outBuffers));
287 [
this, &recycledInstances, counter = 0]()
mutable {
288 auto index = counter++;
289 if (index < recycledInstances.size())
290 return recycledInstances[index];
295 genLength,
sampleRate, wt, inBuffers, outBuffers);
297 sink.Flush(outBuffers);
298 bGoodResult = sink.IsOk();
299 if (bGoodResult && pGenerated) {
303 results->Add(pGenerated);
304 if (!multichannel && !isFirst && narrowTrack) {
309 static_cast<WaveTrack*
>(*std::next(results->rbegin()));
319 const auto defaultTrackVisitor =
322 t.SyncLockAdjust(
mT1,
mT0 + duration);
325 outputs.
Any().VisitWhile(bGoodResult,
326 [&](
auto &&fallthrough){
return [&](
WaveTrack &wt) {
328 return fallthrough();
329 const auto channels = wt.
Channels();
331 waveTrackVisitor(wt, **channels.begin(),
true);
334 for (
const auto pChannel : channels) {
335 waveTrackVisitor(wt, *pChannel, first);
342 mT0 + (*results->begin())->GetEndTime() };
344 static_cast<WaveTrack&
>(*results->DetachFirst()),
345 true,
true, &warper);
361 std::optional<sampleCount> genLength,
368 const auto blockSize = inBuffers.
BlockSize();
370 assert(blockSize == outBuffers.
BlockSize());
377 assert(pSource->AcceptsBlockSize(blockSize));
378 assert(pSource->AcceptsBuffers(outBuffers));
381 return task.RunLoop();
unsigned MakeChannelMap(int nChannels, int channel, ChannelName map[3])
audacity::BasicSettings * gPrefs
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper,...
std::shared_ptr< TrackList > TrackListHolder
static Settings & settings()
Accumulates (non-interleaved) data during effect processing.
void Rewind()
Reset positions to starts of buffers.
void Reinit(unsigned nChannels, size_t blockSize, size_t nBlocks, size_t padding=0)
unsigned Channels() const
void ClearBuffer(unsigned iChannel, size_t n)
Downstream receiver of sample streams, taking Buffers as external context.
virtual bool AcceptsBuffers(const Buffers &buffers) const =0
Upstream producer of sample streams, taking Buffers as external context.
virtual bool AcceptsBlockSize(size_t blockSize) const =0
virtual bool AcceptsBuffers(const Buffers &buffers) const =0
bool IsPreviewing() const
std::shared_ptr< TrackList > mTracks
const AudacityProject * FindProject() const
virtual EffectType GetType() const =0
Type determines how it behaves.
bool TrackGroupProgress(int whichGroup, double frac, const TranslatableString &={}) const
void GetBounds(const WaveTrack &track, sampleCount *start, sampleCount *len)
double CalcPreviewInputLength(const EffectSettings &settings, double previewLength) const override
Default implementation returns previewLength
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
virtual std::shared_ptr< EffectInstance > MakeInstance() const =0
Make an object maintaining short-term state of an Effect.
Performs effect computation.
virtual unsigned GetAudioInCount() const =0
How many input buffers to allocate at once.
virtual size_t SetBlockSize(size_t maxBlockSize)=0
virtual bool NeedsDither() const
virtual unsigned GetAudioOutCount() const =0
How many output buffers to allocate at once.
std::pair< double, double > TimeInterval
static std::unique_ptr< EffectStage > Create(int channel, int nInputChannels, Source &upstream, Buffers &inBuffers, const Factory &factory, EffectSettings &settings, double sampleRate, std::optional< sampleCount > genLength)
Satisfies postcondition of constructor or returns null.
Unit slope but with either a jump (pasting more) or a flat interval (pasting less)
bool ProcessFinalize() noexcept override
bool ProcessInitialize(EffectSettings &settings, double sampleRate, ChannelNames chanMap) override
bool Process(EffectSettings &settings) final
Uses the other virtual functions of this class.
const PerTrackEffect & mProcessor
Base class for many of the effects in Audacity.
std::shared_ptr< EffectOutputTracks > mpOutputTracks
void DestroyOutputTracks() const
bool ProcessPass(TrackList &outputs, Instance &instance, EffectSettings &settings)
std::shared_ptr< EffectOutputTracks > MakeOutputTracks()
bool Process(EffectInstance &instance, EffectSettings &settings) const
~PerTrackEffect() override
static bool ProcessTrack(int channel, const Factory &factory, EffectSettings &settings, AudioGraph::Source &source, AudioGraph::Sink &sink, std::optional< sampleCount > genLength, double sampleRate, const SampleTrack &wt, Buffers &inBuffers, Buffers &outBuffers)
std::function< std::shared_ptr< EffectInstance >()> Factory
static bool IsSyncLockSelected(const Track &track)
Abstract base class for an object holding data associated with points on a time axis.
bool GetSelected() const
Selectedness is always the same for all channels of a group.
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
auto Any() -> TrackIterRange< TrackType >
static TrackListHolder Temporary(AudacityProject *pProject, const Track::Holder &pTrack={})
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
A Track that contains audio waveform data.
void ZipClips(bool mustAlign=true)
double GetRate() const override
size_t NChannels() const override
A constant property.
size_t GetMaxBlockSize() const
void ClearAndPaste(double t0, double t1, const WaveTrack &src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=nullptr, bool clearByTrimming=false)
sampleCount TimeToLongSamples(double t0) const
Adapts WideSampleSequence to the interface AudioGraph::Source.
virtual bool Read(const wxString &key, bool *value) const =0
Positions or offsets within audio files need a wide type.
constexpr auto sampleRate
Copies from a Source to a Sink, mediated by Buffers.
Externalized state of a plug-in.