FIR filters

Mensen,

Ik zit niet meer op school maar ik ben wel ge-interesseerd als inmiddels hoogbejaarde in techniek; de burgemeester is al bij me op bezoek willen komen om mij te feliciteren, hetgeen ik vriendelijk edoch gestreng afwees.

Je moet er niet aan denken dat die man de IC's, of wat ik er voor aanzie, hier over de grond ziet kri-oelen en paren, in verband met mijn hang naar zelfstandigheid.

Steeds spaarzamer wordende lotgenoten hebben mij al een kip aangeraden als weinig eisen stellende huishoudelijk reinigster dienaangaande, die feilloos in staat is de IC's van de insecten te onderscheiden in tegenstelling tot de vanwege de plaatselijke overheid aangewezen ANW dame.

Terzake:

Ik wilde wat experimenteren als rechtgeaard zendamateur met digitale filters.

Nu heb ik een geluids-wav-bestand, voor het gemak heb ik witte ruis gefabriceerd met random nummers, en met een sin(x)/x als impuls response heb ik over 129 samples een FIR geprogrammeerd.

Stop ik daar die ruis in dan blijkt inderdaad met een FFT de aanvankelijk witte ruisband scherp begrensd, met wat bobbels (terugkomers) ernaast.

Nu wil ik echter dat laagdoorlatende filter omtransformeren tot een hoogdoorlatend filter.

Dat zou dan moeten kunnen door de resultaten van het laagdoorlatend filter h[n] af te trekken van een all pass filter d[n].

Oftewel gecombineerd door de oorspronkelijke sin(x)/x van teken om te draaien en er op het symmetrische 0 moment dan 1 bij op te tellen.

Dat blijkt echter niet te werken. Ik lag er vannacht wakker van na een nachtmerrie over een over het plaveisel rollend hoofd van een bromfietser.

de burgemeester die langskomt als je 94 bent geworden? dat is toch pas bij 100jaar?

waar rook was, werkt nu iets niet meer

Op 26 mei 2017 16:31:39 schreef Dr Blan:
Ik lag er vannacht wakker van na een nachtmerrie over een over het plaveisel rollend hoofd van een bromfietser.

De mensen die niet alle topics meelezen snappen er nu weinig meer van :)

If you want to succeed, double your failure rate.

Testman

Verschilt per gemeente heb ik vernomen. Als het bij 100 is woon je in een gezonde gemeente, niet onder de oranje rook van Pernis of zo.

Ze stemmen de leeftijd op een veelvoud van 5 af per gemeente op een corvee bezoek des burgemeesters van een per maand.

Lambiek

Special Member

Op 26 mei 2017 16:38:36 schreef Jochem:
[...]De mensen die niet alle topics meelezen snappen er nu weinig meer van :)

Dat is weer een ander topic Jochem. :)

EDIT:
Oeps, laatste twee regels niet gelezen. Ik raak ook helemaal in de war.

Als je haar maar goed zit, GROETEN LAMBIEK.

EDIT:
Correctie: zie post van zondag 28 mei 2017 06:25:10

