Audacity 3.2.0
Public Member Functions | Private Member Functions | Private Attributes | List of all members
StaffPadTimeAndPitch Class Referencefinal

#include <StaffPadTimeAndPitch.h>

Inheritance diagram for StaffPadTimeAndPitch:
[legend]
Collaboration diagram for StaffPadTimeAndPitch:
[legend]

Public Member Functions

 StaffPadTimeAndPitch (int sampleRate, size_t numChannels, TimeAndPitchSource &, const Parameters &)
 
void GetSamples (float *const *, size_t) override
 
void OnCentShiftChange (int cents) override
 
void OnFormantPreservationChange (bool preserve) override
 
- Public Member Functions inherited from TimeAndPitchInterface
virtual void GetSamples (float *const *, size_t)=0
 
virtual void OnCentShiftChange (int cents)=0
 
virtual void OnFormantPreservationChange (bool preserve)=0
 
virtual ~TimeAndPitchInterface ()
 

Private Member Functions

bool IllState () const
 
void InitializeStretcher ()
 

Private Attributes

const int mSampleRate
 
const std::unique_ptr< FormantShifterLoggerInterfacemFormantShifterLogger
 
TimeAndPitchInterface::Parameters mParameters
 
FormantShifter mFormantShifter
 
std::unique_ptr< staffpad::TimeAndPitchmTimeAndPitch
 
TimeAndPitchSourcemAudioSource
 
AudioContainer mReadBuffer
 
const size_t mNumChannels
 

Additional Inherited Members

- Static Public Member Functions inherited from TimeAndPitchInterface
static bool IsPassThroughMode (double stretchRatio)
 
- Static Public Attributes inherited from TimeAndPitchInterface
static constexpr auto MaxCents = 1200
 
static constexpr auto MinCents = -1200
 

Detailed Description

Definition at line 7 of file StaffPadTimeAndPitch.h.

Constructor & Destructor Documentation

◆ StaffPadTimeAndPitch()

StaffPadTimeAndPitch::StaffPadTimeAndPitch ( int  sampleRate,
size_t  numChannels,
TimeAndPitchSource audioSource,
const Parameters parameters 
)

Definition at line 80 of file StaffPadTimeAndPitch.cpp.

84 , mParameters(parameters)
89 .value_or(0.002),
91 , mAudioSource(audioSource)
92 , mReadBuffer(maxBlockSize, numChannels)
93 , mNumChannels(numChannels)
94{
97 GetFftSize(sampleRate, parameters.preserveFormants));
98 if (
100 // No need for sophisticated comparison for pitch ratio, as our UI doesn't
101 // allow changes smaller than a cent.
104}
void Reset(size_t fftSize)
FormantShifter mFormantShifter
const std::unique_ptr< FormantShifterLoggerInterface > mFormantShifterLogger
TimeAndPitchSource & mAudioSource
TimeAndPitchInterface::Parameters mParameters
static bool IsPassThroughMode(double stretchRatio)
int GetFftSize(int sampleRate, bool formantPreservationOn)
std::unique_ptr< FormantShifterLoggerInterface > GetFormantShifterLogger(int sampleRate)

References anonymous_namespace{StaffPadTimeAndPitch.cpp}::GetFftSize(), InitializeStretcher(), TimeAndPitchInterface::IsPassThroughMode(), mFormantShifter, mParameters, TimeAndPitchInterface::Parameters::pitchRatio, TimeAndPitchInterface::Parameters::preserveFormants, FormantShifter::Reset(), anonymous_namespace{ClipSegmentTest.cpp}::sampleRate, and TimeAndPitchInterface::Parameters::timeRatio.

Here is the call graph for this function:

Member Function Documentation

◆ GetSamples()

void StaffPadTimeAndPitch::GetSamples ( float *const *  output,
size_t  outputLen 
)
overridevirtual

Implements TimeAndPitchInterface.

Definition at line 106 of file StaffPadTimeAndPitch.cpp.

