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.

208 lines
9.5KB

  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 "wave_source.h"
  17. #include "wave_frame.h"
  18. #include "wavetable_component_factory.h"
  19. WaveSource::WaveSource() {
  20. compute_frame_ = std::make_unique<WaveSourceKeyframe>();
  21. interpolation_mode_ = kFrequency;
  22. }
  23. WaveSource::~WaveSource() { }
  24. WavetableKeyframe* WaveSource::createKeyframe(int position) {
  25. WaveSourceKeyframe* keyframe = new WaveSourceKeyframe();
  26. render(keyframe->wave_frame(), position);
  27. return keyframe;
  28. }
  29. void WaveSource::render(vital::WaveFrame* wave_frame, float position) {
  30. compute_frame_->setInterpolationMode(interpolation_mode_);
  31. interpolate(compute_frame_.get(), position);
  32. wave_frame->copy(compute_frame_->wave_frame());
  33. }
  34. WavetableComponentFactory::ComponentType WaveSource::getType() {
  35. return WavetableComponentFactory::kWaveSource;
  36. }
  37. json WaveSource::stateToJson() {
  38. json data = WavetableComponent::stateToJson();
  39. data["interpolation"] = interpolation_mode_;
  40. return data;
  41. }
  42. void WaveSource::jsonToState(json data) {
  43. WavetableComponent::jsonToState(data);
  44. interpolation_mode_ = data["interpolation"];
  45. compute_frame_->setInterpolationMode(interpolation_mode_);
  46. }
  47. vital::WaveFrame* WaveSource::getWaveFrame(int index) {
  48. return getKeyframe(index)->wave_frame();
  49. }
  50. WaveSourceKeyframe* WaveSource::getKeyframe(int index) {
  51. WavetableKeyframe* wavetable_keyframe = keyframes_[index].get();
  52. return dynamic_cast<WaveSourceKeyframe*>(wavetable_keyframe);
  53. }
  54. void WaveSourceKeyframe::copy(const WavetableKeyframe* keyframe) {
  55. const WaveSourceKeyframe* source = dynamic_cast<const WaveSourceKeyframe*>(keyframe);
  56. wave_frame_->copy(source->wave_frame_.get());
  57. }
  58. void WaveSourceKeyframe::linearTimeInterpolate(const vital::WaveFrame* from, const vital::WaveFrame* to, float t) {
  59. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i)
  60. wave_frame_->time_domain[i] = linearTween(from->time_domain[i], to->time_domain[i], t);
  61. wave_frame_->toFrequencyDomain();
  62. }
  63. void WaveSourceKeyframe::cubicTimeInterpolate(const vital::WaveFrame* prev, const vital::WaveFrame* from,
  64. const vital::WaveFrame* to, const vital::WaveFrame* next,
  65. float range_prev, float range, float range_next, float t) {
  66. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  67. wave_frame_->time_domain[i] = cubicTween(prev->time_domain[i], from->time_domain[i],
  68. to->time_domain[i], next->time_domain[i],
  69. range_prev, range, range_next, t);
  70. }
  71. wave_frame_->toFrequencyDomain();
  72. }
  73. void WaveSourceKeyframe::linearFrequencyInterpolate(const vital::WaveFrame* from,
  74. const vital::WaveFrame* to, float t) {
  75. for (int i = 0; i < vital::WaveFrame::kNumRealComplex; ++i) {
  76. float amplitude_from = sqrtf(std::abs(from->frequency_domain[i]));
  77. float amplitude_to = sqrtf(std::abs(to->frequency_domain[i]));
  78. float amplitude = linearTween(amplitude_from, amplitude_to, t);
  79. amplitude *= amplitude;
  80. float phase_from = std::arg(from->frequency_domain[i]);
  81. float phase_delta = std::arg(std::conj(from->frequency_domain[i]) * to->frequency_domain[i]);
  82. float phase = phase_from + t * phase_delta;
  83. if (amplitude_from == 0)
  84. phase = std::arg(to->frequency_domain[i]);
  85. wave_frame_->frequency_domain[i] = std::polar(amplitude, phase);
  86. }
  87. float dc_from = from->frequency_domain[0].real();
  88. float dc_to = to->frequency_domain[0].real();
  89. wave_frame_->frequency_domain[0] = linearTween(dc_from, dc_to, t);
  90. int last = vital::WaveFrame::kNumRealComplex - 1;
  91. float last_harmonic_from = from->frequency_domain[last].real();
  92. float last_harmonic_to = to->frequency_domain[last].real();
  93. wave_frame_->frequency_domain[last] = linearTween(last_harmonic_from, last_harmonic_to, t);
  94. wave_frame_->toTimeDomain();
  95. }
  96. void WaveSourceKeyframe::cubicFrequencyInterpolate(const vital::WaveFrame* prev, const vital::WaveFrame* from,
  97. const vital::WaveFrame* to, const vital::WaveFrame* next,
  98. float range_prev, float range, float range_next, float t) {
  99. for (int i = 0; i < vital::WaveFrame::kNumRealComplex; ++i) {
  100. float amplitude_prev = sqrtf(std::abs(prev->frequency_domain[i]));
  101. float amplitude_from = sqrtf(std::abs(from->frequency_domain[i]));
  102. float amplitude_to = sqrtf(std::abs(to->frequency_domain[i]));
  103. float amplitude_next = sqrtf(std::abs(next->frequency_domain[i]));
  104. float amplitude = cubicTween(amplitude_prev, amplitude_from, amplitude_to, amplitude_next,
  105. range_prev, range, range_next, t);
  106. amplitude *= amplitude;
  107. float phase_delta_from = std::arg(std::conj(prev->frequency_domain[i]) * from->frequency_domain[i]);
  108. float phase_delta_to = std::arg(std::conj(from->frequency_domain[i]) * to->frequency_domain[i]);
  109. float phase_delta_next = std::arg(std::conj(to->frequency_domain[i]) * next->frequency_domain[i]);
  110. float phase_prev = std::arg(prev->frequency_domain[i]);
  111. float phase_from = phase_prev;
  112. if (amplitude_from)
  113. phase_from += phase_delta_from;
  114. float phase_to = phase_from;
  115. if (amplitude_to)
  116. phase_to += phase_delta_to;
  117. float phase_next = phase_to;
  118. if (amplitude_next)
  119. phase_next += phase_delta_next;
  120. float phase = cubicTween(phase_prev, phase_from, phase_to, phase_next, range_prev, range, range_next, t);
  121. wave_frame_->frequency_domain[i] = std::polar(amplitude, phase);
  122. }
  123. float dc_prev = prev->frequency_domain[0].real();
  124. float dc_from = from->frequency_domain[0].real();
  125. float dc_to = to->frequency_domain[0].real();
  126. float dc_next = next->frequency_domain[0].real();
  127. wave_frame_->frequency_domain[0] = cubicTween(dc_prev, dc_from, dc_to, dc_next, range_prev, range, range_next, t);
  128. int last = vital::WaveFrame::kNumRealComplex - 1;
  129. float last_harmonic_prev = prev->frequency_domain[last].real();
  130. float last_harmonic_from = from->frequency_domain[last].real();
  131. float last_harmonic_to = to->frequency_domain[last].real();
  132. float last_harmonic_next = next->frequency_domain[last].real();
  133. wave_frame_->frequency_domain[last] = cubicTween(last_harmonic_prev, last_harmonic_from,
  134. last_harmonic_to, last_harmonic_next,
  135. range_prev, range, range_next, t);
  136. wave_frame_->toTimeDomain();
  137. }
  138. void WaveSourceKeyframe::interpolate(const WavetableKeyframe* from_keyframe,
  139. const WavetableKeyframe* to_keyframe, float t) {
  140. const WaveSourceKeyframe* from = dynamic_cast<const WaveSourceKeyframe*>(from_keyframe);
  141. const WaveSourceKeyframe* to = dynamic_cast<const WaveSourceKeyframe*>(to_keyframe);
  142. if (interpolation_mode_ == WaveSource::kFrequency)
  143. linearFrequencyInterpolate(from->wave_frame_.get(), to->wave_frame_.get(), t);
  144. else
  145. linearTimeInterpolate(from->wave_frame_.get(), to->wave_frame_.get(), t);
  146. }
  147. void WaveSourceKeyframe::smoothInterpolate(const WavetableKeyframe* prev_keyframe,
  148. const WavetableKeyframe* from_keyframe,
  149. const WavetableKeyframe* to_keyframe,
  150. const WavetableKeyframe* next_keyframe, float t) {
  151. const vital::WaveFrame* prev = dynamic_cast<const WaveSourceKeyframe*>(prev_keyframe)->wave_frame_.get();
  152. const vital::WaveFrame* from = dynamic_cast<const WaveSourceKeyframe*>(from_keyframe)->wave_frame_.get();
  153. const vital::WaveFrame* to = dynamic_cast<const WaveSourceKeyframe*>(to_keyframe)->wave_frame_.get();
  154. const vital::WaveFrame* next = dynamic_cast<const WaveSourceKeyframe*>(next_keyframe)->wave_frame_.get();
  155. float range_prev = from_keyframe->position() - prev_keyframe->position();
  156. float range = to_keyframe->position() - from_keyframe->position();
  157. float range_next = next_keyframe->position() - to_keyframe->position();
  158. if (interpolation_mode_ == WaveSource::kFrequency)
  159. cubicFrequencyInterpolate(prev, from, to, next, range_prev, range, range_next, t);
  160. else
  161. cubicTimeInterpolate(prev, from, to, next, range_prev, range, range_next, t);
  162. }
  163. json WaveSourceKeyframe::stateToJson() {
  164. String encoded = Base64::toBase64(wave_frame_->time_domain, sizeof(float) * vital::WaveFrame::kWaveformSize);
  165. json data = WavetableKeyframe::stateToJson();
  166. data["wave_data"] = encoded.toStdString();
  167. return data;
  168. }
  169. void WaveSourceKeyframe::jsonToState(json data) {
  170. WavetableKeyframe::jsonToState(data);
  171. MemoryOutputStream decoded(sizeof(float) * vital::WaveFrame::kWaveformSize);
  172. std::string wave_data = data["wave_data"];
  173. Base64::convertFromBase64(decoded, wave_data);
  174. memcpy(wave_frame_->time_domain, decoded.getData(), sizeof(float) * vital::WaveFrame::kWaveformSize);
  175. wave_frame_->toFrequencyDomain();
  176. }