25 return std::make_shared<RealtimeEffectManager>(project);
75 const Track &track,
unsigned chans,
float rate)
77 auto leader = *track.
GetOwner()->FindLeader(&track);
81 mRates.insert({leader, rate});
85 scope.mInstances.push_back(state.
AddTrack(*leader, chans, rate));
96 mLatency = std::chrono::microseconds(0);
125 float *
const *buffers,
float *
const *scratch,
float *
const dummy,
126 unsigned nBuffers,
size_t numSamples)
135 auto start = std::chrono::steady_clock::now();
139 static_cast<float **
>(alloca(nBuffers *
sizeof(
float *)));
141 static_cast<float **
>(alloca(nBuffers *
sizeof(
float *)));
145 for (
unsigned int i = 0; i < nBuffers; i++) {
146 ibuf[i] = buffers[i];
147 obuf[i] = scratch[i];
154 size_t discardable = 0;
159 state.
Process(track, nBuffers, ibuf, obuf, dummy, numSamples);
160 for (
auto i = 0; i < nBuffers; ++i)
171 for (
unsigned int i = 0; i < nBuffers; i++)
172 memcpy(buffers[i], ibuf[i], numSamples *
sizeof(
float));
175 auto end = std::chrono::steady_clock::now();
176 mLatency = std::chrono::duration_cast<std::chrono::microseconds>(
end - start);
198 : mpManager{ pManager }
210 : mpManager{ other.mpManager }
212 other.mpManager =
nullptr;
218 if (
this != &other) {
220 mpManager = other.mpManager;
221 other.mpManager =
nullptr;
232 for (
auto leader : mpManager->mGroupLeaders)
238std::shared_ptr<RealtimeEffectState>
246 auto &state = *pNewState;
249 auto pInstance = state.Initialize(pScope->
mSampleRate);
254 if (pLeader && pLeader != leader)
256 auto rate =
mRates[leader];
259 if (pInstance2 != pInstance)
267std::pair<Track *, RealtimeEffectList &>
288 if (!states.AddState(pState))
292 pLeader ? pLeader->shared_from_this() :
nullptr
302 auto pOldState = states.GetStateAt(index);
310 if (!states.ReplaceState(index, pNewState))
313 pOldState->Finalize();
316 pLeader ? pLeader->shared_from_this() :
nullptr
323 Track *pTrack,
const std::shared_ptr<RealtimeEffectState> pState)
328 states.RemoveState(pState);
333 pLeader ? pLeader->shared_from_this() :
nullptr
338 Track *pTrack,
const std::shared_ptr<RealtimeEffectState> &pState)
const
341 return states.FindState(pState);
346auto RealtimeEffectManager::GetLatency() const ->
Latency
static TransactionScope::Factory::Scope scope
static const AttachedProjectObjects::RegisteredFactory manager
declares abstract base class Track, TrackList, and iterators over TrackList
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
CallbackReturn Publish(const RealtimeEffectManagerMessage &message)
Send a message to connected callbacks.
static RealtimeEffectList & Get(AudacityProject &project)
AudacityProject & mProject
std::shared_ptr< RealtimeEffectState > AddState(RealtimeEffects::InitializationScope *pScope, Track *pTrack, const PluginID &id)
Main thread appends a global or per-track effect.
std::optional< size_t > FindState(Track *pTrack, const std::shared_ptr< RealtimeEffectState > &pState) const
Report the position of a state in the global or a per-track list.
std::unordered_map< const Track *, double > mRates
void VisitAll(const StateVisitor &func)
Visit the per-project states first, then all tracks from AddTrack.
RealtimeEffectManager(AudacityProject &project)
void SetSuspended(bool value)
To be called only from main thread.
static RealtimeEffectManager & Get(AudacityProject &project)
void Initialize(RealtimeEffects::InitializationScope &scope, double sampleRate)
Main thread begins to define a set of tracks for playback.
void ProcessStart(bool suspended)
size_t Process(bool suspended, const Track &track, float *const *buffers, float *const *scratch, float *dummy, unsigned nBuffers, size_t numSamples)
bool IsActive() const noexcept
To be called only from main thread.
void Finalize() noexcept
Main thread cleans up after playback.
std::shared_ptr< RealtimeEffectState > ReplaceState(RealtimeEffects::InitializationScope *pScope, Track *pTrack, size_t index, const PluginID &id)
Main thread replaces a global or per-track effect.
void RemoveState(RealtimeEffects::InitializationScope *pScope, Track *pTrack, std::shared_ptr< RealtimeEffectState > pState)
Main thread removes a global or per-track effect.
void ProcessEnd(bool suspended) noexcept
std::vector< const Track * > mGroupLeaders
all are non-null
std::shared_ptr< RealtimeEffectState > MakeNewState(RealtimeEffects::InitializationScope *pScope, Track *pLeader, const PluginID &id)
std::chrono::microseconds Latency
void AddTrack(RealtimeEffects::InitializationScope &scope, const Track &track, unsigned chans, float rate)
void VisitGroup(Track &leader, const StateVisitor &func)
Visit the per-project states first, then states for leader if not null.
std::shared_ptr< EffectInstance > AddTrack(const Track &track, unsigned chans, float sampleRate)
Main thread sets up this state before adding it to lists.
bool ProcessEnd()
Worker thread finishes a batch of samples.
bool Finalize() noexcept
Main thread cleans up playback.
bool ProcessStart(bool running)
Worker thread begins a batch of samples.
size_t Process(const Track &track, unsigned chans, const float *const *inbuf, float *const *outbuf, float *dummybuf, size_t numSamples)
Worker thread processes part of a batch of samples.
std::shared_ptr< EffectInstance > Initialize(double rate)
Main thread sets up for playback.
Brackets processing setup and cleanup in the main thread.
std::vector< std::shared_ptr< EffectInstance > > mInstances
unsigned mNumPlaybackChannels
Abstract base class for an object holding data associated with points on a time axis.
std::shared_ptr< TrackList > GetOwner() const
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
std::pair< Track *, RealtimeEffectList & > FindStates(AudacityProject &project, Track *pTrack)
AllListsLock(RealtimeEffectManager *pManager=nullptr)
RealtimeEffectManager * mpManager
AllListsLock & operator=(AllListsLock &&other)
static std::shared_ptr< RealtimeEffectState > make_shared(Args &&...args)