From e93e7927cbfa166a7f81bc9eace15307091dd7ff Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sat, 19 Jul 2014 07:44:42 +0000 Subject: [PATCH] Initial import git-svn-id: http://moon:8086/svn/software/trunk/libsrc/avpflms@1 b431acfa-c32f-4a4a-93f1-934dc6c82436 --- libpflms.dsp | 119 ++++++++++++++ libpflms.dsw | 29 ++++ libpflms.ncb | Bin 0 -> 99328 bytes libpflms.opt | Bin 0 -> 48640 bytes libpflms.plg | 32 ++++ pfft.c | 356 ++++++++++++++++++++++++++++++++++++++++ pfft.c.bak | 332 +++++++++++++++++++++++++++++++++++++ pfft.h | 153 +++++++++++++++++ pfft.h.bak | 69 ++++++++ pflms.c | 287 ++++++++++++++++++++++++++++++++ pflms.h | 39 +++++ pflms2.c | 454 +++++++++++++++++++++++++++++++++++++++++++++++++++ pflms2.h | 39 +++++ pflms_c.bak | 228 ++++++++++++++++++++++++++ 14 files changed, 2137 insertions(+) create mode 100755 libpflms.dsp create mode 100755 libpflms.dsw create mode 100755 libpflms.ncb create mode 100755 libpflms.opt create mode 100755 libpflms.plg create mode 100755 pfft.c create mode 100755 pfft.c.bak create mode 100755 pfft.h create mode 100755 pfft.h.bak create mode 100755 pflms.c create mode 100755 pflms.h create mode 100755 pflms2.c create mode 100755 pflms2.h create mode 100755 pflms_c.bak diff --git a/libpflms.dsp b/libpflms.dsp new file mode 100755 index 0000000..af76ad7 --- /dev/null +++ b/libpflms.dsp @@ -0,0 +1,119 @@ +# Microsoft Developer Studio Project File - Name="libpflms" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=libpflms - Win32 Debug +!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "libpflms.mak". +!MESSAGE +!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "libpflms.mak" CFG="libpflms - Win32 Debug" +!MESSAGE +!MESSAGE Für die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "libpflms - Win32 Release" (basierend auf "Win32 (x86) Static Library") +!MESSAGE "libpflms - Win32 Debug" (basierend auf "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "libpflms - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "../../lib/Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /G6 /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x407 /d "NDEBUG" +# ADD RSC /l 0x407 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "libpflms - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "../../lib/Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x407 /d "_DEBUG" +# ADD RSC /l 0x407 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "libpflms - Win32 Release" +# Name "libpflms - Win32 Debug" +# Begin Group "Quellcodedateien" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\avfft\avfft.c +# End Source File +# Begin Source File + +SOURCE=.\pfft.c +# End Source File +# Begin Source File + +SOURCE=.\pflms.c +# End Source File +# End Group +# Begin Group "Header-Dateien" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\include\pflms.h + +!IF "$(CFG)" == "libpflms - Win32 Release" + +!ELSEIF "$(CFG)" == "libpflms - Win32 Debug" + +# PROP Intermediate_Dir "../lib/Debug" + +!ENDIF + +# End Source File +# End Group +# End Target +# End Project diff --git a/libpflms.dsw b/libpflms.dsw new file mode 100755 index 0000000..d656584 --- /dev/null +++ b/libpflms.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN! + +############################################################################### + +Project: "libpflms"=.\libpflms.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/libpflms.ncb b/libpflms.ncb new file mode 100755 index 0000000000000000000000000000000000000000..8b340ee58bf9badcd4a9b8ed59809bac523dad7e GIT binary patch literal 99328 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 F_`gelOYi^y literal 0 HcmV?d00001 diff --git a/libpflms.opt b/libpflms.opt new file mode 100755 index 0000000000000000000000000000000000000000..c0ef6733ffeb6c91cfdd00b9581969447a8e8373 GIT binary patch literal 48640 zcmeI5PjFLJ6vj{JzZ5EzQV~HU6yB5onVZT0o!$i&{t1a&O){@1A>q zFG*+4+;iXUA2;6p{Ohg1$-HtzD&(KpTB*)C?m%0WF7<-*v$NW^Yi;8Y%Tq+)Z;aK2 z`&I!}LRFC7^BTwr)k15bb&%fYXHc()HbD3Y$VR9E+5|O1&q8YV9O^C5^Uzjk8}tIS z9eNSk0jXUd>LzFx^b+(kv>Vz3?S=M1`ysV$M(u`Lpo5SH@VbNp1N=pASndKXf=C#4KX41XzcVdhcP37NtOOD~)8iLvLhrpRS8n?9<%>HE&1 z^S4ch;5{LiB`I+UN=OVwGKg^mA!8dAs9mxq{TbEIu8yOC>D;OGIQ7Gd(hcu1xdQ(N zt)-WGS>w>}j{Yu|>c39iWc~L@SR$CKQdmw|5C8goRo_}l>0`4RW&JyF|8(q5D>4!v zwZ@apCk_n<%%rhm@!<~7#g6vjQ+?fo1ODOQWcvKDZP*e{#`Ve>xqD$oobGA4{otxd zVn!O#)^fXfT3p%oEwr1n?XS@8ux)ltOCa6WSu9p+TZYrlTSB|9w)r~R+dDe~ZeM3l zx7+LW_qw}#eeG_Kr>o23@%g>2J+0S7^v6PPwBDQyn%UV0XxxKt;FxMVPR?QuZr4yG z+Scj{n30Jw9G7ZmfK1V_BhC*o1>A6ERT-ehd9)6R{7DCt?%vtW}k>G0;D> z{)7pJO~M^0YFQCB0M{t~fQg%E*hE89{#Y~>j6_W$+huKVGBp)9$(BnF{L38}yP$S%oaB<3-$L7_Hu!XXc-Iy_6caj_ChX z77`!<5+DH*AOR8}0TLhq5-2Bu&N}(**sqox{&Tum_@v~_;mjPXCN|4T1}T(Kw^*Z=8CQLg`ctiO14P68xA0wh2JBtQZr zKmx0m0ONnF_ug~nB(PBa^$;?WqX-9TUUae2g#2UOE5J^%EoQIhcj`+v|F{oX^nLQ4 zSnxT59Pm-J#*vL(YT1e z5f}CjSQ7sw&;MwS{|YSqoXh>LIcWuxNfWI)+;e8&NbYOBo%QX?Gg;(tO*RQS)5D&w z#E6Nck|QQzBB4vJCcCeuLoTmNv#HJH)LygiVQ1OP9|^zC%duW~fXnio+g1MPng2b& z`0wIb_$6k(bN%N+Kb|~B0wh2JBtQZrKmsH{0whpY0*wEb6*rxcz!OE_{rj0j=q+|o z&Sh_gIAAP;y#ed&6Pf)Uotga)O(?bK6^owG4JI5jI(=>3uhIl;ZT*#Qp&^@XXLF-S zZ^>Bv!t9=i$mw1u{`0}am`U}e%=n^1Dd0>`WxIPM09mg6A2Z>i5|&Hm#+5Sd&{WPI zk%-(C*_e_0KNi~8a>XK_x%Y|dKlLldLINZ}0wh2JBtQZrKmsICb^?t5l^r=9lE4!~ zz>fbp9LtMV-|D^hoH+^D&wrl9b5O8!&Tl1qt?-}~8<|TAo@2!LU)i4j%=jPUe{F#fk97}*I4Je33j*mH11CS(kMMiNV&L&GxmKkQd8 z+5Hy-*kv*V|Kso;mDCb;e#{KD5&KU%(X4_NTC|w4%6~ntZ?pdM&n)kq`nAjQdiZZw z*}k=2YENs^kKop;?5iu$uDgTH8m|OHmnNcP-u$<%`ET3u-}-F-n%g~>#GOqgFP_HD z{BLLai93w{GX86SlUS1g36KB@kN^pg011!)36Q|b5McawWjL}I5_lR3RAb9T#Of+F z4ERaj1pEj62M);f{U1ubeCzl|t~)+O`wQrpOgp|ry+g(vH&Lq^@Vz literal 0 HcmV?d00001 diff --git a/libpflms.plg b/libpflms.plg new file mode 100755 index 0000000..5cdc906 --- /dev/null +++ b/libpflms.plg @@ -0,0 +1,32 @@ + + +
+

Erstellungsprotokoll

+

+--------------------Konfiguration: libpflms - Win32 Release-------------------- +

+

Befehlszeilen

+Erstellen der temporären Datei "E:\WIN98SE\TEMP\RSP20E6.TMP" mit Inhalten +[ +/nologo /G6 /ML /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fo"Release/" /Fd"Release/" /FD /c +"H:\Develop\80X86\LIBSRC\avfft\avfft.c" +"H:\Develop\80X86\LIBSRC\avpflms\pfft.c" +"H:\Develop\80X86\LIBSRC\avpflms\pflms.c" +] +Creating command line "cl.exe @E:\WIN98SE\TEMP\RSP20E6.TMP" +Erstellen der Befehlzeile "link.exe -lib /nologo /out:"../../lib/Release\libpflms.lib" .\Release\avfft.obj .\Release\pfft.obj .\Release\pflms.obj " +

Ausgabefenster

+Kompilierung läuft... +avfft.c +pfft.c +pflms.c +Generieren von Code... +Bibliothek wird erstellt... + + + +

Ergebnisse

