MicroDexed is a compatible 6-operator-FM-synth based on the Teensy(-3.6/-4.0) Microcontroller. https://www.parasitstudio.de
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.

98 lines
2.6KB

  1. /*
  2. * Copyright 2013 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. // Low frequency oscillator, compatible with DX7
  17. #include "synth.h"
  18. #include "sin.h"
  19. #include "lfo.h"
  20. uint32_t Lfo::unit_;
  21. void Lfo::init(FRAC_NUM sample_rate) {
  22. // constant is 1 << 32 / 15.5s / 11
  23. Lfo::unit_ = (int32_t)(_N_ * 25190424 / sample_rate + 0.5);
  24. }
  25. void Lfo::reset(const uint8_t params[6]) {
  26. int rate = params[0]; // 0..99
  27. int sr = rate == 0 ? 1 : (165 * rate) >> 6;
  28. sr *= sr < 160 ? 11 : (11 + ((sr - 160) >> 4));
  29. delta_ = unit_ * sr;
  30. int a = 99 - params[1]; // LFO delay
  31. if (a == 99) {
  32. delayinc_ = ~0u;
  33. delayinc2_ = ~0u;
  34. } else {
  35. a = (16 + (a & 15)) << (1 + (a >> 4));
  36. delayinc_ = unit_ * a;
  37. a &= 0xff80;
  38. a = max(0x80, a);
  39. delayinc2_ = unit_ * a;
  40. }
  41. waveform_ = params[5];
  42. sync_ = params[4] != 0;
  43. }
  44. int32_t Lfo::getsample() {
  45. phase_ += delta_;
  46. int32_t x;
  47. switch (waveform_) {
  48. case 0: // triangle
  49. x = phase_ >> 7;
  50. x ^= -(phase_ >> 31);
  51. x &= (1 << 24) - 1;
  52. return x;
  53. case 1: // sawtooth down
  54. return (~phase_ ^ (1U << 31)) >> 8;
  55. case 2: // sawtooth up
  56. return (phase_ ^ (1U << 31)) >> 8;
  57. case 3: // square
  58. return ((~phase_) >> 7) & (1 << 24);
  59. case 4: // sine
  60. return (1 << 23) + (Sin::lookup(phase_ >> 8) >> 1);
  61. case 5: // s&h
  62. if (phase_ < delta_) {
  63. randstate_ = (randstate_ * 179 + 17) & 0xff;
  64. }
  65. x = randstate_ ^ 0x80;
  66. return (x + 1) << 16;
  67. }
  68. return 1 << 23;
  69. }
  70. int32_t Lfo::getdelay() {
  71. uint32_t delta = delaystate_ < (1U << 31) ? delayinc_ : delayinc2_;
  72. uint64_t d = ((uint64_t)delaystate_) + delta;
  73. if (d > ~0u) {
  74. return 1 << 24;
  75. }
  76. delaystate_ = d;
  77. if (d < (1U << 31)) {
  78. return 0;
  79. } else {
  80. return (d >> 7) & ((1 << 24) - 1);
  81. }
  82. }
  83. void Lfo::keydown() {
  84. if (sync_) {
  85. phase_ = (1U << 31) - 1;
  86. }
  87. delaystate_ = 0;
  88. }