?? sample.cpp
字號:
// Sample.cpp: implementation of the CSample class.
//
//////////////////////////////////////////////////////////////////////
#include <winsock2.h>
#include <windows.h>
#include <vfw.h>
#include "Sample.h"
#include "math.h"
#include "systemlib.h"
#define pi 3.14159265358979
#define Threshold 3000
#define SAMPLE_RATE 8000
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
static int ntime=0;
CSample::CSample()
{
sample_max_Con = 1;
counter = 0;
gain = 1.0;
silence_counter = 0;
if(ntime==0)
{
#ifdef FILETRACE
// InitLog6("C:\\AudioBalance.txt");
#endif
}
ntime++;
}
CSample::~CSample()
{
ntime--;
if(ntime==0)
{
#ifdef FILETRACE
// UnInitLog6();
#endif
}
}
HRESULT CSample::UnInit()
{
return S_OK;
}
HRESULT CSample::Init()
{
preEnergy = 0.0;
pregain = 1.0;
total = 0;
sample_max_Con = 1.0;
return S_OK;
}
//一維傅立葉變換
void FFT(int iLength, complex *cData);
HRESULT CSample::EchoInData(short* pinData,LONG nLen)
{
//for AudioMultiEqu
int i;
short sample_max=0;
double gain=1.0;
int silence_counter = 0;
double energy=0, Minenergy=0, Maxenergy=0, rate=1.0;
// complex *InData;
int iLength = nLen/2;
complex *InData = new complex [iLength];
short*Data=(short*)pinData;
for (i=0; i < nLen/2; i++)
{
if((*(Data+i))<32767&&(*(Data+i))>-32767)
{
if ((unsigned int)abs(*(Data+i)) > sample_max)
sample_max = abs (*(Data+i));
}
}
//add energy process refer to VAD
// energy = (float) 0.0;
// for (i=0; i < nLen/2; i++)
// {
// short temp = *(Data+i);
// energy += temp*temp;
// }
// Minenergy = (float)preEnergy*0.9;
// Maxenergy = (float)preEnergy*1.1;
// if(energy>Minenergy&&energy<Maxenergy)
// {
// rate = 0.0;
// }
// else rate = 1.0;
//energy process in FFT
// for(i=0; i < nLen/2; i++)
// {
// (InData+i)->real = *(Data+i);
// (InData+i)->imag = 0;
// }
// FFT(iLength, InData);
// for (i=0; i < nLen/2; i++)
// {
// short temp_real = (InData+i)->real;
// short temp_image = (InData+i)->imag;
// energy += (temp_real*temp_real)+(temp_image*temp_image);
// }
// Minenergy = (double)preEnergy*0.99;
// Maxenergy = (double)preEnergy*1.01;
// if(energy>Minenergy&&energy<Maxenergy)
// {
// rate = 0.0;
// }
// else rate = 1.0;
// rate = 1.0;
//method 2
if(sample_max > 30000)
{
gain = 0.5*rate;
for (i=0; i < nLen/2; i++)
{
Data[i] = (int)(Data[i]*gain);
}
}
else
{
if(sample_max < 800)
{
gain = 10*rate;
for (i=0; i < nLen/2; i++)
{
Data[i] = Data[i]*gain;
}
}
else
{
gain = 32700.0/(double)sample_max;//32600.0
gain = gain*rate;
for (i=0; i < nLen/2; i++)
{
Data[i] = (int)(Data[i]*gain);
}
}
}
preEnergy = energy;
// Log6(_QTEXT("\t\tgain=%f\r\n"),gain);
return S_OK;
}
/*
//out only to change the mic volume
HRESULT CSample::EchoOutData(short* poutData,LONG nLen, BYTE* pmic)
{
//for AudioMultiEqu
int i, number=0;
short sample_max=0;
short* Data = (short*) poutData;
BYTE* Temp = (BYTE*)pmic;
for (i=0; i < nLen/2; i++)
{
if((*(Data+i))<32767&&(*(Data+i))>-32767)
{
if ((unsigned int)abs(*(Data+i)) > sample_max)
sample_max = abs (*(Data+i));
}
if(abs(*(Data+i))>Threshold)
number++;
}
total++;
if(total==5)
{
if(sample_max > 20000 && number > (nLen/80))
*Temp = 3;
else
{
if(sample_max > 1000 && number > (nLen/80))
*Temp = 2;
else
{
if(sample_max > 500 && number > (nLen/80))
*Temp = 1;
else
{
if(sample_max < 800 && number < (nLen/80))
*Temp = 6;
else *Temp = 0;
}
}
}
total = 0;
}
else *Temp = 0;
return S_OK;
}
*/
//一維傅立葉變換
void FFT(int iLength, complex *cData)
{
complex *w = NULL; //變換核
double arg, w_real, w_imag, wrecur_real, wrecur_imag, wtemp_real; //變換核用的臨時變量序列
complex *list; //取需要變換的序列用
int length = 0; //記錄序列的長度
complex *xi, *xip, *xj, *wptr;
int le, step, trans;
int rank; //蝶形運算的次數
complex temp, u, tm;
int x = 0;
length = iLength;
arg = log(iLength) / log(2.0);
rank = (int) arg;
le = length / 2;
w = new complex[le-1]; //計算變換核,w0不記
arg = 4.0 * atan(1.0) / le;
wrecur_real = w_real = cos(arg);
wrecur_imag = w_imag = -sin(arg);
xj = w;
for (x = 1; x < le; x++)
{
xj->real = (float) wrecur_real;
xj->imag = (float) wrecur_imag;
xj++;
wtemp_real = wrecur_real * w_real - wrecur_imag * w_imag;
wrecur_imag = wrecur_real * w_imag + wrecur_imag * w_real;
wrecur_real = wtemp_real;
}
list = cData; //讀出數據
le = length;
step = 1; //每一級蝶形運算所用變換核的間隔
for (int j = 0; j < rank; j++) //疊代運算的次數
{
le=le/2;
for (int x = 0; x < length; x = x + 2 * le) //first iteration with no multiplies
{
xi = list + x;
xip = xi + le;
temp.real = xi->real + xip->real;
temp.imag = xi->imag + xip->imag;
xip->real = xi->real - xip->real;
xip->imag = xi->imag - xip->imag;
*xi = temp;
}
wptr = w + step - 1; //找W
for (x = 1; x < le; x++)
{
u = *wptr;
for (int y = x; y < length; y = y + 2 * le)
{
xi = list + y;
xip = xi + le;
temp.real = xi->real + xip->real;
temp.imag = xi->imag + xip->imag;
tm.real = xi->real - xip->real;
tm.imag = xi->imag - xip->imag;
xip->real = tm.real * u.real - tm.imag * u.imag;
xip->imag = tm.real * u.imag + tm.imag * u.real;
*xi=temp;
}
wptr = wptr + step;
}
step = 2 * step;
}
for (x = 0; x < length; x++)
{
trans = 0;
for (int y = 0; y < rank; ++y)
trans = (trans << 1) | (1 & (x >> y));
if (x < trans)
{
xi = list + x;
xj = list + trans;
temp = *xj;
*xj = *xi;
*xi = temp;
}
}
// if (w != NULL) //delete [] w;
// delete w;
//w = NULL;
}
//一維傅立葉反變換
void IFFT(int iLength, complex *cData)
{
complex *w = NULL; //變換核
double arg, w_real, w_imag, wrecur_real, wrecur_imag, wtemp_real; //變換核用的臨時變量序列
complex *list; //取一行序列用
int length = 0; //記錄一行序列的長度
complex *xi, *xip, *xj, *wptr;
int le, step, trans;
int rank; //蝶形運算的次數
complex temp, u, tm;
int x = 0;
length = iLength;
arg = log(iLength) / log(2.0);
rank = (int) arg;
le = length / 2;
w = new complex[le-1]; //計算變換核,w0不記
arg = 4.0 * atan(1.0) / le;
wrecur_real = w_real = cos(arg);
wrecur_imag = w_imag = sin(arg);
xj = w;
for (x = 1; x < le; x++)
{
xj->real = (float) wrecur_real;
xj->imag = (float) wrecur_imag;
xj++;
wtemp_real = wrecur_real * w_real - wrecur_imag * w_imag;
wrecur_imag = wrecur_real * w_imag + wrecur_imag * w_real;
wrecur_real = wtemp_real;
}
list = cData; //讀出第一行數據
le = length;
step = 1; //每一級蝶形運算所用變換核的間隔
for (int j = 0; j < rank; j++) //疊代運算的次數
{
le = le / 2;
for (int x = 0; x < length; x = x + 2 * le) //first iteration with no multiplies
{
xi = list + x;
xip = xi + le;
temp.real = xi->real + xip->real;
temp.imag = xi->imag + xip->imag;
xip->real = xi->real - xip->real;
xip->imag = xi->imag - xip->imag;
*xi = temp;
}
wptr = w + step - 1; //找W
for (x = 1; x < le; x++)
{
u = *wptr;
for (int y = x; y < length; y = y + 2 * le)
{
xi = list + y;
xip = xi + le;
temp.real = xi->real + xip->real;
temp.imag = xi->imag + xip->imag;
tm.real = xi->real - xip->real;
tm.imag = xi->imag - xip->imag;
xip->real = tm.real * u.real - tm.imag * u.imag;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -