两个PCM音频内容,要求混音!
我现在的做法是直接将Wave值相加除二,这显然是不对的!
求教一种恰当的方法:
能给出代码的我将重谢!
任何相关内容提供都将被加分
我现在的做法是直接将Wave值相加除二,这显然是不对的!
求教一种恰当的方法:
能给出代码的我将重谢!
任何相关内容提供都将被加分
解决方案 »
- 谁能够推荐一个vs2008 C++开发环境下,好用的CHART图形控件?
- 可否从两个MFC控件类继承? 发现这样做有一堆错误
- CListCtrl如何设置不同的行高?高手支个招。
- CEdit控件字符显示几个问题
- 用stlport后,出现很多link2001错误
- SDI程序中,我将框架的WS_CAPTION风格,菜单,状态栏,工具栏都去掉,可显示的窗口还是有个边框,如何把这个边框去掉?
- 请问怎么在对话框里新增加焦点呢
- 为什么在使用ADO访问数据时,使用MovePrevious()时出错??(附代码)
- 追女孩也要编程序!!!
- 乱套了!又一倒分者! B4:sundream (阳光梦幻)
- 哪里有Microsoft Visual C++ for Windows CE下载?
- 有《Windows图形编程》这本书吗?
下面给出混音子函数的实现。其中lpDest为目的缓冲区,rgWaveSrc为多路Wave数据源,iNumWaves为Wave数据源的通道数,wLen为目的缓冲区长度。
Void mixit(LPSAMPLE lpDest,LPSAMPLE rgWaveSrc[],int iNumWaves,WORD wLen)
{
int,,iSum;
WORD ctr;
ctr=0
While(wLen)
{
iSum=128;/*静音时数值为128*/
for(I=0;I<iNumWaves;I++=
iSum=iSum+*(rgWaveSrc[I]+ctr)-128;
PEG((int)0,iSum,(int)225);/*对转换结果处理*/
*lpDest++=iSum;
ctr++;
wLen--;
}
}注意一点的是对于单声道数据一个字节表示一个采样值,采样值在0—255之间,各个通道的对应Wave数据相加后,就会溢出,还需要将相加结果转换成0—255之间的数值。
{
public:
void MixData(PBYTE lpWaveSrc[],PBYTE lpWavDst,int iChannels,WORD wLen);
CWaveMix();
virtual ~CWaveMix();
int Open(char*); //打开一个WAV文件
int Play(HWND); //播放一个WAV文件
int Add(char*); //往正在播放的WAV设备中添加WAV 文件
int Stop(); //停止播放
int Close(); //关闭设备
int Continue();
DWORD DataSize;
WAVDATA* lpData;
private:
BOOL OpenFlage;
HGLOBAL hData;
DWORD DataSize_start; PCMWAVEFORMAT pFormat;
WAVEHDR WaveHead;
HWAVEOUT hWaveOut; int m_Channels;
};CWaveMix::CWaveMix()
{
memset(this,0,sizeof(CWaveMix));
}CWaveMix::~CWaveMix()
{
Close();
}int CWaveMix::Open(char* name)
{
HMMIO hMmio;
MMCKINFO pinfo;
MMCKINFO cinfo; if(hMmio)
Close(); //打开WAV文件,返回一个HMMIO句柄
hMmio=mmioOpen(name,NULL,MMIO_READ);
if(!hMmio)
return FALSE;
OpenFlage=1; //查找父块"wave";
pinfo.fccType=mmioFOURCC('W','A','V','E');
if(mmioDescend(hMmio,&pinfo,NULL,MMIO_FINDRIFF))
goto FALSE_END; //查找子块"fmt" parent"riff";
cinfo.ckid=mmioFOURCC('f','m','t',' ');
if(mmioDescend(hMmio,&cinfo,&pinfo,MMIO_FINDCHUNK))
goto FALSE_END; mmioRead(hMmio,(LPSTR)&pFormat,sizeof(PCMWAVEFORMAT));//cinfo.cksize);
if(pFormat.wf.wFormatTag!=WAVE_FORMAT_PCM)
goto FALSE_END; //跳入块"FMT"
mmioAscend(hMmio,&cinfo,0); //查找数据块
cinfo.ckid=mmioFOURCC('d','a','t','a');
if(mmioDescend(hMmio,&cinfo,&pinfo,MMIO_FINDCHUNK))
goto FALSE_END;
DataSize=cinfo.cksize;
//读取数据
hData=GlobalAlloc(GMEM_MOVEABLE
| GMEM_SHARE,DataSize);
lpData=(WAVDATA*)GlobalLock(hData);
if( !hData || !lpData ) goto FALSE_END;
if(mmioRead(hMmio,(HPSTR)lpData,DataSize)!=(LRESULT)DataSize)
goto FALSE_END; //close and return
mmioClose(hMmio,MMIO_FHOPEN);
return TRUE;FALSE_END:
if(hMmio)mmioClose(hMmio,MMIO_FHOPEN);
if(lpData)LocalUnlock(hData);
if(hData)GlobalFree(hData);
memset(this,0,sizeof(CWaveMix));
return 0;
}int CWaveMix::Play(HWND hP)
{
if(!OpenFlage)
return FALSE; //检测系统播放功能
if(waveOutOpen(NULL,WAVE_MAPPER,(WAVEFORMATEX*)&pFormat,NULL,NULL,WAVE_FORMAT_QUERY))
return Close(); if(waveOutOpen(&hWaveOut,WAVE_MAPPER,(WAVEFORMATEX*)&pFormat,(DWORD)hP,0,CALLBACK_WINDOW))
return Close(); WaveHead.lpData=(LPSTR)lpData;
WaveHead.dwBufferLength=DataSize;
WaveHead.dwFlags=0L;
WaveHead.dwLoops=0L;
DataSize_start=DataSize; //往WAV设备中添加数据
if(waveOutPrepareHeader(hWaveOut,&WaveHead, sizeof(WAVEHDR)))
return Close(); if(waveOutWrite(hWaveOut,&WaveHead,sizeof(WAVEHDR)))
return Close(); return TRUE;
}int CWaveMix::Continue()
{
CWaveMix wav;
if(!wav.Open("2.wav"))
return FALSE;
memcpy(lpData,wav.lpData,DataSize);
// WaveHead.lpData=(LPSTR)wav.lpData;
// WaveHead.dwBufferLength=wav.DataSize;
if(waveOutPrepareHeader(hWaveOut,&WaveHead, sizeof(WAVEHDR)))
return Close();
if(waveOutWrite(hWaveOut,&WaveHead,sizeof(WAVEHDR)))
return Close();
return TRUE;
}//#define min(a, b) (((a) < (b)) ? (a) : (b))
int CWaveMix::Add(char* name)
{
register int x;
if(!OpenFlage)
return Open(name); CWaveMix wav;
if(!wav.Open(name))
return FALSE; MMTIME time;
//获得WAV文件当前播放位置
time.wType=TIME_BYTES;
if(waveOutGetPosition(hWaveOut,&time,sizeof(MMTIME)))
time.u.cb=0;
DWORD start=((time.u.cb>>1)<<1);
DWORD end=min(DataSize_start,wav.DataSize);
// DWORD end=wav.DataSize;
register WAVDATA* lpd=lpData+start;
for(register DWORD i=0;i<end;i++)
{
//将两组WAV文件数据相加,并检测数据大小是否合法,如果
//数据大小越界,则分别取最大值和最小值
x=(((*(lpd+i))+(*(wav.lpData+i))))-128;
if(x<0)
x=0;
if(x>255)
x=255;
*(lpd+i)=(BYTE)(x);
}
return TRUE;
}int CWaveMix::Stop()
{
return !waveOutReset(hWaveOut);
}int CWaveMix::Close()
{
if(hWaveOut)
{
waveOutReset(hWaveOut);
waveOutUnprepareHeader(hWaveOut,&WaveHead,sizeof(WAVEHDR));
waveOutClose(hWaveOut);
}
if(lpData)LocalUnlock(hData);
if(hData)GlobalFree(hData);
memset(this,0,sizeof(CWaveMix));
return 0;
}
void CWaveMix::MixData(PBYTE lpWavSrc[], PBYTE lpWavDst, int iChannels, WORD wLen)
{
int i,iSum;
for(int j=0;j<wLen;j++)
{
iSum=128;//静音时数值为128
for(i=0;i<iChannels;i++)
iSum=iSum+*(lpWavSrc[i]+j)-128;
if(iSum<0) iSum=0;
if(iSum>255) iSum=255;
*lpWavDst++=iSum;
}
}