1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
/**********************************************************************
Audacity: A Digital Audio Editor
PerTrackEffect.h
Dominic Mazzoni
Vaughan Johnson
Paul Licameli split from Effect.h
**********************************************************************/
#ifndef __AUDACITY_PER_TRACK_EFFECT__
#define __AUDACITY_PER_TRACK_EFFECT__
#include "AudioGraphSink.h" // to inherit
#include "AudioGraphSource.h" // to inherit
#include "Effect.h" // to inherit
#include "MemoryX.h"
#include "SampleCount.h"
#include <functional>
#include <memory>
class EffectOutputTracks;
class SampleTrack;
//! Base class for Effects that treat each (mono or stereo) track independently
//! of other tracks.
/*!
Its override of Effect::Process() uses ProcessInitialize(),
ProcessBlock(), and ProcessFinalize() methods of its instance made by
MakeInstance(), which must be a subclass of PerTrackEffect::Instance.
Also uses GetLatency() to determine how many leading output samples to
discard and how many extra samples to produce.
*/
class EFFECTS_API PerTrackEffect
: public Effect
{
public:
~PerTrackEffect() override;
class EFFECTS_API Instance : public virtual EffectInstanceEx {
public:
explicit Instance(const PerTrackEffect &processor)
: mProcessor{ processor }
{}
~Instance() override;
//! Uses the other virtual functions of this class
bool Process(EffectSettings &settings) final;
bool ProcessInitialize(EffectSettings &settings,
double sampleRate, ChannelNames chanMap) override;
bool ProcessFinalize() noexcept override;
protected:
const PerTrackEffect &mProcessor;
};
protected:
// These were overridables but the generality wasn't used yet
/* virtual */ bool DoPass1() const;
/* virtual */ bool DoPass2() const;
// non-virtual
bool Process(EffectInstance &instance, EffectSettings &settings) const;
sampleCount mSampleCnt{};
// Pre-compute the output track list
std::shared_ptr<EffectOutputTracks> MakeOutputTracks();
// Clean up unnecessary output track list
void DestroyOutputTracks() const;
private:
using Buffers = AudioGraph::Buffers;
bool ProcessPass(TrackList &outputs,
Instance &instance, EffectSettings &settings);
using Factory = std::function<std::shared_ptr<EffectInstance>()>;
/*!
Previous contents of inBuffers and outBuffers are ignored
@param channel selects one channel if non-negative; else all channels
@pre `source.AcceptsBuffers(inBuffers)`
@pre `source.AcceptsBlockSize(inBuffers.BlockSize())`
@pre `sink.AcceptsBuffers(outBuffers)`
@pre `inBuffers.BlockSize() == outBuffers.BlockSize()`
@pre `channel < track.NChannels()`
*/
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);
// TODO: put this in struct EffectContext? (Which doesn't exist yet)
mutable std::shared_ptr<EffectOutputTracks> mpOutputTracks;
};
#endif
|