通过directsound能够输出正弦、三角波等,
也有别人的程序,但是没有代码,播放已无问题,
问题是怎么指定输出波形的频率,
下面是我的正弦波的代码:
WAVEFORMATEX CWaveSoundDlg::sWave={WAVE_FORMAT_PCM,2,22050,44100,2,8,0};
//初始化m_pDSBuffer,省略...
LPBYTE pBuffer1=NULL,pBuffer2=NULL,pBuffer3=NULL;
int dFreq=1000;//目的是输出1kHz的正弦波;
DWORD dwSize1,dwSize2;//lock data buffer
m_pDSBuffer->Lock(0,pointSize,(LPVOID*)
&pBuffer1,&dwSize1,LPVOID*&pBuffer2,&dwSize2,0);
static double fAngel1;
for (long i=0;i<pointSize;i++)
{
//Write buffer data;标准正弦波
pBuffer1[i]=(LOBYTE)(midValue+midValue*sin(fAngel1));//低八位
if(midValue>128)//如果是8位,一个pBuffer单元就够了,16位必须放到两个单元
{
i=i+1;
pBuffer1[i]=HIBYTE(midValue+midValue*sin(fAngel1));//高八位
}
fAngel1+=(PI*dFreq)/(sWave.nSamplesPerSec);//每增加一个点sin的角度发生应//
if(fAngel1>2*PI)//变化,这里不太确定。
fAngel1-=2*PI;
}
}
//unlock data buffer;and play;
m_pDSBuffer->Unlock(pBuffer1,dwSize1,pBuffer2,dwSize2);
m_pDSBuffer->Play(0,0,dwLooped );
这样声卡就播放出固定频率的正弦波了,
我的目的是不管怎么改动sWave,都输出固定dFreq的波形。
但是通过更改sWave的值,输出的频率会发生变化,我想的是应该仅仅和sWave的采样率(sWave..nSamplesPerSec)有关,实际上还和是否单双通道(sWave..nChannels)有关,偶想不明吧,希望大虾给解释一下,sWave的各个标志位关系也给解释一下;
也有别人的程序,但是没有代码,播放已无问题,
问题是怎么指定输出波形的频率,
下面是我的正弦波的代码:
WAVEFORMATEX CWaveSoundDlg::sWave={WAVE_FORMAT_PCM,2,22050,44100,2,8,0};
//初始化m_pDSBuffer,省略...
LPBYTE pBuffer1=NULL,pBuffer2=NULL,pBuffer3=NULL;
int dFreq=1000;//目的是输出1kHz的正弦波;
DWORD dwSize1,dwSize2;//lock data buffer
m_pDSBuffer->Lock(0,pointSize,(LPVOID*)
&pBuffer1,&dwSize1,LPVOID*&pBuffer2,&dwSize2,0);
static double fAngel1;
for (long i=0;i<pointSize;i++)
{
//Write buffer data;标准正弦波
pBuffer1[i]=(LOBYTE)(midValue+midValue*sin(fAngel1));//低八位
if(midValue>128)//如果是8位,一个pBuffer单元就够了,16位必须放到两个单元
{
i=i+1;
pBuffer1[i]=HIBYTE(midValue+midValue*sin(fAngel1));//高八位
}
fAngel1+=(PI*dFreq)/(sWave.nSamplesPerSec);//每增加一个点sin的角度发生应//
if(fAngel1>2*PI)//变化,这里不太确定。
fAngel1-=2*PI;
}
}
//unlock data buffer;and play;
m_pDSBuffer->Unlock(pBuffer1,dwSize1,pBuffer2,dwSize2);
m_pDSBuffer->Play(0,0,dwLooped );
这样声卡就播放出固定频率的正弦波了,
我的目的是不管怎么改动sWave,都输出固定dFreq的波形。
但是通过更改sWave的值,输出的频率会发生变化,我想的是应该仅仅和sWave的采样率(sWave..nSamplesPerSec)有关,实际上还和是否单双通道(sWave..nChannels)有关,偶想不明吧,希望大虾给解释一下,sWave的各个标志位关系也给解释一下;
基本步骤:
1、初始化directsound
2、创建DirectSoundBuffer
3、锁定Buffer,向其间填充数据(根据波形不同,数据不同);
4、解锁buffer,并播放buffer,得到输出波形(声卡发声);现在我不太确定的问题是:
设定WAVEFORMATEX的格式,对声音的影响,
我想不管怎样设置WAVEFORMATEX的几个成员,总能够得到固定频率的波形。也就是根据WAVEFORMATEX的不同来设置buffer数据的不同。
[email protected]
不能就算了,谢谢!
不过仅是简单的功能,声音重放及捕获
关注!!!
================================================================ok?
今天想了一下,应该是你说的那样子,先去试一下
,谢了。
//初始化DirectSoud,DirectSoundCreate(),略...
WAVEFORMATEX CWaveSoundDlg::sWave={WAVE_FORMAT_PCM,2,22050,44100,2,8,0};
//利用CreateSoundBuffer()和sWave create m_pDSBuffer,设置缓冲区大小等//等,若播放3秒钟,则大小为3*sWave.nAvgBytesPerSec;省略...LPBYTE pBuffer1=NULL,pBuffer2=NULL,pBuffer3=NULL;
WORD dFreq=1000;//输出1kHz的正弦波;DWORD pointSize=3*sWave.nAvgBytesPerSec;//假设3秒钟。
static double fAngel1,fAngel2;
for (DWORD i=0;i<pointSize;i++)
{
if(sWave.nChannels==1)//单声道,左右声道数据相同
{
if (sWave.wBitsPerSample==8)//8 bits 采样率,采样数据只有一个字节。
pBuffer1[i]=(BYTE)(midValue+midValue*sin(fAngel1));
else//16 bits sampling,两个字节,在缓冲区中,分低字节,高字节次序排放。
{
pBuffer1[i]=LOBYTE(midValue+midValue*sin(fAngel1));
i++;
pBuffer1[i]=HIBYTE(midValue+midValue*sin(fAngel1));
}
}
else//立体声,左右声道数据不同,Buffer中的采样数据,按照左声道右声道,依次排列。
{
if(sWave.wBitsPerSample==8)//8bits,一个字节
{
pBuffer1[i]=(BYTE)(midValue+midValue*sin(fAngel1));//left
i++;
pBuffer1[i]=(BYTE)(midValue+midValue*sin(fAngel1));//right
}
else//16 bits双字节
{
pBuffer1[i]=LOBYTE(midValue+midValue*sin(fAngel1));//low byte of left
i++;
pBuffer1[i]=HIBYTE(midValue+midValue*sin(fAngel1));//high byte of left
i++;
pBuffer1[i]=LOBYTE(midValue+midValue*sin(fAngel1));//low byte of right
i++;
pBuffer1[i]=HIBYTE(midValue+midValue*sin(fAngel1));//high byte of right
}
}
fAngel1+=(2*PI*dFreq)/(sWave.nSamplesPerSec);//每一周期采样点数为sWave.nSamplesPerSec/dFreq,因此每一次角度增加为2*PI*dFreq)///(sWave.nSamplesPerSec)
if(fAngel1>2*PI)
fAngel1-=2*PI;
}//解锁数据,开始播放;
m_pDSBuffer->Unlock(pBuffer1,dwSize1,pBuffer2,dwSize2);
m_pDSBuffer->Play(0,0,dwLooped );