[Bericht gewijzigd door Siekmanski op zondag 28 mei 2017 06:30:07 (84%)

Op 27 mei 2017 09:50:20 schreef Siekmanski:
LowPass naar HighPass d.m.v. de FIR coëfficiënten te inverteren.
En vice versa.

In welke taal programmeer je?

Speelt toch geen rol? Het is Borland (Turbo) C op een PC-AT die onder windows 95 draait.

Welnu dit gedoe met een FIR filter ben ik inmiddels verder gaan onderzoeken.

Het idee is dat je een allpass aftrekt van een low pass, zodat er een high pass overblijft. Dat was dus in een set coefficienten gecombineerd, maar het staat je natuurlijk vrij voor het onderzoek dat filter te splitsen in twee takken, een allpass tak en een low pass tak.

Voor de demping van de high pass is het uiteraard van belang dat op elke frequentie de fase van de low pass lineair is dus de impulse response symmetrisch. Daarom nam ik ook 129 coefficenten zodat er links en rechts van de centraalcoefficient er 64 resteren.

Voor het onderzoek bedacht ik vannacht, dat gaat onderbewust blijkbaar, dat ik de zaak eenvoudig kan testen voor het verkrijgen van inzicht met DC als steady state input.
De all pass heeft zijn coefficient 1 op 64 liggen, correct dus, de andere coefficienten 0.

Voor de low pass gebruikte ik weer de reeds geteste sin(x)/x voor x integer in het interval [-64,64]

Voor DC kan ik de output van de allpass berekenen, 1, dat zal duidelijk zijn, en van de lowpass is de output NIET 1 maar 3.zoveel (GEEN pi)

Siekmanski:

code:


/* 27 may 2017 (c) dr Blan HIGH PASS check for DC*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define L 129  /* number of taps  in FIR MUST BE ODD */

int main()
{
double kernel[L],yf;     /* filter coefficients */
int i;

/* make kernel set of coefficients */

for(i=0;i<L;i++)
	{
	if(i==(L-1)/2) kernel[i]=-1.;
	else                  /* 0-63, 64, 65..128*/
	kernel[i]=-sin((double)(i-(L-1)/2))/(double)(i-(L-1)/2);
	}

/* calculate filter output for steady state DC=1 input*/
yf=0.;
for(i=0;i<129;i++)
	{
	yf+=kernel[i];          /* steady state output for DC=1 input */
	}
printf("\n kernel output steady state for DC=1 input = %e",yf);
/* kernel output of dirac function (kernel[64]=1.; kernel[i!=64]=0.; */


yf=1.;
printf("\n kernel output steady state for DC=1 input = %e",yf);

return(0);
}

aanvulling:
Dat de output van de low pass voor DC geen pi is zal komen omdat de zaak qua coefficienten wel symmetrisch is, maar niet tot oneindig doorloopt. Om de zaak in orde te krijgen moet ik dus de all pass niet 1 als coefficienet geven maar sigma( de berekende 129 coefficienten van de low pass) met correct teken.

aanvulling2: Het werkt nu door in plaats van de dirac 1 nu de sigma van de low pass coefficieneten te nemen.
Bedankt voor het meedenken.

EDIT:
Correctie: zie post van zondag 28 mei 2017 06:25:10

[Bericht gewijzigd door Siekmanski op zondag 28 mei 2017 06:30:42 (95%)

Op 27 mei 2017 15:27:01 schreef Siekmanski:
Wanneer de FIR coëfficiënten symmetrisch over de tijd as lopen ( b.v. tussen 1.0 en -1.0 ), hoef je alleen het voor-teken te inverteren om van low naar high pass te gaan en ben je klaar.

Als ik alle coefficienten van teken wissel in een low pass, dan houd ik toch een low pass echter met het outputsignaal van teken verwisseld?
Die dirac all pass lijkt me essentieel.

Mijn assembly ervaring gaat niet verder dan diverse micro's zoals 6800 en 8080 en de latere Intel MCS-51 architecture en een PDP-11, bedankt voor het aanbod, vermoedelijk kan ik MASM met comments wel passief analyseren, maar ik knutsel nog even door met vallen en opstaan op de ingeslagen weg. Ik werk een wav file om in een andere gefilterde, dan speelt processorsnelheid geen rol.

EDIT:
Correctie: zie post van zondag 28 mei 2017 06:25:10

[Bericht gewijzigd door Siekmanski op zondag 28 mei 2017 06:31:03 (93%)

Alex P

Golden Member

Zo'n ding heet SCHAKELENDE, niet "geschakelde" voeding.

Op 27 mei 2017 17:22:28 schreef Alex P:
Goed bezig, Dr Blan!

Dat ben ik altijd Alex, maar ik word weer agressief bejegend, althans, zo ervaar ik dat, elders op dit forum bij de draad over stekkeramateurs. Ze hebben het over zendamateurs, een doorsnee zendamateur, beter dan doorsnee: met morsevaardigheid, kun je zien op https://www.youtube.com/watch?v=dQa8lydtFmE
Zoiets eindigt altijd in een definitieve ban, sinds mijn schooljaren levenslang ervaren, niets nieuws onder de zon.

Siekmanskie: Bedankt voor je reactie en de correctie. Ik beperk me even in mijn beperkte denkraam tot de transformatie van low pass naar high pass.

Als je dan als transformatiealgoritme stelt: Alle coefficienten van de symmetrische impulse response der low pass van teken wisselen UITGEZONDERD die in de verschoven t=0,
dan gaat dat volgens mij ook niet op.

Immers je moet aan de voorwaarde voldoen dat het parallelle all pass
een coefficientenreeks heeft die overal 0 is behalve op het t=0 punt en daar moet hij: minus de som van ALLE coefficienten van de low pas zijn.

Jouw voorbeeldalgoritme gaat dus slechts op als de eindig begrensde som van alle coefficienten van de lowpass gelijk is aan
twee maal de t=0 component van de low pass.

Dr Blan, je hebt gelijk.
Ik heb net een fout in mijn berekening ontdekt.
Ga er morgen mee aan de slag en kom er nog op terug.

Nadeel van de compensatiemethode met een all pass is dat de fasekarakteristiek lineair moet zijn, met symmetrische impulse response dus.

Ik kan ook de lowpassoutput vermenigvuldigen met een sinus op de halve bemonsterfrequentie.
Dat kan gecombineerd in de originele impulsresponse gebeuren door om de andere coefficient in teken te wijzigen.

Als je dit op een wav file met spraak toepast klinkt dat dus als een LSB signaal met de BFO aan de verkeerde kant. Nog niet geprobeerd.
De witte ruis door de ontstane high pass geeft nu:

Als ik een analoog filter maak, laagdoorlatend, met een chebeshev polynoom, en door transformatie een hoogdoorlatend filter, dan kan ik door de juiste grensfrequenties te kiezen en ze te concateneren, een bandfilter laten vormen. Echter als je eene laagdoorlatend filter direct transformeert naar een banddoorlatend is dat veel scherper.

Ik vraag me af of dat digitaal ook zo is. In feite kan ik een cheveshevpolynoom in de noemer van de overdrachtsfunctie om transformeren naar een bandfilter en vervolgens de bilineaire transformatie erop los laten om de FIR filter coefficienten te vinden.

[Bericht gewijzigd door Dr Blan op zondag 28 mei 2017 01:27:24 (36%)

Als het goed is kan men een FIR low-pass naar high-pass converteren door alle voortekens te inverteren.
Daarna bij het center coëfficiënt 1.0 optellen.

Ga deze week mijn routines herschrijven want er zit inderdaad een fout in.

DUS NEGEER MIJN VORIGE POSTS ( sorry, voor het ongemak )

http://www.dspguide.com/ch14/4.htm

http://www.dspguide.com/graphics/F_14_5.gif

Siekmanski,

Wel bedankt voor het meedenken en de referentie.
Maar ik ben er wel uit, zoals je hiervoor kunt lezen.
Dus ik ga dit topic met dit bericht afsluiten.

Die referentie die je geeft kan echter niet kloppen, omdat in het algemeen toevoegen van een 1 als allpass slechts als bandsper werkt, als de modulus van de som van de coefficienten van de low pass gelijk is aan 1.

Nu heb ik gisteren de low pass werkend gekregen en vervolgens door om het andere coefficient van teken te keren, dus te vermenigvuldigeen met de halve bemonsterfrequentie een gespiegelde high pass.

Door die twee op te tellen moet dan een bandsper worden verkregen. Toepassing van de distributieve wet van optelling, want het ene filter geeft van kernelelementen een optellen, het andere parallel geschakelde ook, en per monster kun je apart optellen, dus de kernels per index optellen moet werken.

Hier betekent dat, omdat de ene kernel de andere is met om het andere monster teken verwisseld, dat de oneven elementen 0 worden en de even elementen verdubbeld.

Dat heb ik geprogrammeerd en komt inderdaad een bandsper uit.

Dr Blan, de referentie van dspguide.com klopt wel.

Ben er uit, heb mijn FIR routine herschreven en het werkt.

FIR low-pass naar high-pass converteren door alle voortekens van alle coëfficiënten te inverteren.
Daarna bij het center coëfficiënt 1.0 optellen.

Band-reject is gelijk aan een low-pass filter met kantelfrequentie1 waarvan alle coëfficiënten worden opgeteld met de coëfficiënten van een high-pass filter met kantelfrequentie2.

Band-pass is een band-reject filter waarvan alle coëfficiënten zijn geïnverteerd waarna bij het center coëfficiënt 1.0 wordt opgeteld.

De coëfficiënten van de low-pass en high-pass filters zijn genormaliseerd!

Voorbeeld FIR filters met een Hamming window functie:

sample rate = 4000
filter order = 2 ( == 3 coëfficiënten )
kantelfrequentie1 = 500 Hz
kantelfrequentie2 = 1500 Hz

low-pass:
0.0629563977556293
0.8740872044887413
0.0629563977556293

high-pass:
-0.062956397755629
0.1259127955112586
-0.062956397755629

high-pass2: ( kantelfrequentie2 )
-0.022908443346961
0.0458168866939223
-0.022908443346961

band-reject:
0.0400479544086680
0.9199040911826637
0.0400479544086680

band-pass:
-0.040047954408668
0.0800959088173363
-0.040047954408668