LCOV - code coverage report
Current view: top level - Dynamic - AttackReleaseHysteresisFilter.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 58 58 100.0 %
Date: 2021-02-18 20:07:22 Functions: 12 12 100.0 %

          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             : }

Generated by: LCOV version TK-3.3.0-4-gdba42eea