Audacity 3.2.0
Typedefs | Functions | Variables
MixAndRender.cpp File Reference
#include "MixAndRender.h"
#include "BasicUI.h"
#include "Mix.h"
#include "RealtimeEffectList.h"
#include "StretchingSequence.h"
#include "WaveTrack.h"
#include "RealtimeEffectState.h"
#include "Project.h"
Include dependency graph for MixAndRender.cpp:

Go to the source code of this file.

Typedefs

using WaveTrackConstArray = std::vector< std::shared_ptr< const WaveTrack > >
 

Functions

Track::Holder MixAndRender (const TrackIterRange< const WaveTrack > &trackRange, const Mixer::WarpOptions &warpOptions, const wxString &newTrackName, WaveTrackFactory *trackFactory, double rate, sampleFormat format, double startTime, double endTime)
 Mixes together all input tracks, applying any envelopes, per-track real-time effects, volume, panning and real-time effects in the process. More...
 
template<typename Host >
std::vector< MixerOptions::StageSpecificationGetEffectStagesImpl (const Host &host)
 
std::vector< MixerOptions::StageSpecificationGetEffectStages (const WaveTrack &track)
 
std::vector< MixerOptions::StageSpecificationGetMasterEffectStages (const AudacityProject &project)
 

Variables

static ProjectFileIORegistry::ObjectReaderEntry projectAccessor
 
static ProjectFileIORegistry::ObjectWriterEntry projectWriter
 
static WaveTrackIORegistry::ObjectReaderEntry waveTrackAccessor
 
static WaveTrackIORegistry::ObjectWriterEntry waveTrackWriter
 

Typedef Documentation

◆ WaveTrackConstArray

using WaveTrackConstArray = std::vector < std::shared_ptr < const WaveTrack > >

Definition at line 19 of file MixAndRender.cpp.

Function Documentation

◆ GetEffectStages()

std::vector< MixerOptions::StageSpecification > GetEffectStages ( const WaveTrack track)

Definition at line 196 of file MixAndRender.cpp.

197{
198 return GetEffectStagesImpl(track);
199}
std::vector< MixerOptions::StageSpecification > GetEffectStagesImpl(const Host &host)

References GetEffectStagesImpl().

Referenced by ExportPluginHelpers::CreateMixer(), MixAndRender(), and StereoToMono::ProcessOne().

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

◆ GetEffectStagesImpl()

template<typename Host >
std::vector< MixerOptions::StageSpecification > GetEffectStagesImpl ( const Host &  host)

Definition at line 172 of file MixAndRender.cpp.

173{
174 auto &effects = RealtimeEffectList::Get(host);
175 if (!effects.IsActive())
176 return {};
177 std::vector<MixerOptions::StageSpecification> result;
178 for (size_t i = 0, count = effects.GetStatesCount(); i < count; ++i) {
179 const auto pState = effects.GetStateAt(i);
180 if (!pState->IsEnabled())
181 continue;
182 const auto pEffect = pState->GetEffect();
183 if (!pEffect)
184 continue;
185 const auto &settings = pState->GetSettings();
186 if (!settings.has_value())
187 continue;
188 auto &stage = result.emplace_back(MixerOptions::StageSpecification{
189 [pEffect]{ return pEffect->MakeInstance(); },
190 settings });
191 }
192 return result;
193}
static Settings & settings()
Definition: TrackInfo.cpp:51
static RealtimeEffectList & Get(AudacityProject &project)

References RealtimeEffectList::Get(), and settings().

Referenced by GetEffectStages(), and GetMasterEffectStages().

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

◆ GetMasterEffectStages()

std::vector< MixerOptions::StageSpecification > GetMasterEffectStages ( const AudacityProject project)

Definition at line 202 of file MixAndRender.cpp.

203{
205}
const auto project

References GetEffectStagesImpl(), and project.

Referenced by ExportPluginHelpers::CreateMixer().

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

◆ MixAndRender()

Track::Holder MixAndRender ( const TrackIterRange< const WaveTrack > &  trackRange,
const Mixer::WarpOptions warpOptions,
const wxString &  newTrackName,
WaveTrackFactory factory,
double  rate,
sampleFormat  format,
double  startTime,
double  endTime 
)

Mixes together all input tracks, applying any envelopes, per-track real-time effects, volume, panning and real-time effects in the process.

