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.

133 lines
3.6KB

  1. // Copyright 2014 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // Pitch shifter.
  28. #ifndef CLOUDS_DSP_FX_PITCH_SHIFTER_H_
  29. #define CLOUDS_DSP_FX_PITCH_SHIFTER_H_
  30. #include "stmlib/stmlib.h"
  31. #include "stmlib/dsp/dsp.h"
  32. #include "clouds/resources.h"
  33. #include "clouds/dsp/frame.h"
  34. #include "clouds/dsp/fx/fx_engine.h"
  35. namespace clouds {
  36. class PitchShifter {
  37. public:
  38. PitchShifter() { }
  39. ~PitchShifter() { }
  40. void Init(uint16_t* buffer) {
  41. engine_.Init(buffer);
  42. phase_ = 0;
  43. size_ = 2047.0f;
  44. dry_wet_ = 0.0f;
  45. }
  46. void Clear() {
  47. engine_.Clear();
  48. }
  49. inline void Process(FloatFrame* input_output, size_t size) {
  50. while (size--) {
  51. Process(input_output);
  52. ++input_output;
  53. }
  54. }
  55. void Process(FloatFrame* input_output) {
  56. typedef E::Reserve<2047, E::Reserve<2047> > Memory;
  57. E::DelayLine<Memory, 0> left;
  58. E::DelayLine<Memory, 1> right;
  59. E::Context c;
  60. engine_.Start(&c);
  61. phase_ += (1.0f - ratio_) / size_;
  62. if (phase_ >= 1.0f) {
  63. phase_ -= 1.0f;
  64. }
  65. if (phase_ <= 0.0f) {
  66. phase_ += 1.0f;
  67. }
  68. float tri = 2.0f * (phase_ >= 0.5f ? 1.0f - phase_ : phase_);
  69. tri = stmlib::Interpolate(lut_window, tri, LUT_WINDOW_SIZE-1);
  70. float phase = phase_ * size_;
  71. float half = phase + size_ * 0.5f;
  72. if (half >= size_) {
  73. half -= size_;
  74. }
  75. float wet = 0.0f;
  76. c.Read(input_output->l, 1.0f);
  77. c.Write(left, 0.0f);
  78. c.InterpolateHermite(left, phase, tri);
  79. c.InterpolateHermite(left, half, 1.0f - tri);
  80. c.Write(wet, 0.0f);
  81. input_output->l += (wet - input_output->l) * dry_wet_;
  82. c.Read(input_output->r, 1.0f);
  83. c.Write(right, 0.0f);
  84. c.InterpolateHermite(right, phase, tri);
  85. c.InterpolateHermite(right, half, 1.0f - tri);
  86. c.Write(wet, 0.0f);
  87. input_output->r += (wet - input_output->r) * dry_wet_;
  88. }
  89. inline void set_ratio(float ratio) {
  90. ratio_ = ratio;
  91. }
  92. inline void set_dry_wet(float dry_wet) {
  93. dry_wet_ = dry_wet;
  94. }
  95. inline void set_size(float size) {
  96. float target_size = 128.0f + (2047.0f - 128.0f) * size * size * size;
  97. ONE_POLE(size_, target_size, 0.05f)
  98. }
  99. private:
  100. typedef FxEngine<4096, FORMAT_16_BIT> E;
  101. E engine_;
  102. float phase_;
  103. float ratio_;
  104. float size_;
  105. float dry_wet_;
  106. DISALLOW_COPY_AND_ASSIGN(PitchShifter);
  107. };
  108. } // namespace clouds
  109. #endif // CLOUDS_DSP_FX_MINI_CHORUS_H_