EMG input library biorobortics 31-10-2016

Dependencies:   HIDScope mbed

Fork of EMG by Tom Tom

Committer:
kbruil
Date:
Mon Oct 31 12:30:20 2016 +0000
Revision:
29:98406a20a42b
Parent:
22:c01f61be07e0
Code project biorobotics 31-10-2016;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kbruil 22:c01f61be07e0 1 /*
kbruil 22:c01f61be07e0 2 * FIR filter class, by Mike Perkins
kbruil 22:c01f61be07e0 3 *
kbruil 22:c01f61be07e0 4 * a simple C++ class for linear phase FIR filtering
kbruil 22:c01f61be07e0 5 *
kbruil 22:c01f61be07e0 6 * For background, see the post http://www.cardinalpeak.com/blog?p=1841
kbruil 22:c01f61be07e0 7 *
kbruil 22:c01f61be07e0 8 * Copyright (c) 2013, Cardinal Peak, LLC. http://www.cardinalpeak.com
kbruil 22:c01f61be07e0 9 *
kbruil 22:c01f61be07e0 10 * Redistribution and use in source and binary forms, with or without
kbruil 22:c01f61be07e0 11 * modification, are permitted provided that the following conditions
kbruil 22:c01f61be07e0 12 * are met:
kbruil 22:c01f61be07e0 13 *
kbruil 22:c01f61be07e0 14 * 1) Redistributions of source code must retain the above copyright
kbruil 22:c01f61be07e0 15 * notice, this list of conditions and the following disclaimer.
kbruil 22:c01f61be07e0 16 *
kbruil 22:c01f61be07e0 17 * 2) Redistributions in binary form must reproduce the above
kbruil 22:c01f61be07e0 18 * copyright notice, this list of conditions and the following
kbruil 22:c01f61be07e0 19 * disclaimer in the documentation and/or other materials provided
kbruil 22:c01f61be07e0 20 * with the distribution.
kbruil 22:c01f61be07e0 21 *
kbruil 22:c01f61be07e0 22 * 3) Neither the name of Cardinal Peak nor the names of its
kbruil 22:c01f61be07e0 23 * contributors may be used to endorse or promote products derived
kbruil 22:c01f61be07e0 24 * from this software without specific prior written permission.
kbruil 22:c01f61be07e0 25 *
kbruil 22:c01f61be07e0 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
kbruil 22:c01f61be07e0 27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
kbruil 22:c01f61be07e0 28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
kbruil 22:c01f61be07e0 29 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
kbruil 22:c01f61be07e0 30 * CARDINAL PEAK, LLC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
kbruil 22:c01f61be07e0 31 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
kbruil 22:c01f61be07e0 32 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
kbruil 22:c01f61be07e0 33 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
kbruil 22:c01f61be07e0 34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
kbruil 22:c01f61be07e0 35 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
kbruil 22:c01f61be07e0 36 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
kbruil 22:c01f61be07e0 37 * SUCH DAMAGE.
kbruil 22:c01f61be07e0 38 */
kbruil 22:c01f61be07e0 39
kbruil 22:c01f61be07e0 40 /*
kbruil 22:c01f61be07e0 41 *
kbruil 22:c01f61be07e0 42 * PURPOSE:
kbruil 22:c01f61be07e0 43 * This object designs digital filters and filters digital data streams
kbruil 22:c01f61be07e0 44 *
kbruil 22:c01f61be07e0 45 * USAGE:
kbruil 22:c01f61be07e0 46 * Invoke an object of type Filter. Two constructors are available.
kbruil 22:c01f61be07e0 47 * One is used for LPF and HPF filters, one is used for BPFs.
kbruil 22:c01f61be07e0 48 * The arguments to the constructors are as follows:
kbruil 22:c01f61be07e0 49 *
kbruil 22:c01f61be07e0 50 * // For LPF or HPF only
kbruil 22:c01f61be07e0 51 * Filter(filterType filt_t, int num_taps, double Fs, double Fx);
kbruil 22:c01f61be07e0 52 * // For BPF only
kbruil 22:c01f61be07e0 53 * Filter(filterType filt_t, int num_taps, double Fs, double Fl, double Fu);
kbruil 22:c01f61be07e0 54 *
kbruil 22:c01f61be07e0 55 * filt_t: is LPF, HPF or BPF
kbruil 22:c01f61be07e0 56 * num_taps: is the number of taps you want the filter to use
kbruil 22:c01f61be07e0 57 * Fs: is the sampling frequency of the digital data being filtered
kbruil 22:c01f61be07e0 58 * Fx: is the "transition" frequency for LPF and HPF filters
kbruil 22:c01f61be07e0 59 * Fl, Fu: are the upper and lower transition frequencies for BPF filters
kbruil 22:c01f61be07e0 60 *
kbruil 22:c01f61be07e0 61 * Once the filter is created, you can start filtering data. Here
kbruil 22:c01f61be07e0 62 * is an example for 51 tap lowpass filtering of an audio stream sampled at
kbruil 22:c01f61be07e0 63 * 44.1Khz (the CD sampling rate), where the goal is to create a signal
kbruil 22:c01f61be07e0 64 * of "telephone" bandwidth (4Khz):
kbruil 22:c01f61be07e0 65 *
kbruil 22:c01f61be07e0 66 * Filter *my_filter;
kbruil 22:c01f61be07e0 67 *
kbruil 22:c01f61be07e0 68 * my_filter = new Filter(LPF, 51, 44.1, 4.0)
kbruil 22:c01f61be07e0 69 * if( my_filter->get_error_flag() != 0 ) // abort in an appropriate manner
kbruil 22:c01f61be07e0 70 *
kbruil 22:c01f61be07e0 71 * while(data_to_be_filtered){
kbruil 22:c01f61be07e0 72 * next_sample = // Get the next sample from the data stream somehow
kbruil 22:c01f61be07e0 73 * filtered_sample = my_filter->do_sample( next_sample );
kbruil 22:c01f61be07e0 74 * .
kbruil 22:c01f61be07e0 75 * .
kbruil 22:c01f61be07e0 76 * .
kbruil 22:c01f61be07e0 77 * }
kbruil 22:c01f61be07e0 78 * delete my_filter;
kbruil 22:c01f61be07e0 79 *
kbruil 22:c01f61be07e0 80 * Several helper functions are provided:
kbruil 22:c01f61be07e0 81 * init(): The filter can be re-initialized with a call to this function
kbruil 22:c01f61be07e0 82 * get_taps(double *taps): returns the filter taps in the array "taps"
kbruil 22:c01f61be07e0 83 * write_taps_to_file(char *filename): writes the filter taps to a file
kbruil 22:c01f61be07e0 84 * write_freqres_to_file(char *filename): output frequency response to a file
kbruil 22:c01f61be07e0 85 *
kbruil 22:c01f61be07e0 86 * Finally, a get_error_flag() function is provided. Recommended usage
kbruil 22:c01f61be07e0 87 * is to check the get_error_flag() return value for a non-zero
kbruil 22:c01f61be07e0 88 * value after the new Filter object is created. If it is non-zero, print
kbruil 22:c01f61be07e0 89 * out the non-zero value and look at the following table to see the
kbruil 22:c01f61be07e0 90 * error:
kbruil 22:c01f61be07e0 91 * -1: Fs <= 0
kbruil 22:c01f61be07e0 92 * -2: Fx <= 0 or Fx >= Fs/2
kbruil 22:c01f61be07e0 93 * -3: num_taps <= 0 or num_taps >= MAX_NUM_FILTER_TAPS
kbruil 22:c01f61be07e0 94 * -4: memory allocation for the needed arrays failed
kbruil 22:c01f61be07e0 95 * -5: an invalid filterType was passed into a constructor
kbruil 22:c01f61be07e0 96 * -10: Fs <= 0 (BPF case)
kbruil 22:c01f61be07e0 97 * -11: Fl >= Fu
kbruil 22:c01f61be07e0 98 * -12: Fl <= 0 || Fl >= Fs/2
kbruil 22:c01f61be07e0 99 * -13: Fu <= 0 || Fu >= Fs/2
kbruil 22:c01f61be07e0 100 * -14: num_taps <= 0 or num_taps >= MAX_NUM_FILTER_TAPS (BPF case)
kbruil 22:c01f61be07e0 101 * -15: memory allocation for the needed arrays failed (BPF case)
kbruil 22:c01f61be07e0 102 * -16: an invalid filterType was passed into a constructor (BPF case)
kbruil 22:c01f61be07e0 103 *
kbruil 22:c01f61be07e0 104 * Note that if a non-zero error code value occurs, every call to do_sample()
kbruil 22:c01f61be07e0 105 * will return the value 0. write_taps_fo_file() will fail and return a -1 (it
kbruil 22:c01f61be07e0 106 * also returns a -1 if it fails to open the tap file passed into it).
kbruil 22:c01f61be07e0 107 * get_taps() will have no effect on the array passed in if the error_flag
kbruil 22:c01f61be07e0 108 * is non-zero. write_freqres_to_file( ) returns different error codes
kbruil 22:c01f61be07e0 109 * depending on the nature of the error...see the function itself for details.
kbruil 22:c01f61be07e0 110 *
kbruil 22:c01f61be07e0 111 * The filters are designed using the "Fourier Series Method". This
kbruil 22:c01f61be07e0 112 * means that the coefficients of a Fourier Series approximation to the
kbruil 22:c01f61be07e0 113 * frequency response of an ideal filter (LPF, HPF, BPF) are used as
kbruil 22:c01f61be07e0 114 * the filter taps. The resulting filters have some ripple in the passband
kbruil 22:c01f61be07e0 115 * due to the Gibbs phenomenon; the filters are linear phase.
kbruil 22:c01f61be07e0 116 */
kbruil 22:c01f61be07e0 117
kbruil 22:c01f61be07e0 118 #ifndef _FILTER_H
kbruil 22:c01f61be07e0 119 #define _FILTER_H
kbruil 22:c01f61be07e0 120
kbruil 22:c01f61be07e0 121 #define MAX_NUM_FILTER_TAPS 1000
kbruil 22:c01f61be07e0 122
kbruil 22:c01f61be07e0 123 #include <stdio.h>
kbruil 22:c01f61be07e0 124 #include <math.h>
kbruil 22:c01f61be07e0 125 #include <stdlib.h>
kbruil 22:c01f61be07e0 126 //#include <unistd.h>
kbruil 22:c01f61be07e0 127 #include <string.h>
kbruil 22:c01f61be07e0 128 #include <inttypes.h>
kbruil 22:c01f61be07e0 129
kbruil 22:c01f61be07e0 130 #ifndef M_PI
kbruil 22:c01f61be07e0 131 #define M_PI 3.14159265358979323846
kbruil 22:c01f61be07e0 132 #endif
kbruil 22:c01f61be07e0 133
kbruil 22:c01f61be07e0 134 enum filterType {LPF, HPF, BPF};
kbruil 22:c01f61be07e0 135
kbruil 22:c01f61be07e0 136 class Filter{
kbruil 22:c01f61be07e0 137 private:
kbruil 22:c01f61be07e0 138 filterType m_filt_t;
kbruil 22:c01f61be07e0 139 int m_num_taps;
kbruil 22:c01f61be07e0 140 int m_error_flag;
kbruil 22:c01f61be07e0 141 double m_Fs;
kbruil 22:c01f61be07e0 142 double m_Fx;
kbruil 22:c01f61be07e0 143 double m_lambda;
kbruil 22:c01f61be07e0 144 double *m_taps;
kbruil 22:c01f61be07e0 145 double *m_sr;
kbruil 22:c01f61be07e0 146 void designLPF();
kbruil 22:c01f61be07e0 147 void designHPF();
kbruil 22:c01f61be07e0 148
kbruil 22:c01f61be07e0 149 // Only needed for the bandpass filter case
kbruil 22:c01f61be07e0 150 double m_Fu, m_phi;
kbruil 22:c01f61be07e0 151 void designBPF();
kbruil 22:c01f61be07e0 152
kbruil 22:c01f61be07e0 153 public:
kbruil 22:c01f61be07e0 154 Filter(filterType filt_t, int num_taps, double Fs, double Fx);
kbruil 22:c01f61be07e0 155 Filter(filterType filt_t, int num_taps, double Fs, double Fl, double Fu);
kbruil 22:c01f61be07e0 156 ~Filter( );
kbruil 22:c01f61be07e0 157 void init();
kbruil 22:c01f61be07e0 158 double do_sample(double data_sample);
kbruil 22:c01f61be07e0 159 int get_error_flag(){return m_error_flag;};
kbruil 22:c01f61be07e0 160 void get_taps( double *taps );
kbruil 22:c01f61be07e0 161 int write_taps_to_file( char* filename );
kbruil 22:c01f61be07e0 162 int write_freqres_to_file( char* filename );
kbruil 22:c01f61be07e0 163 };
kbruil 22:c01f61be07e0 164
kbruil 22:c01f61be07e0 165 #endif