/* ============================================================================== This file is part of the JUCE 6 technical preview. Copyright (c) 2020 - Raw Material Software Limited You may use this code under the terms of the GPL v3 (see www.gnu.org/licenses). For this technical preview, this file is not subject to commercial licensing. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE DISCLAIMED. ============================================================================== */ namespace juce { namespace dsp { //============================================================================== template Phaser::Phaser() { auto oscFunction = [] (SampleType x) { return std::sin (x); }; osc.initialise (oscFunction); for (auto n = 0; n < numStages; ++n) { filters.add (new FirstOrderTPTFilter()); filters[n]->setType (FirstOrderTPTFilterType::allpass); } dryWet.setMixingRule (DryWetMixingRule::linear); } template void Phaser::setRate (SampleType newRateHz) { jassert (isPositiveAndBelow (newRateHz, static_cast (100.0))); rate = newRateHz; update(); } template void Phaser::setDepth (SampleType newDepth) { jassert (isPositiveAndNotGreaterThan (newDepth, static_cast (1.0))); depth = newDepth; update(); } template void Phaser::setCentreFrequency (SampleType newCentreHz) { jassert (isPositiveAndBelow (newCentreHz, static_cast (sampleRate * 0.5))); centreFrequency = newCentreHz; normCentreFrequency = mapToLog10 (centreFrequency, static_cast (20.0), static_cast (jmin (20000.0, 0.49 * sampleRate))); } template void Phaser::setFeedback (SampleType newFeedback) { jassert (newFeedback >= static_cast (-1.0) && newFeedback <= static_cast (1.0)); feedback = newFeedback; update(); } template void Phaser::setMix (SampleType newMix) { jassert (isPositiveAndNotGreaterThan (newMix, static_cast (1.0))); mix = newMix; update(); } //============================================================================== template void Phaser::prepare (const ProcessSpec& spec) { jassert (spec.sampleRate > 0); jassert (spec.numChannels > 0); sampleRate = spec.sampleRate; for (auto n = 0; n < numStages; ++n) filters[n]->prepare (spec); dryWet.prepare (spec); feedbackVolume.resize (spec.numChannels); lastOutput.resize (spec.numChannels); auto specDown = spec; specDown.sampleRate /= (double) maxUpdateCounter; specDown.maximumBlockSize = specDown.maximumBlockSize / (uint32) maxUpdateCounter + 1; osc.prepare (specDown); bufferFrequency.setSize (1, (int) specDown.maximumBlockSize, false, false, true); update(); reset(); } template void Phaser::reset() { std::fill (lastOutput.begin(), lastOutput.end(), static_cast (0)); for (auto n = 0; n < numStages; ++n) filters[n]->reset(); osc.reset(); dryWet.reset(); oscVolume.reset (sampleRate / (double) maxUpdateCounter, 0.05); for (auto& vol : feedbackVolume) vol.reset (sampleRate, 0.05); updateCounter = 0; } template void Phaser::update() { osc.setFrequency (rate); oscVolume.setTargetValue (depth * (SampleType) 0.5); dryWet.setWetMixProportion (mix); for (auto& vol : feedbackVolume) vol.setTargetValue (feedback); } //============================================================================== template class Phaser; template class Phaser; } // namespace dsp } // namespace juce