Takes one or more tracks as input; of all the WaveTracs, it mixes together all input tracks, applying any envelopes, per-track real-time effects, volume, panning and real-time effects in the process. The resulting pair of tracks (stereo) are "rendered" and have no effects, volume, panning, or envelopes. Other sorts of tracks are ignored. If the start and end times passed are the same this is taken as meaning no explicit time range to process, and the whole occupied length of the input tracks is processed.

Channel group properties of the result are copied from the first input track, except that newTrackName is applied when more than one track is mixed.

Parameters
newTrackNameused only when there is more than one input track (one mono channel or a stereo pair); else the unique track's name is copied

Definition at line 22 of file MixAndRender.cpp.

28{
29 if (trackRange.empty())
30 return {};
31
32 // This function was formerly known as "Quick Mix".
33 bool mono = false; /* flag if output can be mono without losing anything*/
34 bool oneinput = false; /* flag set to true if there is only one input track
35 (mono or stereo) */
36
37 auto first = *trackRange.begin();
38 assert(first); // because the range is known to be nonempty
39
40 // this only iterates tracks which are relevant to this function, i.e.
41 // selected WaveTracks. The tracklist is (confusingly) the list of all
42 // tracks in the project
43
44 size_t numWaves = 0; /* number of wave tracks in the selection */
45 size_t numMono = 0; /* number of mono, centre-panned wave tracks in selection*/
46 for (auto wt : trackRange) {
47 numWaves += wt->NChannels();
48 if (IsMono(*wt) && wt->GetPan() == 0)
49 numMono++;
50 }
51
52 if (numMono == numWaves)
53 mono = true;
54
55 /* the next loop will do two things at once:
56 * 1. build an array of all the wave tracks were are trying to process
57 * 2. determine when the set of WaveTracks starts and ends, in case we
58 * need to work out for ourselves when to start and stop rendering.
59 */
60
61 double mixStartTime = 0.0; /* start time of first track to start */
62 bool gotstart = false; // flag indicates we have found a start time
63 double mixEndTime = 0.0; /* end time of last track to end */
64 double tstart, tend; // start and end times for one track.
65
66 Mixer::Inputs waveArray;
67
68 for (auto wt : trackRange) {
69 const auto stretchingSequence =
70 StretchingSequence::Create(*wt, wt->GetClipInterfaces());
71 waveArray.emplace_back(stretchingSequence, GetEffectStages(*wt));
72 tstart = wt->GetStartTime();
73 tend = wt->GetEndTime();
74 if (tend > mixEndTime)
75 mixEndTime = tend;
76 // try and get the start time. If the track is empty we will get 0,
77 // which is ambiguous because it could just mean the track starts at
78 // the beginning of the project, as well as empty track. The give-away
79 // is that an empty track also ends at zero.
80
81 if (tstart != tend) {
82 // we don't get empty tracks here
83 if (!gotstart) {
84 // no previous start, use this one unconditionally
85 mixStartTime = tstart;
86 gotstart = true;
87 } else if (tstart < mixStartTime)
88 mixStartTime = tstart; // have a start, only make it smaller
89 } // end if start and end are different
90 }
91
92 /* create the destination track (NEW track) */
93 if (numWaves == first->NChannels())
94 oneinput = true;
95 // only one input track (either 1 mono or one linked stereo pair)
96
97 auto mix = trackFactory->Create(mono ? 1 : 2, *first);
98 mix->SetPan(0);
99 mix->SetVolume(1.0f);
100 mix->SetRate(rate);
101 mix->ConvertToSampleFormat(format);
102 if(!oneinput)
103 mix->SetName(newTrackName);
104 mix->MoveTo(mixStartTime);
105
106 auto maxBlockLen = mix->GetIdealBlockSize();
107
108 // If the caller didn't specify a time range, use the whole range in which
109 // any input track had clips in it.
110 if (startTime == endTime) {
111 startTime = mixStartTime;
112 endTime = mixEndTime;
113 }
114
115 Mixer mixer(
116 std::move(waveArray), std::nullopt,
117 // Throw to abort mix-and-render if read fails:
118 true, warpOptions, startTime, endTime, mono ? 1 : 2, maxBlockLen, false,
119 rate, format);
120
121 using namespace BasicUI;
122 auto updateResult = ProgressResult::Success;
123 {
124 auto effectiveFormat = mixer.EffectiveFormat();
125 auto pProgress = MakeProgress(XO("Mix and Render"),
126 XO("Mixing and rendering tracks"));
127
128 while (updateResult == ProgressResult::Success) {
129 auto blockLen = mixer.Process();
130
131 if (blockLen == 0)
132 break;
133
134 for(auto channel : mix->Channels())
135 {
136 auto buffer = mixer.GetBuffer(channel->GetChannelIndex());
137 channel->AppendBuffer(buffer, format, blockLen, 1, effectiveFormat);
138 }
139
140 updateResult = pProgress->Poll(
141 mixer.MixGetCurrentTime() - startTime, endTime - startTime);
142 }
143 }
144 mix->Flush();
145 if (updateResult == ProgressResult::Cancelled ||
146 updateResult == ProgressResult::Failed)
147 return {};
148 else {
149#if 0
150 int elapsedMS = wxGetElapsedTime();
151 double elapsedTime = elapsedMS * 0.001;
152 double maxTracks = totalTime / (elapsedTime / numWaves);
153
154 // Note: these shouldn't be translated - they're for debugging
155 // and profiling only.
156 wxPrintf(" Tracks: %d\n", numWaves);
157 wxPrintf(" Mix length: %f sec\n", totalTime);
158 wxPrintf("Elapsed time: %f sec\n", elapsedTime);
159 wxPrintf("Max number of tracks to mix in real time: %f\n", maxTracks);
160#endif
162 }
163
164 return mix;
165}
XO("Cut/Copy/Paste")
std::vector< MixerOptions::StageSpecification > GetEffectStages(const WaveTrack &track)
Functions for doing the mixdown of the tracks.
Definition: Mix.h:31
std::vector< Input > Inputs
Definition: Mix.h:49
void Clear()
Use only in the main thread. Sends Remove messages.
static std::shared_ptr< StretchingSequence > Create(const PlayableSequence &, const ClipConstHolders &clips)
std::shared_ptr< WaveTrack > Create()
Creates an unnamed empty WaveTrack with default sample format and default rate.
Definition: WaveTrack.cpp:391
bool IsMono(const Channel &channel)
Whether the channel is mono.
std::unique_ptr< ProgressDialog > MakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flags=(ProgressShowStop|ProgressShowCancel), const TranslatableString &remainingLabelText={})
Create and display a progress dialog.
Definition: BasicUI.h:302
bool empty() const
Definition: IteratorX.h:58
Iterator begin() const
Definition: IteratorX.h:52

