通过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的各个标志位关系也给解释一下;

解决方案 »

  1.   

    刚接触,等两天。顺便问个初级问题directsound支持98 2000 xp吗?
      

  2.   

    这是什么方面的知识,directx 吗,我不知道,有谁知道关于directx编程方面的好书?
      

  3.   

    我的目的是用声卡作为波形发生器。
    基本步骤:
    1、初始化directsound
    2、创建DirectSoundBuffer
    3、锁定Buffer,向其间填充数据(根据波形不同,数据不同);
    4、解锁buffer,并播放buffer,得到输出波形(声卡发声);现在我不太确定的问题是:
    设定WAVEFORMATEX的格式,对声音的影响,
    我想不管怎样设置WAVEFORMATEX的几个成员,总能够得到固定频率的波形。也就是根据WAVEFORMATEX的不同来设置buffer数据的不同。 
      

  4.   

    能不能把你的代码给我看一看?
    [email protected]
    不能就算了,谢谢!
      

  5.   

    我倒是用过directsound 但是真正没有你的深度,不过改变WAVEFORMATEX不同则buffer长度不同
      

  6.   

    directsound 用过
    不过仅是简单的功能,声音重放及捕获
    关注!!!
      

  7.   

    你最好不要用buffer的大小来判断,以时间为标准,buffer的数据量也以时间来计.
      

  8.   

    应该主要和声道数有关,我看你传进去的参数是双声道,双声道数据组织一般左声道一个字节(假设一个采样点值一个字节)右声道一个字节,以此类推,因此只要根据声道值的不同相应调整buffer的数据就可以了。
      

  9.   

    up
    ================================================================ok?
      

  10.   

    to feng():
    今天想了一下,应该是你说的那样子,先去试一下
    ,谢了。
      

  11.   

    现在已经成功了,多谢各位,把代码贴一下:
    //初始化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 );