Forums

split Hilberts

Started by jasontje32 1 month ago7 replieslatest reply 1 month ago127 views
I'm trying to get my arms around tradeoffs related to Hilbert filters in IQ SDR radio. It seems that split 45 deg filters can be inherently matched for performance & delay whereas a single 90 deg filter needs to be balanced by a corresponding delay in the opposite channel. Also, the single filter approach seems like it would have more group delay, everything else being equal. Am I correct?

What other factors should be considered?
[ - ]
Reply by SlartibartfastOctober 23, 2020

Is there are reason to not just use a mixer (i.e., complex mix to baseband)?   Hilbert transformers tend to add distortion, which can affect performance in a link.   A properly implemented mixer does not.

[ - ]
Reply by cpeckhamOctober 23, 2020

You are coorrect in your assumptions. I have been using hilbert filter +- 45 degrees for over a year in SDR ham radios. i use filters designed by Ron, G4GXO. He also has a filter desing program in the files section of groups.io/edendsp. 

another advantage is that the filters use the same coefficients.one filter uses the coefficients from top to bottom and the other filter uses them from bottom to top. In my case these are implmented on a Microchip DSPic processor and work great.

[ - ]
Reply by fharrisOctober 23, 2020

in analog phase shifting hilbert transforms the two arms are +/-45 degrees to get a 90 phase difference. Much easier to do in DSP land.... are comfortable there. As far as i can tell all transceivers use the DSP based Hilbert transforms. My dad was a ham and I now his used the DSP filters. I an pass on more information... Are you comfortable with matlab? I can add some matlab examples...


let me know.. 

The mixer version... the one called a weaver modulator only has about 40 dB dynamic range due to the imbalance of the miv=xers and filters... the DSP versions easily have more than 100 dB rejection of the opposing sideband.  I have some neat audio effects that use the Hilbert transform filter to shift the spectra away from or towards DC to make to harmonics (overtones) non harmonic...


fred h  

[ - ]
Reply by Lito844October 24, 2020

fharris: Don't know about the OP but I would certainly be interested in reviewing your MATLAB examples of +/-45 degree Hilbert filters.

[ - ]
Reply by fharrisOctober 24, 2020

% linear Phase FIR filter Hilbert Transform, two lengths

h=1:2:30;

h1=1./h;

h2=reshape([h1;zeros(1,15)],1,30);

h4=[-fliplr(h2) 0 h2];

hh=kaiser(61,8)';

h3=(2/pi)*[0 h2 zeros(1,500) -fliplr(h2)].*[hh(31:61) zeros(1,500) hh(1:30)];

figure(1)

subplot(3,1,1)

plot(-0.5:1/561:0.5-1/561,fftshift(real(fft([1 zeros(1,560)]))),'linewidth',2)

hold on

plot(-0.5:1/561:0.5-1/561,fftshift(real(fft(j*h3))),'r','linewidth',2)

hold off

grid on

subplot(3,1,2)

plot(-0.5:1/561:0.5-1/561,fftshift(abs(fft([1 zeros(1,560)]+j*h3))),'linewidth',2)

grid on

subplot(3,1,3)

plot(-0.5:1/561:0.5-1/561,fftshift(20*log10(abs(fft([1 zeros(1,560)]+j*h3)/2))),'linewidth',2)

grid on

axis([-0.5 0.5 -100 10])

figure(2)

subplot(5,1,1)

stem(-30:30,[zeros(1,30) 1 zeros(1,30)],'linewidth',2);

grid on

title('Impulse Response Direct Path Filter, h0(n)')

axis([-35 35 -1.1 1.1])

subplot(5,1,2)

stem(-30:30,h4.*hh,'r','linewidth',2)

grid on

title('Impulse Response Hilbert Transform Filter, h1(n)')

axis([-35 35 -1.1 1.1])

subplot(5,1,3)

plot(-0.5:1/561:0.5-1/561,fftshift(real(fft([1 zeros(1,560)]))),'linewidth',2)

grid on

title('Real Part, Frequency Response Direct Path Filter, H0(w)')

axis([-0.5 0.5 -2.1 2.1])

subplot(5,1,4)

plot(-0.5:1/561:0.5-1/561,fftshift(real(fft(j*h3))),'r','linewidth',2)

grid on

title('Imaginary Part, Response Hilbert Transform Filter, H1(w)')

axis([-0.5 0.5 -2.1 2.1])

subplot(5,1,5)

plot(-0.5:1/561:0.5-1/561,fftshift(abs(fft([1 zeros(1,560)]+j*h3))),'linewidth',2)

