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.

142 lines
3.6KB

  1. /*
  2. * Copyright 2017 Pascal Gauthier.
  3. * Copyright 2012 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include <math.h>
  18. #include "synth.h"
  19. #include "env.h"
  20. //using namespace std;
  21. uint32_t Env::sr_multiplier = (1<<24);
  22. const int levellut[] = {
  23. 0, 5, 9, 13, 17, 20, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 42, 43, 45, 46
  24. };
  25. void Env::init_sr(FRAC_NUM sampleRate) {
  26. sr_multiplier = (44100.0 / sampleRate) * (1<<24);
  27. }
  28. void Env::init(const int r[4], const int l[4], int32_t ol, int rate_scaling) {
  29. for (int i = 0; i < 4; i++) {
  30. rates_[i] = r[i];
  31. levels_[i] = l[i];
  32. }
  33. outlevel_ = ol;
  34. rate_scaling_ = rate_scaling;
  35. level_ = 0;
  36. down_ = true;
  37. advance(0);
  38. }
  39. int32_t Env::getsample() {
  40. if (ix_ < 3 || ((ix_ < 4) && !down_)) {
  41. if (rising_) {
  42. const int jumptarget = 1716;
  43. if (level_ < (jumptarget << 16)) {
  44. level_ = jumptarget << 16;
  45. }
  46. level_ += (((17 << 24) - level_) >> 24) * inc_;
  47. // TODO: should probably be more accurate when inc is large
  48. if (level_ >= targetlevel_) {
  49. level_ = targetlevel_;
  50. advance(ix_ + 1);
  51. }
  52. } else { // !rising
  53. level_ -= inc_;
  54. if (level_ <= targetlevel_) {
  55. level_ = targetlevel_;
  56. advance(ix_ + 1);
  57. }
  58. }
  59. }
  60. // TODO: this would be a good place to set level to 0 when under threshold
  61. return level_;
  62. }
  63. void Env::keydown(bool d) {
  64. if (down_ != d) {
  65. down_ = d;
  66. advance(d ? 0 : 3);
  67. }
  68. }
  69. int Env::scaleoutlevel(int outlevel) {
  70. return outlevel >= 20 ? 28 + outlevel : levellut[outlevel];
  71. }
  72. void Env::advance(int newix) {
  73. ix_ = newix;
  74. if (ix_ < 4) {
  75. int newlevel = levels_[ix_];
  76. int actuallevel = scaleoutlevel(newlevel) >> 1;
  77. actuallevel = (actuallevel << 6) + outlevel_ - 4256;
  78. actuallevel = actuallevel < 16 ? 16 : actuallevel;
  79. // level here is same as Java impl
  80. targetlevel_ = actuallevel << 16;
  81. rising_ = (targetlevel_ > level_);
  82. // rate
  83. int qrate = (rates_[ix_] * 41) >> 6;
  84. qrate += rate_scaling_;
  85. qrate = min(qrate, 63);
  86. inc_ = (4 + (qrate & 3)) << (2 + LG_N + (qrate >> 2));
  87. // meh, this should be fixed elsewhere
  88. inc_ = ((int64_t)inc_ * (int64_t)sr_multiplier) >> 24;
  89. }
  90. }
  91. void Env::update(const int r[4], const int l[4], int32_t ol, int rate_scaling) {
  92. for (int i = 0; i < 4; i++) {
  93. rates_[i] = r[i];
  94. levels_[i] = l[i];
  95. }
  96. outlevel_ = ol;
  97. rate_scaling_ = rate_scaling;
  98. if ( down_ ) {
  99. // for now we simply reset ourselve at level 3
  100. int newlevel = levels_[2];
  101. int actuallevel = scaleoutlevel(newlevel) >> 1;
  102. actuallevel = (actuallevel << 6) - 4256;
  103. actuallevel = actuallevel < 16 ? 16 : actuallevel;
  104. targetlevel_ = actuallevel << 16;
  105. advance(2);
  106. }
  107. }
  108. void Env::getPosition(char *step) {
  109. *step = ix_;
  110. }
  111. void Env::transfer(Env &src) {
  112. for(int i=0;i<4;i++) {
  113. rates_[i] = src.rates_[i];
  114. levels_[i] = src.levels_[i];
  115. }
  116. outlevel_ = src.outlevel_;
  117. rate_scaling_ = src.rate_scaling_;
  118. level_ = src.level_;
  119. targetlevel_ = src.targetlevel_;
  120. rising_= src.rising_;
  121. ix_ = src.ix_;
  122. inc_ = src.inc_;
  123. down_ = src.down_;
  124. }