Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

LMS Algorithm for noise cancelling

Hi!

I'm trying to develop an ANC system using the LMS filter. I'm using NIOSII processor and the altera Audio UP IP core. Simulating the algorithm in Matlab, it works very well, but when i code it in C I cannot achieve any result. I think the problem is related to the use of integer instead of float. Probably some shift operations are wrong but i can't find the error. I post both the C code and Matlab code.

Thanks!

Matlab Code:


close all
%clear all
w0 = 0;
w1 = 0;
w2 = 0;
w3 = 0;
u0 = 0;
u1 = 0;
u2 = 0;
u3 = 0;
load song
iterations = 500000;
%song = wavread('C:\Users\Dan\Desktop\a.wav',500000);
s = 0.5*song;
n = 0.3*(rand(1,size(s))-0.5);
n_f = filter(,1,n);
x = transpose(s)+n_f;
mu = 0.001;
for i=1:iterations,
    y = x(i);
    u3 = n(i);
    yf = w0*u3 + w1*u2 + w2*u1 + w3*u0;
    e(i) = y-yf;
    w0 = w0 + mu*e(i)*sign(u3);
    w1 = w1 + mu*e(i)*sign(u2);
    w2 = w2 + mu*e(i)*sign(u1);
    w3 = w3 + mu*e(i)*sign(u0);
    u0=u1;
    u1=u2;
    u2=u3;
end
wavplay(e',44100);
    

C Code:

#include "sys/alt_stdio.h"
# include "altera_up_avalon_audio.h"
# include "altera_avalon_pio_regs.h"
# define LENGHT 10
int main(void){
	alt_putstr("Hello from Nios II! audio TEST\n");
	alt_up_audio_dev * audio_dev;
	int * sw_ptr = (int *) 0x01101020; // sw address
	int l_buf,r_buf,mono_data;
	int sw;
	int u, w;
	int y, e;
	int mu = 214;
	int m,temp;
	// open the Audio port
	audio_dev = alt_up_audio_open_dev ("/dev/audio_0");
	if ( audio_dev == NULL)
		alt_printf ("Error: could not open audio device \n");
	else
		alt_printf ("Opened audio device \n");
	for(m=0;m<LENGHT;m++){
		w=0;
		u=0;
	}
	/* read and filter audio data */
	while(1)
	{
		int fifospace = alt_up_audio_read_fifo_avail (audio_dev, ALT_UP_AUDIO_RIGHT);
//		IOWR_ALTERA_AVALON_PIO_DATA(LEDR_BASE, fifospace);
//		// demo swithes and leds
//		sw=IORD_ALTERA_AVALON_PIO_DATA(SWITCHES_BASE);
//		IOWR_ALTERA_AVALON_PIO_DATA(LEDG_BASE, sw);
		if ( fifospace > 15 ) // check if data is available
		{
			// read audio buffer
			alt_up_audio_read_fifo (audio_dev, &(r_buf), 1, ALT_UP_AUDIO_RIGHT);//Suono + rumore
			alt_up_audio_read_fifo (audio_dev, &(l_buf), 1, ALT_UP_AUDIO_LEFT);//Rumore
			if(*sw_ptr == 1){
				u = l_buf;
				y = 0;
				for(m=0;m<LENGHT;m++){
					y += (int)(((long)(w*(u)))>>15);
				}
				e = r_buf - y;//Segnale errore (stima)
				alt_up_audio_write_fifo (audio_dev, &(e), 1, ALT_UP_AUDIO_RIGHT);
				alt_up_audio_write_fifo (audio_dev, &(e), 1, ALT_UP_AUDIO_LEFT);
				temp = (int)(((long)(mu*e))>>15);
				for(m=0;m<LENGHT;m++){
					w=(w + (int)((long)(u*temp))>>15);
				}
				for(m=0;m<LENGHT-1;m++){
					u = u;
				}
			}
			else{
				alt_up_audio_write_fifo (audio_dev, &(r_buf), 1, ALT_UP_AUDIO_RIGHT);
				alt_up_audio_write_fifo (audio_dev, &(l_buf), 1, ALT_UP_AUDIO_LEFT);
			}
		}
	}
	return 0;
}

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What do you mean by "can't achieve any result"? Do you mean the noise is not cancelled or do you mean there is no output from the system at all? Have you tried greatly increasing your mu value to see if you are having any affect on the signal at all (even if the system oscillates then at least you know you are doing SOMETHING). It could be a scaling problem, have you tried debug mode and stepping through the code to see if your input data is scaled properly and if your weights are accumulating as they should?