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.

140 lines
4.0KB

  1. // Copyright 2014 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // Vactrol.
  28. #ifndef STREAMS_VACTROL_H_
  29. #define STREAMS_VACTROL_H_
  30. #include "stmlib/stmlib.h"
  31. #include "streams/meta_parameters.h"
  32. #include "streams/resources.h"
  33. namespace streams {
  34. class Vactrol {
  35. public:
  36. Vactrol() { }
  37. ~Vactrol() { }
  38. void Init();
  39. void Process(
  40. int16_t audio,
  41. int16_t excite,
  42. uint16_t* gain,
  43. uint16_t* frequency);
  44. void Configure(bool alternate, int32_t* parameters, int32_t* globals) {
  45. uint16_t attack_time;
  46. uint16_t decay_time;
  47. if (globals) {
  48. // Attack: 10ms to 1000ms
  49. attack_time = 128 + (globals[0] >> 8);
  50. // Decay: 10ms to 5000ms
  51. decay_time = 128 + (globals[2] * 355 >> 16);
  52. ComputeAmountOffset(
  53. parameters[1],
  54. &target_frequency_amount_,
  55. &target_frequency_offset_);
  56. } else {
  57. uint16_t shape = parameters[0];
  58. ComputeAmountOffset(
  59. parameters[1],
  60. &target_frequency_amount_,
  61. &target_frequency_offset_);
  62. if (shape < 32768) {
  63. // attack: 10ms
  64. attack_time = 128;
  65. // decay: 50ms to 2000ms
  66. decay_time = 227 + (shape * 196 >> 15);
  67. } else if (shape < 49512) {
  68. shape -= 32768;
  69. // attack: 10ms to 500ms.
  70. attack_time = 128 + (shape * 227 >> 15);
  71. // decay: 2000ms to 1000ms.
  72. decay_time = 423 - (89 * shape >> 15);
  73. } else {
  74. shape -= 49512;
  75. // attack: 500ms to 50ms.
  76. attack_time = 355 - (shape >> 7);
  77. // decay: 1000ms to 100ms.
  78. decay_time = 384 - (128 * shape >> 15);
  79. }
  80. }
  81. attack_coefficient_ = lut_lp_coefficients[attack_time];
  82. fast_attack_coefficient_ = lut_lp_coefficients[attack_time - 128];
  83. decay_coefficient_ = lut_lp_coefficients[decay_time];
  84. fast_decay_coefficient_ = lut_lp_coefficients[decay_time - 128];
  85. plucked_ = alternate;
  86. if (alternate) {
  87. fast_attack_coefficient_ <<= 4;
  88. } else {
  89. decay_coefficient_ >>= 1;
  90. }
  91. int32_t ringing_tail = 8192;
  92. int32_t headroom = 65535 - target_frequency_offset_;
  93. if (ringing_tail > headroom) {
  94. ringing_tail = headroom;
  95. }
  96. if (ringing_tail > target_frequency_amount_) {
  97. ringing_tail = target_frequency_amount_;
  98. }
  99. target_frequency_offset_ += ringing_tail;
  100. target_frequency_amount_ -= ringing_tail;
  101. }
  102. private:
  103. int32_t target_frequency_amount_;
  104. int32_t target_frequency_offset_;
  105. int32_t frequency_amount_;
  106. int32_t frequency_offset_;
  107. int32_t attack_coefficient_;
  108. int32_t decay_coefficient_;
  109. int32_t fast_attack_coefficient_;
  110. int32_t fast_decay_coefficient_;
  111. int32_t state_[4];
  112. int32_t excite_;
  113. bool gate_;
  114. bool plucked_;
  115. DISALLOW_COPY_AND_ASSIGN(Vactrol);
  116. };
  117. } // namespace streams
  118. #endif // STREAMS_VACTROL_H_