The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
4.4KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce::dsp
  19. {
  20. enum class PannerRule
  21. {
  22. linear, // regular 6 dB or linear panning rule, allows the panned sound to be
  23. // perceived as having a constant level when summed to mono
  24. balanced, // both left and right are 1 when pan value is 0, with left decreasing
  25. // to 0 above this value and right decreasing to 0 below it
  26. sin3dB, // alternate version of the regular 3 dB panning rule with a sine curve
  27. sin4p5dB, // alternate version of the regular 4.5 dB panning rule with a sine curve
  28. sin6dB, // alternate version of the regular 6 dB panning rule with a sine curve
  29. squareRoot3dB, // regular 3 dB or constant power panning rule, allows the panned sound
  30. // to be perceived as having a constant level regardless of the pan position
  31. squareRoot4p5dB // regular 4.5 dB panning rule, a compromise option between 3 dB and 6 dB panning rules
  32. };
  33. /**
  34. A processor to perform panning operations on stereo buffers.
  35. @tags{DSP}
  36. */
  37. template <typename SampleType>
  38. class Panner
  39. {
  40. public:
  41. //==============================================================================
  42. using Rule = PannerRule;
  43. //==============================================================================
  44. /** Constructor. */
  45. Panner();
  46. //==============================================================================
  47. /** Sets the panning rule. */
  48. void setRule (Rule newRule);
  49. /** Sets the current panning value, between -1 (full left) and 1 (full right). */
  50. void setPan (SampleType newPan);
  51. //==============================================================================
  52. /** Initialises the processor. */
  53. void prepare (const ProcessSpec& spec);
  54. /** Resets the internal state variables of the processor. */
  55. void reset();
  56. //==============================================================================
  57. /** Processes the input and output samples supplied in the processing context. */
  58. template <typename ProcessContext>
  59. void process (const ProcessContext& context) noexcept
  60. {
  61. const auto& inputBlock = context.getInputBlock();
  62. auto& outputBlock = context.getOutputBlock();
  63. const auto numInputChannels = inputBlock.getNumChannels();
  64. const auto numOutputChannels = outputBlock.getNumChannels();
  65. [[maybe_unused]] const auto numSamples = outputBlock.getNumSamples();
  66. jassert (inputBlock.getNumSamples() == numSamples);
  67. if (numOutputChannels != 2 || numInputChannels == 0 || numInputChannels > 2)
  68. return;
  69. if (numInputChannels == 2)
  70. {
  71. outputBlock.copyFrom (inputBlock);
  72. }
  73. else
  74. {
  75. outputBlock.getSingleChannelBlock (0).copyFrom (inputBlock);
  76. outputBlock.getSingleChannelBlock (1).copyFrom (inputBlock);
  77. }
  78. if (context.isBypassed)
  79. return;
  80. outputBlock.getSingleChannelBlock (0).multiplyBy (leftVolume);
  81. outputBlock.getSingleChannelBlock (1).multiplyBy (rightVolume);
  82. }
  83. private:
  84. //==============================================================================
  85. void update();
  86. //==============================================================================
  87. Rule currentRule = Rule::balanced;
  88. SampleType pan = 0.0;
  89. SmoothedValue<SampleType> leftVolume, rightVolume;
  90. double sampleRate = 44100.0;
  91. };
  92. } // namespace juce::dsp