29visualizaciones (últimos 30días)
Mostrar comentarios más antiguos
Markus el 28 de Abr. de 2011
Respuesta aceptada: Teja Muppirala
Hi,
I am working in a project where I need to filter a sound signal. The filter is called G-filter and it is specified in the ISO 7196 standard (Frequency-weighing characteristics for infrasound measurements).
The filter is specified in s-plane by it's poles and zeros. My signal is digital (time discrete) and thus I need to estimate a digital filter. I have tried yule-walker and bilinear transform but neither gives an acceptable estimate. Is there a better way?
clear all
close all
%%Define G-filter in s-plane according to ISO 7196:1995E
%poles
p=[ -0.707+j* 0.707
-0.707-j* 0.707
-19.27+j* 5.16
-19.27-j* 5.16
-14.11+j*14.11
-14.11-j*14.11
-5.16+j*19.27
-5.16-j*19.27];
%zeros
z=[0 0 0 0]';
%scalar gain
k=10^(116/20);
%get analog filter coefficients
[bG,aG] = zp2tf(z,p,k);
%get filter response
[hG,fG] = freqs(bG,aG,[0 logspace(log10(0.2),log10(200),1000)]);
%%Try to get digital coefficients from yule-walker method
fs=400;
[b,a] = yulewalk(8,fG/max(fG),abs(hG));
%get digital filter response
[h,f] = freqz(b,a,100*fs,fs);
%%Try to get digital coefficients from bilinear transform
[bz,az]=bilinear(bG,aG,fs);
%get digital filter response
[Hz, fz]= freqz(bz,az,100*fs,fs);
%%plot
figure
semilogx(fG,20*log10(abs(hG)),'--'...
,f,20*log10(abs(h))...
,fz,20*log10(abs(Hz)))
xlim([0.2 fs])
xlabel('frequency (Hz)'), ylabel('response (dB)')
legend('G in s-plane','G in z-plane, yule-walker','G in z-plane, bilinear');
set(gca,'XTick',[0.2 0.5 1 2 5 10 20 50 100 200])
set(gca,'XTickLabel',{'0,2','0,5','1','2','5','10','20','50','100','200'})
The blue curve is the desired filter response. According to the standard, the response is most important in the 1-20Hz range where errors of 1dB are allowed. Below 1Hz and above 20Hz the error is allowed to be -infinity to +1dB. Clearly the estimated filters are not good enough. Any advice is appreciated! Thanks, Markus
0 comentarios Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Iniciar sesión para comentar.
Iniciar sesión para responder a esta pregunta.
Respuesta aceptada
Teja Muppirala el 28 de Abr. de 2011
Have you tried c2d?
clear all
close all
%%Define G-filter in s-plane according to ISO 7196:1995E
%poles
p=[ -0.707+j* 0.707
-0.707-j* 0.707
-19.27+j* 5.16
-19.27-j* 5.16
-14.11+j*14.11
-14.11-j*14.11
-5.16+j*19.27
-5.16-j*19.27];
%zeros
z=[0 0 0 0]';
%scalar gain
k=10^(116/20);
G_0 = zpk(z,p,k)
fs = 400;
G_1 = c2d(G_0,1/fs,'tustin');
bode(G_0);
hold all;
bode(G_1);
legend({'continuous' 'discrete filter'})
% Extract the filter coefficients
G_1_tf = tf(G_1);
B = G_1_tf.num{1}
A = G_1_tf.den{1}
% Compare the time series output using a random input signal
figure;
r = randn(1,10000);
t = 1/fs * (0:9999);
y1 = lsim(G_0,r,t);
y2 = filter(B,A,r);
plot(t,y1,t,y2,'r:');
legend({'continuous' 'discrete filter'})
0 comentarios Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Iniciar sesión para comentar.
Más respuestas (2)
Markus el 28 de Abr. de 2011
Hi Teja, thanks for your answer.
Unfortunately I don't have the system toolboxes so I can't use c2d( ) and tf( ).
However, I found that if I divide the frequency by 2pi in the bilinear function I get a much better output :-)
0 comentarios Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Iniciar sesión para comentar.
Markus el 28 de Abr. de 2011
The only difference is
[bz,az]=bilinear(bG,aG,fs/(2*pi));
instead of
[bz,az]=bilinear(bG,aG,fs);
The code:
clear all
close all
%%G-filter in s-plane according to ISO 7196:1995E
%poles
p=[ -0.707+j* 0.707
-0.707-j* 0.707
-19.27+j* 5.16
-19.27-j* 5.16
-14.11+j*14.11
-14.11-j*14.11
-5.16+j*19.27
-5.16-j*19.27];
%zeros
z=[0 0 0 0]';
%scalar gain
k=10^(116/20);
%get analog filter coefficients
[bG,aG] = zp2tf(z,p,k);
%get filter response
[hG,fG] = freqs(bG,aG,[0 logspace(log10(0.2),log10(200),1000)]);
%%Try to get digital coefficients from yule-walker method
fs=200;
[b,a] = yulewalk(8,fG/max(fG),abs(hG));
%get digital filter response
[h,f] = freqz(b,a,100*fs,fs);
%%Try to get digital coefficients from bilinear transform
[bz,az]=bilinear(bG,aG,fs/(2*pi));
%get digital filter response
[Hz, fz]= freqz(bz,az,100*fs,fs);
%%plot
figure
semilogx(fG,20*log10(abs(hG)),'--'...
,f,20*log10(abs(h))...
,fz,20*log10(abs(Hz)))
xlim([0.2 fs])
xlabel('frequency (Hz)'), ylabel('response (dB)')
legend('G in s-plane','G in z-plane, yule-walker','G in z-plane, bilinear');
set(gca,'XTick',[0.2 0.5 1 2 5 10 20 50 100 200])
set(gca,'XTickLabel',{'0,2','0,5','1','2','5','10','20','50','100','200'})
0 comentarios Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Mostrar -2 comentarios más antiguosOcultar -2 comentarios más antiguos
Iniciar sesión para comentar.
Iniciar sesión para responder a esta pregunta.
Ver también
Categorías
Signal ProcessingSignal Processing ToolboxDigital and Analog FiltersAnalog Filters
Signal ProcessingSignal Processing ToolboxTransforms, Correlation, and ModelingTransformsz-transforms
Signal ProcessingDSP System ToolboxTransforms and Spectral Analysis
Más información sobre Analog Filters en Help Center y File Exchange.
Etiquetas
- bilinear
- yule
- filter
- discrete
- continuous
- sound
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
Se ha producido un error
No se puede completar la acción debido a los cambios realizados en la página. Vuelva a cargar la página para ver el estado actualizado.
Seleccione un país/idioma
Seleccione un país/idioma para obtener contenido traducido, si está disponible, y ver eventos y ofertas de productos y servicios locales. Según su ubicación geográfica, recomendamos que seleccione: .
También puede seleccionar uno de estos países/idiomas:
América
- América Latina (Español)
- Canada (English)
- United States (English)
Europa
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- Deutsch
- English
- Français
- United Kingdom(English)
Asia-Pacífico
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)
Comuníquese con su oficina local