107{
108 if (!mTimeAndPitch)
109 // Pass-through
110 return mAudioSource.Pull(output, outputLen);
111
112 auto numOutputSamples = 0u;
113 while (numOutputSamples < outputLen)
114 {
115 if (IllState())
116 {
117 for (auto i = 0u; i < mNumChannels; ++i)
118 std::fill_n(
119 output[i] + numOutputSamples, outputLen - numOutputSamples, 0.f);
120 return;
121 }
122 auto numOutputSamplesAvailable =
123 mTimeAndPitch->getNumAvailableOutputSamples();
124 while (numOutputSamplesAvailable <= 0)
125 {
126 auto numRequired = mTimeAndPitch->getSamplesToNextHop();
127 while (numRequired > 0)
128 {
129 const auto numSamplesToFeed = std::min(numRequired, maxBlockSize);
130 mAudioSource.Pull(mReadBuffer.Get(), numSamplesToFeed);
131 mFormantShifterLogger->NewSamplesComing(numSamplesToFeed);
132 mTimeAndPitch->feedAudio(mReadBuffer.Get(), numSamplesToFeed);
133 numRequired -= numSamplesToFeed;
134 }
135 numOutputSamplesAvailable =
136 mTimeAndPitch->getNumAvailableOutputSamples();
137 }
138 while (numOutputSamples < outputLen && numOutputSamplesAvailable > 0)
139 {
140 const auto numSamplesToGet =
141 std::min({ maxBlockSize, numOutputSamplesAvailable,
142 static_cast<int>(outputLen - numOutputSamples) });
143 // More-than-stereo isn't supported
144 assert(mNumChannels <= 2);
145 float* buffer[2] {};
146 GetOffsetBuffer(buffer, output, mNumChannels, numOutputSamples);
147 mTimeAndPitch->retrieveAudio(buffer, numSamplesToGet);
148 numOutputSamplesAvailable -= numSamplesToGet;
149 numOutputSamples += numSamplesToGet;
150 }
151 }
152}
int min(int a, int b)
std::unique_ptr< staffpad::TimeAndPitch > mTimeAndPitch
virtual void Pull(float *const *, size_t samplesPerChannel)=0
void GetOffsetBuffer(float **offsetBuffer, float *const *buffer, size_t numChannels, size_t offset)
float *const * Get() const

References AudioContainer::Get(), anonymous_namespace{StaffPadTimeAndPitch.cpp}::GetOffsetBuffer(), IllState(), mAudioSource, anonymous_namespace{StaffPadTimeAndPitch.cpp}::maxBlockSize, mFormantShifterLogger, min(), mNumChannels, mReadBuffer, mTimeAndPitch, and TimeAndPitchSource::Pull().

Referenced by TEST_CASE().

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

◆ IllState()

bool StaffPadTimeAndPitch::IllState ( ) const
private

Definition at line 213 of file StaffPadTimeAndPitch.cpp.

214{
215 // It doesn't require samples, yet it doesn't have output samples available.
216 // Note that this must not be a permanent state, and may recover if the user
217 // changes the pitch shift.
218 // TODO: try to fix this in the stretcher implementation.
219 return mTimeAndPitch->getSamplesToNextHop() <= 0 &&
220 mTimeAndPitch->getNumAvailableOutputSamples() <= 0;
221}

References mTimeAndPitch.

Referenced by GetSamples(), and InitializeStretcher().

Here is the caller graph for this function:

◆ InitializeStretcher()

void StaffPadTimeAndPitch::InitializeStretcher ( )
private

Definition at line 178 of file StaffPadTimeAndPitch.cpp.

