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.

139 lines
4.2KB

  1. // Copyright 2013 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. // Trigger to gate converter with pre-delay, duration, and repetitions.
  28. #include "peaks/pulse_processor/pulse_shaper.h"
  29. #include <algorithm>
  30. #include "stmlib/utils/dsp.h"
  31. #include "peaks/resources.h"
  32. namespace peaks {
  33. using namespace stmlib;
  34. void PulseShaper::Init() {
  35. initial_delay_ = 0;
  36. duration_ = 0;
  37. delay_ = 0;
  38. num_repetitions_ = 0;
  39. Pulse p;
  40. p.initial_delay_counter = 0;
  41. p.duration_counter = 0;
  42. p.delay_counter = 0;
  43. p.repetition_counter = 0;
  44. std::fill(&pulse_buffer_[0], &pulse_buffer_[kPulseBufferSize], p);
  45. previous_num_pulses_ = 0;
  46. retrig_counter_ = 0;
  47. }
  48. inline uint16_t PulseShaper::delay() const {
  49. return Interpolate88(lut_delay_times, delay_) - 1;
  50. }
  51. inline uint16_t PulseShaper::duration() const {
  52. return Interpolate88(lut_delay_times, duration_);
  53. }
  54. inline uint16_t PulseShaper::initial_delay() const {
  55. return Interpolate88(lut_delay_times, initial_delay_);
  56. }
  57. void PulseShaper::FillBuffer(
  58. InputBuffer* input_buffer,
  59. OutputBuffer* output_buffer) {
  60. bool new_pulse = false;
  61. for (uint8_t i = 0; i < kBlockSize; ++i) {
  62. uint8_t control = input_buffer->ImmediateRead();
  63. new_pulse |= control & CONTROL_GATE_RISING;
  64. }
  65. uint8_t num_pulses = 0;
  66. for (uint8_t i = 0; i < kPulseBufferSize; ++i) {
  67. Pulse& p = pulse_buffer_[i];
  68. if (p.repetition_counter) {
  69. // Handle the case when the duration of the pulse is larger than the
  70. // delay time. In this case, set the duration to just a sample below
  71. // the delay time.
  72. if (p.delay_counter < p.duration_counter && p.repetition_counter > 1) {
  73. p.duration_counter = p.delay_counter;
  74. }
  75. if (p.initial_delay_counter == 0) {
  76. if (p.duration_counter) {
  77. // ON
  78. --p.duration_counter;
  79. ++num_pulses;
  80. }
  81. if (p.delay_counter) {
  82. --p.delay_counter;
  83. } else {
  84. // Retrigger
  85. --p.repetition_counter;
  86. p.duration_counter = duration();
  87. p.delay_counter = delay();
  88. }
  89. } else {
  90. // Still in pre-delay phase...
  91. --p.initial_delay_counter;
  92. }
  93. } else {
  94. if (new_pulse) {
  95. p.repetition_counter = num_repetitions_ + 1;
  96. p.initial_delay_counter = initial_delay();
  97. p.duration_counter = duration();
  98. p.delay_counter = delay();
  99. new_pulse = false;
  100. num_pulses += p.initial_delay_counter ? 0 : 1;
  101. }
  102. }
  103. }
  104. // The output is already high, but a new pulse is arriving. Create
  105. // a short dip in the output to retrigger.
  106. if (previous_num_pulses_ && num_pulses > previous_num_pulses_) {
  107. retrig_counter_ = 6;
  108. }
  109. previous_num_pulses_ = num_pulses;
  110. if (retrig_counter_) {
  111. --retrig_counter_;
  112. }
  113. uint16_t output = num_pulses > 0 && !retrig_counter_ ? 20480 : 0;
  114. for (uint8_t i = 0; i < kBlockSize; ++i) {
  115. output_buffer->Overwrite(output);
  116. }
  117. }
  118. } // namespace peaks