11namespace tracktion {
inline namespace engine
16 static constexpr int samplesPerBlock = 512;
24 if (timestretcher ==
nullptr || mode != newMode || elastiqueOptions != newOptions)
27 elastiqueOptions = newOptions;
31 if (! timestretcher->isInitialised())
33 timestretcher->initialise (sr, samplesPerBlock, 2, mode, elastiqueOptions,
true);
34 jassert (timestretcher->isInitialised());
37 if (timestretcher->isInitialised())
39 timestretcher->reset();
40 timestretcher->setSpeedAndPitch (1.0f, semitonesUp);
42 latencySamples = timestretcher->getMaxFramesNeeded();
44 inputFifo.setSize (2, latencySamples + 2000);
45 outputFifo.setSize (2, latencySamples + 2000);
51 outputFifo.writeSilence (latencySamples);
53 latencySeconds = latencySamples / sr;
60 if (timestretcher->isInitialised())
63 auto newOptions = owner.elastiqueOptions.get();
65 if (newMode != mode || newOptions != elastiqueOptions)
66 initialise (owner.sampleRate, semis, newMode, newOptions);
70 if (! timestretcher->setSpeedAndPitch (1.0f, semis))
75 int needed = timestretcher->getFramesNeeded();
79 if (inputFifo.getNumReady() < needed)
82 if (outputFifo.getFreeSpace() < samplesPerBlock)
85 timestretcher->processData (inputFifo, needed, outputFifo);
86 needed = timestretcher->getFramesNeeded();
114 AudioFifo inputFifo { 2, 2000 }, outputFifo { 2, 2000 };
116 int latencySamples = 8192;
117 double latencySeconds = latencySamples / 44100.0;
127 auto um = getUndoManager();
129 semitones = addParam (
"semitones up",
TRANS(
"Semitones"),
130 { -PitchShiftPlugin::getMaximumSemitones(), PitchShiftPlugin::getMaximumSemitones() },
131 [] (
float value) {
return std::abs (value) < 0.01f ?
"(" +
TRANS(
"Original pitch") +
")"
132 : getSemitonesAsString (value); },
134 PitchShiftPlugin::getMaximumSemitones(),
135 s.getFloatValue()); });
137 semitonesValue.referTo (state, IDs::semitonesUp, um);
139 elastiqueOptions.referTo (state, IDs::elastiqueOptions, um);
141 semitones->attachToCurrentValue (semitonesValue);
145 : PitchShiftPlugin (PluginCreationInfo (ed, v, false))
149PitchShiftPlugin::~PitchShiftPlugin()
151 notifyListenersOfDeletion();
153 semitones->detachFromCurrentValue();
158 return createValueTree (IDs::PLUGIN,
159 IDs::type, xmlTypeName);
162const char* PitchShiftPlugin::xmlTypeName =
"pitchShifter";
167 pimpl->initialise (info.sampleRate, semitones->getCurrentValue(),
177 pimpl->applyToBuffer (fc, semitones->getCurrentValue());
182double PitchShiftPlugin::getLatencySeconds()
184 return pimpl->latencySeconds;
189 return TRANS(
"Pitch Shifter Plugin");
192void PitchShiftPlugin::restorePluginStateFromValueTree (
const juce::ValueTree& v)
194 copyPropertiesToCachedValues (v, semitonesValue, mode);
196 for (
auto p : getAutomatableParameters())
197 p->updateFromAttachedValue();
Type get() const noexcept
void applyToBuffer(const PluginRenderContext &) override
Process the next block of data.
juce::String getSelectableDescription() override
Subclasses must return a description of what they are.
void deinitialise() override
Called after play stops to release resources.
Mode
Holds the various algorithms to which can be used (if enabled).
@ defaultMode
Default mode.
@ disabled
No algorithm enabled.
#define TRANS(stringLiteral)
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
int roundToInt(const FloatType value) noexcept
Passed into Plugins when they are being initialised, to give them useful contextual information that ...
The context passed to plugin render methods to provide it with buffers to fill.
int bufferNumSamples
The number of samples to write into the audio buffer.
MidiMessageArray * bufferForMidiMessages
A buffer of MIDI events to process.
juce::AudioBuffer< float > * destBuffer
The target audio buffer which needs to be filled.
int bufferStartSample
The index of the start point in the audio buffer from which data must be written.
A set of options that can be used in conjunction with the elastiquePro Mode to fine tune the algorith...