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.

123 lines
3.4KB

  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. // Create random repetitions of a pulse.
  28. #include "peaks/pulse_processor/pulse_randomizer.h"
  29. #include <algorithm>
  30. #include "stmlib/utils/dsp.h"
  31. #include "stmlib/utils/random.h"
  32. #include "peaks/resources.h"
  33. namespace peaks {
  34. using namespace stmlib;
  35. static const uint8_t kDownsample = 8;
  36. void PulseRandomizer::Init() {
  37. repetition_probability_ = 32767;
  38. acceptance_probability_ = 65535;
  39. delay_average_ = 32767;
  40. delay_randomness_ = 0;
  41. std::fill(
  42. &delay_counter_[0],
  43. &delay_counter_[kTriggerPulseBufferSize],
  44. 0xffff);
  45. num_pulses_ = 0;
  46. retrig_counter_ = 0;
  47. }
  48. inline uint16_t PulseRandomizer::delay() const {
  49. int32_t delay = delay_average_;
  50. delay += delay_average_ + (Random::GetSample() * delay_randomness_ >> 16);
  51. if (delay < 0) {
  52. delay = 0;
  53. } else if (delay > 0xffff) {
  54. delay = 0xffff;
  55. }
  56. return Interpolate88(lut_delay_times, delay);
  57. }
  58. void PulseRandomizer::FillBuffer(
  59. InputBuffer* input_buffer,
  60. OutputBuffer* output_buffer) {
  61. bool new_pulse = false;
  62. for (uint8_t i = 0; i < kBlockSize; ++i) {
  63. uint8_t control = input_buffer->ImmediateRead();
  64. new_pulse |= control & CONTROL_GATE_RISING;
  65. }
  66. if ((Random::GetWord() >> 16) > acceptance_probability_) {
  67. // Randomly ignore incoming pulses.
  68. new_pulse = false;
  69. }
  70. if (new_pulse) {
  71. ++num_pulses_;
  72. }
  73. for (uint8_t i = 0; i < kTriggerPulseBufferSize; ++i) {
  74. if (delay_counter_[i] == 0xffff) {
  75. if (new_pulse) {
  76. delay_counter_[i] = delay();
  77. new_pulse = false;
  78. }
  79. } else if (delay_counter_[i]) {
  80. --delay_counter_[i];
  81. } else {
  82. if ((Random::GetWord() >> 16) < repetition_probability_) {
  83. ++num_pulses_;
  84. delay_counter_[i] = delay();
  85. } else {
  86. delay_counter_[i] = 0xffff;
  87. }
  88. }
  89. }
  90. if (retrig_counter_) {
  91. --retrig_counter_;
  92. } else {
  93. if (num_pulses_) {
  94. retrig_counter_ = 12;
  95. --num_pulses_;
  96. }
  97. }
  98. uint16_t output = retrig_counter_ > 6 ? 20480 : 0;
  99. for (uint8_t i = 0; i < kBlockSize; ++i) {
  100. output_buffer->Overwrite(output);
  101. }
  102. }
  103. } // namespace peaks