DSPRelated.com

2D Matrix Downsample

Ron April 1, 2011 Coded in Matlab
function [ Y ] = downsample2d(M)
x = 2;
y = 2;

N = downsample(M,x);
N = N';
P = downsample(N,y);
P = P'
end

Decimate WAV file

Ron April 1, 2011 Coded in Matlab
factor = 8;
[X, fs, nbits] = wavread('file.wav');
Y = decimate(X,factor);
wavwrite (Y, fs/factor, nbits, 'file-decimate.wav');

IIR Bandstop Filter

Ron April 1, 2011 Coded in C for the TI C67x
// Include the filter coefficients and corresponding variables
#include "IIRBSF.h"

// The intermediate values in the Direct Form II filter
float delay_w[MWSPT_NSEC][3];	// delay_w[i][j] <=> w_i(n-j), j=0,1,2	
				// i is the section, j the delay
						
float sectionOut;		// yk[n] <=> sectionout

interrupt void isr()	 	//Interrupt function t=125us, f = 8kHz
{	
  short i; 			// i loops through the MWSPT_NSEC number of sections

  //  Do the filtering if DIP switch 1 up
  if (get_DIP1() == 1) {
			
	// In the first section, read in the x-value, apply the first stage gain
	sectionOut = NUM[0][0] * get_sample();

	for (i=1; i<MWSPT_NSEC; i++) { // Loop through all the sections
	
		// Get the new delay_w[0];
		delay_w[i][0] = sectionOut - DEN[i][1]*delay_w[i][1] - DEN[i][2]*delay_w[i][2];

		// Get the output of this section		
		sectionOut = NUM[i][0]*delay_w[i][0] + NUM[i][1]*delay_w[i][1] + NUM[i][2]*delay_w[i][2];
	
		// Delay the w's for the next interrupt
		delay_w[i][2] = delay_w[i][1];
		delay_w[i][1] = delay_w[i][0];

	}

	// Apply the gain, convert to short and send out
	send_output((short)(2 * sectionOut));
	// Gain of 2 chosen heuristically for speech from PC

  } else { // If DIP switch 1 down, == 0, then just pass through signal.

	send_output(get_sample());
  }
 	return;	//interrupt done
}

void main()
{
	short i,j;
 	for (i=0; i<MWSPT_NSEC; i++)
 		for (j=0; j<3; j++) 
			delay_w[i][j] = 0;      // init intermediate array			
	init_all();                  	// init all
	while(1);    		   	// infinite loop
}

IIR FIlter and add tone

Ron April 1, 2011 Coded in C for the TI C67x
//iirFilter.c  

// Include the filter coefficients and corresponding variables
#include "IIRLPF.h"
#define A 1		//The amplitude of added wave
#define FREQ 1000	//The frequency of the sine wave in Hz

// The intermediate values in the Direct Form II filter
float delay_w[MWSPT_NSEC][3];		
						// delay_w[i][j] <=> w_i(n-j), j=0,1,2
						// i is the section, j the delay
						
float sectionOut;		// yk[n] <=> sectionout

interrupt void isr()	 //Interrupt function t=125us, f = 8kHz
{	
  short i; 			// i loops through the MWSPT_NSEC number of sections
  int period = 8000 / FREQ;
  float rad = FREQ * 2 * pi;
  int j = 0;

  //  Do the filtering if DIP switch 1 up
  if (get_DIP1() == 1) {
			
	// In the first section, we read in the x-value, apply the first stage gain
	sectionOut = NUM[0][0] * get_sample();

	for (i=1; i<MWSPT_NSEC; i++) { // Loop through all the sections
	
		// Get the new delay_w[0];
		delay_w[i][0] = sectionOut - DEN[i][1]*delay_w[i][1] - DEN[i][2]*delay_w[i][2];

		// Get the output of this section		
		sectionOut = NUM[i][0]*delay_w[i][0] + NUM[i][1]*delay_w[i][1] + NUM[i][2]*delay_w[i][2];
	
		// Delay the w's for the next interrupt
		delay_w[i][2] = delay_w[i][1];
		delay_w[i][1] = delay_w[i][0];

	}

	//Add a tone to sectionOut
	sectionOut = sectionOut + A*sin(rad*j); //Add a sine wave of freq rad to sectionOut
	j = (j + 1) % period; //Increment the sine wave counter

	// Apply the gain, convert to short and send out
	send_output((short)(2 * sectionOut));
	// Gain of 2 chosen heuristically for speech from PC

  } else { // If DIP switch 1 down, == 0, then just pass through signal.

	send_output(get_sample());
  }

 	return;							// return from interrupt
}