axis([-0.5 0.5 -0.1 2.1])

grid on

title('Frequency Response Analytic Filter: FFT(h0(n)+j*h1(n)) = H0(w)+j*H1(w)')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

h=1:2:60;

h1=1./h;

h2=reshape([h1;zeros(1,30)],1,60);

h4=[-fliplr(h2) 0 h2];

hh=kaiser(121,8)';

h3=(2/pi)*[0 h2 zeros(1,500) -fliplr(h2)].*[hh(61:121) zeros(1,500) hh(1:60)];

figure(3)

subplot(3,1,1)

plot(-0.5:1/621:0.5-1/621,fftshift(real(fft([1 zeros(1,620)]))),'linewidth',2)

hold on

plot(-0.5:1/621:0.5-1/621,fftshift(real(fft(j*h3))),'r','linewidth',2)

hold off

grid on

subplot(3,1,2)

plot(-0.5:1/621:0.5-1/621,fftshift(abs(fft([1 zeros(1,620)]+j*h3))),'linewidth',2)

grid on

subplot(3,1,3)

plot(-0.5:1/621:0.5-1/621,fftshift(20*log10(abs(fft([1 zeros(1,620)]+j*h3)/2))),'linewidth',2)

grid on

axis([-0.5 0.5 -100 10])

figure(4)

subplot(5,1,1)

stem(-60:60,[zeros(1,60) 1 zeros(1,60)],'linewidth',2);

grid on

title('Impulse Response Direct Path Filter, h0(n)')

axis([-65 65 -1.1 1.1])

subplot(5,1,2)

stem(-60:60,h4.*hh,'r','linewidth',2)

grid on

title('Impulse Response Hilbert Transform Filter, h1(n)')

axis([-65 65 -1.1 1.1])

subplot(5,1,3)

plot(-0.5:1/621:0.5-1/621,fftshift(real(fft([1 zeros(1,620)]))),'linewidth',2)

grid on

title('Real Part, Frequency Response Direct Path Filter, H0(w)')

axis([-0.5 0.5 -2.1 2.1])

subplot(5,1,4)

plot(-0.5:1/621:0.5-1/621,fftshift(real(fft(j*h3))),'r','linewidth',2)

grid on

title('Imaginary Part, Response Hilbert Transform Filter, H1(w)')

axis([-0.5 0.5 -2.1 2.1])

subplot(5,1,5)

plot(-0.5:1/621:0.5-1/621,fftshift(abs(fft([1 zeros(1,620)]+j*h3))),'linewidth',2)

axis([-0.5 0.5 -0.1 2.1])

grid on

title('Frequency Response Analytic Filter: FFT(h0(n)+j*h1(n)) = H0(w)+j*H1(w)')



Recursive Hilberts

from harris text book, Multirate signal processing

% fig_10_57, fig_10_58, and fig_10_59

%function all_pass_x4c

clear all

% Denominator of top path all-pass filter

hh01=[1    0    -0.09974023698395];

hh02=[1    0    -0.60748212697287];

% Denominator of bottom path all-pass filter

hh11=[1    0    -0.33760288599006];

hh12=[1    0    -0.86530628076387];

% delay in bottom path

gg2=[1.00   0];

xx=zeros(1,200);

xx(1)=1;

% impulse response, top path

[h1,w1]=freqz(fliplr(hh01),hh01,1000,'whole');

yt=filter(fliplr(hh01),hh01,xx);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr1=r1;

tt1=h1;

[h1,w1]=freqz(fliplr(hh02),hh02,1000,'whole');

yt=filter(fliplr(hh02),hh02,yt);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr1=rr1+r1;

tt1=tt1.*h1;

% impulse reponse, bottom path

[h1,w1]=freqz(fliplr(hh11),hh11,1000,'whole');

yb=filter(fliplr(hh11),hh11,xx);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr2=r1;

tt2=h1;

[h1,w1]=freqz(fliplr(hh12),hh12,1000,'whole');

yb=filter(fliplr(hh12),hh12,yb);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr2=rr2+r1;

tt2=tt2.*h1;

[h1,w1]=freqz(j*fliplr(gg2),gg2,1000,'whole');

yb=j*filter(fliplr(gg2),gg2,yb);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr2=rr2+r1;

tt2=tt2.*h1;

figure(1)

subplot(3,1,1)

stem(0:199,yt,'b','linewidth',2)

grid on

axis([-2 30 -1 1])

title('Impulse Response, Top Path, 4-Coefficient, IIR All-Pass Hilbert Transform ')

subplot(3,1,2)

