Audacity 3.2.0
ClipSegment.cpp
Go to the documentation of this file.
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*!********************************************************************
3
4 Audacity: A Digital Audio Editor
5
6 ClipSegment.cpp
7
8 Matthieu Hodgkinson
9
10**********************************************************************/
11#include "ClipSegment.h"
12#include "ClipInterface.h"
13#include "SampleFormat.h"
15#include <cassert>
16#include <cmath>
17#include <functional>
18
19namespace
20{
23{
25 params.timeRatio = clip.GetStretchRatio();
26 params.pitchRatio = std::pow(2., clip.GetCentShift() / 1200.);
27 params.preserveFormants =
29 return params;
30}
31
33GetTotalNumSamplesToProduce(const ClipInterface& clip, double durationToDiscard)
34{
36 clip.GetStretchRatio() -
37 durationToDiscard * clip.GetRate() + .5 };
38}
39} // namespace
40
42 const ClipInterface& clip, double durationToDiscard,
43 PlaybackDirection direction)
44 : mTotalNumSamplesToProduce { GetTotalNumSamplesToProduce(
45 clip, durationToDiscard) }
46 , mSource { clip, durationToDiscard, direction }
47 , mPreserveFormants { clip.GetPitchAndSpeedPreset() ==
49 , mCentShift { clip.GetCentShift() }
50 , mStretcher { std::make_unique<StaffPadTimeAndPitch>(
51 clip.GetRate(), clip.NChannels(), mSource,
53 , mOnSemitoneShiftChangeSubscription { clip.SubscribeToCentShiftChange(
54 [this](int cents) {
55 mCentShift = cents;
56 mUpdateCentShift = true;
57 }) }
58 , mOnFormantPreservationChangeSubscription {
61 mPreserveFormants =
63 mUpdateFormantPreservation = true;
64 })
65 }
66{
67}
68
70{
73}
74
75size_t ClipSegment::GetFloats(float* const* buffers, size_t numSamples)
76{
77 // Check if formant preservation of pitch shift needs to be updated.
78 // This approach is not immune to a race condition, but it is unlikely and
79 // not critical, as it would only affect one playback pass, during which the
80 // user could easily correct the mistake if needed. On the other hand, we
81 // cannot trust that the observer subscriptions do not get called after
82 // destruction of this object, so better not do anything too sophisticated
83 // there.
84 if (mUpdateFormantPreservation.exchange(false))
85 mStretcher->OnFormantPreservationChange(mPreserveFormants);
86 if (mUpdateCentShift.exchange(false))
87 mStretcher->OnCentShiftChange(mCentShift);
88 const auto numSamplesToProduce = limitSampleBufferSize(
90 mStretcher->GetSamples(buffers, numSamplesToProduce);
91 mTotalNumSamplesProduced += numSamplesToProduce;
92 return numSamplesToProduce;
93}
94
96{
98}
99
101{
102 return mSource.NChannels();
103}
PitchAndSpeedPreset
Definition: ClipInterface.h:40
EffectDistortionSettings params
PlaybackDirection
ReverbSettings preset
Definition: ReverbBase.cpp:25
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
Definition: SampleCount.cpp:22
virtual int GetCentShift() const =0
virtual PitchAndSpeedPreset GetPitchAndSpeedPreset() const =0
virtual Observer::Subscription SubscribeToPitchAndSpeedPresetChange(std::function< void(PitchAndSpeedPreset)> cb) const =0
size_t NChannels() const override
The number of channels in the segment.
int mCentShift
Definition: ClipSegment.h:47
Observer::Subscription mOnSemitoneShiftChangeSubscription
Definition: ClipSegment.h:54
~ClipSegment() override
Definition: ClipSegment.cpp:69
ClipTimeAndPitchSource mSource
Definition: ClipSegment.h:45
ClipSegment(const ClipInterface &, double durationToDiscard, PlaybackDirection)
Definition: ClipSegment.cpp:41
sampleCount mTotalNumSamplesProduced
Definition: ClipSegment.h:44
std::unique_ptr< TimeAndPitchInterface > mStretcher
Definition: ClipSegment.h:53
Observer::Subscription mOnFormantPreservationChangeSubscription
Definition: ClipSegment.h:55
size_t GetFloats(float *const *buffers, size_t numSamples) override
Fills buffers with as many as numSamples or the number of remaining samples, whichever is smaller.
Definition: ClipSegment.cpp:75
bool mPreserveFormants
Definition: ClipSegment.h:46
bool Empty() const override
Whether the segment has no more samples to provide.
Definition: ClipSegment.cpp:95
std::atomic< bool > mUpdateCentShift
Definition: ClipSegment.h:49
std::atomic< bool > mUpdateFormantPreservation
Definition: ClipSegment.h:48
const sampleCount mTotalNumSamplesToProduce
Definition: ClipSegment.h:43
virtual int GetRate() const =0
virtual double GetStretchRatio() const =0
virtual sampleCount GetVisibleSampleCount() const =0
void Reset() noexcept
Breaks the connection (constant time)
Definition: Observer.cpp:101
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
double as_double() const
Definition: SampleCount.h:46
TimeAndPitchInterface::Parameters GetStretchingParameters(const ClipInterface &clip)
Definition: ClipSegment.cpp:22
sampleCount GetTotalNumSamplesToProduce(const ClipInterface &clip, double durationToDiscard)
Definition: ClipSegment.cpp:33
double GetRate(const Track &track)
Definition: TimeTrack.cpp:182
STL namespace.