void main()
{
	short i,j;

 	for (i=0; i<MWSPT_NSEC; i++)
 		for (j=0; j<3; j++) 
			delay_w[i][j] = 0;      // init intermediate array
			
	init_all();                  	// init all
	while(1);    		  	// infinite loop
}

Dual DIP-switched IIR Filter

Ron April 1, 2011 Coded in C for the TI C67x
//iirFilterSwitch.c  

// Include the filter coefficients and corresponding variables
#include "IIRLPF.h"
#include "IIRHPF.h"

// The intermediate values in the Direct Form II filter
float delay_w1[MWSPT_NSEC1][3];		
float delay_w2[MWSPT_NSEC2][3];
						// delay_w[i][j] <=> w_i(n-j), j=0,1,2
						// i is the section, j the delay
						
float sectionOut;		// yk[n] <=> sectionout

interrupt void isr()	 //Interrupt function
{	
  short i; 			// i loops through the MWSPT_NSEC number of sections

  //  Use the LPF if DIP switch 1 up
  if (get_DIP1() == 1) {
			
	// In the first section, we read in the x-value, apply the first stage gain
	sectionOut = NUM1[0][0] * get_sample();

	for (i=1; i<MWSPT_NSEC1; i++) { // Loop through all the sections
	
		// Get the new delay_w1[0];
		delay_w1[i][0] = sectionOut - DEN1[i][1]*delay_w1[i][1] - DEN1[i][2]*delay_w1[i][2];

		// Get the output of this section		
		sectionOut = NUM1[i][0]*delay_w1[i][0] + NUM1[i][1]*delay_w1[i][1] + NUM1[i][2]*delay_w1[i][2];
	
		// Delay the w's for the next interrupt
		delay_w1[i][2] = delay_w1[i][1];
		delay_w1[i][1] = delay_w1[i][0];

	}

	// Apply the gain, convert to short and send out
	send_output((short)(2 * sectionOut));
	// Gain of 2 chosen heuristically for speech from PC

  } else { // If DIP switch 1 down, == 0, then use HPF

	sectionOut = NUM2[0][0] * get_sample();

	for (i=1; i<MWSPT_NSEC2; i++) { // Loop through all the sections
	
		// Get the new delay_w2[0];
		delay_w2[i][0] = sectionOut - DEN2[i][1]*delay_w2[i][1] - DEN2[i][2]*delay_w2[i][2];

		// Get the output of this section		
		sectionOut = NUM2[i][0]*delay_w2[i][0] + NUM2[i][1]*delay_w2[i][1] + NUM2[i][2]*delay_w2[i][2];
	
		// Delay the w's for the next interrupt
		delay_w2[i][2] = delay_w2[i][1];
		delay_w2[i][1] = delay_w2[i][0];

	}

	// Apply the gain, convert to short and send out
	send_output((short)(2 * sectionOut));
	// Gain of 2 chosen heuristically for speech from PC

  }

 	return;							// return from interrupt
}

void main()
{
	short i,j;

 	for (i=0; i<MWSPT_NSEC1; i++)
 		for (j=0; j<3; j++) 
			delay_w1[i][j] = 0;      // init intermediate array

 	for (i=0; i<MWSPT_NSEC2; i++)
 		for (j=0; j<3; j++) 
			delay_w2[i][j] = 0;      // init intermediate array
			
	init_all();                  	// init all
	while(1);    			// infinite loop
}

Circular Buffer FIR Filter

Ron April 1, 20111 comment Coded in C for the TI C67x
// These coefficients are used to filter
#include "yourfiltercoeffs.h"

