Merhabalar, Yazılım bilen arkadaşlar C 'de ve Delphi 'de yazıl bu LMS türü gürültü ve parazit engelleyici filitreyi PIC 'e veya her.gi bir entegreye yükleyerek denemeniz mümkün mü ?
Sonuc olumlu olursa şema olarak paylaşırsanız sevinirim.
Saygılar.
Еще раз прошу хелпа по LMS шумопонижению. Надыбал алгоритм LMS шумопонижения "вслепую". Вот исходники на СИ:
// Denoise.cpp: implementation of the CDenoise class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RxDisp.h"
#include "Denoise.h"
#include "Soundcard.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDenoise::CDenoise()
{
}
CDenoise::~CDenoise()
{
}
void CDenoise::Denoise(float *InBuff)
{
int i, j;
float fSampleOut, fErr, mu;
mu = (float)0.017;
for (i = 0; i < FRAMES_PER_BUFFER; i++)
{
// Filter the samples with the previous coefficients.
fSampleOut = ShiftReg[DLY_LEN]*Coeff[0];
for (j = 1; j < FLT_LEN; j++)
fSampleOut += (ShiftReg[DLY_LEN + j]*Coeff[j]);
// Compare the input sample with the filtered output
fErr = (float)(mu*(InBuff - fSampleOut));
// Update the filter coefficients.
for (j = 0; j < FLT_LEN; j++)
{
Coeff[j] *= (float)DECAY;
Coeff[j] += (float)(fErr*ShiftReg[DLY_LEN + j]);
}
// Shift the sample into the delay line/filter.
for ( j = REG_LEN-1; j > 0; j--) ShiftReg[j] = ShiftReg[j - 1];
ShiftReg[0] = InBuff;
InBuff = fSampleOut;
}
}
void CDenoise::InitLMS()
{
int i;
for (i = 0; i < REG_LEN; i++) ShiftReg = 0;
for (i = 0; i < FLT_LEN; i++) Coeff = 0;
}
// Denoise.h: interface for the CDenoise class.
//
//////////////////////////////////////////////////////////////////////
#define FLT_LEN 32
#define DLY_LEN 1
#define REG_LEN FLT_LEN + DLY_LEN
#define DECAY 0.9995
#if !defined(AFX_DENOISE_H__C3207BF8_1B38_483B_8870_F03AA311F77E__INCLUDED_)
#define AFX_DENOISE_H__C3207BF8_1B38_483B_8870_F03AA311F77E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CDenoise : public CObject
{
public:
void InitLMS();
void Denoise(float *);
CDenoise();
virtual ~CDenoise();
private:
float ShiftReg[REG_LEN];
float Coeff[FLT_LEN];
};
#endif // !defined(AFX_DENOISE_H__C3207BF8_1B38_483B_8870_F03AA311F77E__INCLUDED_)
Вот то же самое на делфи:
Delphi' de yazılmış yazılım:
procedure THiAsmClass.doLMS(var _Data:TData; Index:word);
var ofl,i,j,lor:integer;
Arr:PArray;
Ind,Val:TData;
yn,err:single;
ala:integer;
//als:string;
//ald:integer;
begin
ofl := ReadInteger(_Data,GoLMS,_prop_GoLMS);//если включено
if ofl>0 then
begin
mu := ReadReal(_Data,Mju,_prop_Mju); //читаем МЮ
Arr := ReadArray(ArrC);
lor := ReadInteger(_Data,L_R,_prop_L_R);
if lor = 0 then i :=0 else i := 1;//переключение левого и правого каналов
if Arr<>nil then
begin
while i <= 2*nn-1 do //загружаем блок в массив
begin
Ind := _DoData(i); Arr._Get(Ind,Val); {ald}al[i div 2] := ToInteger(Val);
//als := Int2Str(ald); al[i div 2] := Str2Double(als);
inc(i,2);
end;
end;
//*************************************
for i := 0 to nn-1 do//LMS фильтрация блока по каждому семплу
begin
yn := reg[1]*coef[0];//выходной сигнал
for j := 1 to M-1 do yn := yn + reg[j+1]*coef[j];
err := mu*(al - yn);//ошибка
for j := 0 to M-1 do //правка коэфф. фильтра
begin
coef[j] := coef[j]*dcy;
coef[j] := coef[j] + err*reg[j+1];//есть исполнение проги при откл. этой строки
end;
j := M; //сдвиг регистра
while j > 0 do
begin
reg[j] := reg[j-1];
dec(j);
end;
reg[0] := al;//есть исполнение проги при откл. этой строки
al := yn;
end;
//**************************************
if lor = 0 then i :=0 else i := 1;//грузим результат
if Arr<>nil then
begin
while i <= 2*nn-1 do //загружаем блок
begin
Ind := _DoData(i);
ala := trunc(al[i div 2]);
if ala > 32767 then ala := 32767;//ограничение выхода
if ala < -32767 then ala := -32767;
Val := _DoData(ala);
Arr._Set(Ind,Val);
inc(i,2);
end;
end;
end;
_hi_OnEvent(onLMS,yn);
end;