/* ============================================================================== This file is part of the JUCE library. Copyright (c) 2022 - Raw Material Software Limited JUCE is an open source library subject to commercial or open-source licensing. By using JUCE, you agree to the terms of both the JUCE 7 End-User License Agreement and JUCE Privacy Policy. End User License Agreement: www.juce.com/juce-7-licence Privacy Policy: www.juce.com/juce-privacy-policy Or: You may also use this code under the terms of the GPL v3 (see www.gnu.org/licenses). 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 Panner::Panner() { update(); reset(); } //============================================================================== template void Panner::setRule (Rule newRule) { currentRule = newRule; update(); } template void Panner::setPan (SampleType newPan) { jassert (newPan >= -1.0 && newPan <= 1.0); pan = jlimit (static_cast (-1.0), static_cast (1.0), newPan); update(); } //============================================================================== template void Panner::prepare (const ProcessSpec& spec) { jassert (spec.sampleRate > 0); jassert (spec.numChannels > 0); sampleRate = spec.sampleRate; reset(); } template void Panner::reset() { leftVolume .reset (sampleRate, 0.05); rightVolume.reset (sampleRate, 0.05); } //============================================================================== template void Panner::update() { SampleType leftValue, rightValue, boostValue; auto normalisedPan = static_cast (0.5) * (pan + static_cast (1.0)); switch (currentRule) { case Rule::balanced: leftValue = jmin (static_cast (0.5), static_cast (1.0) - normalisedPan); rightValue = jmin (static_cast (0.5), normalisedPan); boostValue = static_cast (2.0); break; case Rule::linear: leftValue = static_cast (1.0) - normalisedPan; rightValue = normalisedPan; boostValue = static_cast (2.0); break; case Rule::sin3dB: leftValue = static_cast (std::sin (0.5 * MathConstants::pi * (1.0 - normalisedPan))); rightValue = static_cast (std::sin (0.5 * MathConstants::pi * normalisedPan)); boostValue = std::sqrt (static_cast (2.0)); break; case Rule::sin4p5dB: leftValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * (1.0 - normalisedPan)), 1.5)); rightValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * normalisedPan), 1.5)); boostValue = static_cast (std::pow (2.0, 3.0 / 4.0)); break; case Rule::sin6dB: leftValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * (1.0 - normalisedPan)), 2.0)); rightValue = static_cast (std::pow (std::sin (0.5 * MathConstants::pi * normalisedPan), 2.0)); boostValue = static_cast (2.0); break; case Rule::squareRoot3dB: leftValue = std::sqrt (static_cast (1.0) - normalisedPan); rightValue = std::sqrt (normalisedPan); boostValue = std::sqrt (static_cast (2.0)); break; case Rule::squareRoot4p5dB: leftValue = static_cast (std::pow (std::sqrt (1.0 - normalisedPan), 1.5)); rightValue = static_cast (std::pow (std::sqrt (normalisedPan), 1.5)); boostValue = static_cast (std::pow (2.0, 3.0 / 4.0)); break; default: leftValue = jmin (static_cast (0.5), static_cast (1.0) - normalisedPan); rightValue = jmin (static_cast (0.5), normalisedPan); boostValue = static_cast (2.0); break; } leftVolume .setTargetValue (leftValue * boostValue); rightVolume.setTargetValue (rightValue * boostValue); } //============================================================================== template class Panner; template class Panner; } // namespace dsp } // namespace juce