www.pudn.com > AudioTest.rar > WaveAnalysis.cpp
// WaveAnalysis.cpp: implementation of the CWaveAnalysis class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "audiotest.h"
#include "WaveAnalysis.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWaveAnalysis::CWaveAnalysis()
{
which_window=0;
is_db=0;
samplingfreq=11025;
}
CWaveAnalysis::~CWaveAnalysis()
{
}
/////////////////////////////////////////////
// FFT calculation
void CWaveAnalysis::FftCal(BYTE* InW, int N, double *p_power)
{
int P;
double M_PI = 3.1415927;
int N_2 = N/2;
int i,j,k,kp,m,h;
double m_double;
double w1, w2;
double t1,t2,s1,s2;
int x0 = 80;
int y0 = 200;
double* p_fReal=new double[N];
double* p_fImag=new double[N];
double* p_tri=new double[N];
double* p_win=new double[N];
i = N; P = 0;
while (i != 1) {
i = i / 2;
P++;
}
if(which_window == HANNING_WIDOW)
{
// Hanning Window
for( i = 0; i < N; i++ ) {
p_win[i] = 0.5 * (1.0 - cos(M_PI * 2 * i / (N-1)));
}
}
else if(which_window == HAMMING_WINDOW)
{
// Hamming Window
for( i = 0; i < N; i++ )
{
p_win[i] = 0.54 - 0.46 * cos(M_PI * 2 * i / (N-1));
}
}
else if(which_window == BLACKMAN_WINDOW)
{
// Blackman Window
for( i = 0; i < N; i++ ) {
p_win[i] = 0.42 - 0.5 * cos(M_PI * 2 * i / (N-1)) +
0.08 * cos(2.0 * M_PI * 2 * i / (N-1));
}
}
else if(which_window == BLACKMAN_HARRIS_WINDOW)
{
// Blackman-Harris Window
double a0 = 0.35875;
double a1 = 0.48829;
double a2 = 0.14128;
double a3 = 0.01168;
for( i = 0; i < N; i++ ) {
p_win[i] = a0 - a1 * cos(M_PI * 2 * (i+0.5) / N) +
a2 * cos(M_PI * 2 * 2.0 * (i+0.5) / N) -
a3 * cos(M_PI * 2 * 3.0 * (i+0.5) / N);
}
}
else if(which_window == BARTLETT_WINDOW)
{
// Bartlett Window
for( i = 0; i <= (N-1)/2; i++ ) {
p_win[i] = 2.0 * i / (N-1);
}
for( i = (N-1)/2; i < N; i++ ) {
p_win[i] = 2.0 - 2.0 * i / (N-1);
}
}
if(which_window == 0)
{
for (i = 0; i < N; i++) {
p_fReal[i] = InW[i]; p_fImag[i] = 0.0;
}
}
else
{
for (i = 0; i < N; i++) {
p_fReal[i] = InW[i]; p_fImag[i] = 0.0;
}
}
for ( j = 0; j < N_2; j++ ) {
p_tri[j] = cos( 2 * j * M_PI / N );
p_tri[j + N_2] = (-1.0) * sin( 2 * j * M_PI / N );
}
j = 0;
for ( i = 0; i <= N-2; i++ ) {
if (i < j) {
t1 = p_fReal[j]; p_fReal[j] = p_fReal[i]; p_fReal[i] = t1;
t2 = p_fImag[j]; p_fImag[j] = p_fImag[i]; p_fImag[i] = t2;
}
k = N_2;
while (k <= j) {
j = j - k; k = k/2;
}
j = j + k;
}
for ( i = 1; i <= P; i++ ) {
m_double = pow(2.0, double(i));
m = int(m_double);
h = m/2;
for ( j = 0; j < h; j ++ ) {
w1 = p_tri[j*(N/m)];
w2 = p_tri[j*(N/m) + N_2];
for( k = j; k < N; k+=m ) {
kp = k + h;
s1 = p_fReal[kp] * w1 - p_fImag[kp] * w2;
s2 = p_fReal[kp] * w2 + p_fImag[kp] * w1;
t1 = p_fReal[k] + s1; p_fReal[kp] = p_fReal[k] - s1; p_fReal[k] = t1;
t2 = p_fImag[k] + s2; p_fImag[kp] = p_fImag[k] - s2; p_fImag[k] = t2;
}
}
}
for ( i = 0; i < N; i++ ) {
p_power[i] = sqrt(p_fReal[i] * p_fReal[i] + p_fImag[i] * p_fImag[i]) / N;
}
delete[] p_fReal;
delete[] p_fImag;
delete[] p_tri;
delete[] p_win;
}
void CWaveAnalysis::FftCal(double* InW, int N, double* p_power)
{
// int N = 256;
int P;
double M_PI = 3.1415927;
int N_2 = N/2;
int i,j,k,kp,m,h;
double m_double;
double w1, w2;
double t1,t2,s1,s2;
int x0 = 80;
int y0 = 200;
double* p_fReal=new double[N];
double* p_fImag=new double[N];
double* p_tri=new double[N];
double* p_win=new double[N];
i = N; P = 0;
while (i != 1) {
i = i / 2;
P++;
}
if(which_window == HANNING_WIDOW)
{
// Hanning Window
for( i = 0; i < N; i++ ) {
p_win[i] = 0.5 * (1.0 - cos(M_PI * 2 * i / (N-1)));
}
}
else if(which_window == HAMMING_WINDOW)
{
// Hamming Window
for( i = 0; i < N; i++ )
{
p_win[i] = 0.54 - 0.46 * cos(M_PI * 2 * i / (N-1));
}
}
else if(which_window == BLACKMAN_WINDOW)
{
// Blackman Window
for( i = 0; i < N; i++ ) {
p_win[i] = 0.42 - 0.5 * cos(M_PI * 2 * i / (N-1)) +
0.08 * cos(2.0 * M_PI * 2 * i / (N-1));
}
}
else if(which_window == BLACKMAN_HARRIS_WINDOW)
{
// Blackman-Harris Window
double a0 = 0.35875;
double a1 = 0.48829;
double a2 = 0.14128;
double a3 = 0.01168;
for( i = 0; i < N; i++ ) {
p_win[i] = a0 - a1 * cos(M_PI * 2 * (i+0.5) / N) +
a2 * cos(M_PI * 2 * 2.0 * (i+0.5) / N) -
a3 * cos(M_PI * 2 * 3.0 * (i+0.5) / N);
}
}
else if(which_window == BARTLETT_WINDOW)
{
// Bartlett Window
for( i = 0; i <= (N-1)/2; i++ ) {
p_win[i] = 2.0 * i / (N-1);
}
for( i = (N-1)/2; i < N; i++ ) {
p_win[i] = 2.0 - 2.0 * i / (N-1);
}
}
if(which_window == 0)
{
for (i = 0; i < N; i++) {
p_fReal[i] = InW[i]; p_fImag[i] = 0.0;
}
}
else
{
for (i = 0; i < N; i++) {
p_fReal[i] = InW[i]; p_fImag[i] = 0.0;
}
}
for ( j = 0; j < N_2; j++ ) {
p_tri[j] = cos( 2 * j * M_PI / N );
p_tri[j + N_2] = (-1.0) * sin( 2 * j * M_PI / N );
}
j = 0;
for ( i = 0; i <= N-2; i++ ) {
if (i < j) {
t1 = p_fReal[j]; p_fReal[j] = p_fReal[i]; p_fReal[i] = t1;
t2 = p_fImag[j]; p_fImag[j] = p_fImag[i]; p_fImag[i] = t2;
}
k = N_2;
while (k <= j) {
j = j - k; k = k/2;
}
j = j + k;
}
for ( i = 1; i <= P; i++ ) {
m_double = pow(2.0, double(i));
m = int(m_double);
h = m/2;
for ( j = 0; j < h; j ++ ) {
w1 = p_tri[j*(N/m)];
w2 = p_tri[j*(N/m) + N_2];
for( k = j; k < N; k+=m ) {
kp = k + h;
s1 = p_fReal[kp] * w1 - p_fImag[kp] * w2;
s2 = p_fReal[kp] * w2 + p_fImag[kp] * w1;
t1 = p_fReal[k] + s1; p_fReal[kp] = p_fReal[k] - s1; p_fReal[k] = t1;
t2 = p_fImag[k] + s2; p_fImag[kp] = p_fImag[k] - s2; p_fImag[k] = t2;
}
}
}
for ( i = 0; i < N; i++ ) {
double x= sqrt(p_fReal[i] * p_fReal[i] + p_fImag[i] * p_fImag[i]) / N;
p_power[i] = x;
}
delete[] p_fReal;
delete[] p_fImag;
delete[] p_tri;
delete[] p_win;
}
/////////////////////////////////////////////
// FFT Drawing
void CWaveAnalysis::FftDraw(CPaintDC &dc, int x0, int y0,int yzoom,double* Xfr,int N)
{
double start_fr, end_fr, mid_fr;
int i;
char freq_char[15];
double mag_scale = 40;
int yscale = 1;
int xscale = 5;
CPen myPen;
CPen* pOldPen;
start_fr = 0.0;
end_fr = samplingfreq;
mid_fr = samplingfreq / 2.0;
sprintf(freq_char,"%9.1f", start_fr);
dc.TextOut(x0, y0+170, freq_char);
sprintf(freq_char,"%9.1f", mid_fr);
dc.TextOut(x0 + 128*3, y0 + 170, freq_char);
sprintf(freq_char,"%9.1f", end_fr);
dc.TextOut(x0 + 128*6, y0 + 170, freq_char);
dc.TextOut(x0 + 128*6+50, y0 + 170,"[Hz]");
// dc.TextOut(x0 - 30, y0 + 100 - 8,"0.0");
// sprintf(mag_char,"%9.1f", mag_scale );
// dc.TextOut(x0 - 70, y0 - 10, mag_char);
myPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
pOldPen = dc.SelectObject(&myPen);
if( is_db==0)
{
for(i = 0; i < N-1; i++) {
dc.MoveTo(x0 + i, y0);
dc.LineTo(x0 + i,-yzoom*(int)(Xfr[i])+y0);
}
}
else if( is_db==1)
{
for(i = 0; i < 256-1; i++) {
dc.MoveTo(x0 + i*2, int(20*log10(y0 + 100 - (int)(Xfr[i]))));
dc.LineTo(x0 + (i + 1)*2, int(20*log10(y0 + 100 - (int)(Xfr[i + 1]))));
}
}
dc.SelectObject(pOldPen);
//myPen.DeleteObject();
}
//fft waveform ----end