What other factors should be considered?
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.
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.
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
fharris: Don't know about the OP but I would certainly be interested in reviewing your MATLAB examples of +/-45 degree Hilbert filters.
% 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')
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.
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