| 372 | } |
| 373 | |
| 374 | void SoundTouchBase::Finalize( |
| 375 | WaveTrack &orig, WaveTrack &out, const TimeWarper &warper) |
| 376 | { |
| 377 | assert(out.NChannels() == orig.NChannels()); |
| 378 | if (mPreserveLength) { |
| 379 | auto newLen = out.GetVisibleSampleCount(); |
| 380 | auto oldLen = out.TimeToLongSamples(mT1) - out.TimeToLongSamples(mT0); |
| 381 | |
| 382 | // Pad output track to original length since SoundTouch may remove samples |
| 383 | if (newLen < oldLen) { |
| 384 | const auto t = out.LongSamplesToTime(newLen - 1); |
| 385 | const auto len = out.LongSamplesToTime(oldLen - newLen); |
| 386 | out.InsertSilence(t, len); |
| 387 | } |
| 388 | // Trim output track to original length since SoundTouch may add extra samples |
| 389 | else if (newLen > oldLen) { |
| 390 | const auto t1 = out.LongSamplesToTime(oldLen); |
| 391 | out.Trim(0, t1); |
| 392 | } |
| 393 | } |
| 394 | |
| 395 | // Silenced samples will be inserted in gaps between clips, so capture where |
| 396 | // these gaps are for later deletion |
| 397 | std::vector<std::pair<double, double>> gaps; |
| 398 | double last = mT0; |
| 399 | auto clips = orig.SortedIntervalArray(); |
| 400 | auto front = clips.front(); |
| 401 | auto back = clips.back(); |
| 402 | for (auto &clip : clips) { |
| 403 | auto st = clip->GetPlayStartTime(); |
| 404 | auto et = clip->GetPlayEndTime(); |
| 405 | |
| 406 | if (st >= mT0 || et < mT1) { |
| 407 | if (mT0 < st && clip == front) { |
| 408 | gaps.push_back(std::make_pair(mT0, st)); |
| 409 | } |
| 410 | else if (last < st && mT0 <= last ) { |
| 411 | gaps.push_back(std::make_pair(last, st)); |
| 412 | } |
| 413 | |
| 414 | if (et < mT1 && clip == back) { |
| 415 | gaps.push_back(std::make_pair(et, mT1)); |
| 416 | } |
| 417 | } |
| 418 | last = et; |
| 419 | } |
| 420 | |
| 421 | // Take the output track and insert it in place of the original sample data |
| 422 | orig.ClearAndPaste(mT0, mT1, out, true, true, &warper); |
| 423 | |
| 424 | // Finally, recreate the gaps |
| 425 | for (auto gap : gaps) { |
| 426 | const auto st = orig.SnapToSample(gap.first); |
| 427 | const auto et = orig.SnapToSample(gap.second); |
| 428 | if (st >= mT0 && et <= mT1 && st != et) |
| 429 | orig.SplitDelete(warper.Warp(st), warper.Warp(et)); |
| 430 | } |
| 431 | } |
nothing calls this directly
no test coverage detected