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.7KB

  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 "wavetable_group.h"
  17. #include "synth_constants.h"
  18. #include "wave_frame.h"
  19. #include "wave_source.h"
  20. #include "wavetable.h"
  21. int WavetableGroup::getComponentIndex(WavetableComponent* component) {
  22. for (int i = 0; i < components_.size(); ++i) {
  23. if (components_[i].get() == component)
  24. return i;
  25. }
  26. return -1;
  27. }
  28. void WavetableGroup::moveUp(int index) {
  29. if (index <= 0)
  30. return;
  31. components_[index].swap(components_[index - 1]);
  32. }
  33. void WavetableGroup::moveDown(int index) {
  34. if (index < 0 || index >= components_.size() - 1)
  35. return;
  36. components_[index].swap(components_[index + 1]);
  37. }
  38. void WavetableGroup::removeComponent(int index) {
  39. if (index < 0 || index >= components_.size())
  40. return;
  41. std::unique_ptr<WavetableComponent> component = std::move(components_[index]);
  42. components_.erase(components_.begin() + index);
  43. }
  44. void WavetableGroup::reset() {
  45. components_.clear();
  46. loadDefaultGroup();
  47. }
  48. void WavetableGroup::prerender() {
  49. for (auto& component : components_)
  50. component->prerender();
  51. }
  52. bool WavetableGroup::isShepardTone() {
  53. for (auto& component : components_) {
  54. if (component->getType() != WavetableComponentFactory::kShepardToneSource)
  55. return false;
  56. }
  57. return true;
  58. }
  59. void WavetableGroup::render(vital::WaveFrame* wave_frame, float position) const {
  60. wave_frame->index = position;
  61. for (auto& component : components_)
  62. component->render(wave_frame, position);
  63. }
  64. void WavetableGroup::renderTo(vital::Wavetable* wavetable) {
  65. for (int i = 0; i < vital::kNumOscillatorWaveFrames; ++i) {
  66. compute_frame_.index = i;
  67. for (auto& component : components_)
  68. component->render(&compute_frame_, i);
  69. wavetable->loadWaveFrame(&compute_frame_);
  70. }
  71. }
  72. void WavetableGroup::loadDefaultGroup() {
  73. WaveSource* wave_source = new WaveSource();
  74. wave_source->insertNewKeyframe(0);
  75. vital::WaveFrame* wave_frame = wave_source->getWaveFrame(0);
  76. for (int i = 0; i < vital::WaveFrame::kWaveformSize; ++i) {
  77. float t = i / (vital::WaveFrame::kWaveformSize - 1.0f);
  78. int half_shift = (i + vital::WaveFrame::kWaveformSize / 2) % vital::WaveFrame::kWaveformSize;
  79. wave_frame->time_domain[half_shift] = 1.0f - 2.0f * t;
  80. }
  81. wave_frame->toFrequencyDomain();
  82. addComponent(wave_source);
  83. }
  84. int WavetableGroup::getLastKeyframePosition() {
  85. int last_position = 0;
  86. for (auto& component : components_)
  87. last_position = std::max(last_position, component->getLastKeyframePosition());
  88. return last_position;
  89. }
  90. json WavetableGroup::stateToJson() {
  91. json json_components;
  92. for (auto& component : components_) {
  93. json json_component = component->stateToJson();
  94. json_components.push_back(json_component);
  95. }
  96. return { { "components", json_components } };
  97. }
  98. void WavetableGroup::jsonToState(json data) {
  99. components_.clear();
  100. json json_components = data["components"];
  101. for (json json_component : json_components) {
  102. std::string type = json_component["type"];
  103. WavetableComponent* component = WavetableComponentFactory::createComponent(type);
  104. component->jsonToState(json_component);
  105. addComponent(component);
  106. }
  107. }