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

          Line data    Source code
       1             : /**
       2             :  * \file TS9OverdriveFilter.cpp
       3             :  */
       4             : 
       5             : #include "TS9OverdriveFilter.h"
       6             : #include <ATK/Utility/fmath.h>
       7             : #include <ATK/Utility/ScalarNewtonRaphson.h>
       8             : 
       9             : #include <boost/math/special_functions/sign.hpp>
      10             : 
      11             : #include <stdexcept>
      12             : 
      13             : namespace ATK
      14             : {
      15             :   template<typename DataType_>
      16             :   class TS9OverdriveFilter<DataType_>::TS9OverdriveFunction
      17             :   {
      18             :   public:
      19             :     using DataType = DataType_;
      20             :   protected:
      21             :     const DataType R;
      22             :     const DataType R1;
      23             :     const DataType Q;
      24             :     const DataType C;
      25             :     DataType drive = 0.5;
      26             :     const DataType is;
      27             :     const DataType vt;
      28             : 
      29             :     DataType ieq{0};
      30             :     DataType i{0};
      31             : 
      32             :     DataType expdiode_y1_p{1};
      33             :     DataType expdiode_y1_m{1};
      34             : 
      35             :   public:
      36           1 :     TS9OverdriveFunction(DataType dt, DataType R, DataType R1, DataType Q, DataType C, DataType is, DataType vt)
      37           1 :       :R(R), R1(R1), Q(Q), C(2 * C / dt), is(is), vt(vt)
      38             :     {
      39           1 :     }
      40             :     
      41           2 :     void set_drive(DataType drive)
      42             :     {
      43           2 :       this->drive = (R1 + drive * Q);
      44           2 :     }
      45             : 
      46        7752 :     std::pair<DataType, DataType> operator()(const DataType* ATK_RESTRICT input, DataType* ATK_RESTRICT output, DataType y1)
      47             :     {
      48        7752 :       auto x1 = input[0];
      49        7752 :       y1 -= x1;
      50        7752 :       expdiode_y1_p = fmath::exp(y1 / vt);
      51        7752 :       expdiode_y1_m = 1 / expdiode_y1_p;
      52             : 
      53        7752 :       DataType diode1 = is * (expdiode_y1_p - expdiode_y1_m );
      54        7752 :       DataType diode1_derivative = is * (expdiode_y1_p + expdiode_y1_m) / vt;
      55             : 
      56        7752 :       i = (C * x1 - ieq) / (1 + R * C);
      57             : 
      58        7752 :       return std::make_pair(y1 / drive + diode1 - i, 1 / drive + diode1_derivative);
      59             :     }
      60             :     
      61        4000 :     void update_state(const DataType* ATK_RESTRICT input, DataType* ATK_RESTRICT output)
      62             :     {
      63        4000 :       auto x1 = input[0];
      64        4000 :       ieq = 2 * C * (x1 - i * R) - ieq;
      65        4000 :     }
      66             : 
      67        4000 :     DataType estimate(const DataType* ATK_RESTRICT input, DataType* ATK_RESTRICT output)
      68             :     {
      69        4000 :       auto x0 = input[-1];
      70        4000 :       auto x1 = input[0];
      71        4000 :       auto y0 = output[-1];
      72        4000 :       return affine_estimate(x0, x1, y0);
      73             :     }
      74             : 
      75        4000 :     DataType affine_estimate(DataType x0, DataType x1, DataType y0)
      76             :     {
      77        4000 :       y0 -= x0;
      78        4000 :       auto sinh = is * (expdiode_y1_p - expdiode_y1_m );
      79        4000 :       auto cosh = is * (expdiode_y1_p + expdiode_y1_m);
      80        4000 :       auto i = (C * x1 - ieq) / (1 + R * C);
      81             : 
      82        4000 :       return (i - (sinh - y0 / vt * cosh)) / (cosh / vt + (1 / drive)) + x1;
      83             :     }
      84             :   };
      85             :   
      86             :   template <typename DataType>
      87           4 :   TS9OverdriveFilter<DataType>::TS9OverdriveFilter()
      88           4 :     :TypedBaseFilter<DataType>(1, 1)
      89             :   {
      90           4 :     input_delay = 1;
      91           4 :     output_delay = 1;
      92           4 :   }
      93             : 
      94             :   template <typename DataType>
      95           4 :   TS9OverdriveFilter<DataType>::~TS9OverdriveFilter()
      96             :   {
      97           4 :   }
      98             : 
      99             :   template <typename DataType>
     100           1 :   void TS9OverdriveFilter<DataType>::setup()
     101             :   {
     102           1 :     Parent::setup();
     103           1 :     optimizer = std::make_unique<ScalarNewtonRaphson<TS9OverdriveFunction, num_iterations, true>>(TS9OverdriveFunction(static_cast<DataType>(1. / input_sampling_rate),
     104             :       static_cast<DataType>(4.7e3), static_cast<DataType>(51e3), static_cast<DataType>(500e3),
     105             :       static_cast<DataType>(0.047e-6), static_cast<DataType>(1e-12), static_cast<DataType>(26e-3)));
     106             : 
     107           1 :     optimizer->get_function().set_drive(drive);
     108           1 :   }
     109             : 
     110             :   template <typename DataType_>
     111           4 :   void TS9OverdriveFilter<DataType_>::set_drive(DataType_ drive)
     112             :   {
     113           4 :     if(drive < 0 || drive > 1)
     114             :     {
     115           2 :       throw std::out_of_range("Drive must be a value between 0 and 1");
     116             :     }
     117           2 :     this->drive = drive;
     118           2 :     if(optimizer)
     119             :     {
     120           1 :         optimizer->get_function().set_drive(drive);
     121             :     }
     122           2 :   }
     123             : 
     124             :   template <typename DataType_>
     125           1 :   DataType_ TS9OverdriveFilter<DataType_>::get_drive() const
     126             :   {
     127           1 :     return drive;
     128             :   }
     129             : 
     130             :   template <typename DataType>
     131           1 :   void TS9OverdriveFilter<DataType>::process_impl(gsl::index size) const
     132             :   {
     133           1 :     const DataType* ATK_RESTRICT input = converted_inputs[0];
     134           1 :     DataType* ATK_RESTRICT output = outputs[0];
     135        4001 :     for(gsl::index i = 0; i < size; ++i)
     136             :     {
     137        4000 :       optimizer->optimize(input + i, output + i);
     138        4000 :       optimizer->get_function().update_state(input + i, output + i);
     139             :     }
     140           1 :   }
     141             : 
     142             : #if ATK_ENABLE_INSTANTIATION
     143             :   template class TS9OverdriveFilter<float>;
     144             : #endif
     145             :   template class TS9OverdriveFilter<double>;
     146             : }

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