本文属spanzhang原创,其blog地址为:http://blog.csdn.net/spanzhang。引用或转贴请注明出处,谢谢!!
/*/////////////////////////////////////////////////////////////////////
文件:waverecorder.cpp
描述:录音类实现文件
作者:张友邦
时间:2004-09-10
声明:本文件系作者辛苦熬夜的产物,任何人使用本文件请保留本描述文本。
历史:
/*/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "waverecorder.h"
#include "graphseed.h"
//////////////////////////////////////////////////////////////////////
// constructions/destruction
namespace wa
{
//////////////////////////////////////////////////////////////////////
#define maxinputbuffers 25
#define buffersize 1024 * 1
float waverecorder::samplecoef = 1.0;
waverecorder::waverecorder()
{
memset(&waveformat, 0x00, sizeof(waveformatex));
waveformat.wformattag = wave_format_pcm;
waveformat.nchannels = 1;
waveformat.wbitspersample = 8;
waveformat.cbsize = 0;
waveformat.nsamplespersec = 44100;
waveformat.navgbytespersec = waveformat.nsamplespersec
*(waveformat.wbitspersample>>3);
waveformat.nblockalign =
(waveformat.wbitspersample>>3)*
waveformat.nchannels;
status = e_status_stoped;
samplecoef = 1.0;
}
waverecorder::waverecorder(const waveformatex& waveformatconfig)
{
waveformat = waveformatconfig;
status = e_status_stoped;
samplecoef = 1.0;
}
waverecorder::waverecorder(const int& frequency, const int& channels)
{
memset(&waveformat, 0x00, sizeof(waveformatex));
waveformat.wformattag = wave_format_pcm;
waveformat.nchannels = channels;
waveformat.wbitspersample = 16;
waveformat.cbsize = 0;
waveformat.nsamplespersec = frequency;
waveformat.navgbytespersec = waveformat.nsamplespersec
*(waveformat.wbitspersample>>3);
waveformat.nblockalign =
(waveformat.wbitspersample>>3)*
waveformat.nchannels;
status = e_status_stoped;
samplecoef = 1.0;
}
waverecorder::~waverecorder()
{
try
{
stop();
}
catch (...)
{
}
}
float waverecorder::constraint(char v)
{
if (v == -128)
return 127.0 * samplecoef;
return float(v) * samplecoef;
}
void waverecorder::smooth(char* input, int* output, int length,
double smoothness/* = 0.8*/, int scale /*= 100*/)
{
double a = 1.0 - (2.4 / scale);
double b = smoothness;
double acoef = a;
double bcoef = a * b;
double ccoef = a * b * b;
double mastergain = 1.0 / (-1.0 / (log(a) + 2.0 * log(b)) +
2.0 / (log(a) + log(b)) - 1.0 / log(a));
double again = mastergain;
double bgain = mastergain * (log(a * b * b) * (log(a) - log(a * b)) /
((log(a * b * b) - log(a * b)) * log(a * b))
- log(a) / log(a * b));
double cgain = mastergain * (-(log(a) - log(a * b)) /
(log(a * b * b) - log(a * b)));
double areg = 0;
double breg = 0;
double creg = 0;
//第一次循环,取得reg的平均值
for (int j = 0; j < length; ++j)
{
float v = constraint(input[j]);
areg = acoef * areg + v;
breg = bcoef * breg + v;
creg = ccoef * creg + v;
}
//得到基音
float base = again * areg + bgain * breg + cgain * creg;
output[0] = base;
//用基音作为其始作循环得到其他数据
for (int i = 1; i < length; ++i)
{
int v = constraint(input[i - 1]);
areg = acoef * areg + v;
breg = bcoef * breg + v;
creg = ccoef * creg + v;
output[i] = again * areg + bgain * breg + cgain * creg - base;
}
}
void callback waverecorder::waveinproc
(
hwavein hwi, //音频设备句柄
uint umsg, //消息标识
dword dwinstance, //用户定义数据
dword dwparam1, //消息参数
dword dwparam2 //消息参数
)
{
//过滤消息(只处理数据消息)