stem(0:199,imag(yb),'r','linewidth',2)

grid on

axis([-2 30 -1 1])

title('Impulse Response, Bottom Path, 4-Coefficient, IIR All-Pass Hilbert Transform ')

subplot(3,1,3)

plot((-0.5:1/1000:0.5-1/1000),fftshift(20*log10(abs(tt1+tt2)/2)),'linewidth',2);

grid

axis([-0.5 0.5 -90 10])

title('Spectrum, Two-Path 8-Coefficient IIR Hilbert Transform Filter')

figure(2)

plot(-0.5:1/1000:0.5-1/1000,(rr1)+3,'b')

hold on

plot(-0.5:1/1000:0.5-1/1000,(rr2)+4,'r')

hold off

grid

title('Phase of Two-path IIR Filter')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

figure(8)

subplot(2,1,1)

plot(-0.5:1/1000:0.5-1/1000,(rr1)+3,'b')

hold on

plot(-0.5:1/1000:0.5-1/1000,(rr2)+4,'r')

hold off

grid

title('Phase of Nonuniform Phase Two-path IIR Filter')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

den1=conv(hh01,hh02);

num1=fliplr(den1);

den2=conv(hh11,hh12);

den2=conv(den2,gg2);

num2=fliplr(den2);

num_t=conv(num1,den2)+j*conv(num2,den1);

den_t=conv(den1,den2);

figure(3)

plot(exp(j*2*pi*(0:.01:1)),'r')

hold on

plot(roots(num_t),'o')

plot(roots(den_t),zeros(1,9),'x')

hold off

grid

axis([-1.5 1.5 -1.5 1.5])

axis('square')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%

figure(9)

subplot(1,2,1)

plot(exp(j*2*pi*(0:.01:1)),'r')

hold on

plot(roots(num_t),'o')

plot(roots(den_t),zeros(1,9),'x')

hold off

grid

axis([-1.8 1.8 -1.8 1.8])

axis('square')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

figure(4)

subplot(2,1,1)

plot((-0.5:1/1000:0.5-1/1000),fftshift(20*log10(abs(tt1+tt2)/2)));

grid

axis([-0.5 0.5 -90 10])

title('Spectrum, Two-path IIR Filter')

subplot(2,1,2)

phs=fftshift(unwrap(angle((tt1+tt2)/2))/(2*pi));

plot((-0.5:1/1000:0.5-1/1000),phs);

grid

%axis([-0.5 0.5 0 50])

title('Phase, Two-path IIR Filter')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%

figure(10)

subplot(2,2,1)

plot((-0.5:1/1000:0.5-1/1000),fftshift(20*log10(abs(tt1+tt2)/2)));

grid

axis([-0.5 0.5 -90 10])

title('Spectrum, Two-path IIR Filter')

subplot(2,2,3)

phs=fftshift(unwrap(angle((tt1+tt2)/2))/(2*pi));

plot((-0.5:1/1000:0.5-1/1000),phs);

grid

%axis([-0.5 0.5 0 50])

title('Phase, Two-path IIR Filter')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% %plot((0:1/1000:1-1/1000)*0.5,phs+2*pi);

% figure(4)

% phs=fftshift(unwrap(angle((tt1+tt2)/2))/(2*pi));

% %plot((0:1/1000:1-1/1000)*0.5,phs+2*pi);

% %grid

% %axis([0 0.5 -90 10])

% %title('Phase Angle, Two-path IIR Filter')

% %pause

% pp=filter([1 -1],[1 0],-phs*2000);

% reg=[0 0 0];

% for nn=1:length(pp);

% pp_m(nn)=median(reg);

% reg(2:3)=reg(1:2);

% reg(1)=pp(nn);

% end

% pp_m(1)=pp_m(4);

% pp_m(2)=pp_m(4);

% pp_m(3)=pp_m(4);

% % plot((-0.5:1/1000:0.5-1/1000),pp_m);

% plot((-0.5:1/1000:0.5-1/1000),phs);

% grid

% %axis([-0.5 0.5 0 50])

% title('Group Delay, Two-path IIR Filter')

hh11=[1    0     0.80751160088130];

hh12=[1    0     0.523291126198461   0  0.1826273278813162];

hh13=[1    0    -0.6671747645127255  0  0.1372281517339095];

hh14=[1    0    -0.1718144130467638  0  0.1463729351820391];

hh11(3)=-hh11(3);

hh12(3)=-hh12(3);

hh13(3)=-hh13(3);

hh14(3)=-hh14(3);

hh01=[1 zeros(1,13)];