179{
182 auto numOutputSamplesToDiscard =
183 mTimeAndPitch->getLatencySamplesForStretchRatio(
186 while (numOutputSamplesToDiscard > 0)
187 {
188 if (IllState())
189 return;
190 auto numRequired = mTimeAndPitch->getSamplesToNextHop();
191 while (numRequired > 0)
192 {
193 const auto numSamplesToFeed = std::min(maxBlockSize, numRequired);
194 mAudioSource.Pull(container.Get(), numSamplesToFeed);
195 mTimeAndPitch->feedAudio(container.Get(), numSamplesToFeed);
196 numRequired -= numSamplesToFeed;
197 }
198 const auto totalNumSamplesToRetrieve = std::min(
199 mTimeAndPitch->getNumAvailableOutputSamples(),
200 numOutputSamplesToDiscard);
201 auto totalNumRetrievedSamples = 0;
202 while (totalNumRetrievedSamples < totalNumSamplesToRetrieve)
203 {
204 const auto numSamplesToRetrieve = std::min(
205 maxBlockSize, totalNumSamplesToRetrieve - totalNumRetrievedSamples);
206 mTimeAndPitch->retrieveAudio(container.Get(), numSamplesToRetrieve);
207 totalNumRetrievedSamples += numSamplesToRetrieve;
208 }
209 numOutputSamplesToDiscard -= totalNumSamplesToRetrieve;
210 }
211}
std::unique_ptr< staffpad::TimeAndPitch > CreateTimeAndPitch(int sampleRate, size_t numChannels, const TimeAndPitchInterface::Parameters &params, FormantShifter &shifter)

References anonymous_namespace{StaffPadTimeAndPitch.cpp}::CreateTimeAndPitch(), AudioContainer::Get(), IllState(), mAudioSource, anonymous_namespace{StaffPadTimeAndPitch.cpp}::maxBlockSize, mFormantShifter, min(), mNumChannels, mParameters, mSampleRate, mTimeAndPitch, TimeAndPitchInterface::Parameters::pitchRatio, TimeAndPitchSource::Pull(), and TimeAndPitchInterface::Parameters::timeRatio.

Referenced by OnCentShiftChange(), OnFormantPreservationChange(), and StaffPadTimeAndPitch().

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

◆ OnCentShiftChange()

void StaffPadTimeAndPitch::OnCentShiftChange ( int  cents)
overridevirtual

Implements TimeAndPitchInterface.

Definition at line 154 of file StaffPadTimeAndPitch.cpp.

155{
156 mParameters.pitchRatio = std::pow(2., cents / 1200.);
157 // If pitch shifing was zero before, now it isn't. If it was non-zero before,
158 // we don't unset the stretcher even if the new pitch shift is zero, or
159 // someone playing around with the effect could hear glitches.
160 if (!mTimeAndPitch)
162 else
163 mTimeAndPitch->setTimeStretchAndPitchFactor(
165}

References InitializeStretcher(), mParameters, mTimeAndPitch, TimeAndPitchInterface::Parameters::pitchRatio, and TimeAndPitchInterface::Parameters::timeRatio.

Here is the call graph for this function:

◆ OnFormantPreservationChange()

void StaffPadTimeAndPitch::OnFormantPreservationChange ( bool  preserve)
overridevirtual

Implements TimeAndPitchInterface.

Definition at line 167 of file StaffPadTimeAndPitch.cpp.

168{
169 mParameters.preserveFormants = preserve;
170 const auto fftSize = GetFftSize(mSampleRate, preserve);
171 preserve ? mFormantShifter.Reset(fftSize) : mFormantShifter.Reset();
172 // FFT size is a constant of the stretcher, so we need to reset it - if there
173 // is a stretcher.
174 if (mTimeAndPitch)
176}

References anonymous_namespace{StaffPadTimeAndPitch.cpp}::GetFftSize(), InitializeStretcher(), mFormantShifter, mParameters, mSampleRate, mTimeAndPitch, TimeAndPitchInterface::Parameters::preserveFormants, and FormantShifter::Reset().

Here is the call graph for this function:

Member Data Documentation

◆ mAudioSource

TimeAndPitchSource& StaffPadTimeAndPitch::mAudioSource
private

Definition at line 27 of file StaffPadTimeAndPitch.h.

Referenced by GetSamples(), and InitializeStretcher().

◆ mFormantShifter

FormantShifter StaffPadTimeAndPitch::mFormantShifter
private

◆ mFormantShifterLogger

const std::unique_ptr<FormantShifterLoggerInterface> StaffPadTimeAndPitch::mFormantShifterLogger
private

Definition at line 23 of file StaffPadTimeAndPitch.h.

Referenced by GetSamples().

◆ mNumChannels

const size_t StaffPadTimeAndPitch::mNumChannels
private

Definition at line 29 of file StaffPadTimeAndPitch.h.

Referenced by GetSamples(), and InitializeStretcher().

◆ mParameters

TimeAndPitchInterface::Parameters StaffPadTimeAndPitch::mParameters
private

◆ mReadBuffer

AudioContainer StaffPadTimeAndPitch::mReadBuffer
private

Definition at line 28 of file StaffPadTimeAndPitch.h.

Referenced by GetSamples().

◆ mSampleRate

const int StaffPadTimeAndPitch::mSampleRate
private

Definition at line 22 of file StaffPadTimeAndPitch.h.

Referenced by InitializeStretcher(), and OnFormantPreservationChange().

◆ mTimeAndPitch

std::unique_ptr<staffpad::TimeAndPitch> StaffPadTimeAndPitch::mTimeAndPitch
private

The documentation for this class was generated from the following files: