Using FPGA to sample and filter audio based off switch selection

26 Views Asked by At

I was provided with the task of getting a FPGA to sample audio for 4s before and applying either a low pass, high pass or bandpass fiter to it based off the boards switch configuration (or a combination of these). I have created 7 possible cases in C code and the code builds and run however no audio comes it. Perhaps i have made an obvious error with my IIR filter output or in my case definitions

I have tried tracking variables for output produced by my filter which says the expression can not be found. I have also track my starting varible mask and it appears to be set at -1 and not change depending on the switches. Here is the code below:

                     //---------------------------------------------------------
// main example 3
//---------------------------------------------------------
#include "hellocfg.h" //BIOS include file
#include "framework.h"
#include "IIR.h"
int16_t volatile mask = 0xffff;

//---------------------------------------------------------
//---------------------------------------------------------

// Global Definitions:

// Index
int i = 0;
double t = 0;
double y;

uint32_t dip_all;

int state = 3;
int filt = 0;
int state_mask =  0x3;
int filt_mask =  0x7;


// Assigning of Sampling Rate:
#define fs 8000

// Defining Length of Buffer:
#define time  4

// Assigning Time Stamps for Buffer Length:
#define n  time * fs

#define BUFFER_SIZE 8
float circularBuffer[BUFFER_SIZE] = {0};
int bufferIndex = 0;

// Defining Empty Arrays for Populating with Filter Values
float IIR_A[N_IIR_A] = {0};
float IIR_B[N_IIR_B] = {0};

// Defining Audio Buffers:
float audio_in[n] = {0};


void main(void)
{
    initAll();
return; // return to BIOS scheduler
}

//---------------------------------------------------------
//---------------------------------------------------------
void dipPRD(void)
{

    // Get Values for Power and Operational Switch:
    DIP_getAll(&dip_all);
    dip_all ^= 0xfff;

    // Numerically getting the value of switches:
        // switch 6 is 4, switch 7 is 3 and switch 8 is 1,
        // these values fed into truth table such that each
        // value can be used
    state = dip_all & state_mask;
    filt = (dip_all >> 5) & filt_mask;

    if (state == 1)
    {
        mask = 0xffff;
        // System Records for 4 s
    }
    else if (state == 3)
        {
            // Switch Case Statements:
                // Look up Header File for obtaining filter coeffs for which filter is implemented:
            switch (filt) {
            // Call Header Function and Rename A and B coefficients N_IIR_A and N_IIR_B, respectively
            case 0:
                // No Switches are Called => Pass Nothing Through Filter
                IIR_A[0] = 0; IIR_A[1] = 0; IIR_A[2] = 0; IIR_A[3] = 0; IIR_A[4] = 0; IIR_A[5] = 0; IIR_A[6] = 0; IIR_A[7] = 0;
                IIR_B[0] = 0; IIR_B[1] = 0; IIR_B[2] = 0; IIR_B[3] = 0; IIR_B[4] = 0; IIR_B[5] = 0; IIR_B[6] = 0; IIR_B[7] = 0;
                break;
            case 1:
                // Switch 6 is used:
                    // LPF with cut-off Frequency of 8000/6 Hz
                IIR_A[0] = DenLP[0]; IIR_A[1] = DenLP[1]; IIR_A[2] = DenLP[2]; IIR_A[3] = DenLP[3]; IIR_A[4] = DenLP[4]; IIR_A[5] = DenLP[5]; IIR_A[6] = DenLP[6]; IIR_A[7] = DenLP[7];
                IIR_B[0] = NumLP[0]; IIR_B[1] = NumLP[1]; IIR_B[2] = NumLP[2]; IIR_B[3] = NumLP[3]; IIR_B[4] = NumLP[4]; IIR_B[5] = NumLP[5]; IIR_B[6] = NumLP[6]; IIR_B[7] = NumLP[7];
                break;
            case 2:
                // Switch 7 is used:
                    // BPF with 8000/3 and 8000/6 Hz
                IIR_A[0] = DenBP[0]; IIR_A[1] = DenBP[1]; IIR_A[2] = DenBP[2]; IIR_A[3] = DenBP[3]; IIR_A[4] = DenBP[4]; IIR_A[5] = DenBP[5]; IIR_A[6] = DenBP[6]; IIR_A[7] = DenBP[7];
                IIR_B[0] = NumBP[0]; IIR_B[1] = NumBP[1]; IIR_B[2] = NumBP[2]; IIR_B[3] = NumBP[3]; IIR_B[4] = NumBP[4]; IIR_B[5] = NumBP[5]; IIR_B[6] = NumBP[6]; IIR_B[7] = NumBP[7];
                break;
            case 3:
                // Switches 6 and 7 are used:
                    // LPF with cut-off Frequency of 8000/3 Hz
                IIR_A[0] = DenLPBP[0]; IIR_A[1] = DenLPBP[1]; IIR_A[2] = DenLPBP[2]; IIR_A[3] = DenLPBP[3]; IIR_A[4] = DenLPBP[4]; IIR_A[5] = DenLPBP[5]; IIR_A[6] = DenLPBP[6]; IIR_A[7] = DenLPBP[7];
                IIR_B[0] = NumLPBP[0]; IIR_B[1] = NumLPBP[1]; IIR_B[2] = NumLPBP[2]; IIR_B[3] = NumLPBP[3]; IIR_B[4] = NumLPBP[4]; IIR_B[5] = NumLPBP[5]; IIR_B[6] = NumLPBP[6]; IIR_B[7] = NumLPBP[7];
                break;
            case 4:
                // Switch 8 is used:
                    // HPF with Cut off Frequency of 8000/3 Hz
                IIR_A[0] = DenHP[0]; IIR_A[1] = DenHP[1]; IIR_A[2] = DenHP[2]; IIR_A[3] = DenHP[3]; IIR_A[4] = DenHP[4]; IIR_A[5] = DenHP[5]; IIR_A[6] = DenHP[6]; IIR_A[7] = DenHP[7];
                IIR_B[0] = NumHP[0]; IIR_B[1] = NumHP[1]; IIR_B[2] = NumHP[2]; IIR_B[3] = NumHP[3]; IIR_B[4] = NumHP[4]; IIR_B[5] = NumHP[5]; IIR_B[6] = NumHP[6]; IIR_B[7] = NumHP[7];
                break;
            case 5:
                // Switches 6 and 8 are used:
                    // Band Stop Filter with 8000/3 and 8000/6 Hz
                IIR_A[0] = DenLPHP[0]; IIR_A[1] = DenLPHP[1]; IIR_A[2] = DenLPHP[2]; IIR_A[3] = DenLPHP[3]; IIR_A[4] = DenLPHP[4]; IIR_A[5] = DenLPHP[5]; IIR_A[6] = DenLPHP[6]; IIR_A[7] = DenLPHP[7];
                IIR_B[0] = NumLPHP[0]; IIR_B[1] = NumLPHP[1]; IIR_B[2] = NumLPHP[2]; IIR_B[3] = NumLPHP[3]; IIR_B[4] = NumLPHP[4]; IIR_B[5] = NumLPHP[5]; IIR_B[6] = NumLPHP[6]; IIR_B[7] = NumLPHP[7];
                break;
            case 6:
                // Switches 7 and 8 are used:
                    // HPF with 8000/6 Hz
                IIR_A[0] = DenBPHP[0]; IIR_A[1] = DenBPHP[1]; IIR_A[2] = DenBPHP[2]; IIR_A[3] = DenBPHP[3]; IIR_A[4] = DenBPHP[4]; IIR_A[5] = DenBPHP[5]; IIR_A[6] = DenBPHP[6]; IIR_A[7] = DenBPHP[7];
                IIR_B[0] = NumBPHP[0]; IIR_B[1] = NumBPHP[1]; IIR_B[2] = NumBPHP[2]; IIR_B[3] = NumBPHP[3]; IIR_B[4] = NumBPHP[4]; IIR_B[5] = NumBPHP[5]; IIR_B[6] = NumBPHP[6]; IIR_B[7] = NumBPHP[7];
                break;
            case 7:
                // All Switches Switches are used => all values are passed
                IIR_A[0] = 1; IIR_A[1] = 1; IIR_A[2] = 1; IIR_A[3] = 1; IIR_A[4] = 1; IIR_A[5] = 1; IIR_A[6] = 1; IIR_A[7] = 1;
                IIR_B[0] = 1; IIR_B[1] = 1; IIR_B[2] = 1; IIR_B[3] = 1; IIR_B[4] = 1; IIR_B[5] = 1; IIR_B[6] = 1; IIR_B[7] = 1;
                break;

            }

        }
    else
    {
        LED_turnOff(LED_1);
        LED_turnOff(LED_2);
    }

}