// scale factor, S_h = 2^K.
#define K	15

int	filterout = 0; // In fixed-point implementation, the accumulator is 32-bit int
short delay[LENGTH];  // Short is the 16-bit integer variable

interrupt void isr()	 // Interrupt function
{
	short 	i;
	int 	Sx = 1;
	
	//  Do the filtering as per fixfilt if DIP switch 1 up
	if (get_DIP1() == 1) {
		// Direct-Form FIR
		delay[0] = Sx * get_sample();     	// input for filter
		filterout = hMax[0] * delay[0];   	// Set up filter sum
		// Notice, C-arrays go from 0..LENGTH-1
		for (i = LENGTH-1; i > 0; i--){		// Get sum of products
     			filterout += hMax[i] * delay[i];	
		     	delay[i] = delay[i-1];      	// Renew input array
		}			
		filterout = (filterout>>K); //Move into the lower 16 bits, reverses scaling
			//Sign extension carries the upper bit down if negative
	 	send_output(filterout);		// output for filter
	} else { // If DIP switch 1 down, == 0, then just pass through signal.
		send_output(get_sample());
	}

 	return;						// return from interrupt
}

void main()
{
	short i;

 	for (i=0; i<= LENGTH-1; i++) { 
		delay[i] = 0;          	// init filter processing array
    	}
	init_all();            		// init all
	while(1);    		   	// infinite loop
}

Max Amplitude Sine Wave

Ron April 1, 2011 Coded in C for the TI C67x
#define ARRAY_LEN  8
short index = 0;
int sample[ARRAY_LEN] = {0,23170,32767,23170,0,-23170,-32767,-23170};
interrupt void isr()	 
{
  	send_output(sample[index]); 
  	index = (++index) % ARRAY_LEN;
	return;	//interrupt servicing complete
}

FIR 2kHz Bandstop Comb Filter

Ron April 1, 2011 Coded in C for the TI C67x
#define COMB_FILTER_ORDER		3	// Filter Order, i.e., M
#define DELAY_ARRAY_SIZE		9	// Number of (delayed) input samples to store

int   filtersum;			 	// Sum-of-products accumulator for calculating the filter output value
int   delay[DELAY_ARRAY_SIZE];			// Array for storing (delayed) input samples

static int gain1 = 1;				
static int gain2 = 4;				

interrupt void isr()	 			//Interrupt service routine
{							
     short i; 		 			// Loop counter	 
     delay[0] = get_sample() / gain1;		// Read filter input sample from ADC  and scale the sample		
     filtersum = delay[0];			// Initialize the accumulator
     for (i = COMB_FILTER_ORDER; i > 0; i--)
     {
     	filtersum += delay[i];			// Accumulate array elements
	delay[i] = delay[i-1];			// Shift delay elements by one sample
     }
     filtersum *= gain2;			// Scale the sum-of-products
     send_output(filtersum);			// write filter output sample to DAC
     return;					// interrupt servicing complete
}

void main()
{
     short i;	// loop counter
     for (i=0; i< DELAY_ARRAY_SIZE; i++)	// Initialize delay elements with 0
     { 
          delay[i] = 0;
     }
     init_all();                  		// global initialization
     while(1);    		   		// infinite loop
						// do nothing except wait for the interrupt	 
}

Passthrough a2d2a

Ron April 1, 2011 Coded in C for the TI C67x
int sample;            		       
interrupt void isr()	 //interrupt start
{
	sample = get_sample();	//input from A2D
 	send_output(sample);	//output to D2A
 	return;			//interrupt complete
}

Magnitude Approximation functions in BSV

March 29, 20111 comment Coded in Bluespec SystemVerilog (BSV) for the FPGA/ASIC (RTL)
// |V| = Max + Min/2
function UInt#(18) magEst1(Complex#(UInt#(18)) c);
  if (c.rel > c.img) return( c.rel   +  c.img/2);
  else               return( c.rel/2 +  c.img);
endfunction

// |V| = 15(Max + Min/2)/16
function UInt#(18) magEst2(Complex#(UInt#(18)) c);
  let v = magEst1(c);
  return( v - v/16);
endfunction