| 124 | |
| 125 | |
| 126 | int perform_lowpass (double *data, int data_len, int sampling_rate, double cutoff, int order, |
| 127 | int filter_type, double ripple) |
| 128 | { |
| 129 | if ((order < 1) || (order > MAX_FILTER_ORDER) || (!data) || (cutoff < 0) || (sampling_rate < 1)) |
| 130 | { |
| 131 | data_logger->error ( |
| 132 | "Order must be from 1-8 and data cannot be empty. Order:{} , Data:{} , Cutoff:{}", |
| 133 | order, (data != NULL), cutoff); |
| 134 | return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; |
| 135 | } |
| 136 | |
| 137 | double *filter_data[1]; |
| 138 | filter_data[0] = data; |
| 139 | Dsp::Filter *f = NULL; |
| 140 | |
| 141 | switch (static_cast<FilterTypes> (filter_type)) |
| 142 | { |
| 143 | case FilterTypes::BUTTERWORTH: |
| 144 | f = new Dsp::FilterDesign<Dsp::Butterworth::Design::LowPass<MAX_FILTER_ORDER>, 1> (); |
| 145 | break; |
| 146 | case FilterTypes::BUTTERWORTH_ZERO_PHASE: |
| 147 | f = new Dsp::FilterDesign<Dsp::Butterworth::Design::LowPass<MAX_FILTER_ORDER>, 1> (); |
| 148 | break; |
| 149 | case FilterTypes::CHEBYSHEV_TYPE_1: |
| 150 | f = new Dsp::FilterDesign<Dsp::ChebyshevI::Design::LowPass<MAX_FILTER_ORDER>, 1> (); |
| 151 | break; |
| 152 | case FilterTypes::CHEBYSHEV_TYPE_1_ZERO_PHASE: |
| 153 | f = new Dsp::FilterDesign<Dsp::ChebyshevI::Design::LowPass<MAX_FILTER_ORDER>, 1> (); |
| 154 | break; |
| 155 | case FilterTypes::BESSEL: |
| 156 | f = new Dsp::FilterDesign<Dsp::Bessel::Design::LowPass<MAX_FILTER_ORDER>, 1> (); |
| 157 | break; |
| 158 | case FilterTypes::BESSEL_ZERO_PHASE: |
| 159 | f = new Dsp::FilterDesign<Dsp::Bessel::Design::LowPass<MAX_FILTER_ORDER>, 1> (); |
| 160 | break; |
| 161 | default: |
| 162 | data_logger->error ("Filter type {} is Invalid", filter_type); |
| 163 | return (int)BrainFlowExitCodes::INVALID_ARGUMENTS_ERROR; |
| 164 | } |
| 165 | |
| 166 | Dsp::Params params; |
| 167 | params[0] = sampling_rate; // sample rate |
| 168 | params[1] = order; // order |
| 169 | params[2] = cutoff; // cutoff |
| 170 | if ((filter_type == (int)FilterTypes::CHEBYSHEV_TYPE_1) || |
| 171 | (filter_type == (int)FilterTypes::CHEBYSHEV_TYPE_1_ZERO_PHASE)) |
| 172 | { |
| 173 | params[3] = ripple; // ripple |
| 174 | } |
| 175 | f->setParams (params); |
| 176 | f->process (data_len, filter_data); |
| 177 | if ((filter_type == (int)FilterTypes::BUTTERWORTH_ZERO_PHASE) || |
| 178 | (filter_type == (int)FilterTypes::CHEBYSHEV_TYPE_1_ZERO_PHASE) || |
| 179 | (filter_type == (int)FilterTypes::BESSEL_ZERO_PHASE)) |
| 180 | { |
| 181 | reverse_array (data, data_len); |
| 182 | f->process (data_len, filter_data); |
| 183 | reverse_array (data, data_len); |
no test coverage detected