+libpflms.lib - 0 Fehler, 0 Warnung(en) +
+ + diff --git a/pfft.c b/pfft.c new file mode 100755 index 0000000..2befdfd --- /dev/null +++ b/pfft.c @@ -0,0 +1,356 @@ +/*------------------------------------------------------------------------- + * pfft.c Partioned Fast Fourier Transform + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ +#define AVNEEDFLOAT + +#ifdef _DEBUG +#include +#endif +#include +#include "avtypes.h" +#include "averror.h" +#include "avrtl.h" +#include "avfft.h" +#include "pfft.h" + + +/*************************************************************************/ +AVERR PfftInit( +PFFT *pObj, /* Zeiger auf Objekt */ +UINT32 N, /* Filterlaenge N */ +UINT32 P, /* Anzahl Filterpartitionen */ +UINT32 S, /* Anzahl Filtersegmente pro Partition */ +UINT32 L, /* Laenge der Eingangsdaten (Blocklaenge */ +UINT32 C /* FFT-Laenge */ +) +{ + UINT32 i, s, NP, C_L; + CMPXBUF *pX; /* Temporaerer Zeiger fuer Bufferinit.*/ + + /* Auto-Param */ + if ((N*L)==0) + return AV_E_FAIL; + + if (P==0) + { + if ((N%L) != 0) + return AV_E_FAIL; + P = N/L; + } + + /* Auto-guess FFT-Groesse C */ + if (C==0) + pObj->C = (UINT32)pow(2,ceil(log(L+N/P-1)/log(2.0))); + else + pObj->C = C; + + /* Objekt initialisieren */ + pObj->L = L; + pObj->N = N; + pObj->P = P; + pObj->S = S; + NP = pObj->S * pObj->L; + C_L = pObj->C - pObj->L; + + /*-------------------------------------------------------*/ + /* Speicher allokieren */ + /*-------------------------------------------------------*/ + + /* Speicher fuer X[P*S][C] (komplex) */ + pObj->pBufX = (CMPXBUF*)AvMemAlloc(pObj->P*pObj->S*sizeof(CMPXBUF)); + + for (i=0; i < pObj->P*pObj->S; i++) + { + pObj->pBufX[i].cmpxData.pReal = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + pObj->pBufX[i].cmpxData.pImag = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pBufX[i].cmpxData.pReal,pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pBufX[i].cmpxData.pImag,pObj->C*sizeof(avfloat_t)); + pObj->pBufX[i].pNext = &pObj->pBufX[i+1]; + pObj->pBufX[i].pLast = &pObj->pBufX[i-1]; + pObj->pBufX[i].pLastPS = NULL; + pObj->pBufX[i].user = i; + } + pObj->pBufX[i-1].pNext = &pObj->pBufX[0]; + pObj->pBufX[0].pLast = &pObj->pBufX[i-1]; + + /* Zeiger auf X[k-p*S] */ + for (i=0; i < pObj->P*pObj->S; i++) + { + pX = pObj->pBufX[i].pLast; + for (s=1; s < pObj->S; s++) + pX = pX->pLast; + + pObj->pBufX[i].pLastPS = pX; + } + + /* Ergebnis 'Y' der Faltung (komplex) */ + pObj->pY = (COMPLEX*)AvMemAlloc(sizeof(COMPLEX)); + pObj->pY->pReal = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + pObj->pY->pImag = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pY->pReal,pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pY->pImag,pObj->C*sizeof(avfloat_t)); + + /* Overlap-Save 'xs' (reell) */ + pObj->BufXsave.pReal = (avfloat_t*)AvMemAlloc(C_L*sizeof(avfloat_t)); + pObj->BufXsave.pImag = (avfloat_t*)AvMemAlloc(C_L*sizeof(avfloat_t)); + AvZeroMem(pObj->BufXsave.pReal, C_L*sizeof(avfloat_t)); + AvZeroMem(pObj->BufXsave.pImag, C_L*sizeof(avfloat_t)); + + /* FFT initialisieren */ + pObj->pFFT = (FFT*)AvMemAlloc(sizeof(FFT)); + FFTinit(pObj->pFFT, pObj->C); + + /* Arbeitszeiger initialisieren */ + pObj->pX = pObj->pBufX; + + return AV_E_OK; +} + +/*-----------------------------------------------------------------------*/ +/* Partitioned FLMS Filterinitialisierung +/* 1. Partitionierung der Filterstartwerte in P-Partitionen +/* 2. Transformation der P Teil-Filter in den Frequenzbereich +/* Element pBufWS wird veraendert +/*-----------------------------------------------------------------------*/ +AVERR PfftFilterInit( +PFFT *pObj, /* Zeiger auf Objekt */ +COMPLEX WTD, +CMPXBUF *pWS) /* N Filterkoeffizienten im Zeitbereich */ +{ + UINT32 p, NP, C_SL; + + NP = pObj->S * pObj->L; + C_SL = pObj->C - NP; + + for (p=0; p < pObj->P; p++) + { + /* Arbeitspuffer WS auffuellen + Re{WS[p][0..C-L-1]}=wi[p*N/P..(p+1)*N/P-1] */ + AvMemCpy(pWS[p].cmpxData.pReal, + &WTD.pReal[p*NP], NP*sizeof(avfloat_t)); + + /* Arbeitspuffer WS auffuellen + Im{WS[p][0..C-L-1]}=wi[p*N/P..(p+1)*N/P-1] */ + AvMemCpy(pWS[p].cmpxData.pImag, + &WTD.pImag[p*NP], NP*sizeof(avfloat_t)); + + /* Re{WS[C-L..C]} = {0} (vorsichtshalber) */ + AvZeroMem(&pWS[p].cmpxData.pReal[NP], C_SL *sizeof(avfloat_t)); + + /* Im{WS[C-L..C]} = {0} (vorsichtshalber) */ + AvZeroMem(&pWS[p].cmpxData.pImag[NP], C_SL *sizeof(avfloat_t)); + + /* In den Frequenzbereich transformieren + WS[p][0..C-1] = 1/C*FFT{wi[p*N/P..(p+1)*N/P-1]} */ + ffts(pObj->pFFT, pWS[p].cmpxData.pReal, pWS[p].cmpxData.pImag); + } + return AV_E_OK; +} + +avfloat_t *PfftGetBufInRe(PFFT *pObj) +{ + UINT32 C_L; + C_L = pObj->C - pObj->L; /* C-L */ + return &pObj->pX->cmpxData.pReal[C_L]; +} +avfloat_t *PfftGetBufInIm(PFFT *pObj) +{ + UINT32 C_L; + C_L = pObj->C - pObj->L; /* C-L */ + return &pObj->pX->cmpxData.pImag[C_L]; +} + +avfloat_t *PfftGetBufOutRe(PFFT *pObj) +{ + UINT32 C_L; + C_L = pObj->C - pObj->L; /* C-L */ + return &pObj->pY->pReal[C_L]; +} + +avfloat_t *PfftGetBufOutIm(PFFT *pObj) +{ + UINT32 C_L; + C_L = pObj->C - pObj->L; /* C-L */ + return &pObj->pY->pImag[C_L]; +} + +/*---------------------------------------------------------------*/ +/* Speicher zuweisen fuer Koeffizienten H +/*---------------------------------------------------------------*/ +AVERR PfftFilterAlloc(PFFT *pObj, CMPXBUF **ppH) +{ + + UINT32 i; + + /* Speicher fuer WS[P][C] (komplex) */ + *ppH = (CMPXBUF*)AvMemAlloc(pObj->P*pObj->S*sizeof(CMPXBUF)); + + for (i=0; i < pObj->P*pObj->S; i++) + { + (*ppH)[i].cmpxData.pReal = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + (*ppH)[i].cmpxData.pImag = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem((*ppH)[i].cmpxData.pReal,pObj->C*sizeof(avfloat_t)); + AvZeroMem((*ppH)[i].cmpxData.pImag,pObj->C*sizeof(avfloat_t)); + (*ppH)[i].pNext = &(*ppH)[i+1]; + (*ppH)[i].pLast = &(*ppH)[i-1]; + (*ppH)[i].pLastPS = NULL; + (*ppH)[i].user = i; + } + (*ppH)[i-1].pNext = &(*ppH)[0]; + (*ppH)[0].pLast = &(*ppH)[i-1]; + + return AV_E_OK; +} + +/*---------------------------------------------------------------*/ +/* Partitioned FFT-Filterung +/*---------------------------------------------------------------*/ +AVERR PfftFilter(PFFT *pObj, CMPXBUF *pH, COMPLEX x, COMPLEX y) +{ + UINT32 p, NP, C_L; + + CMPXBUF *pX; + COMPLEX *pY; + + /* Arbeitszeiger */ + pX = pObj->pX; /* Aktueller Zeiger X[k] */ + pY = pObj->pY; /* 'Y' wird nach der Filterung als + temporaerer Speicher benutzt */ + + NP = pObj->S*pObj->L; /* N/P = S*L */ + C_L = pObj->C - pObj->L; /* C-L */ + + + /* Arbeitspuffer 'X' auffuellen Re{X[S*L..C-1]} = x[0..L-1] */ + AvMemCpy(&pX->cmpxData.pReal[C_L],x.pReal, + pObj->L*sizeof(avfloat_t)); + + /* Saveblock 'xs' anfuegen Re{X[0..C-L-1]} = xs[0..C-L-1] */ + AvMemCpy(pX->cmpxData.pReal,pObj->BufXsave.pReal, + C_L*sizeof(avfloat_t)); + + /* Saveblock aktualisieren xs[0..C-L-1] = x[L..C-1] */ + AvMemCpy(pObj->BufXsave.pReal, &pX->cmpxData.pReal[pObj->L], + C_L*sizeof(avfloat_t)); + + /* Arbeitspuffer 'X' auffuellen Im{X[S*L..C-1]} = x[0..L-1] */ + AvMemCpy(&pX->cmpxData.pImag[C_L],x.pImag, + pObj->L*sizeof(avfloat_t)); + + /* Saveblock 'xs' anfuegen Im{X[0..C-L-1]} = xs[0..C-L-1] */ + AvMemCpy(pX->cmpxData.pImag,pObj->BufXsave.pImag, + C_L*sizeof(avfloat_t)); + + /* Saveblock aktualisieren xs[0..C-L-1] = x[L..C-1] */ + AvMemCpy(pObj->BufXsave.pImag, &pX->cmpxData.pImag[pObj->L], + C_L*sizeof(avfloat_t)); + + /* X = FFT{x} */ + fft(pObj->pFFT, pX->cmpxData.pReal, pX->cmpxData.pImag); + + /* 1. Partition Multiplikation im Frequenzbereich + Y = X[k][0..C-1] * H[0][0..C-1] */ + CmpxVectMul(&pX->cmpxData, &pH->cmpxData, + pY, pObj->C); + + /* 2. Partition bis P-te Partition */ + for (p=1; p < pObj->P; p++) + { + pH = pH->pNext; + + /* X[k-p*S] suchen */ + pX = pX->pLastPS; + + /* Y = X[k-p*S][0..C-1] * H[p][0..C-1] */ + CmpxVectMac(&pX->cmpxData, &pH->cmpxData, + pY, pObj->C); + } + + /* In den Zeitbereich transformieren, y = IFFT{Y} */ + ifft(pObj->pFFT, pY->pReal, pY->pImag); + + /* Abspeichern der letzten L Daten ys[0..L-1] = Re{Y[C-L..C-1] */ + AvMemCpy(y.pReal, &pY->pReal[C_L], pObj->L*sizeof(avfloat_t)); + + /* Abspeichern der letzten L Daten ys[0..L-1] = Im{Y[C-L..C-1] */ + AvMemCpy(y.pImag, &pY->pImag[C_L], pObj->L*sizeof(avfloat_t)); + + /* Fuer den naechsten Aufruf Zeiger aktualisieren */ + /* Naechstes X[k] ist: */ + pObj->pX = pObj->pX->pNext; + + return AV_E_OK; +} + +AVERR PfftFilterFast(PFFT *pObj, CMPXBUF *pH) +{ + UINT32 p, NP, C_L; + + CMPXBUF *pX; + COMPLEX *pY; + + /* Arbeitszeiger */ + pX = pObj->pX; /* Aktueller Zeiger X[k] */ + pY = pObj->pY; /* 'Y' wird nach der Filterung als + temporaerer Speicher benutzt */ + + NP = pObj->S*pObj->L; /* N/P = S*L */ + C_L = pObj->C - pObj->L; /* C-L */ + + + /* Saveblock 'xs' anfuegen Re{X[0..C-L-1]} = xs[0..C-L-1] */ + AvMemCpy(pX->cmpxData.pReal,pObj->BufXsave.pReal, + C_L*sizeof(avfloat_t)); + + /* Saveblock aktualisieren xs[0..C-L-1] = x[L..C-1] */ + AvMemCpy(pObj->BufXsave.pReal, &pX->cmpxData.pReal[pObj->L], + C_L*sizeof(avfloat_t)); + + /* Saveblock 'xs' anfuegen Im{X[0..C-L-1]} = xs[0..C-L-1] */ + AvMemCpy(pX->cmpxData.pImag,pObj->BufXsave.pImag, + C_L*sizeof(avfloat_t)); + + /* Saveblock aktualisieren xs[0..C-L-1] = x[L..C-1] */ + AvMemCpy(pObj->BufXsave.pImag, &pX->cmpxData.pImag[pObj->L], + C_L*sizeof(avfloat_t)); + + /* X = FFT{x} */ + fft(pObj->pFFT, pX->cmpxData.pReal, pX->cmpxData.pImag); + + /* 1. Partition Multiplikation im Frequenzbereich + Y = X[k][0..C-1] * H[0][0..C-1] */ + CmpxVectMul(&pX->cmpxData, &pH->cmpxData, + pY, pObj->C); + + /* 2. Partition bis P-te Partition */ + for (p=1; p < pObj->P; p++) + { + pH = pH->pNext; + + /* X[k-p*S] suchen */ + pX = pX->pLastPS; + + /* Y = X[k-p*S][0..C-1] * H[p][0..C-1] */ + CmpxVectMac(&pX->cmpxData, &pH->cmpxData, + pY, pObj->C); + } + + /* In den Zeitbereich transformieren, y = IFFT{Y} */ + ifft(pObj->pFFT, pY->pReal, pY->pImag); + + /* Fuer den naechsten Aufruf Zeiger aktualisieren */ + /* Naechstes X[k] ist: */ + pObj->pX = pObj->pX->pNext; + + return AV_E_OK; +} + + +/*------------------------------------------------------------------*/ + diff --git a/pfft.c.bak b/pfft.c.bak new file mode 100755 index 0000000..0dc2f24 --- /dev/null +++ b/pfft.c.bak @@ -0,0 +1,332 @@ +/*------------------------------------------------------------------------- + * pfft.c Partioned Fast Fourier Transform + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ +#define AVNEEDFLOAT + +#ifdef _DEBUG +#include +#endif +#include +#include "avtypes.h" +#include "averror.h" +#include "avrtl.h" +#include "avfft.h" +#include "pfft.h" + + +/*************************************************************************/ +AVERR PfftInit( +PFFT *pObj, /* Zeiger auf Objekt */ +UINT32 N, /* Filterlaenge N */ +UINT32 P, /* Anzahl Filterpartitionen */ +UINT32 S, /* Anzahl Filtersegmente pro Partition */ +UINT32 L, /* Laenge der Eingangsdaten (Blocklaenge */ +UINT32 C /* FFT-Laenge */ +) +{ + UINT32 i, s, NP, C_L; + CMPXBUF *pX; /* Temporaerer Zeiger fuer Bufferinit.*/ + + /* Auto-Param */ + if ((N*L)==0) + return AV_E_FAIL; + + if (P==0) + { + if ((N%L) != 0) + return AV_E_FAIL; + P = N/L; + } + + /* Auto-guess FFT-Groesse C */ + if (C==0) + pObj->C = (UINT32)pow(2,ceil(log(L+N/P-1)/log(2.0))); + else + pObj->C = C; + + /* Objekt initialisieren */ + pObj->L = L; + pObj->N = N; + pObj->P = P; + pObj->S = S; + NP = pObj->S * pObj->L; + C_L = pObj->C - pObj->L; + + /*-------------------------------------------------------*/ + /* Speicher allokieren */ + /*-------------------------------------------------------*/ + + /* Speicher fuer X[P*S][C] (komplex) */ + pObj->pBufX = (CMPXBUF*)AvMemAlloc(pObj->P*pObj->S*sizeof(CMPXBUF)); + + for (i=0; i < pObj->P*pObj->S; i++) + { + pObj->pBufX[i].cmpxData.pReal = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + pObj->pBufX[i].cmpxData.pImag = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pBufX[i].cmpxData.pReal,pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pBufX[i].cmpxData.pImag,pObj->C*sizeof(avfloat_t)); + pObj->pBufX[i].pNext = &pObj->pBufX[i+1]; + pObj->pBufX[i].pLast = &pObj->pBufX[i-1]; + pObj->pBufX[i].pLastPS = NULL; + pObj->pBufX[i].user = i; + } + pObj->pBufX[i-1].pNext = &pObj->pBufX[0]; + pObj->pBufX[0].pLast = &pObj->pBufX[i-1]; + + /* Zeiger auf X[k-p*S] */ + for (i=0; i < pObj->P*pObj->S; i++) + { + pX = pObj->pBufX[i].pLast; + for (s=1; s < pObj->S; s++) + pX = pX->pLast; + + pObj->pBufX[i].pLastPS = pX; + } + + /* Ergebnis 'Y' der Faltung (komplex) */ + pObj->pY = (COMPLEX*)AvMemAlloc(sizeof(COMPLEX)); + pObj->pY->pReal = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + pObj->pY->pImag = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pY->pReal,pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pY->pImag,pObj->C*sizeof(avfloat_t)); + + /* Overlap-Save 'xs' (reell) */ + pObj->pBufXsave = (avfloat_t*)AvMemAlloc(C_L*sizeof(avfloat_t)); + AvZeroMem(pObj->pBufXsave, C_L*sizeof(avfloat_t)); + + /* FFT initialisieren */ + pObj->pFFT = (FFT*)AvMemAlloc(sizeof(FFT)); + FFTinit(pObj->pFFT, pObj->C); + + /* Arbeitszeiger initialisieren */ + pObj->pX = pObj->pBufX; + + return AV_E_OK; +} + +/*-----------------------------------------------------------------------*/ +/* Partitioned FLMS Filterinitialisierung +/* 1. Partitionierung der Filterstartwerte in P-Partitionen +/* 2. Transformation der P Teil-Filter in den Frequenzbereich +/* Element pBufWS wird veraendert +/*-----------------------------------------------------------------------*/ +AVERR PfftFilterInit( +PFFT *pObj, /* Zeiger auf Objekt */ +avfloat_t *pWTD, +CMPXBUF *pWS) /* N Filterkoeffizienten im Zeitbereich */ +{ + UINT32 p, NP, C_SL; + + NP = pObj->S * pObj->L; + C_SL = pObj->C - NP; + + for (p=0; p < pObj->P; p++) + { + /* Arbeitspuffer WS auffuellen + Re{WS[p][0..C-L-1]}=wi[p*N/P..(p+1)*N/P-1] */ + AvMemCpy(pWS[p].cmpxData.pReal, + &pWTD[p*NP], NP*sizeof(avfloat_t)); + + /* Re{WS[C-L..C]} = {0} (vorsichtshalber) */ + AvZeroMem(&pWS[p].cmpxData.pReal[NP], C_SL *sizeof(avfloat_t)); + + /* Im{WS[0..C-1]} = {0} */ + AvZeroMem(pWS[p].cmpxData.pImag, pObj->C *sizeof(avfloat_t)); + + /* In den Frequenzbereich transformieren + WS[p][0..C-1] = 1/C*FFT{wi[p*N/P..(p+1)*N/P-1]} */ + ffts(pObj->pFFT, pWS[p].cmpxData.pReal, pWS[p].cmpxData.pImag); + } + return AV_E_OK; +} + +/*---------------------------------------------------------------*/ +/* Speicher zuweisen fuer Koeffizienten H +/*---------------------------------------------------------------*/ +AVERR PfftFilterAlloc(PFFT *pObj, CMPXBUF **ppH) +{ + + UINT32 i; + + /* Speicher fuer WS[P][C] (komplex) */ + *ppH = (CMPXBUF*)AvMemAlloc(pObj->P*pObj->S*sizeof(CMPXBUF)); + + for (i=0; i < pObj->P*pObj->S; i++) + { + (*ppH)[i].cmpxData.pReal = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + (*ppH)[i].cmpxData.pImag = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem((*ppH)[i].cmpxData.pReal,pObj->C*sizeof(avfloat_t)); + AvZeroMem((*ppH)[i].cmpxData.pImag,pObj->C*sizeof(avfloat_t)); + (*ppH)[i].pNext = &(*ppH)[i+1]; + (*ppH)[i].pLast = &(*ppH)[i-1]; + (*ppH)[i].pLastPS = NULL; + (*ppH)[i].user = i; + } + (*ppH)[i-1].pNext = &(*ppH)[0]; + (*ppH)[0].pLast = &(*ppH)[i-1]; + + return AV_E_OK; +} + +/*---------------------------------------------------------------*/ +/* Partitioned FFT-Filterung +/*---------------------------------------------------------------*/ +AVERR PfftFilter(PFFT *pObj, CMPXBUF *pH, avfloat_t *px, avfloat_t *py) +{ + UINT32 p, NP, C_L; + + CMPXBUF *pX; + COMPLEX *pY; + + /* Arbeitszeiger */ + pX = pObj->pX; /* Aktueller Zeiger X[k] */ + pY = pObj->pY; /* 'Y' wird nach der Filterung als + temporaerer Speicher benutzt */ + + NP = pObj->S*pObj->L; /* N/P = S*L */ + C_L = pObj->C - pObj->L; /* C-L */ + + + /* Arbeitspuffer 'X' auffuellen Re{X[S*L..C-1]} = x[0..L-1] */ + AvMemCpy(&pX->cmpxData.pReal[C_L],px, + pObj->L*sizeof(avfloat_t)); + + /* Saveblock 'xs' anfuegen Re{X[0..C-L-1]} = xs[0..C-L-1] */ + AvMemCpy(pX->cmpxData.pReal,pObj->pBufXsave, + C_L*sizeof(avfloat_t)); + + /* Saveblock aktualisieren xs[0..C-L-1] = x[L..C-1] */ + AvMemCpy(pObj->pBufXsave, &pX->cmpxData.pReal[pObj->L], + C_L*sizeof(avfloat_t)); + + /* Imaginaerteil von 'X' auf Null setzen Im{X[0..C-1]} = {0} */ + AvZeroMem(pX->cmpxData.pImag,pObj->C*sizeof(avfloat_t)); + + /* X = 1/C*FFT{x} */ + ffts(pObj->pFFT, pX->cmpxData.pReal, pX->cmpxData.pImag); + + /* 1. Partition Multiplikation im Frequenzbereich + Y = X[k][0..C-1] * H[0][0..C-1] * C */ + CmpxVectMulS(&pX->cmpxData, &pH->cmpxData, + pY, pObj->C); + + /* 2. Partition bis P-te Partition */ + for (p=1; p < pObj->P; p++) + { + pH = pH->pNext; + + /* X[k-p*S] suchen */ + pX = pX->pLastPS; + + /* Y = X[k-p*S][0..C-1] * H[p][0..C-1] * C */ + CmpxVectMacS(&pX->cmpxData, &pH->cmpxData, + pY, pObj->C); + } + + /* In den Zeitbereich transformieren, y = IFFT{Y} */ + ifft(pObj->pFFT, pY->pReal, pY->pImag); + + /* Abspeichern der letzten L Daten ys[0..L-1] = Re{Y[C-L..C-1] */ + AvMemCpy(py, &pY->pReal[C_L], pObj->L*sizeof(avfloat_t)); + + /* Fuer den naechsten Aufruf Zeiger aktualisieren */ + /* Naechstes X[k] ist: */ + pObj->pX = pObj->pX->pNext; + + return AV_E_OK; +} + +/*-----------------------------------------------------------------*/ +/* Complex-Funktionen +/*-----------------------------------------------------------------*/ +void CmpxVectMul( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] = pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i]; + pAB->pImag[i] = pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i]; + } +} + +void CmpxVectAdd( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] = pA->pReal[i] + pB->pReal[i]; + pAB->pImag[i] = pA->pImag[i] + pB->pImag[i]; + } +} + +void CmpxVectMac( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] += pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i]; + pAB->pImag[i] += pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i]; + } +} + +void CmpxVectMulS( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] = (pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i])*len; + pAB->pImag[i] = (pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i])*len; + } +} + +void CmpxVectMacS( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] += (pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i])*len; + pAB->pImag[i] += (pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i])*len; + } +} + +/*------------------------------------------------------------------*/ + diff --git a/pfft.h b/pfft.h new file mode 100755 index 0000000..cfae86c --- /dev/null +++ b/pfft.h @@ -0,0 +1,153 @@ +/*------------------------------------------------------------------------- + * pfft.h Partioned Fast Fourier Transform + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ + +#ifndef _PFFT_H +#define _PFFT_H +#include "avtypes.h" +#include "avfft.h" + +/*-----------------------------------------------------------------------*/ +/* PFLMS-Parameter */ +/*-----------------------------------------------------------------------*/ + +typedef struct _sCOMPLEX +{ + avfloat_t *pReal, *pImag; +} COMPLEX; + +typedef struct _sREALBUF +{ + avfloat_t *pData; + struct _sREALBUF *pNext, *pLast, *pLastPS; + UINT32 user; +} REALBUF; + +typedef struct _sCMPXBUF +{ + struct _sCOMPLEX cmpxData; + struct _sCMPXBUF *pNext, *pLast, *pLastPS; + UINT32 user; +} CMPXBUF; + +typedef struct _sPFFT +{ + UINT32 N, P, S, L, C; /* PFLMS-Parameter N, P, S, L, C */ + CMPXBUF *pBufX; /* komplexer Puffer X[P*S][C] */ + CMPXBUF *pX; /* aktuelle Zeiger auf Puffer[p][] */ + COMPLEX *pY; /* temporaerer Puffer fuer Y[] und E[] */ + COMPLEX BufXsave; /* Overlap-Save Puffer xs[S*L] */ + FFT *pFFT; /* FFT-Objekt */ +} PFFT; + +#ifdef __cplusplus +extern "C" { +#endif + +AVERR PfftInit(PFFT *pObj,UINT32 N, UINT32 P, UINT32 S, UINT32 L, UINT32 C); +AVERR PfftFilterAlloc(PFFT *pObj, CMPXBUF **ppH); +AVERR PfftFilterInit(PFFT *pObj, COMPLEX WTD, CMPXBUF *pH); +AVERR PfftFilter(PFFT *pObj, CMPXBUF *pH, COMPLEX x, COMPLEX y); +AVERR PfftFilterFast(PFFT *pObj, CMPXBUF *pH); +avfloat_t *PfftGetBufInRe(PFFT *pObj); +avfloat_t *PfftGetBufInIm(PFFT *pObj); +avfloat_t *PfftGetBufOutRe(PFFT *pObj); +avfloat_t *PfftGetBufOutIm(PFFT *pObj); + +/*-----------------------------------------------------------------*/ +/* Complex-Funktionen +/*-----------------------------------------------------------------*/ +_inline void CmpxVectMul( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] = pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i]; + pAB->pImag[i] = pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i]; + } +} + +_inline void CmpxVectAdd( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] = pA->pReal[i] + pB->pReal[i]; + pAB->pImag[i] = pA->pImag[i] + pB->pImag[i]; + } +} + +_inline void CmpxVectMac( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] += pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i]; + pAB->pImag[i] += pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i]; + } +} + +_inline void CmpxVectMulS( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] = (pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i])*len; + pAB->pImag[i] = (pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i])*len; + } +} + +_inline void CmpxVectMacS( +struct _sCOMPLEX *pA, +struct _sCOMPLEX *pB, +struct _sCOMPLEX *pAB, +UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB->pReal[i] += (pA->pReal[i]*pB->pReal[i] + - pA->pImag[i]*pB->pImag[i])*len; + pAB->pImag[i] += (pA->pReal[i]*pB->pImag[i] + + pA->pImag[i]*pB->pReal[i])*len; + } +} + +#ifdef __cplusplus +} +#endif +#endif /* _PFFT_H */ + diff --git a/pfft.h.bak b/pfft.h.bak new file mode 100755 index 0000000..ef1d712 --- /dev/null +++ b/pfft.h.bak @@ -0,0 +1,69 @@ +/*------------------------------------------------------------------------- + * pfft.h Partioned Fast Fourier Transform + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ + +#ifndef _PFFT_H +#define _PFFT_H +#include "avtypes.h" +#include "avfft.h" + +/*-----------------------------------------------------------------------*/ +/* PFLMS-Parameter */ +/*-----------------------------------------------------------------------*/ + +typedef struct _sCOMPLEX +{ + avfloat_t *pReal, *pImag; +} COMPLEX; + +typedef struct _sREALBUF +{ + avfloat_t *pData; + struct _sREALBUF *pNext, *pLast, *pLastPS; + UINT32 user; +} REALBUF; + +typedef struct _sCMPXBUF +{ + struct _sCOMPLEX cmpxData; + struct _sCMPXBUF *pNext, *pLast, *pLastPS; + UINT32 user; +} CMPXBUF; + +typedef struct _sPFFT +{ + UINT32 N, P, S, L, C; /* PFLMS-Parameter N, P, S, L, C */ + CMPXBUF *pBufX; /* komplexer Puffer X[P*S][C] */ + CMPXBUF *pX; /* aktuelle Zeiger auf Puffer[p][] */ + COMPLEX *pY; /* temporaerer Puffer fuer Y[] und E[] */ + avfloat_t *pBufXsave; /* Overlap-Save Puffer xs[S*L] */ + FFT *pFFT; /* FFT-Objekt */ +} PFFT; + + +void CmpxVectMul(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len); +void CmpxVectAdd(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len); +void CmpxVectMac(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len); +void CmpxVectMulS(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len); +void CmpxVectMacS(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len); + +#ifdef __cplusplus +extern "C" { +#endif + +AVERR PfftInit(PFFT *pObj,UINT32 N, UINT32 P, UINT32 S, UINT32 L, UINT32 C); +AVERR PfftFilterAlloc(PFFT *pObj, CMPXBUF **ppH); +AVERR PfftFilterInit(PFFT *pObj, avfloat_t *pWTD, CMPXBUF *pH); +AVERR PfftFilter(PFFT *pObj, CMPXBUF *pH, avfloat_t *px, avfloat_t *py); + +#ifdef __cplusplus +} +#endif +#endif /* _PFFT_H */ + diff --git a/pflms.c b/pflms.c new file mode 100755 index 0000000..2436d13 --- /dev/null +++ b/pflms.c @@ -0,0 +1,287 @@ +/*------------------------------------------------------------------------- + * pflms.c Partioned Frequency Least-Mean-Square adaptive algorithm + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ +#define AVNEEDFLOAT + +#ifdef _DEBUG +#include +#endif +#include +#include "avtypes.h" +#include "averror.h" +#include "avrtl.h" +#include "avfft.h" +#include "pfft.h" +#include "pflms.h" + +/*-----------------------------------------------------------------------*/ +#define LAMBDA 0.6 +#define pTHIS pObj + +AVERR PflmsInit( +PFLMS *pObj, /* Zeiger auf Objekt */ +UINT32 N, /* Filterlaenge N */ +UINT32 P, /* Anzahl Filterpartitionen */ +UINT32 S, /* Anzahl Filtersegmente pro Partition */ +UINT32 L, /* Laenge der Eingangsdaten (Blocklaenge */ +UINT32 C /* FFT-Laenge */ +) +{ + UINT32 i, s, NP, C_L; + REALBUF *pMu; /* Temporaerer Zeiger fuer Bufferinit.*/ + +#ifdef _DEBUG + UINT32 memMu, memPX, memY; + UINT32 nBufMu, nBufPX, nBufY; +#endif + + /* PFFT initialisieren */ + pObj->pFilter = (PFFT*)AvMemAlloc(sizeof(PFFT)); + PfftInit(pObj->pFilter, N, P, S, L, C); + + /* Objekt initialisieren */ + pObj->L = pObj->pFilter->L; + pObj->N = pObj->pFilter->N; + pObj->P = pObj->pFilter->P; + pObj->S = pObj->pFilter->S; + pObj->C = pObj->pFilter->C; + NP = pObj->S * pObj->L; + C_L = pObj->C - pObj->L; + +#ifdef _DEBUG + printf("PFLMS Init:\n"); + printf("N = %d\n",pObj->N); + printf("P = %d\n",pObj->P); + printf("S = %d\n",pObj->S); + printf("L = %d\n",pObj->L); + printf("NP = %d\n",NP); + printf("C = %d\n",pObj->C); + printf("C-L = %d\n",C_L); +#endif + + /*-------------------------------------------------------*/ + /* Speicher allokieren */ + /*-------------------------------------------------------*/ + /* Speicher fuer Mu[P*S][C] (reell) */ + pObj->pBufMu = (REALBUF*)AvMemAlloc(pObj->P*pObj->S*sizeof(REALBUF)); + + for (i=0; i < pObj->P*pObj->S; i++) + { + pObj->pBufMu[i].pData = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pBufMu[i].pData,pObj->C*sizeof(avfloat_t)); + pObj->pBufMu[i].pNext = &pObj->pBufMu[i+1]; + pObj->pBufMu[i].pLast = &pObj->pBufMu[i-1]; + pObj->pBufMu[i].pLastPS = NULL; + pObj->pBufMu[i].user = i; + } + pObj->pBufMu[i-1].pNext = &pObj->pBufMu[0]; + pObj->pBufMu[0].pLast = &pObj->pBufMu[i-1]; + + /* Zeiger auf Mu[k-p*S] */ + for (i=0; i < pObj->P*pObj->S; i++) + { + pMu = pObj->pBufMu[i].pLast; + for (s=1; s < pObj->S; s++) + pMu = pMu->pLast; + + pObj->pBufMu[i].pLastPS = pMu; + } + +#ifdef _DEBUG + printf("* Speichernutzung *\n"); + + /* Speichernutzung fuer Mu ausgeben */ + nBufMu = pObj->P*pObj->S; + memMu = pObj->P*pObj->S*pObj->C*sizeof(avfloat_t) + + pObj->P*pObj->S*sizeof(REALBUF); + + printf("Mu:\n"); + printf("Anzahl reelle Buffer : %d\n", nBufMu); + printf("Gesamt Buffergroesse : %d bytes\n", memMu); +#endif + + + /* Speicher fuer PX[C] (reell) */ + pObj->pBufPX = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pBufPX,pObj->C*sizeof(avfloat_t)); + +#ifdef _DEBUG + /* Speichernutzung fuer PX ausgeben */ + nBufPX = 1; + memPX = pObj->C*sizeof(avfloat_t); + + printf("PX:\n"); + printf("Anzahl reelle Buffer : %d\n", nBufPX); + printf("Gesamt Buffergroesse : %d bytes\n", memPX); +#endif + + /* Ergebnis 'Y' der Faltung (komplex) */ + pObj->pTemp = (COMPLEX*)AvMemAlloc(sizeof(COMPLEX)); + pObj->pTemp->pReal = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + pObj->pTemp->pImag = (avfloat_t*)AvMemAlloc(pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pTemp->pReal,pObj->C*sizeof(avfloat_t)); + AvZeroMem(pObj->pTemp->pImag,pObj->C*sizeof(avfloat_t)); + + #ifdef _DEBUG + /* Speichernutzung fuer Y ausgeben */ + nBufY = 1; + memY = pObj->C*sizeof(CMPXBUF); + + printf("Y:\n"); + printf("Anzahl complexe Buffer : %d\n", nBufY); + printf("Gesamt Buffergroesse : %d bytes\n", memY); +#endif + + /* FFT initialisieren */ + pObj->pFFT = (FFT*)AvMemAlloc(sizeof(FFT)); + FFTinit(pObj->pFFT, pObj->C); + + /* Speicher fuer WS[P][C] (komplex) zuweisen */ + PfftFilterAlloc(pObj->pFilter, &pObj->pBufWS); + + /* Arbeitszeiger initialisieren */ + pObj->pX = pObj->pFilter->pBufX; + pObj->pPj = pObj->pBufWS; + pObj->pMu = pObj->pBufMu; + + /* Sicherheitskonstannte vermeidet Division durch Null */ + pObj->gamma = (avfloat_t)1.0/pObj->C; + + return AV_E_OK; +} + +/*-----------------------------------------------------------------------*/ +/* Partitioned FLMS Filterinitialisierung +/* 1. Partitionierung der Filterstartwerte in P-Partitionen +/* 2. Transformation der P Teil-Filter in den Frequenzbereich +/* Element pBufWS wird veraendert +/*-----------------------------------------------------------------------*/ +AVERR PflmsInitFilter( +PFLMS *pObj, /* Zeiger auf Objekt */ +avfloat_t *pWTD) /* N Filterkoeffizienten im Zeitbereich */ +{ + return PfftFilterInit(pObj->pFilter, pWTD, pObj->pBufWS); +} + +/*-----------------------------------------------------------------*/ +/* Partitioned FLMS +/*-----------------------------------------------------------------*/ +AVERR Pflms( +PFLMS *pObj, /* Zeiger auf Objekt */ +avfloat_t *pInTDx, /* Ein: Daten x[0..L-1] */ +avfloat_t *pInTDd, /* Ein: Referenzsignal d[0..L-1] */ +avfloat_t *pOutTDy, /* Aus: Filterausgang y[0..L-1] */ +avfloat_t *pOutTDe, /* Aus: Fehlersignal e[0..L-1] */ +avfloat_t alpha) +{ + + UINT32 i, p, NP, C_L; + + CMPXBUF *pX, *pWS, *pPj; + REALBUF *pMu; + COMPLEX *pTemp; + avfloat_t muNom; + + /* Arbeitszeiger */ + pX = pObj->pX; /* Aktueller Zeiger X[k] */ + pWS = pObj->pBufWS; /* Aktueller Zeiger WS[0] */ + pPj = pObj->pPj; /* Aktueller Zeiger Pj[] */ + pMu = pObj->pMu; /* Aktueller Zeiger Mu[k] */ + pTemp = pObj->pTemp; /* 'Y' wird nach der Filterung als + temporaerer Speicher benutzt */ + + NP = pObj->S*pObj->L; /* N/P = S*L */ + C_L = pObj->C - pObj->L; /* C-L */ + + /*---------------------------------------------------------------*/ + /* Partitioned FFT-Filterung + /*---------------------------------------------------------------*/ + /* TODO: PFFT Kommentar */ + PfftFilter(pObj->pFilter, pObj->pBufWS, pInTDx, pOutTDy); + + /*---------------------------------------------------------------*/ + /* Fehlersignal 'e = d - y' berechnen */ + /* Transformation von 'e' in den Frequenzbereich */ + /*---------------------------------------------------------------*/ + for (i=0; i < pObj->L; i++) + pOutTDe[i] = pInTDd[i] - pOutTDy[i]; + + /* Variable Y wird fuer E missbraucht, da nicht mehr gebraucht */ + /* Imaginaerteil von 'Y' auf Null setzen Im{Y[0..C-1]} = {0} */ + + AvZeroMem(pTemp->pImag,pObj->C*sizeof(avfloat_t)); + + /* Re{Y[0..C-L-1]} = {0} */ + AvZeroMem(pTemp->pReal,C_L*sizeof(avfloat_t)); + + /* Re{Y[C-L..C-1]} = e[0..L-1] */ + AvMemCpy(&pTemp->pReal[C_L], + pOutTDe,pObj->L*sizeof(avfloat_t)); + + /* E = 1/C*fft{e[0[0..C-L-1],e[0..L]} */ + ffts(pObj->pFFT, pTemp->pReal, pTemp->pImag); + + /*---------------------------------------------------------------*/ + /* Berechnung PX und Mu + /*---------------------------------------------------------------*/ + /* Zaehler Alpha*Gamma/P */ + muNom = (avfloat_t)(alpha*pObj->gamma/pObj->P); + + for (i=0; i < pObj->C; i++) + { + /* Schaetzung der mittleren Eingangsleistung PX */ + pObj->pBufPX[i] = (avfloat_t)fabs((1.0-LAMBDA) * pObj->C + * (pX->cmpxData.pReal[i]*pX->cmpxData.pReal[i] + + pX->cmpxData.pImag[i]*pX->cmpxData.pImag[i]) + + LAMBDA*pObj->pBufPX[i]); + + /* Berechnung der variablen Schrittweite Mu */ + /* mu[k] = (Alpha*Gamma) / (P*(PX+Gamma)) */ + pObj->pMu->pData[i] = muNom / (pObj->pBufPX[i] + pObj->gamma); + } + + /* Aktualisierung der Filterkoeffizienten */ + for (p=0; p < pObj->P; p++) + { + for (i=0; i < pObj->C; i++) + { + pWS->cmpxData.pReal[i] += ((pX->cmpxData.pReal[i] * pTemp->pReal[i] + + pX->cmpxData.pImag[i] * pTemp->pImag[i]) + * pMu->pData[i] * pObj->C); + pWS->cmpxData.pImag[i] += ((pX->cmpxData.pReal[i] * pTemp->pImag[i] + - pX->cmpxData.pImag[i] * pTemp->pReal[i]) + * pMu->pData[i] * pObj->C); + } + pWS = pWS->pNext; + pX = pX->pLastPS; + pMu= pMu->pLastPS; + } + + /* Effiziente Projektion der Filterkoeffizienten */ + ifft(pObj->pFFT, pPj->cmpxData.pReal, pPj->cmpxData.pImag); + AvZeroMem(pPj->cmpxData.pImag, pObj->C*sizeof(avfloat_t)); + AvZeroMem(&pPj->cmpxData.pReal[NP],(pObj->C-NP)*sizeof(avfloat_t)); + ffts(pObj->pFFT, pPj->cmpxData.pReal, pPj->cmpxData.pImag); + + /* Fuer den naechsten Aufruf Zeiger aktualisieren */ + /* Naechstes X[k] ist: */ + pObj->pX = pObj->pX->pNext; + + /* Naechstes Mu[k] ist: */ + pObj->pMu = pObj->pMu->pNext; + + /* Naechstes Teilfilter fuer Projektion ist: */ + pObj->pPj = pObj->pPj->pNext; + + return AV_E_OK; + +} + +/*------------------------------------------------------------------*/ + diff --git a/pflms.h b/pflms.h new file mode 100755 index 0000000..2d6bacd --- /dev/null +++ b/pflms.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * pflms.h Partioned Frequency Least-Mean-Square adaptive algorithm + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ + +#ifndef _PFLMS_H +#define _PFLMS_H +#include "pfft.h" + +/*-----------------------------------------------------------------------*/ +/* PFLMS-Parameter */ +/*-----------------------------------------------------------------------*/ + +typedef struct _sPFLMS +{ + UINT32 N, P, S, L, C; /* PFLMS-Parameter N, P, S, L, C */ + avfloat_t gamma; /* Sicherheitskonstannte */ + CMPXBUF *pBufWS; /* komplexe Puffer X[P*S][C], WS[P][C] */ + CMPXBUF *pX, *pWS, *pPj; /* aktuelle Zeiger auf Puffer[p][] */ + COMPLEX *pTemp; /* temporaerer Puffer fuer Y[] und E[] */ + REALBUF *pBufMu; /* reeller Puffer Mu[P*S][C] */ + REALBUF *pMu; /* Aktueller zeiger auf Mu[k-p*S] */ + avfloat_t *pBufPX; /* reeller Puffer PX[C] */ + FFT *pFFT; /* FFT-Objekt */ + PFFT *pFilter; /* Filter-Objekt */ +} PFLMS; + + +AVERR PflmsInit(PFLMS *pObj,UINT32 N, UINT32 P, UINT32 S, UINT32 L, UINT32 C); +AVERR PflmsInitFilter(PFLMS *pObj, avfloat_t *pWTD); +AVERR Pflms(PFLMS *pObj, avfloat_t *pInTDx, avfloat_t *pInTDd, avfloat_t *pOutTDy, avfloat_t *pOutTDe, avfloat_t alpha); + +#endif /* _PFLMS_H */ + diff --git a/pflms2.c b/pflms2.c new file mode 100755 index 0000000..3f035d4 --- /dev/null +++ b/pflms2.c @@ -0,0 +1,454 @@ +/*------------------------------------------------------------------------- + * pflms.c Partioned Frequency Least-Mean-Square adaptive algorithm + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ +#define AVNEEDFLOAT + +#ifdef _DEBUG +#include +#endif +#include +#include "avtypes.h" +#include "averror.h" +#include "avrtl.h" +#include "avfft.h" +#include "pfft.h" +#include "pflms.h" + +/*-----------------------------------------------------------------------*/ +#define LAMBDA 0.6 +#define pTHIS pObj + +AVERR PflmsInit( +PFLMS *pObj, /* Zeiger auf Objekt */ +UINT32 N, /* Filterlaenge N */ +UINT32 P, /* Anzahl Filterpartitionen */ +UINT32 S, /* Anzahl Filtersegmente pro Partition */ +UINT32 L, /* Laenge der Eingangsdaten (Blocklaenge */ +UINT32 C /* FFT-Laenge */ +) +{ + UINT32 i, s, NP, C_L; + CMPXBUF *pX; /* Temporaerer Zeiger fuer Bufferinit.*/ + REALBUF *pMu; /* Temporaerer Zeiger fuer Bufferinit.*/ + +#ifdef _DEBUG + UINT32 memMu, memPX, memX, memWS, memY, memXs; + UINT32 nBufMu, nBufPX, nBufX, nBufWS, nBufY, nBufXs; +#endif + + /* Auto-Param */ + if ((N*L)==0) + return AV_E_FAIL; + + if (P==0) + { + if ((N%L) != 0) + return AV_E_FAIL; + P = N/L; + } + + /* Auto-guess FFT-Groesse C */ + if (C==0) + pObj->C = (UINT32)pow(2,ceil(log(L+N/P-1)/log(2.0))); + + /* Objekt initialisieren */ + pObj->L = L; + pObj->N = N; + pObj->P = P; + pObj->S = S; + NP = pObj->S * pObj->L; + C_L = pObj->C - pObj->L; + +#ifdef _DEBUG + printf("PFLMS Init:\n"); + printf("N = %d\n",pObj->N); + printf("P = %d\n",pObj->P); + printf("S = %d\n",pObj->S); + printf("L = %d\n",pObj->L); + printf("NP = %d\n",NP); + printf("C = %d\n",pObj->C); + printf("C-L = %d\n",C_L); +#endif + + /*-------------------------------------------------------*/ + /* Speicher allokieren */ + /*-------------------------------------------------------*/ + /* Speicher fuer Mu[P*S][C] (reell) */ + pObj->pBufMu = (REALBUF*)AvMemAlloc(pObj->P*pObj->S*sizeof(REALBUF)); + + for (i=0; i < pObj->P*pObj->S; i++) + { + pObj->pBufMu[i].pData = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pBufMu[i].pData,pObj->C*sizeof(FLOAT32)); + pObj->pBufMu[i].pNext = &pObj->pBufMu[i+1]; + pObj->pBufMu[i].pLast = &pObj->pBufMu[i-1]; + pObj->pBufMu[i].pLastPS = NULL; + pObj->pBufMu[i].user = i; + } + pObj->pBufMu[i-1].pNext = &pObj->pBufMu[0]; + pObj->pBufMu[0].pLast = &pObj->pBufMu[i-1]; + + /* Zeiger auf Mu[k-p*S] */ + for (i=0; i < pObj->P*pObj->S; i++) + { + pMu = pObj->pBufMu[i].pLast; + for (s=1; s < pObj->S; s++) + pMu = pMu->pLast; + + pObj->pBufMu[i].pLastPS = pMu; + } + +#ifdef _DEBUG + printf("* Speichernutzung *\n"); + + /* Speichernutzung fuer Mu ausgeben */ + nBufMu = pObj->P*pObj->S; + memMu = pObj->P*pObj->S*pObj->C*sizeof(FLOAT32) + + pObj->P*pObj->S*sizeof(REALBUF); + + printf("Mu:\n"); + printf("Anzahl reelle Buffer : %d\n", nBufMu); + printf("Gesamt Buffergroesse : %d bytes\n", memMu); +#endif + + + /* Speicher fuer PX[C] (reell) */ + pObj->pBufPX = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pBufPX,pObj->C*sizeof(FLOAT32)); + +#ifdef _DEBUG + /* Speichernutzung fuer PX ausgeben */ + nBufPX = 1; + memPX = pObj->C*sizeof(FLOAT32); + + printf("PX:\n"); + printf("Anzahl reelle Buffer : %d\n", nBufPX); + printf("Gesamt Buffergroesse : %d bytes\n", memPX); +#endif + + + /* Speicher fuer X[P*S][C] (komplex) */ + pObj->pBufX = (CMPXBUF*)AvMemAlloc(pObj->P*pObj->S*sizeof(CMPXBUF)); + + for (i=0; i < pObj->P*pObj->S; i++) + { + pObj->pBufX[i].cmpxData.pReal = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + pObj->pBufX[i].cmpxData.pImag = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pBufX[i].cmpxData.pReal,pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pBufX[i].cmpxData.pImag,pObj->C*sizeof(FLOAT32)); + pObj->pBufX[i].pNext = &pObj->pBufX[i+1]; + pObj->pBufX[i].pLast = &pObj->pBufX[i-1]; + pObj->pBufX[i].pLastPS = NULL; + pObj->pBufX[i].user = i; + } + pObj->pBufX[i-1].pNext = &pObj->pBufX[0]; + pObj->pBufX[0].pLast = &pObj->pBufX[i-1]; + + /* Zeiger auf X[k-p*S] */ + for (i=0; i < pObj->P*pObj->S; i++) + { + pX = pObj->pBufX[i].pLast; + for (s=1; s < pObj->S; s++) + pX = pX->pLast; + + pObj->pBufX[i].pLastPS = pX; + } + +#ifdef _DEBUG + /* Speichernutzung fuer X ausgeben */ + nBufX = pObj->P*pObj->S; + memX = pObj->P*pObj->S*pObj->C*sizeof(CMPXBUF); + + printf("X:\n"); + printf("Anzahl complexe Buffer : %d\n", nBufX); + printf("Gesamt Buffergroesse : %d bytes\n", memX); +#endif + + /* Speicher fuer WS[P][C] (komplex) */ + pObj->pBufWS = (CMPXBUF*)AvMemAlloc(P*S*sizeof(CMPXBUF)); + + for (i=0; i < P*S; i++) + { + pObj->pBufWS[i].cmpxData.pReal = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + pObj->pBufWS[i].cmpxData.pImag = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pBufWS[i].cmpxData.pReal,pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pBufWS[i].cmpxData.pImag,pObj->C*sizeof(FLOAT32)); + pObj->pBufWS[i].pNext = &pObj->pBufWS[i+1]; + pObj->pBufWS[i].pLast = &pObj->pBufWS[i-1]; + pObj->pBufWS[i].pLastPS = NULL; + pObj->pBufWS[i].user = i; + } + pObj->pBufWS[i-1].pNext = &pObj->pBufWS[0]; + pObj->pBufWS[0].pLast = &pObj->pBufWS[i-1]; + +#ifdef _DEBUG + /* Speichernutzung fuer WS ausgeben */ + nBufWS = pObj->P; + memWS = pObj->P*pObj->C*sizeof(CMPXBUF); + + printf("WS:\n"); + printf("Anzahl complexe Buffer : %d\n", nBufWS); + printf("Gesamt Buffergroesse : %d bytes\n", memWS); +#endif + + /* Ergebnis 'Y' der Faltung (komplex) */ + pObj->pTemp = (COMPLEX*)AvMemAlloc(sizeof(COMPLEX)); + pObj->pTemp->pReal = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + pObj->pTemp->pImag = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pTemp->pReal,pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pTemp->pImag,pObj->C*sizeof(FLOAT32)); + + #ifdef _DEBUG + /* Speichernutzung fuer Y ausgeben */ + nBufY = 1; + memY = pObj->C*sizeof(CMPXBUF); + + printf("Y:\n"); + printf("Anzahl complexe Buffer : %d\n", nBufY); + printf("Gesamt Buffergroesse : %d bytes\n", memY); +#endif + + /* Overlap-Save 'xs' (reell) */ + pObj->pBufXsave = (FLOAT32*)AvMemAlloc(C_L*sizeof(FLOAT32)); + AvZeroMem(pObj->pBufXsave, C_L*sizeof(FLOAT32)); + +#ifdef _DEBUG + /* Speichernutzung fuer Xsave ausgeben */ + nBufXs = 1; + memXs = C_L*sizeof(FLOAT32); + + printf("Xsave:\n"); + printf("Anzahl reelle Buffer : %d\n", nBufXs); + printf("Gesamt Buffergroesse : %d bytes\n", memXs); +#endif + + /* FFT initialisieren */ + pObj->pFFT = (FFT*)AvMemAlloc(sizeof(FFT)); + FFTinit(pObj->pFFT, pObj->C); + + /* Arbeitszeiger initialisieren */ + pObj->pX = pObj->pBufX; + pObj->pPj = pObj->pBufWS; + pObj->pMu = pObj->pBufMu; + + /* Sicherheitskonstannte vermeidet Division durch Null */ + pObj->gamma = (FLOAT32)1.0/pObj->C; + + return AV_E_OK; +} + +/*-----------------------------------------------------------------------*/ +/* Partitioned FLMS Filterinitialisierung +/* 1. Partitionierung der Filterstartwerte in P-Partitionen +/* 2. Transformation der P Teil-Filter in den Frequenzbereich +/* Element pBufWS wird veraendert +/*-----------------------------------------------------------------------*/ +AVERR PflmsInitFilter( +PFLMS *pObj, /* Zeiger auf Objekt */ +FLOAT32 *pWTD) /* N Filterkoeffizienten im Zeitbereich */ +{ + UINT32 p, NP, C_SL; + + NP = pObj->S * pObj->L; + C_SL = pObj->C - NP; + + for (p=0; p < pObj->P; p++) + { + /* Arbeitspuffer WS auffuellen + Re{WS[p][0..C-L-1]}=wi[p*N/P..(p+1)*N/P-1] */ + AvMemCpy(pObj->pBufWS[p].cmpxData.pReal, + &pWTD[p*NP], NP*sizeof(FLOAT32)); + + /* Re{WS[C-L..C]} = {0} (vorsichtshalber) */ + AvZeroMem(&pObj->pBufWS[p].cmpxData.pReal[NP], + C_SL *sizeof(FLOAT32)); + + /* Im{WS[0..C-1]} = {0} */ + AvZeroMem(pObj->pBufWS[p].cmpxData.pImag, pObj->C *sizeof(FLOAT32)); + + /* In den Frequenzbereich transformieren + WS[p][0..C-1] = 1/C*FFT{wi[p*N/P..(p+1)*N/P-1]} */ + ffts(pObj->pFFT, pObj->pBufWS[p].cmpxData.pReal, + pObj->pBufWS[p].cmpxData.pImag); + } + return AV_E_OK; +} + +/*-----------------------------------------------------------------*/ +/* Partitioned FLMS +/*-----------------------------------------------------------------*/ +AVERR Pflms( +PFLMS *pObj, /* Zeiger auf Objekt */ +FLOAT32 *pInTDx, /* Ein: Daten x[0..L-1] */ +FLOAT32 *pInTDd, /* Ein: Referenzsignal d[0..L-1] */ +FLOAT32 *pOutTDy, /* Aus: Filterausgang y[0..L-1] */ +FLOAT32 *pOutTDe, /* Aus: Fehlersignal e[0..L-1] */ +FLOAT32 alpha) +{ + + UINT32 i, p, NP, C_L; + + CMPXBUF *pX, *pWS, *pPj; + REALBUF *pMu; + COMPLEX *pTemp; + FLOAT32 muNom; + + /*---------------------------------------------------------------*/ + /* Beginn: Partitioned FFT-Filterung + /*---------------------------------------------------------------*/ + /* TODO: Standalone Version der Partitioned-FFT-Filterung */ + + /* Arbeitszeiger */ + pX = pObj->pX; /* Aktueller Zeiger X[k] */ + pWS = pObj->pBufWS; /* Aktueller Zeiger WS[0] */ + pPj = pObj->pPj; /* Aktueller Zeiger Pj[] */ + pMu = pObj->pMu; /* Aktueller Zeiger Mu[k] */ + pTemp = pObj->pTemp; /* 'Y' wird nach der Filterung als + temporaerer Speicher benutzt */ + + NP = pObj->S*pObj->L; /* N/P = S*L */ + C_L = pObj->C - pObj->L; /* C-L */ + + + /* Arbeitspuffer 'X' auffuellen Re{X[S*L..C-1]} = x[0..L-1] */ + AvMemCpy(&pX->cmpxData.pReal[C_L],pInTDx, + pObj->L*sizeof(FLOAT32)); + + /* Saveblock 'xs' anfuegen Re{X[0..C-L-1]} = xs[0..C-L-1] */ + AvMemCpy(pX->cmpxData.pReal,pObj->pBufXsave, + C_L*sizeof(FLOAT32)); + + /* Saveblock aktualisieren xs[0..C-L-1] = x[L..C-1] */ + AvMemCpy(pObj->pBufXsave, &pX->cmpxData.pReal[pObj->L], + C_L*sizeof(FLOAT32)); + + /* Imaginaerteil von 'X' auf Null setzen Im{X[0..C-1]} = {0} */ + AvZeroMem(pX->cmpxData.pImag,pObj->C*sizeof(FLOAT32)); + + /* X = 1/C*FFT{x} */ + ffts(pObj->pFFT, pX->cmpxData.pReal, pX->cmpxData.pImag); + + /* 1. Partition Multiplikation im Frequenzbereich + Y = X[k][0..C-1] * H[0][0..C-1] * C */ + CmpxVectMulS(&pX->cmpxData, &pWS->cmpxData, + pTemp, pObj->C); + + /* 2. Partition bis P-te Partition */ + for (p=1; p < pObj->P; p++) + { + pWS = pWS->pNext; + + /* X[k-p*S] suchen */ + pX = pX->pLastPS; + + /* Y = X[k-p*S][0..C-1] * H[p][0..C-1] * C */ + CmpxVectMacS(&pX->cmpxData, &pWS->cmpxData, + pTemp, pObj->C); + } + + /* Zeiger wieder WS[0] setzten */ + pWS = pObj->pBufWS; + + /* Zeiger wieder auf aktuellen Block X[k] setzten */ + pX = pObj->pX; + + /* In den Zeitbereich transformieren, y = IFFT{Y} */ + ifft(pObj->pFFT, pTemp->pReal, pTemp->pImag); + + /* Abspeichern der letzten L Daten ys[0..L-1] = Re{Y[C-L..C-1] */ + AvMemCpy(pOutTDy, &pTemp->pReal[C_L], + pObj->L*sizeof(FLOAT32)); + + /*---------------------------------------------------------------*/ + /* Ende: Partitioned FFT-Filterung + /*---------------------------------------------------------------*/ + /* Die Variable 'Y' wird nun nicht mehr gebraucht. + /* In den Nachfolgenden Abschnitten wird 'Y' als temporaerer + /* Speicher benutzt. + + /*---------------------------------------------------------------*/ + /* Fehlersignal 'e = d - y' berechnen */ + /* Transformation von 'e' in den Frequenzbereich */ + /*---------------------------------------------------------------*/ + + for (i=0; i < pObj->L; i++) + pOutTDe[i] = pInTDd[i] - pOutTDy[i]; + + /* Variable Y wird fuer E missbraucht, da nicht mehr gebraucht */ + /* Imaginaerteil von 'Y' auf Null setzen Im{Y[0..C-1]} = {0} */ + + AvZeroMem(pTemp->pImag,pObj->C*sizeof(FLOAT32)); + + /* Re{Y[0..C-L-1]} = {0} */ + AvZeroMem(pTemp->pReal,C_L*sizeof(FLOAT32)); + + /* Re{Y[C-L..C-1]} = e[0..L-1] */ + AvMemCpy(&pTemp->pReal[C_L], + pOutTDe,pObj->L*sizeof(FLOAT32)); + + /* E = 1/C*fft{e[0[0..C-L-1],e[0..L]} */ + ffts(pObj->pFFT, pTemp->pReal, pTemp->pImag); + + /*---------------------------------------------------------------*/ + /* Berechnung PX und Mu + /*---------------------------------------------------------------*/ + /* Zaehler Alpha*Gamma/P */ + muNom = (FLOAT32)(alpha*pObj->gamma/pObj->P); + + for (i=0; i < pObj->C; i++) + { + /* Schaetzung der mittleren Eingangsleistung PX */ + pObj->pBufPX[i] = (FLOAT32)fabs((pX->cmpxData.pReal[i]*pX->cmpxData.pReal[i] + + pX->cmpxData.pImag[i]*pX->cmpxData.pImag[i]) + * (1.0-LAMBDA) * pObj->C + LAMBDA*pObj->pBufPX[i]); + + /* Berechnung der variablen Schrittweite Mu */ + /* mu[k] = (Alpha*Gamma) / (P*(PX+Gamma)) */ + pObj->pMu->pData[i] = muNom / (pObj->pBufPX[i] + pObj->gamma); + } + + /* Aktualisierung der Filterkoeffizienten */ + for (p=0; p < pObj->P; p++) + { + for (i=0; i < pObj->C; i++) + { + pWS->cmpxData.pReal[i] += ((pX->cmpxData.pReal[i] * pTemp->pReal[i] + + pX->cmpxData.pImag[i] * pTemp->pImag[i]) + * pMu->pData[i] * pObj->C); + pWS->cmpxData.pImag[i] += ((pX->cmpxData.pReal[i] * pTemp->pImag[i] + - pX->cmpxData.pImag[i] * pTemp->pReal[i]) + * pMu->pData[i] * pObj->C); + } + pWS = pWS->pNext; + pX = pX->pLastPS; + pMu= pMu->pLastPS; + } + + /* Effiziente Projektion der Filterkoeffizienten */ + ifft(pObj->pFFT, pPj->cmpxData.pReal, pPj->cmpxData.pImag); + AvZeroMem(pPj->cmpxData.pImag, pObj->C*sizeof(FLOAT32)); + AvZeroMem(&pPj->cmpxData.pReal[NP],(pObj->C-NP)*sizeof(FLOAT32)); + ffts(pObj->pFFT, pPj->cmpxData.pReal, pPj->cmpxData.pImag); + + /* Fuer den naechsten Aufruf Zeiger aktualisieren */ + /* Naechstes X[k] ist: */ + pObj->pX = pObj->pX->pNext; + + /* Naechstes Mu[k] ist: */ + pObj->pMu = pObj->pMu->pNext; + + /* Naechstes Teilfilter fuer Projektion ist: */ + pObj->pPj = pObj->pPj->pNext; + + return AV_E_OK; + +} + +/*------------------------------------------------------------------*/ + diff --git a/pflms2.h b/pflms2.h new file mode 100755 index 0000000..17b459f --- /dev/null +++ b/pflms2.h @@ -0,0 +1,39 @@ +/*------------------------------------------------------------------------- + * pflms.h Partioned Frequency Least-Mean-Square adaptive algorithm + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ + +#ifndef _PFLMS_H +#define _PFLMS_H +#include "pfft.h" + +/*-----------------------------------------------------------------------*/ +/* PFLMS-Parameter */ +/*-----------------------------------------------------------------------*/ + +typedef struct _sPFLMS +{ + UINT32 N, P, S, L, C; /* PFLMS-Parameter N, P, S, L, C */ + FLOAT32 gamma; /* Sicherheitskonstannte */ + CMPXBUF *pBufX, *pBufWS; /* komplexe Puffer X[P*S][C], WS[P][C] */ + CMPXBUF *pX, *pWS, *pPj; /* aktuelle Zeiger auf Puffer[p][] */ + COMPLEX *pTemp; /* temporaerer Puffer fuer Y[] und E[] */ + REALBUF *pBufMu; /* reeller Puffer Mu[P*S][C] */ + REALBUF *pMu; /* Aktueller zeiger auf Mu[k-p*S] */ + FLOAT32 *pBufPX; /* reeller Puffer PX[C] */ + FLOAT32 *pBufXsave; /* Overlap-Save Puffer xs[S*L] */ + FFT *pFFT; /* FFT-Objekt */ +} PFLMS; + + +AVERR PflmsInit(PFLMS *pObj,UINT32 N, UINT32 P, UINT32 S, UINT32 L, UINT32 C); +AVERR PflmsInitFilter(PFLMS *pObj, FLOAT32 *pWTD); +AVERR Pflms(PFLMS *pObj, FLOAT32 *pInTDx, FLOAT32 *pInTDd, FLOAT32 *pOutTDy, FLOAT32 *pOutTDe, FLOAT32 alpha); + +#endif /* _PFLMS_H */ + diff --git a/pflms_c.bak b/pflms_c.bak new file mode 100755 index 0000000..dbe1592 --- /dev/null +++ b/pflms_c.bak @@ -0,0 +1,228 @@ +/*------------------------------------------------------------------------- + * pflms.c Partioned Frequency Least-Mean-Square adaptive algorithm + * $Id: $ + *------------------------------------------------------------------------- + * + * Copyright (C) 2001 Algo Vision Systems GmbH + * + *------------------------------------------------------------------------- + */ +#define AVNEEDFLOAT + +#include +#include "../../../include/avtypes.h" +#include "../../../include/averror.h" +#include "../../../include/avrtl.h" +#include "../../../include/fft.h" +#include "pflms.h" + +/*-----------------------------------------------------------------------*/ + +AVERR PflmsInit( +PFLMS *pObj, /* Zeiger auf PFLMS-Objekt */ +UINT32 N, +UINT32 P, +UINT32 S, +UINT32 L, +UINT32 C +) +{ + UINT32 i, NP; + + /* Auto-Param */ + if ((N*L)==0) + return AV_E_FAIL; + + if (P==0) + { + if ((N%L) != 0) + return AV_E_FAIL; + P = N/L; + } + + /* Auto-guess FFT-Groesse C */ + if (C==0) + pObj->C = (UINT32)pow(2,ceil(log(L+N/P-1)/log(2.0))); + + /* Objekt initialisieren */ + pObj->L = L; + pObj->N = N; + pObj->P = P; + pObj->S = S; + NP = pObj->S * pObj->L; + + /*-------------------------------------------------------*/ + /* Speicher allokieren */ + /*-------------------------------------------------------*/ + /* Speicher fuer Mu[P*S][C] (reell) */ + pObj->pMu = (REALBUF*)AvMemAlloc(P*S*sizeof(REALBUF)); + + for (i=0; i < P*S; i++) + { + pObj->pMu[i].pData = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pMu[i].pData,pObj->C*sizeof(FLOAT32)); + pObj->pMu[i].pNext = &pObj->pMu[i+1]; + pObj->pMu[i].pLast = &pObj->pMu[i-1]; + pObj->pMu[i].user = i; + } + pObj->pMu[i-1].pNext = &pObj->pMu[0]; + pObj->pMu[0].pLast = &pObj->pMu[i-1]; + + /* Speicher fuer PX[C] (reell) */ + pObj->pPX = (REALBUF*)AvMemAlloc(sizeof(REALBUF)); + pObj->pPX->pData = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pPX->pData,pObj->C*sizeof(FLOAT32)); + pObj->pPX->pNext = pObj->pPX; + pObj->pPX->pLast = pObj->pPX; + pObj->pPX->user = 0; + + + /* Speicher fuer X[P*S][C] (complex) */ + pObj->pX = (CMPXBUF*)AvMemAlloc(P*S*sizeof(CMPXBUF)); + + for (i=0; i < P*S; i++) + { + pObj->pX[i].cmpxData.pReal = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + pObj->pX[i].cmpxData.pImag = (FLOAT32*)AvMemAlloc(pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pX[i].cmpxData.pReal,pObj->C*sizeof(FLOAT32)); + AvZeroMem(pObj->pX[i].cmpxData.pImag,pObj->C*sizeof(FLOAT32)); + pObj->pX[i].pNext = &pObj->pX[i+1]; + pObj->pX[i].pLast = &pObj->pX[i-1]; + pObj->pX[i].user = i; + } + pObj->pX[i-1].pNext = &pObj->pX[0]; + pObj->pX[0].pLast = &pObj->pX[i-1]; + + + /* Speicher fuer WS[P][C] (complex) */ + pObj->pWS = (CMPXBUF*)AvMemAlloc(P*S*sizeof(CMPXBUF)); + + for (i=0; i < P*S; i++) + { + pObj->pWS[i].pData = (COMPLEX*)AvMemAlloc(pObj->C*sizeof(COMPLEX)); + AvZeroMem(pObj->pWS[i].pData,pObj->C*sizeof(COMPLEX)); + pObj->pWS[i].pNext = &pObj->pWS[i+1]; + pObj->pWS[i].pLast = &pObj->pWS[i-1]; + pObj->pWS[i].user = i; + + } + pObj->pWS[i-1].pNext = &pObj->pWS[0]; + pObj->pWS[0].pLast = &pObj->pWS[i-1]; + pObj->pPj = pObj->pWS; /* aktueller Buffer fuer Projektion */ + + /* Ergebnis 'Y' der Faltung (complex) */ + pObj->pY = (COMPLEX*)AvMemAlloc(pObj->C*sizeof(COMPLEX)); + AvZeroMem(pObj->pY,pObj->C*sizeof(COMPLEX)); + + /* Overlap-Save 'xs' */ + pObj->pXsave = (FLOAT32*)AvMemAlloc(NP*sizeof(FLOAT32)); + AvZeroMem(pObj->pXsave,NP*sizeof(FLOAT32)); + + /* FFT initialisieren */ + pObj->pFFT = (FFT*)AvMemAlloc(sizeof(FFT)); + FFTinit(pObj->pFFT, pObj->C); + + return AV_E_OK; +} + +/*-----------------------------------------------------------------------*/ +/* Partitioned FFT +/*-----------------------------------------------------------------------*/ +AVERR Pflms(PFLMS *pObj, FLOAT32 *pDataTD) +{ + + UINT32 p, s, NP; + + CMPXBUF *pX, *pWS; + NP = pObj->S*pObj->L; + + pX = pObj->pX; /* Aktueller Zeiger *X[C] */ + pWS = pObj->pWS; /* Aktueller Zeiger *WS[C] */ + + /* Arbeitspuffer 'X' auffuellen Re{X[S*L..C-1]} = x[0..L] */ + AvMemCpy(&pX->pData[NP].real,pDataTD, pObj->L*sizeof(FLOAT32)); + + /* letzten Saveblock 'xs' anfuegen Re{X[0..S*L-1]} = xs[0..S*L-1] */ + AvMemCpy(&pX->pData->real,pObj->pXsave, NP*sizeof(FLOAT32)); + + /* Saveblock aktualisieren xs[0..S*L-1] = x[L..C-1] */ + AvMemCpy(pObj->pXsave, &pDataTD[pObj->L], NP*sizeof(FLOAT32)); + + /* Imaginaerteil von 'X' auf Null setzen Im{X[0..C-1]} = 0 */ + AvZeroMem(&pX->pData->imag,pObj->C*sizeof(FLOAT32)); + + /* X = FFT{x} */ + fft(pObj->pFFT, &pX->pData->real, &pX->pData->imag); + + /* 1. Partition Faltung im Frequenzbereich Y = X * H */ + CmpxVectMul(pX->pData, pWS->pData, pObj->pY, pObj->C); + + /* 2. Partition bis P-te Partition */ + for (p=1; p < pObj->P; p++) + { + pWS = pWS->pNext; + + for (s=0; s < pObj->S; s++) + pX = pX->pLast; + + CmpxVectMac(pX->pData, pWS->pData, pObj->pY, pObj->C); + } + + /* y = IFFT{Y} */ + ifft(pObj->pFFT, &pObj->pY->real, &pObj->pY->imag); + + /* Abspeichern der letzten L Daten */ + AvMemCpy(pDataTD, &pObj->pY[NP].real, pObj->L*sizeof(FLOAT32)); + + return AV_E_OK; + +} + +/*-----------------------------------------------------------------------*/ +/* Complex-Funktionen +/*-----------------------------------------------------------------------*/ +void CmpxVectMul(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB[i].real = pA[i].real*pB[i].real - pA[i].imag*pB[i].imag; + pAB[i].imag = pA[i].real*pB[i].imag + pA[i].imag*pB[i].real; + } +} + +void CmpxVectAdd(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB[i].real = pA[i].real + pB[i].real; + pAB[i].imag = pA[i].imag + pB[i].imag; + } +} + +void CmpxVectMac(struct _sCOMPLEX *pA, struct _sCOMPLEX *pB, struct _sCOMPLEX *pAB, UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAB[i].real += pA[i].real*pB[i].real - pA[i].imag*pB[i].imag; + pAB[i].imag += pA[i].real*pB[i].imag + pA[i].imag*pB[i].real; + } +} + +void RealVectSquConj(struct _sCOMPLEX *pA, FLOAT32 *pAA, UINT32 len) +{ + UINT32 i; + + for (i=0; i < len; i++) + { + pAA[i] = pA[i].real*pA[i].real + pA[i].imag*pA[i].imag; + } +} + +/*-----------------------------------------------------------------------*/ +