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
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*!********************************************************************
Audacity: A Digital Audio Editor
AudioSegmentFactory.cpp
Matthieu Hodgkinson
**********************************************************************/
#include "AudioSegmentFactory.h"
#include "ClipInterface.h"
#include "ClipSegment.h"
#include "SilenceSegment.h"
#include "TimeAndPitchInterface.h"
#include <algorithm>
using ClipConstHolder = std::shared_ptr<const ClipInterface>;
AudioSegmentFactory::AudioSegmentFactory(
int sampleRate, int numChannels, ClipConstHolders clips)
: mClips { std::move(clips) }
, mSampleRate { sampleRate }
, mNumChannels { numChannels }
{
}
std::vector<std::shared_ptr<AudioSegment>>
AudioSegmentFactory::CreateAudioSegmentSequence(
double playbackStartTime, PlaybackDirection direction)
{
return direction == PlaybackDirection::forward ?
CreateAudioSegmentSequenceForward(playbackStartTime) :
CreateAudioSegmentSequenceBackward(playbackStartTime);
}
std::vector<std::shared_ptr<AudioSegment>>
AudioSegmentFactory::CreateAudioSegmentSequenceForward(double t0)
{
auto sortedClips = mClips;
std::sort(
sortedClips.begin(), sortedClips.end(),
[](const std::shared_ptr<const ClipInterface>& a,
const std::shared_ptr<const ClipInterface>& b) {
return a->GetPlayStartTime() < b->GetPlayStartTime();
});
std::vector<std::shared_ptr<AudioSegment>> segments;
for (const auto& clip : sortedClips)
{
if (clip->GetPlayStartTime() > t0)
{
const auto numSamples =
sampleCount { (clip->GetPlayStartTime() - t0) * mSampleRate + .5 };
segments.push_back(
std::make_shared<SilenceSegment>(mNumChannels, numSamples));
t0 = clip->GetPlayStartTime();
}
else if (clip->GetPlayEndTime() <= t0)
continue;
segments.push_back(std::make_shared<ClipSegment>(
*clip, t0 - clip->GetPlayStartTime(), PlaybackDirection::forward));
t0 = clip->GetPlayEndTime();
}
return segments;
}
std::vector<std::shared_ptr<AudioSegment>>
AudioSegmentFactory::CreateAudioSegmentSequenceBackward(double t0)
{
auto sortedClips = mClips;
std::sort(
sortedClips.begin(), sortedClips.end(),
[&](
const std::shared_ptr<const ClipInterface>& a,
const std::shared_ptr<const ClipInterface>& b) {
return a->GetPlayEndTime() > b->GetPlayEndTime();
});
std::vector<std::shared_ptr<AudioSegment>> segments;
for (const auto& clip : sortedClips)
{
if (clip->GetPlayEndTime() < t0)
{
const auto numSamples =
sampleCount { (t0 - clip->GetPlayEndTime()) * mSampleRate + .5 };
segments.push_back(
std::make_shared<SilenceSegment>(mNumChannels, numSamples));
t0 = clip->GetPlayEndTime();
}
else if (clip->GetPlayStartTime() >= t0)
continue;
segments.push_back(std::make_shared<ClipSegment>(
*clip, clip->GetPlayEndTime() - t0, PlaybackDirection::backward));
t0 = clip->GetPlayStartTime();
}
return segments;
}
|