Implementar Hann ventana
-
30-09-2019 - |
Pregunta
Tomo bloques de datos entrantes y pasarlas por fftw para obtener alguna información espectral. Todo parece estar funcionando, sin embargo, creo que estoy recibiendo algunos problemas de aliasing.
He estado tratando de encontrar la manera de poner en práctica una ventana de Hann en mis bloques de datos. Google me ha fallado para ver ejemplos. Cualquier idea o enlaces que debe mirar?
double dataIn[2048] > /* windowing here? */ > FFT > double freqBins[2048]
Actualizar
Gracias a Oli para señalar el problema en realidad estoy tratando de arreglar es espectral fugas, NO aliasing ...
Solución
http://en.wikipedia.org/wiki/Hann_function . La aplicación de la definición manera bastante directa. Sólo tiene que utilizar la función w(n)
como multiplicador, recorrer todos sus muestras (cambiando a medida que avanza n
), y eso es todo.
for (int i = 0; i < 2048; i++) {
double multiplier = 0.5 * (1 - cos(2*PI*i/2047));
dataOut[i] = multiplier * dataIn[i];
}
Otros consejos
¿Por qué no usar Hann de Math.NET de ventanas implementación?
double[] hannDoubles = MathNet.Numerics.Window.HannPeriodic(dataIn.Length);
for (int i = 0; i < dataIn.Length; i++)
{
dataOut[i] = hannDoubles[i] * dataIn[i];
}
Situado aquí: https://numerics.mathdotnet.com/api/ MathNet.Numerics / Window.htm
Wikipedia es su amigo: ventana de Hanning
Sin duda, su googlear ocurrió Wikipedia ?! De todos modos sólo crear una función que devuelve una matriz de longitud N con los coeficientes de Hanning y multiplicar esta matriz por su dataIn[2048]
.
No es una respuesta a su pregunta, pero un aparte de su problema. De ventanas consigue solucionar espectral de fuga problemas, no aliasing problemas.
efectos Spectral-fugas se producen cuando los componentes de frecuencia de la forma de onda no son exactas número entero sub-múltiplos de la frecuencia de muestreo.
Si ha aliasing, entonces usted está fundamentalmente atornillado. Ya sea que usted necesidad de aumentar la frecuencia de muestreo, o poner en un (mejor) anti-aliasing de filtro antes de muestra.
La función completa que es equivalente a MATLAB de hanning.m
se puede encontrar aquí :
/* function w = hanning(varargin)
% HANNING Hanning window.
% HANNING(N) returns the N-point symmetric Hanning window in a column
% vector. Note that the first and last zero-weighted window samples
% are not included.
%
% HANNING(N,'symmetric') returns the same result as HANNING(N).
%
% HANNING(N,'periodic') returns the N-point periodic Hanning window,
% and includes the first zero-weighted window sample.
%
% NOTE: Use the HANN function to get a Hanning window which has the
% first and last zero-weighted samples.ep
itype = 1 --> periodic
itype = 0 --> symmetric
default itype=0 (symmetric)
Copyright 1988-2004 The MathWorks, Inc.
% $Revision: 1.11.4.3 $ $Date: 2007/12/14 15:05:04 $
*/
float *hanning(int N, short itype)
{
int half, i, idx, n;
float *w;
w = (float*) calloc(N, sizeof(float));
memset(w, 0, N*sizeof(float));
if(itype==1) //periodic function
n = N-1;
else
n = N;
if(n%2==0)
{
half = n/2;
for(i=0; i<half; i++) //CALC_HANNING Calculates Hanning window samples.
w[i] = 0.5 * (1 - cos(2*PI*(i+1) / (n+1)));
idx = half-1;
for(i=half; i<n; i++) {
w[i] = w[idx];
idx--;
}
}
else
{
half = (n+1)/2;
for(i=0; i<half; i++) //CALC_HANNING Calculates Hanning window samples.
w[i] = 0.5 * (1 - cos(2*PI*(i+1) / (n+1)));
idx = half-2;
for(i=half; i<n; i++) {
w[i] = w[idx];
idx--;
}
}
if(itype==1) //periodic function
{
for(i=N-1; i>=1; i--)
w[i] = w[i-1];
w[0] = 0.0;
}
return(w);
}
Esto está muy bien, pero la mayoría de la gente probablemente quiere hacer esto en miles de conjuntos completos de datos. Usted puede llenar una matriz de multiplicadores constantes solo una vez que la inicialización (utilice la misma matriz de tamaño usted alimenta a FFT) a continuación, sólo se multiplican cada punto de su programa en su conjunto de bienes por cada punto en la matriz de multiplicadores. Más rápido / más barato que tomar todos los cosenos de nuevo cada vez.