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.

128 lines
4.9KB

  1. /* Copyright 2013-2019 Matt Tytel
  2. *
  3. * vital is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * vital is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with vital. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "phase_modifier.h"
  17. #include "wave_frame.h"
  18. #include "wavetable_component_factory.h"
  19. namespace {
  20. std::complex<float> multiplyAndMix(std::complex<float> value, std::complex<float> mult, float mix) {
  21. std::complex<float> result = value * mult;
  22. return mix * result + (1.0f - mix) * value;
  23. }
  24. } // namespace
  25. PhaseModifier::PhaseModifierKeyframe::PhaseModifierKeyframe() : phase_(0.0f), mix_(1.0f), phase_style_(kNormal) { }
  26. void PhaseModifier::PhaseModifierKeyframe::copy(const WavetableKeyframe* keyframe) {
  27. const PhaseModifierKeyframe* source = dynamic_cast<const PhaseModifierKeyframe*>(keyframe);
  28. phase_ = source->phase_;
  29. mix_ = source->mix_;
  30. }
  31. void PhaseModifier::PhaseModifierKeyframe::interpolate(const WavetableKeyframe* from_keyframe,
  32. const WavetableKeyframe* to_keyframe,
  33. float t) {
  34. const PhaseModifierKeyframe* from = dynamic_cast<const PhaseModifierKeyframe*>(from_keyframe);
  35. const PhaseModifierKeyframe* to = dynamic_cast<const PhaseModifierKeyframe*>(to_keyframe);
  36. phase_ = linearTween(from->phase_, to->phase_, t);
  37. mix_ = linearTween(from->mix_, to->mix_, t);
  38. }
  39. void PhaseModifier::PhaseModifierKeyframe::render(vital::WaveFrame* wave_frame) {
  40. std::complex<float> phase_shift = std::polar(1.0f, -phase_);
  41. if (phase_style_ == kHarmonic) {
  42. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i)
  43. wave_frame->frequency_domain[i] = multiplyAndMix(wave_frame->frequency_domain[i], phase_shift, mix_);
  44. }
  45. else if (phase_style_ == kHarmonicEvenOdd) {
  46. std::complex<float> odd_shift = 1.0f / phase_shift;
  47. for (int i = 0; i < vital::WaveFrame::kWaveformSize; i += 2) {
  48. wave_frame->frequency_domain[i] = multiplyAndMix(wave_frame->frequency_domain[i], phase_shift, mix_);
  49. wave_frame->frequency_domain[i + 1] = multiplyAndMix(wave_frame->frequency_domain[i + 1], odd_shift, mix_);
  50. }
  51. }
  52. else if (phase_style_ == kNormal) {
  53. std::complex<float> current_phase_shift = 1.0f;
  54. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  55. wave_frame->frequency_domain[i] = multiplyAndMix(wave_frame->frequency_domain[i], current_phase_shift, mix_);
  56. current_phase_shift *= phase_shift;
  57. }
  58. }
  59. else if (phase_style_ == kEvenOdd) {
  60. std::complex<float> current_phase_shift = 1.0f;
  61. for (int i = 0; i < vital::WaveFrame::kWaveformSize; i += 2) {
  62. wave_frame->frequency_domain[i] = multiplyAndMix(wave_frame->frequency_domain[i], current_phase_shift, mix_);
  63. std::complex<float> odd_shift = 1.0f / (current_phase_shift * phase_shift);
  64. wave_frame->frequency_domain[i + 1] = multiplyAndMix(wave_frame->frequency_domain[i + 1], odd_shift, mix_);
  65. current_phase_shift *= phase_shift * phase_shift;
  66. }
  67. }
  68. else if (phase_style_ == kClear) {
  69. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i)
  70. wave_frame->frequency_domain[i] = std::abs(wave_frame->frequency_domain[i]);
  71. }
  72. wave_frame->toTimeDomain();
  73. }
  74. json PhaseModifier::PhaseModifierKeyframe::stateToJson() {
  75. json data = WavetableKeyframe::stateToJson();
  76. data["phase"] = phase_;
  77. data["mix"] = mix_;
  78. return data;
  79. }
  80. void PhaseModifier::PhaseModifierKeyframe::jsonToState(json data) {
  81. WavetableKeyframe::jsonToState(data);
  82. phase_ = data["phase"];
  83. mix_ = data["mix"];
  84. }
  85. WavetableKeyframe* PhaseModifier::createKeyframe(int position) {
  86. PhaseModifierKeyframe* keyframe = new PhaseModifierKeyframe();
  87. interpolate(keyframe, position);
  88. return keyframe;
  89. }
  90. void PhaseModifier::render(vital::WaveFrame* wave_frame, float position) {
  91. compute_frame_.setPhaseStyle(phase_style_);
  92. interpolate(&compute_frame_, position);
  93. compute_frame_.render(wave_frame);
  94. }
  95. WavetableComponentFactory::ComponentType PhaseModifier::getType() {
  96. return WavetableComponentFactory::kPhaseModifier;
  97. }
  98. json PhaseModifier::stateToJson() {
  99. json data = WavetableComponent::stateToJson();
  100. data["style"] = phase_style_;
  101. return data;
  102. }
  103. void PhaseModifier::jsonToState(json data) {
  104. WavetableComponent::jsonToState(data);
  105. phase_style_ = data["style"];
  106. }
  107. PhaseModifier::PhaseModifierKeyframe* PhaseModifier::getKeyframe(int index) {
  108. WavetableKeyframe* wavetable_keyframe = keyframes_[index].get();
  109. return dynamic_cast<PhaseModifier::PhaseModifierKeyframe*>(wavetable_keyframe);
  110. }