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.

125 lines
3.5KB

  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. // Variant of the grain class used for WSOLA.
  28. #ifndef CLOUDS_DSP_WINDOW_H_
  29. #define CLOUDS_DSP_WINDOW_H_
  30. #include "stmlib/stmlib.h"
  31. #include "stmlib/dsp/dsp.h"
  32. #include "clouds/dsp/audio_buffer.h"
  33. #include "clouds/resources.h"
  34. namespace clouds {
  35. enum WindowFlags {
  36. WINDOW_FLAGS_HALF_DONE = 1,
  37. WINDOW_FLAGS_REGENERATED = 2,
  38. WINDOW_FLAGS_DONE = 4
  39. };
  40. class Window {
  41. public:
  42. Window() { }
  43. ~Window() { }
  44. void Init() {
  45. done_ = true;
  46. regenerated_ = false;
  47. half_ = false;
  48. }
  49. void Start(
  50. int32_t buffer_size,
  51. int32_t start,
  52. int32_t width,
  53. int32_t phase_increment) {
  54. first_sample_ = (start + buffer_size) % buffer_size;
  55. phase_increment_ = phase_increment;
  56. phase_ = 0;
  57. done_ = false;
  58. regenerated_ = false;
  59. done_ = false;
  60. envelope_phase_increment_ = 2.0f / static_cast<float>(width);
  61. }
  62. template<Resolution resolution>
  63. inline void OverlapAdd(
  64. const AudioBuffer<resolution>* buffer,
  65. float* samples,
  66. int32_t channels) {
  67. if (done_) {
  68. return;
  69. }
  70. int32_t phase_integral = phase_ >> 16;
  71. int32_t phase_fractional = phase_ & 0xffff;
  72. int32_t sample_index = first_sample_ + phase_integral;
  73. float envelope_phase = phase_integral * envelope_phase_increment_;
  74. done_ = envelope_phase >= 2.0f;
  75. half_ = envelope_phase >= 1.0f;
  76. float gain = envelope_phase >= 1.0f
  77. ? 2.0f - envelope_phase
  78. : envelope_phase;
  79. float l = buffer[0].ReadHermite(sample_index, phase_fractional) * gain;
  80. if (channels == 1) {
  81. *samples++ += l;
  82. *samples++ += l;
  83. } else if (channels == 2) {
  84. float r = buffer[1].ReadHermite(sample_index, phase_fractional) * gain;
  85. *samples++ += l;
  86. *samples++ += r;
  87. }
  88. phase_ += phase_increment_;
  89. }
  90. inline bool done() { return done_; }
  91. inline bool needs_regeneration() { return half_ && !regenerated_; }
  92. inline void MarkAsRegenerated() { regenerated_ = true; }
  93. private:
  94. Window* next_;
  95. int32_t first_sample_;
  96. int32_t phase_;
  97. int32_t phase_increment_;
  98. float envelope_phase_increment_;
  99. bool done_;
  100. bool half_;
  101. bool regenerated_;
  102. DISALLOW_COPY_AND_ASSIGN(Window);
  103. };
  104. } // namespace clouds
  105. #endif // CLOUDS_DSP_WINDOW_H_