Line data Source code
1 : /** 2 : * \file AttackReleaseHysteresisFilter.cpp 3 : */ 4 : 5 : #include "AttackReleaseHysteresisFilter.h" 6 : #include <ATK/Core/Utilities.h> 7 : 8 : #include <cassert> 9 : #include <cmath> 10 : #include <cstdint> 11 : 12 : namespace ATK 13 : { 14 : template<typename DataType_> 15 16 : AttackReleaseHysteresisFilter<DataType_>::AttackReleaseHysteresisFilter(gsl::index nb_channels) 16 16 : :Parent(nb_channels, nb_channels) 17 : { 18 16 : output_delay = 1; 19 16 : } 20 : 21 : template<typename DataType_> 22 5 : void AttackReleaseHysteresisFilter<DataType_>::set_attack(DataType_ attack) 23 : { 24 5 : if(attack < 0) 25 : { 26 1 : throw ATK::RuntimeError("Attack factor must be positive value"); 27 : } 28 4 : if(attack > 1) 29 : { 30 1 : throw ATK::RuntimeError("Attack factor must be less than 1"); 31 : } 32 3 : this->attack = attack; 33 3 : } 34 : 35 : template<typename DataType_> 36 1 : DataType_ AttackReleaseHysteresisFilter<DataType_>::get_attack() const 37 : { 38 1 : return attack; 39 : } 40 : 41 : template<typename DataType_> 42 5 : void AttackReleaseHysteresisFilter<DataType_>::set_release(DataType_ release) 43 : { 44 5 : if(release < 0) 45 : { 46 1 : throw ATK::RuntimeError("Release factor must be positive value"); 47 : } 48 4 : if(release > 1) 49 : { 50 1 : throw ATK::RuntimeError("Release factor must be less than 1"); 51 : } 52 3 : this->release = release; 53 3 : } 54 : 55 : template<typename DataType_> 56 1 : DataType_ AttackReleaseHysteresisFilter<DataType_>::get_release() const 57 : { 58 1 : return release; 59 : } 60 : 61 : template<typename DataType_> 62 4 : void AttackReleaseHysteresisFilter<DataType_>::set_attack_hysteresis(DataType_ attack_hysteresis) 63 : { 64 4 : if(attack_hysteresis < release_hysteresis) 65 : { 66 1 : throw ATK::RuntimeError("Attack hysteresis factor must be bigger than release hysteresis"); 67 : } 68 3 : if(attack_hysteresis > 1) 69 : { 70 1 : throw ATK::RuntimeError("Attack hysteresis factor must be smaller than 1"); 71 : } 72 2 : this->attack_hysteresis = attack_hysteresis; 73 2 : } 74 : 75 : template<typename DataType_> 76 1 : void AttackReleaseHysteresisFilter<DataType_>::set_attack_hysteresis_db(DataType_ attack_hysteresis_db) 77 : { 78 1 : set_attack_hysteresis(static_cast<DataType_>(std::pow(10., attack_hysteresis_db/20))); 79 1 : } 80 : 81 : template<typename DataType_> 82 2 : DataType_ AttackReleaseHysteresisFilter<DataType_>::get_attack_hysteresis() const 83 : { 84 2 : return attack_hysteresis; 85 : } 86 : 87 : template<typename DataType_> 88 8 : void AttackReleaseHysteresisFilter<DataType_>::set_release_hysteresis(DataType_ release_hysteresis) 89 : { 90 8 : if(release_hysteresis < 0) 91 : { 92 1 : throw ATK::RuntimeError("Release hysteresis factor must be positive"); 93 : } 94 7 : if(release_hysteresis > 1) 95 : { 96 1 : throw ATK::RuntimeError("Release hysteresis factor must be smaller than 1"); 97 : } 98 6 : this->release_hysteresis = release_hysteresis; 99 6 : } 100 : 101 : template<typename DataType_> 102 1 : void AttackReleaseHysteresisFilter<DataType_>::set_release_hysteresis_db(DataType_ release_hysteresis_db) 103 : { 104 1 : set_release_hysteresis(static_cast<DataType_>(std::pow(10., release_hysteresis_db/20))); 105 1 : } 106 : 107 : template<typename DataType_> 108 2 : DataType_ AttackReleaseHysteresisFilter<DataType_>::get_release_hysteresis() const 109 : { 110 2 : return release_hysteresis; 111 : } 112 : 113 : template<typename DataType_> 114 2 : void AttackReleaseHysteresisFilter<DataType_>::process_impl(gsl::index size) const 115 : { 116 2 : assert(nb_input_ports == nb_output_ports); 117 4 : for(gsl::index channel = 0; channel < nb_input_ports; ++channel) 118 : { 119 2 : const DataType* ATK_RESTRICT input = converted_inputs[channel]; 120 2 : DataType* ATK_RESTRICT output = outputs[channel]; 121 65545 : for(gsl::index i = 0; i < size; ++i) 122 : { 123 65543 : if(output[i-1] * attack_hysteresis < input[i]) 124 : { 125 1 : output[i] = (1 - attack) * input[i] + attack * output[i-1];//attack phase 126 : } 127 : else 128 : { 129 65542 : if(output[i-1] * release_hysteresis > input[i]) 130 : { 131 3 : output[i] = (1 - release) * input[i] + release * output[i-1];//release phase 132 : } 133 : else 134 : { 135 65539 : output[i] = output[i-1]; 136 : } 137 : } 138 : } 139 : } 140 2 : } 141 : 142 : #if ATK_ENABLE_INSTANTIATION 143 : template class AttackReleaseHysteresisFilter<float>; 144 : #endif 145 : template class AttackReleaseHysteresisFilter<double>; 146 : }