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.

175 lines
4.9KB

  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. // Generic class interfacing all dynamics processors.
  28. #ifndef STREAMS_PROCESSOR_H_
  29. #define STREAMS_PROCESSOR_H_
  30. #include <cstdio>
  31. #include "stmlib/stmlib.h"
  32. #include "streams/compressor.h"
  33. #include "streams/envelope.h"
  34. #include "streams/filter_controller.h"
  35. #include "streams/follower.h"
  36. #include "streams/lorenz_generator.h"
  37. #include "streams/vactrol.h"
  38. namespace streams {
  39. enum ProcessorFunction {
  40. PROCESSOR_FUNCTION_ENVELOPE,
  41. PROCESSOR_FUNCTION_VACTROL,
  42. PROCESSOR_FUNCTION_FOLLOWER,
  43. PROCESSOR_FUNCTION_COMPRESSOR,
  44. PROCESSOR_FUNCTION_FILTER_CONTROLLER,
  45. PROCESSOR_FUNCTION_LORENZ_GENERATOR,
  46. PROCESSOR_FUNCTION_LAST
  47. };
  48. #define DECLARE_PROCESSOR(ClassName, variable) \
  49. void ClassName ## Init() { \
  50. variable.Init(); \
  51. } \
  52. void ClassName ## Process(int16_t a, int16_t e, uint16_t* g, uint16_t* f) { \
  53. variable.Process(a, e, g, f); \
  54. } \
  55. void ClassName ## Configure(bool a, int32_t* p, int32_t* g) { \
  56. variable.Configure(a, p, g); \
  57. } \
  58. ClassName variable;
  59. class Processor {
  60. public:
  61. Processor() { }
  62. ~Processor() { }
  63. void Init(uint8_t index);
  64. void Init() { Init(0); }
  65. typedef void (Processor::*InitFn)();
  66. typedef void (Processor::*ProcessFn)(
  67. int16_t,
  68. int16_t,
  69. uint16_t*,
  70. uint16_t*);
  71. typedef void (Processor::*ConfigureFn)(
  72. bool,
  73. int32_t*,
  74. int32_t*);
  75. struct ProcessorCallbacks {
  76. InitFn init;
  77. ProcessFn process;
  78. ConfigureFn configure;
  79. };
  80. inline void set_function(ProcessorFunction function) {
  81. function_ = function;
  82. callbacks_ = callbacks_table_[function];
  83. (this->*callbacks_.init)();
  84. dirty_ = true;
  85. }
  86. inline void set_alternate(bool alternate) {
  87. alternate_ = alternate;
  88. dirty_ = true;
  89. }
  90. inline void set_linked(bool linked) {
  91. linked_ = linked;
  92. dirty_ = true;
  93. }
  94. inline void set_parameter(uint16_t index, uint16_t value) {
  95. parameters_[index] = value;
  96. dirty_ = true;
  97. }
  98. inline void set_global(uint16_t index, uint16_t value) {
  99. globals_[index] = value;
  100. dirty_ = linked_;
  101. }
  102. inline ProcessorFunction function() const { return function_; }
  103. inline bool alternate() const { return alternate_; }
  104. inline bool linked() const { return linked_; }
  105. inline uint8_t last_frequency() const { return last_frequency_value_ >> 8; }
  106. inline uint8_t last_gain() const { return last_gain_value_ >> 8; }
  107. inline int32_t gain_reduction() const { return compressor_.gain_reduction(); }
  108. inline void Process(
  109. int16_t audio,
  110. int16_t excite,
  111. uint16_t* gain,
  112. uint16_t* frequency) {
  113. (this->*callbacks_.process)(audio, excite, gain, frequency);
  114. last_gain_value_ = *gain;
  115. last_frequency_value_ = *frequency;
  116. }
  117. void Configure() {
  118. if (!dirty_) {
  119. return;
  120. }
  121. (this->*callbacks_.configure)(
  122. alternate_,
  123. parameters_,
  124. linked_ ? globals_ : NULL);
  125. dirty_ = false;
  126. }
  127. private:
  128. uint8_t index_;
  129. ProcessorFunction function_;
  130. bool linked_;
  131. bool alternate_;
  132. bool dirty_;
  133. int32_t parameters_[2];
  134. int32_t globals_[4];
  135. uint16_t last_gain_value_;
  136. uint16_t last_frequency_value_;
  137. ProcessorCallbacks callbacks_;
  138. static const ProcessorCallbacks callbacks_table_[PROCESSOR_FUNCTION_LAST];
  139. DECLARE_PROCESSOR(Envelope, envelope_);
  140. DECLARE_PROCESSOR(Vactrol, vactrol_);
  141. DECLARE_PROCESSOR(Follower, follower_);
  142. DECLARE_PROCESSOR(Compressor, compressor_);
  143. DECLARE_PROCESSOR(FilterController, filter_controller_);
  144. DECLARE_PROCESSOR(LorenzGenerator, lorenz_generator_);
  145. DISALLOW_COPY_AND_ASSIGN(Processor);
  146. };
  147. } // namespace streams
  148. #endif // STREAMS_PROCESSOR_H_