// Functions to Trigger LEDs:

void twentyHz(void)
{
    if (state == 1)
    {
        LED_toggle(LED_1);
        LED_toggle(LED_2);
    }
    else
    {
        LED_turnOff(LED_1);
        LED_turnOff(LED_2);
    }
}

void twoHz(void)
{
    if (state == 3)
    {
        LED_toggle(LED_1);
    }
}

void sixHz(void)
{
    if (state == 3)
    {
        LED_toggle(LED_2);
    }
}

//---------------------------------------------------------
// HW Audio:
//---------------------------------------------------------
void audioHWI(void)
{
    int16_t m;
    m = read_audio_sample();

    if (MCASP->RSLOT)
        {
            // THIS IS THE LEFT CHANNEL!!!
            m &= mask;
        }
    else {
            // THIS IS THE RIGHT CHANNEL!!!
            m &= mask;

            audio_in[i % (n)] = m;

            // Filtering operation
            int j;
            int M;

            for (i = 0; i <= n; i++) {
                M = 8; // Assuming M is constant for all iterations
                float currentOutput = 0.0;
                currentOutput += m * IIR_B[0];

                for (j = 1; (j <= i) && (j <= M - 1); j++) {
                    int circularIndex = (bufferIndex - j + BUFFER_SIZE) % BUFFER_SIZE;
                    currentOutput += circularBuffer[circularIndex] * IIR_B[j];
                }
                for (j = 1; (j <= i) && (j <= M - 1); j++) {
                    int circularIndex = (bufferIndex - j + BUFFER_SIZE) % BUFFER_SIZE;
                    currentOutput -= circularBuffer[circularIndex] * IIR_A[j];
                }
                circularBuffer[bufferIndex] = currentOutput;
                bufferIndex = (bufferIndex + 1) % BUFFER_SIZE;

                int16_t filtered_output = (int16_t)currentOutput;
                write_audio_sample(filtered_output);
    }
}
}

0

There are 0 best solutions below