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