xx=zeros(1,200);

xx(1)=1;

[h1,w1]=freqz(fliplr(hh01),hh01,1000,'whole');

yt=filter(fliplr(hh01),hh01,xx);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr1=r1;

tt1=h1;

[h1,w1]=freqz(fliplr(hh11),hh11,1000,'whole');

yb=filter(fliplr(hh11),hh11,xx);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr2=r1;

tt2=h1;

[h1,w1]=freqz(fliplr(hh12),hh12,1000,'whole');

yb=filter(fliplr(hh12),hh12,yb);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr2=rr2+r1;

tt2=tt2.*h1;

[h1,w1]=freqz(fliplr(hh13),hh13,1000,'whole');

yb=filter(fliplr(hh13),hh13,yb);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr2=rr2+r1;

tt2=tt2.*h1;

[h1,w1]=freqz(j*fliplr(hh14),hh14,1000,'whole');

yb=j*filter(fliplr(hh14),hh14,yb);

r1=unwrap(fftshift(angle(h1)))/(2*pi);

rr2=rr2+r1;

tt2=tt2.*h1;

figure(5)

plot(-0.5:1/1000:0.5-1/1000,(rr1)+6,'b')

hold on

plot(-0.5:1/1000:0.5-1/1000,(rr2)+7,'r')

hold off

grid

title('Phase Slopes of Two-path IIR Filter')

%%%%%%%%%%%%%%%%%%%%%

figure(8)

subplot(2,1,2)

plot(-0.5:1/1000:0.5-1/1000,(rr1)+6,'b')

hold on

plot(-0.5:1/1000:0.5-1/1000,(rr2)+7,'r')

hold off

grid

title('Phase of Uniform Phase Two-path IIR Filter')

%%%%%%%%%%%%%%%%%%%%

den1=hh01;

num1=fliplr(den1);

den2=conv(hh11,hh12);

den2=conv(den2,hh13);

den2=conv(den2,hh14);

num2=fliplr(den2);

num_t=conv(num1,den2)+j*conv(num2,den1);

den_t=conv(den1,den2);

figure(6)

plot(exp(j*2*pi*(0:.01:1)),'r')

hold on

plot(roots(num_t),'o')

plot(roots(den_t),'x')

hold off

grid

axis([-1.8 1.8 -1.8 1.8])

axis('square')

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

figure(9)

subplot(1,2,2)

plot(exp(j*2*pi*(0:.01:1)),'r')

hold on

plot(roots(num_t),'o')

plot(roots(den_t),'x')

hold off

grid

axis([-1.8 1.8 -1.8 1.8])

axis('square')

%%%%%%%%%%%%%%%%%%%%%%%%%%%

figure(7)

subplot(2,1,1)

plot((-0.5:1/1000:0.5-1/1000),fftshift(20*log10(abs(tt1+tt2)/2)));

grid

axis([-0.5 0.5 -90 10])

title('Spectrum, Two-path IIR Filter')

subplot(2,1,2)

phs=unwrap(fftshift(angle(tt1+tt2)))/(2*pi);

plot((-0.5:1/1000:0.5-1/1000),phs+3);

grid

%axis([-0.5 0.5 0 50])

title('Phase, Two-path IIR Filter')

%%%%%%%%%%%%%%%%%%%%%%

figure(10)

subplot(2,2,2)

plot((-0.5:1/1000:0.5-1/1000),fftshift(20*log10(abs(tt1+tt2)/2)));

grid

axis([-0.5 0.5 -90 10])

title('Spectrum, Two-path IIR Filter')

subplot(2,2,4)

phs=unwrap(fftshift(angle(tt1+tt2)))/(2*pi);

plot((-0.5:1/1000:0.5-1/1000),phs+3);

grid

%axis([-0.5 0.5 0 50])

title('Phase, Two-path IIR Filter')

[ - ]
Reply by Lito844October 25, 2020

fharris: Thank you very much for your Hilbert demo code. It really helped reinforce my understanding of the 2-path half-band formulations in your text. In terms of the OP, one takeaway is that in DSP there's no advantage to using +/-45° branches, I suppose since path matching is not an issue.

Instead linear phase FIR or lower order modified half-band IIR with either uniform or non-uniform phase are easily constructed with the requisite 90° difference.

Thanks again.

[ - ]
Reply by fharrisOctober 25, 2020

Exactly,


The sampled data domain has access to pure delay lines that the continuous domain does not. That simple access changes the rules and is one of the reason's that DSP has made such dramatic impact on applications in so many areas. 


Glad I was able to hep you!


fred