References IteratorRange< Iterator >::begin(), BasicUI::Cancelled, RealtimeEffectList::Clear(), WaveTrackFactory::Create(), StretchingSequence::Create(), Mixer::EffectiveFormat(), IteratorRange< Iterator >::empty(), BasicUI::Failed, anonymous_namespace{ExportPCM.cpp}::format, RealtimeEffectList::Get(), Mixer::GetBuffer(), GetEffectStages(), AudioGraph::IsMono(), BasicUI::MakeProgress(), Mixer::MixGetCurrentTime(), Mixer::Process(), BasicUI::Success, and XO().

Referenced by anonymous_namespace{TrackMenus.cpp}::DoMixAndRender(), EffectPreview(), and WaveTrackMenuTable::OnMergeStereo().

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

Variable Documentation

◆ projectAccessor

Initial value:
{
}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static const std::string & XMLTag()

Definition at line 219 of file MixAndRender.cpp.

◆ projectWriter

Initial value:
{
[](const AudacityProject &project, XMLWriter &xmlFile){
} }
void WriteXML(XMLWriter &xmlFile) const
Use only in the main thread, to avoid races.
Base class for XMLFileWriter and XMLStringWriter that provides the general functionality for creating...
Definition: XMLWriter.h:25

Definition at line 224 of file MixAndRender.cpp.

◆ waveTrackAccessor

WaveTrackIORegistry::ObjectReaderEntry waveTrackAccessor
static
Initial value:
{
[](WaveTrack &track) { return &RealtimeEffectList::Get(track); }
}
A Track that contains audio waveform data.
Definition: WaveTrack.h:203

Definition at line 229 of file MixAndRender.cpp.

◆ waveTrackWriter

Initial value:
{
[](const WaveTrack &track, auto &xmlFile) {
} }

Definition at line 234 of file MixAndRender.cpp.