void CALLBACK CWaveIn::waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
switch(uMsg) {
case MM_WIM_DATA:
WAVEHDR* pWaveHdr = ( (WAVEHDR*)dwParam1 );
FLOAT fValue=0;
dwSize=waveFmt.nBlockAlign; // 这里dwSize=2
for (DWORD i=0;i<pWaveHdr->dwBytesRecorded ;i++)
{
DWORD k=0;
for (DWORD j=0;j<dwSize;j++)
{
k|=(DWORD)pWaveHdr->lpData[i+j] << (j*8);
}
fValue+= (FLOAT) k;
}
原以为计算出的fValue就是音量大小,可事实并不是这样。
不向microphone说话时pWaveHdr->lpData指向的音频数据的值都很大(多数为0xfd90)
,当有的时候那些值又变得很小(多数为0x01df)。
}
{
switch(uMsg) {
case MM_WIM_DATA:
WAVEHDR* pWaveHdr = ( (WAVEHDR*)dwParam1 );
FLOAT fValue=0;
dwSize=waveFmt.nBlockAlign; // 这里dwSize=2
for (DWORD i=0;i<pWaveHdr->dwBytesRecorded ;i++)
{
DWORD k=0;
for (DWORD j=0;j<dwSize;j++)
{
k|=(DWORD)pWaveHdr->lpData[i+j] << (j*8);
}
fValue+= (FLOAT) k;
}
原以为计算出的fValue就是音量大小,可事实并不是这样。
不向microphone说话时pWaveHdr->lpData指向的音频数据的值都很大(多数为0xfd90)
,当有的时候那些值又变得很小(多数为0x01df)。
}
解决方案 »
- 如何动态的创建Image,可以new Image吗?
- RS232 接收数据
- 知道了一个PCI的内存范围和IO范围,怎么访问它的IO啊?
- 无法设置button的caption
- 为什么我编写的ocx每次都被浏览器block?
- vc能够调试系统服务的启动吗?
- odbc连接问题---求救
- easy->我用VC++的向导生成了一个基于对话框的MFC应用程序框架,我想在这个对话框上加菜单,不知如何实现?另我用vc++生成单文档MFC应用程序框架,如何在文档区加入按钮等控件?
- 帮忙看一下这断代码,很经典
- 谁是DCOM高手?
- 怎样在新的工程中去调试新写好的Atl下的dll模式的com
- 请问如何在VC++中加入表格?谢谢!
for (DWORD i=0;i<pWaveHdr->dwBytesRecorded ;i++)
{
DWORD k=0;
for (DWORD j=0;j<dwSize;j++)
{
k|=(DWORD)pWaveHdr->lpData[i+j] << (j*8);
}
fValue+= (FLOAT) k;
}
不知你的采样格式是怎么的,几通道?样本位数?
nBlockAlign = nChannels * wBitsPerSample /8;
通过nBlockAlign并无法确定lpData数据排列是怎样的吧,可根据nChannels和wBitsPerSample这两个来确定lpData数据的排列。双通道和单通道,8位和16位采样精度的数据排列都不一样的。
dwSize=nChannels * (wBitsPerSample /8);
根据MSDN所说的,这两个不就等值吗?
那位高手能帮我解决,我高分相赠啊
1、你的提法有问题,音量大小怎么能够根据waveInProc中的数据来计算呢?!!!里面存储的仅仅是声音数据而已,音量大小是控制声卡和波形来得到的。
2、然后再给你解释为什么lpData里面的值为什么会那么大:因为声音的字节可以8位,16位(甚至8的整数倍),字节数越大能包含的声音信息越精确。因此,从这个角度来说,怎么能直接加它们来得到音量呢?!!!
3、你要计算平均音量大小,就先要知道声音的存储数据的字节数。你可以把所有的变换成8位来计算;这样就一样了。
当然,你加完之后再换也可以。
满意了吧?!
///////////////////////
哎!打了这么多字,肚皮都饿了。
:)
我用了那么多的WAVE API,就是得不到声音数据,也播放不出来,求救。
给你个最简单的吧:PlaySound("文件路径\\文件名");
应该为:
dwSize=fmtWave.nBlockAlign;
for (DWORD i=0; i<pWaveHdr->dwBytesRecorded / dwSize ;i++)
{
DWORD k=0;
for (DWORD j=0;j<dwSize;j++)
{
k|=(DWORD)pWaveHdr->lpData[i*dwSize+j] << (j*8);
}
fValue+= (FLOAT) k;
}
请真正的高手帮帮忙啊
lpData格式: nChannels==2: 左声道|右声道|左声道|右声道....
当wBitsPerSample==16时,每个声道的数据又是这样排列的: 高8位|低8位.....
对双通道的来说,dwSize是两个通道的一次采样的值,就以8bit2channels的来说,一个样本数据是:
左声道8位|右声道8位, 假设有个样本是0xaa|0xa0,本来是要分成两个通道分别加的,但被这么一移位,变成了0xa0aa,假设再有一个这样的样本,那就变成0xa0aa+0xa0aa了。但本来应该是左声道:0xaa+0xaa,右声道0xa0+0xa0的。 这两种计算方法会得到一样的结果吗?
void CALLBACK CRecorderCtrlCtrl::GetWaveValue(LPBYTE lpWaveBuffer, DWORD dwWaveBufferLen,DWORD dwBitsPerSample,DWORD dwUserData)
{
CRecorderCtrlCtrl* pCtrl=(CRecorderCtrlCtrl*) (dwUserData);
if (dwUserData!=0 && pCtrl->GetSafeHwnd() && dwBitsPerSample!=0)
{
CClientDC dc(pCtrl);
CDC dcMem;
dcMem.CreateCompatibleDC (&dc);
CPen pen;
CPen* pOldPen;
static int nRed= (::GetTickCount ()+rand()) % 256 ;
static int nGreen = (::GetTickCount ()+rand()) % 256 ;
static int nBlue= (::GetTickCount ()+rand()) % 256 ;
pen.CreatePen (PS_SOLID,1,RGB(nRed,nGreen,nBlue));
pOldPen=dcMem.SelectObject(&pen);
CRect rcClient;
pCtrl->GetClientRect(&rcClient);
CBitmap bitmap;
CBitmap* pOldBitmap;
bitmap.CreateCompatibleBitmap(&dc,rcClient.Width (),rcClient.Height ());
pOldBitmap =(CBitmap*)dcMem.SelectObject(&bitmap);
pCtrl->DrawBackgroundToDc(&dcMem);
DWORD size;
size = dwBitsPerSample == 16 ? dwWaveBufferLen/2 : dwWaveBufferLen;
int yy = rcClient.Height()/2;
dcMem.MoveTo (0,yy);
int h=yy;
BOOL bTalk=FALSE; // useless,remove it if it's unecessary
short sample;
int x,y;
int oldx=0;
for(int register i = 0 ; i <(long)size ; i++) //to draw first channel
{
sample = dwBitsPerSample == 16 ? ((*((short*)lpWaveBuffer+i))*h)/(65535/2) : ( (*((BYTE*)lpWaveBuffer+i)-128)*h)/128;
x = int(((float)i/size)*(rcClient.Width()));
y = yy-sample;
if( abs(sample) > 15 && !bTalk )
{
bTalk = TRUE;
}
if (x!=oldx)
{
dcMem.LineTo (x,y);
//static int nGreen=150;
dcMem.SelectObject(pOldPen);
pen.DeleteObject();
pen.CreatePen (PS_SOLID,1,RGB(nRed++,nGreen++,nBlue++));
if (nGreen>255)
nGreen=50;
if (nRed > 255)
nRed=30;
if (nBlue>255)
nBlue=70;
pOldPen=dcMem.SelectObject (&pen);
oldx=x;
}
}
//dc.StretchBlt(0,0,rcClient.Width (),rcClient.Height (),&dcMem,0,0,rcClient.Width ()
// ,rcClient.Height(),SRCCOPY);
dc.BitBlt (0,0,rcClient.Width (),rcClient.Height(),&dcMem,0,0,SRCCOPY);
dcMem.SelectObject(pOldPen);
}}