头文件:
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * window.h * * This file includes seven usually used windows in signal processing: * Rectangle Bartlett Hanning Hamming * Blackman Kaiser Gauss * All of them are same to those in "Matlab". * * Zhang Ming, 2010-01, Xi'an Jiaotong University. *****************************************************************************/ #ifndef WINDOW_H #define WINDOW_H #include <vector.h> namespace splab { template<typename Type> Vector<Type> window( const string&, int, Type ); template<typename Type> Vector<Type> window( const string&, int, Type, Type ); template<typename Type> Vector<Type> rectangle( int, Type ); template<typename Type> Vector<Type> bartlett( int, Type ); template<typename Type> Vector<Type> hanning( int, Type ); template<typename Type> Vector<Type> hamming( int, Type ); template<typename Type> Vector<Type> blackman( int, Type ); template<typename Type> Vector<Type> kaiser( int, Type, Type ); template<typename Type> Vector<Type> gauss( int, Type, Type ); template<typename Type> Type I0( Type alpha ); #include <window-impl.h> } // namespace splab #endif // WINDOW_H
实现文件:
/* * Copyright (c) 2008-2011 Zhang Ming (M. Zhang), [email protected] * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 2 or any later version. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. A copy of the GNU General Public License is available at: * http://www.fsf.org/licensing/licenses */ /***************************************************************************** * window.h * * Implementation for window function. * * Zhang Ming, 2010-01, Xi'an Jiaotong University. *****************************************************************************/ /** * Get the specified window. */ template <typename Type> Vector<Type> window( const string &wnName, int N, Type amp ) { if( wnName == "Rectangle" ) return rectangle( N, amp ); else if( wnName == "Bartlett" ) return bartlett( N, amp ); else if( wnName == "Hanning" ) return hanning( N, amp ); else if( wnName == "Hamming" ) return hamming( N, amp ); else if( wnName == "Blackman" ) return blackman( N, amp ); else { cerr << "No such type window!" << endl; return Vector<Type> (0); } } template <typename Type> Vector<Type> window( const string &wnName, int N, Type alpha, Type amp ) { if( wnName=="Kaiser" ) return kaiser( N, alpha, amp ); else if( wnName=="Gauss" ) return gauss( N, alpha, amp ); else { cerr << "No such type window!" << endl; return Vector<Type> (0); } } /** * Calculates rectangle window coefficients. */ template <typename Type> Vector<Type> rectangle( int N, Type amp ) { Vector<Type> win(N); for( int i=0; i<(N+1)/2; ++i ) { win[i] = amp; win[N-1-i] = win[i]; } return win; } /** * Calculates bartlett window coefficients. */ template <typename Type> Vector<Type> bartlett( int N, Type amp ) { Vector<Type> win(N); for( int i=0; i<(N+1)/2; ++i ) { win[i] = amp*2*i / (N-1); win[N-1-i] = win[i]; } return win; } /** * Calculates hanning window coefficients. */ template <typename Type> Vector<Type> hanning( int N, Type amp ) { Vector<Type> win(N); for( int i=0; i<(N+1)/2; ++i ) { win[i] = amp * Type( 0.5 - 0.5*cos(TWOPI*i/(N-1)) ); win[N-1-i] = win[i]; } return win; } /** * Calculates hamming window coefficients. */ template <typename Type> Vector<Type> hamming( int N, Type amp ) { Vector<Type> win(N); for( int i=0; i<(N+1)/2; ++i ) { win[i] = amp * Type( 0.54 - 0.46*cos(TWOPI*i/(N-1.0)) ); win[N-1-i] = win[i]; } return win; } /** * Calculates hamming window coefficients. */ template <typename Type> Vector<Type> blackman( int N, Type amp ) { Vector<Type> win(N); for( int i=0; i<(N+1)/2; ++i ) { win[i] = amp * Type ( 0.42 - 0.50*cos(TWOPI*i/(N-1.0)) + 0.08*cos(2*TWOPI*i/(N-1.0)) ); win[N-1-i] = win[i]; } return win; } /** * Calculates hamming window coefficients. */ template <typename Type> Vector<Type> kaiser( int N, Type alpha, Type amp ) { Vector<Type> win(N); for( int i=0; i<(N+1)/2; ++i ) { Type beta = 2*alpha * Type( sqrt(i*(N-i-1.0))/(N-1.0) ); win[i] = amp * I0(beta) / I0(alpha); win[N-1-i] = win[i]; } return win; } /** * Calculates gauss window coefficients. "Alpha: is a optional parameter, * the default value is 2.5. */ template <typename Type> Vector<Type> gauss( int N, Type alpha, Type amp ) { Vector<Type> win(N); Type center = (N-1)/Type(2); for( int i=0; i<(N+1)/2; ++i ) { Type tmp = alpha*(i-center) / center; win[i] = amp * Type( exp(-0.5*tmp*tmp ) ); win[N-1-i] = win[i]; } return win; } /** * The zeroth N modified Bessel function of the first kind. */ template <typename Type> Type I0( Type alpha ) { double J = 1.0, K = alpha / 2.0, iOld = 1.0, iNew; bool converge = false; // Use series expansion definition of Bessel. for( int i=1; i<MAXTERM; ++i ) { J *= K/i; iNew = iOld + J*J; if( (iNew-iOld) < EPS ) { converge = true; break; } iOld = iNew; } if( !converge ) return Type(0); return Type(iNew); }
测试代码:
/***************************************************************************** * window_test.cpp * * Windows function testing. * * Zhang Ming, 2010-01, Xi'an Jiaotong University. *****************************************************************************/ #define BOUNDS_CHECK #include <iostream> #include <iomanip> #include <window.h> using namespace std; using namespace splab; typedef double Type; int main() { int N = 5; Type A = 1.0; cout << setiosflags(ios::fixed) << setprecision(4); cout << "Rectangle window : " << rectangle(N,A) << endl; cout << "Bartlett window : " << bartlett(N,A) << endl; cout << "Hanning window : " << hanning(N,A) << endl; cout << "Hamming window : " << hamming(N,A) << endl; cout << "Blackman window : " << blackman(N,A) << endl; cout << "Kaiser window : " << kaiser(N,Type(8/PI),A) << endl; cout << "Gauss window : " << gauss(N,Type(2.5),A) << endl; cout << "Rectangle window : " << window("Rectangle",N,A) << endl; cout << "Bartlett window : " << window("Bartlett",N,A) << endl; cout << "Hanning window : " << window("Hanning",N,A) << endl; cout << "Hamming window : " << window("Hamming",N,A) << endl; cout << "Blackman window : " << window("Blackman",N,A) << endl; cout << "Kaiser window : " << window("Kaiser",N, Type(8/PI),A) << endl; cout << "Gauss window : " << window("Gauss",N,Type(2.5),A) << endl; return 0; }
运行结果:
Rectangle window : size: 5 by 1 1.0000 1.0000 1.0000 1.0000 1.0000 Bartlett window : size: 5 by 1 0.0000 0.5000 1.0000 0.5000 0.0000 Hanning window : size: 5 by 1 0.0000 0.5000 1.0000 0.5000 0.0000 Hamming window : size: 5 by 1 0.0800 0.5400 1.0000 0.5400 0.0800 Blackman window : size: 5 by 1 -0.0000 0.3400 1.0000 0.3400 -0.0000 Kaiser window : size: 5 by 1 0.2933 0.7742 1.0000 0.7742 0.2933 Gauss window : size: 5 by 1 0.0439 0.4578 1.0000 0.4578 0.0439 Rectangle window : size: 5 by 1 1.0000 1.0000 1.0000 1.0000 1.0000 Bartlett window : size: 5 by 1 0.0000 0.5000 1.0000 0.5000 0.0000 Hanning window : size: 5 by 1 0.0000 0.5000 1.0000 0.5000 0.0000 Hamming window : size: 5 by 1 0.0800 0.5400 1.0000 0.5400 0.0800 Blackman window : size: 5 by 1 -0.0000 0.3400 1.0000 0.3400 -0.0000 Kaiser window : size: 5 by 1 0.2933 0.7742 1.0000 0.7742 0.2933 Gauss window : size: 5 by 1 0.0439 0.4578 1.0000 0.4578 0.0439 Process returned 0 (0x0) execution time : 0.140 s Press any key to continue.