MCPcopy Create free account
hub / github.com/audacity/audacity / RebuildJoinedEnvelope

Function RebuildJoinedEnvelope

libraries/lib-wave-track/WaveTrack.cpp:2174–2319  ·  view source on GitHub ↗

Build an envelope for `target` from the visible (play-range) automation points of each clip in `sources`, in order. The audio side of `target` is left untouched; only its envelope is replaced. Boundary preserves are emitted at every clip's play start and play end. At seams between adjacent clips the preserves coincide in time: - if their values agree (within kSeamValueTolerance), the second emiss

Source from the content-addressed store, hash-verified

2172// - if their values disagree, the second emission is appended via raw
2173// Envelope::Insert after the first.
2174void RebuildJoinedEnvelope(
2175 WaveClip& target, const WaveTrack::IntervalHolders& sources, int rate)
2176{
2177 const auto& templateEnv = target.GetEnvelope();
2178 auto rebuilt = std::make_unique<Envelope>(
2179 templateEnv.GetExponential(),
2180 templateEnv.GetMinValue(),
2181 templateEnv.GetMaxValue(),
2182 templateEnv.GetDefaultValue());
2183 rebuilt->SetOffset(target.GetSequenceStartTime());
2184 const double newSeqLen
2185 =target.GetSequenceEndTime() - target.GetSequenceStartTime();
2186 const double sampleDur = 1.0 / rate;
2187 rebuilt->SetTrackLen(newSeqLen, sampleDur);
2188
2189 const double interiorMargin = sampleDur / 2;
2190 // Tolerance for deciding whether two boundary values are the same.
2191 // Matches the constant used inside Envelope.cpp.
2192 constexpr double kSeamValueTolerance = 0.001;
2193 const double offset = rebuilt->GetOffset();
2194
2195 bool hasLast = false;
2196 double lastT = 0.0;
2197 double lastV = 0.0;
2198
2199 auto emit = [&](double absT, double value) {
2200 const double relT = absT - offset;
2201 if (!hasLast || relT > lastT + interiorMargin) {
2202 rebuilt->Insert(relT, value);
2203 hasLast = true;
2204 lastT = relT;
2205 lastV = value;
2206 return;
2207 }
2208 // Coincident in time with the previous emission.
2209 if (fabs(value - lastV) <= kSeamValueTolerance) {
2210 return; // same point, suppress duplicate
2211 }
2212 // Genuine seam discontinuity: append a second point at the same
2213 // time with the new value. Raw indexed Insert is needed because
2214 // InsertOrReplace would overwrite the previous point.
2215 rebuilt->Insert(
2216 static_cast<int>(rebuilt->GetNumberOfPoints()),
2217 EnvPoint { relT, value });
2218 lastV = value;
2219 };
2220
2221 // Returns true if the source envelope has an explicit control point at
2222 // absT (within interiorMargin). Used to decide whether to keep the
2223 // outer boundary points -- we skip them when they were synthesized by
2224 // the trim, but preserve them when the user had placed a real point
2225 // there before the join.
2226 auto hasExplicitPointAt = [&](const Envelope& env, double absT) {
2227 const double srcOffset = env.GetOffset();
2228 const auto n = env.GetNumberOfPoints();
2229 for (size_t j = 0; j < n; ++j) {
2230 const double t = srcOffset + env[static_cast<int>(j)].GetT();
2231 if (t < absT - interiorMargin) {

Callers 1

JoinMethod · 0.85

Calls 15

moveFunction · 0.85
GetDefaultValueMethod · 0.80
SetOffsetMethod · 0.80
GetSequenceStartTimeMethod · 0.80
GetSequenceEndTimeMethod · 0.80
SetTrackLenMethod · 0.80
GetNumberOfPointsMethod · 0.80
GetTMethod · 0.80
GetValMethod · 0.80
SetEnvelopeMethod · 0.80
GetMinValueMethod · 0.45
GetMaxValueMethod · 0.45

Tested by

no test coverage detected