DSP FIR-Filter Improvements and Comments

FIR Filter Improvements

/*
dsp_fir
This software uses the algorithm and code found on the mbed.org Web site at 
http://mbed.org/handbook/Matlab-FIR-Filter.
I removed the code used to compare the filtered output with a calculated
1000-Hz sine wave. Someone might use this code for a demonstration, but I wanted
to examine FIR outputs for different test signals added to the 1000-Hz signal.
I place no restrictions on the use of this code.

To calculate FIR-filter coefficients, see the ScopeFIR software from Iowegian International
http://www.iowegian.com/.

Cypress Semiconductor has filter blocks for the PSoC programmable system-on-a-chip
devices. The design software--PSoC Creator--might provide FIR coefficients
http://www.cypress.com/?id=2494

Microchip Technology provides filter-design software for the dsPIC family of
microcontrollers. For more information:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en023602

You also can find FIR-filter coefficient-calculator progrograms on the Internet.

Code modifoed and commented by Jon Titus, 01 July 2013.

*/

#include "mbed.h"
#include "dsp.h"
// dsp.h links to math_helper.h, arm_math.h, FIR_f32.h, and Sine_f32.h.
// This software uses 10 blocks of 32 to simplify the floating-point-math
// operations.  It uses 320 samples overall. You can "pad" the results
// with 192 0's in Excel to run a 512-point DFT in Excel.

#define BLOCK_SIZE              (32)
#define NUM_BLOCKS              (10)
#define TEST_LENGTH_SAMPLES     (BLOCK_SIZE * NUM_BLOCKS)
// the calculation above gives you 320 samples, total

//Rate set at 48,000 samples/second
#define SAMPLE_RATE             (48000)

// set up serial connection with PC so you can see filtered data values.
Serial pc(USBTX, USBRX); // tx, rx

// set up an array for the output of the filter
float32_t          output[TEST_LENGTH_SAMPLES];

// set up an array for floating-point values produced by the FIR filter
unsigned short  loop_count;

// FIR coefficients buffer generated using fir1() MATLAB function; 29 filter "taps"
#define NUM_TAPS            29

// These are the coefficients in floating-point format
const float32_t firCoeffs32[NUM_TAPS] = { 
    -0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f,
    +0.0085302217f, -0.0000000000f, -0.0173976984f, -0.0341458607f, -0.0333591565f,
    +0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f,
    +0.2229246956f, +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f,
    -0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f, +0.0080754303f,
    +0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f
};
#define WARMUP    (NUM_TAPS-1)
#define DELAY     (WARMUP/2)

int main()
{
    
    //Define two sine-wave characteristics for use later by Sine_f32.cpp routines
    // parameters: frequency in Hz, sample rate, amplitude     
    Sine_f32 sine_1KHz(  1000, SAMPLE_RATE, 1.0);
    Sine_f32 sine_15KHz(7500, SAMPLE_RATE, 1.0);  //Note: changed to 7500 Hz!
    
    FIR_f32<NUM_TAPS> fir(firCoeffs32);
    
    // create buffer_a for 1000-Hz sine wave
    float32_t buffer_a[BLOCK_SIZE];
    
    // create buffer_b for second test signal. Note, set to 7500 Hz in this code.
    float32_t buffer_b[BLOCK_SIZE];
    
    
    // create signals one block at a time. The 1000-Hz signal gets added to second
    // test signal, with summed results going into buffer_b
    for (float32_t *sgn=output; sgn<(output+TEST_LENGTH_SAMPLES); sgn += BLOCK_SIZE)
     {
        sine_1KHz.generate(buffer_a);           // Generate a 1KHz sine wave
        sine_15KHz.process(buffer_a, buffer_b); // Add a test sine wave
        
        // FIR low pass filter function with 6-kHz cutoff using coefficients above.
        //Note: Measured cut-off frequency closer to 5500 Hz.
        fir.process(buffer_b, sgn);
     }
    
    // Transmit filter-output data to PC, default 9600 bits/sec., 8 bits, 1 stop bit
    // no parity.  Use Tera Term VT emulation mode as terminal software on a PC.
    for (loop_count = 0; loop_count < 319; loop_count++)
        {
            pc.printf("%f\n\r", output[loop_count]);
        }
}


Please log in to post comments.