新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 用DirectSound实现增强的音频特技效果 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 9268 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 用DirectSound实现增强的音频特技效果 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 用DirectSound实现增强的音频特技效果

    DirectSound的基本特技。

      DirectSound提供8个基本的音频特技。

      1、Chorus 和声,这里说的和声不是指很多人合唱,而是指声音的重叠,即通过原声和回声的重叠,使得声音加宽,加厚。

      2、Compression 压限,是针对声音不同部分的音量进行增减也就是说,可以对某段音频中音量低于某一限度的部分进行平滑的音量提升(其余部分不变);对音量高于某一限度的部分进行平滑的音量衰减(其余部分不变),或二者同时作用,简单说,就是平衡音量。

      3、Distortion 失真。

      4、Echo 回声,模拟声音被远处的平面反射回来的效果。

      5、Environmental Reverberation反射(混响),简单说就是声音余韵,音源在空间反射出来的声音。适当设置混响,可以更真实、更有现场感的再现声音源,也可以起到修饰、美化的作用。表现宽阔的,传声真实的效果。

      6、Flange,一般翻译为波浪特技,用于设置变调效果,通过拷贝失调的声音,或者把某个频率点改变,调节声音分离的时间、音调深度。可以用来产生颤动、急促的声音。

      7、Gargle ,咕噜效果处理。一种可以试音源产生咕噜声的调幅处理模式。

      8、Parametric Equalizer参数平衡,用于为音频设置参数均衡器。强化或衰减指定的频率。对于增强音乐的效果特别有效。

      DiectSound对于每一种特技,都提供了一个接口 ,通过这个接口,我们可以调整特技的参数,接口定义如下:

      ·IDirectSoundFXChorus8 和声特技接口

      ·IDirectSoundFXCompressor8 压限特技接口

      ·IDirectSoundFXDistortion8 失真特技接口

      ·IDirectSoundFXEcho8 回声特技接口

      ·IDirectSoundFXWavesReverb8混响特技接口
     
      ·IDirectSoundFXFlanger8 波浪特技接口

      ·IDirectSoundFXGargle8 咕噜特技接口

      ·IDirectSoundFXParamEq8 参数平衡特技接口

      我们可以通过DirectSound缓冲区接口,即IDirectSoundBuffer8的GetObjectInPath方法获得所支持音频特技的接口。

      下面先说一下DirectSound中的音频特技实现的过程。

      1、首先创建 DirectSound对象和辅助缓冲区,辅助缓冲区一定要设置DSBCAPS_CTRLFX标志。

      2、通过辅助缓冲区buffer即IDirectSoundBuffer8的SetFX方法设置特效;

      3、IDirectSoundBuffer8的GetObjectInPath方法获得特效的接口;

      4、特效接口的SetAllParameters方法设置参数;

      5、然后就是通过缓冲区的play方法来播放音频文件。在播放音频的同时我们也可以调整特技的参数。

      下面开始我们的例子吧,关于例子的界面很简单,都是通过MFC 自动提供的,我没有做什么修饰,呵呵,我们只关心功能,所以其他的我就不详细讲,具体你可以参见例子代码,例子的源码会随着本文一起发布,例子的界面如下


    图 音频特技的示例

      界面很简单,流程也不复杂,我在这里主要是用来演示如何来实现音频特技的,所以下面我们一起看看如何来实现音频的特技。这里我要说明一下,因为8个特技实现过程基本是一样,所以我这里只是以chorus(回声)特技 举例,其他特技的实现和chorus类似,避免代码重复,就不一一列出,具体的可以参见例子的源码。

      第1步: 首先要定义我们用到的一些变量,这里我定义的全是全局的变量,你可以根据自己的情况来定义这些变量。

    LPDIRECTSOUNDBUFFER8 g_pDSBuffer8 = NULL; //缓冲区对象
    LPDIRECTSOUND8 g_pDsd = NULL; ///Directsound对象
    CWaveFile *g_pWaveFile= NULL; // 操作wave文件的 对象
    //下面的8个指针接口对应着8个音频特技
    LPDIRECTSOUNDFXCHORUS8 g_pChorus = NULL;
    LPDIRECTSOUNDFXCOMPRESSOR8 g_pCompressor = NULL;
    LPDIRECTSOUNDFXDISTORTION8 g_pDistortion = NULL;
    LPDIRECTSOUNDFXECHO8 g_pEcho = NULL;
    LPDIRECTSOUNDFXFLANGER8 g_pFlanger = NULL;
    LPDIRECTSOUNDFXGARGLE8 g_pGargle = NULL;
    LPDIRECTSOUNDFXPARAMEQ8 g_pParamEq = NULL;
    LPDIRECTSOUNDFXWAVESREVERB8 g_pReverb = NULL;
    //用于设置特技的参数,每种音频特技对应着一个参数。
    DSFXChorus g_paramsChorus;
    DSFXCompressor g_paramsCompressor;
    DSFXDistortion g_paramsDistortion;
    DSFXEcho g_paramsEcho;
    DSFXFlanger g_paramsFlanger;
    DSFXGargle g_paramsGargle;
    DSFXParamEq g_paramsParamEq;
    DSFXWavesReverb g_paramsReverb;

      定义完这些变量,就可以开始我们的工作了

      第2步 初始化Directsound,获取IDrectSoundBuffer8的接口。这一步骤的工作可以放到程序的初始化的地方。

    CoInitialize( NULL );
    HRESULT hr;
    if(FAILED(hr = DirectSoundCreate8(NULL,&g_pDsd,NULL)))
     return FALSE;
    if(FAILED(hr = g_pDsd->SetCooperativeLevel(m_hWnd,DSSCL_PRIORITY)))
     return FALSE;
    //
    for(int i =0; i< MAX_AUDIO_BUF; i++)
    g_event[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
    //设置音频的格式
    WAVEFORMATEX waveformat;
    waveformat.wFormatTag = WAVE_FORMAT_PCM;
    waveformat.nChannels = 2;
    waveformat.nSamplesPerSec = 48000;
    waveformat.wBitsPerSample = 16;
    waveformat.nBlockAlign = waveformat.nChannels * waveformat.wBitsPerSample /8;
    waveformat.nAvgBytesPerSec = waveformat.nBlockAlign * waveformat.nSamplesPerSec;

    DSBUFFERDESC dsbd;
    ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
    dsbd.dwSize = sizeof(DSBUFFERDESC);
    dsbd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLFX| DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2;
    // 创建缓冲区的时候,一定不要忘了设置DSBCAPS_CTRLFX标志
    dsbd.dwBufferBytes = MAX_AUDIO_BUF * BUFFERNOTIFYSIZE ;
    dsbd.lpwfxFormat = &waveformat;
    LPDIRECTSOUNDBUFFER lpbuffer;
    if(FAILED(hr = g_pDsd->CreateSoundBuffer(&dsbd,&lpbuffer,NULL)))
     return FALSE;

    if( FAILED( hr = lpbuffer->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &g_pDSBuffer8) ) )
     return FALSE;
    lpbuffer->Release();

      需要注意的几个地方:

      ·DirectX通过DirectX Media Objects(DMOs)来支持在声音中添加特技。因为特技使用到了COM组件,所以首先要通过CoInitialize()来初始化Com库,当然,你别忘了在退出程序时调用CoUninitialize() 。

      ·创建缓冲区的时候,一定不要忘了对 DSBUFFERDESC结构的dwFlages设置DSBCAPS_CTRLFX标志,如果忘了设置这个标志,那么你后面的音频特技全是无效的。但是,在设置这个标志时,buffer一定要处于停止状态并且没有被锁定。在DiectX 9.0中,特技不是依靠硬件来实现的。当然也可以在硬件缓冲区中设置特技,但这样做没有任何的好处。

      ·最后一个要注意的问题,就是缓冲区的大小,缓冲区的size过小,特技并不能好好工作,DirectSound建议缓冲区的大小应该在小于150毫秒的数据数据量,缓冲区中使用特技,这个值被定义为DSBSIZ_FX_MIN。

      在上面的例子中,waveformat.nAvgBytesPerSec = waveformat.nBlockAlign * waveformat.nSamplesPerSec; = 2*16*4800/8 = 19200 bytes/m

      那么dsbd.dwBufferBytes 的最小值应该大于 19200*0.15 = 2880字节。

      我刚开始就没有注意这个问题,结果后面总是出错,我一直纳闷不已,因为代码没有问题的,后来重新看了一下帮助才发现这个问题。

      第3步 通过缓冲区对象IDirectSoundBuffer8设置缓冲区支持的具体特技,并通过IDirectSoundBuffer8 对象的GetObjectInPath方法获得具体的音频特技的接口;这里以chorus特技为例:如下

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_CHORUS;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     hr = g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( FAILED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_CHORUS, 0, IID_IDirectSoundFXChorus8,(LPVOID*) &g_pChorus ) ) )
      return ;
     g_pChorus->GetAllParameters(&g_paramsChorus);
    }

      第4步 通过特效接口的SetAllParameters方法设置参数,手动拖动滑动条,来设置特技参数,可以在例子中看到如下的代码,以chorus为例:

    void CDsoundEffectDemoDlg::OnEffectChanged()
    {
     switch( g_dwCurrentFXType )
     {
      case eSFX_chorus:
      {
       //下面的代码主要是为了获取滑动条上参数的数值。
       SaveSingleParameter( IDC_PARAM_NAME1, &g_paramsChorus.fWetDryMix, DSFXCHORUS_WETDRYMIX_MIN, DSFXCHORUS_WETDRYMIX_MAX );
       SaveSingleParameter( IDC_PARAM_NAME2, &g_paramsChorus.fDepth, DSFXCHORUS_DEPTH_MIN, DSFXCHORUS_DEPTH_MAX );
       SaveSingleParameter( IDC_PARAM_NAME3, &g_paramsChorus.fFeedback, DSFXCHORUS_FEEDBACK_MIN, DSFXCHORUS_FEEDBACK_MAX );
       SaveSingleParameter( IDC_PARAM_NAME4, &g_paramsChorus.fFrequency, DSFXCHORUS_FREQUENCY_MIN, DSFXCHORUS_FREQUENCY_MAX );
       SaveSingleParameter( IDC_PARAM_NAME5, &g_paramsChorus.fDelay, DSFXCHORUS_DELAY_MIN, DSFXCHORUS_DELAY_MAX );

       if( ((CButton*)GetDlgItem(IDC_RADIO_TRIANGLE ))->GetCheck() == BST_CHECKED )
        g_paramsChorus.lWaveform = DSFXCHORUS_WAVE_TRIANGLE;
       else
        g_paramsChorus.lWaveform = DSFXCHORUS_WAVE_SIN

       if( ((CButton*)GetDlgItem(IDC_RADIO_NEG_180 ))->GetCheck() == BST_CHECKED )
        g_paramsChorus.lPhase = DSFXCHORUS_PHASE_NEG_180;
       else if( ((CButton*)GetDlgItem(IDC_RADIO_NEG_90 ))->GetCheck() == BST_CHECKED )
        g_paramsChorus.lPhase = DSFXCHORUS_PHASE_NEG_90;
       else if( ((CButton*)GetDlgItem( IDC_RADIO_ZERO ))->GetCheck() == BST_CHECKED )
        g_paramsChorus.lPhase = DSFXCHORUS_PHASE_ZERO;
       else if( ((CButton*)GetDlgItem(IDC_RADIO_90))->GetCheck() == BST_CHECKED )
        g_paramsChorus.lPhase = DSFXCHORUS_PHASE_90;
       else
        g_paramsChorus.lPhase = DSFXCHORUS_PHASE_180;

       if( g_pChorus) //设置合生特技的参数
        g_pChorus->SetAllParameters( &g_paramsChorus );

      break;
     }
     ......//下面是其他特技的参数设置 ,略,具体可以见例子中的代码。
    }

      注: 在音频播放的同时拖动滑动条调解音频特技的参数,可以随时调整音频特技的效果。

      第5步 一切都ok了,下面就是调用IDRIRECTSOUNDBUFFER8 的play函数来播放音频文件了。

    DWORD res;
    LPVOID lplockbuf;
    DWORD len;
    DWORD dwWrite;

    g_pDSBuffer8->Lock(0,0,&lplockbuf,&len,NULL,NULL,DSBLOCK_ENTIREBUFFER);
    g_pWaveFile->Read((BYTE*)lplockbuf,len,&dwWrite);
    g_pDSBuffer8->Unlock(lplockbuf,len,NULL,0);
    g_pDSBuffer8->SetCurrentPosition(0);
    g_pDSBuffer8->Play(0,0,DSBPLAY_LOOPING);

      上面讲了Directsound音频特技开发的主要流程,其中的设置音频过程我只是用chorus为例,其实其他的几个特技的使用方法跟chorus很类似,唯一不同的就是参数结构的不同,限于篇幅,对于其他特技的代码就不一一列出了,具体的可一参看本文实例的代码。

      下面我们看看每个特技的参数都需要设置什么。


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/9/7 15:39:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    1、和声(Chorus)特技,参数设置的界面如下:

    按此在新窗口浏览图片

      合声特技的参数通过下面的结构来调整:

    typedef struct _DSFXChorus {
     FLOAT fWetDryMix;//压缩信号和未压缩信号的比率,缺省值50
     FLOAT fDepth; //低频率振荡器调制信号的延迟时间的百分比,缺省是10%
     FLOAT fFeedback;//输出信号对特技输入信号的反馈百分比,缺省25%
     FLOAT fFrequency;//LFO的频率,缺省是1.1
     LONG lWaveform;//LFO的波形类型,缺省是正弦波
     FLOAT fDelay;//音频播放时的延迟时间,缺省是16ms
     LONG lPhase; //左右声道声波的相位差别,取值为-180,-90,0,90,180 度
    } DSFXChorus, *LPDSFXChorus;

      我们在程序中可以定义这个结构的对象,如下:

    DSFXChorus g_paramsChorus;
    LPDIRECTSOUNDFXCHORUS8 g_pChorus = NULL;

      然后通过通过滑动条来设置g_paramsChorus对象的值,设置后可以调用:

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_CHORUS;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     hr = g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( SUCCEED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_CHORUS, 0, IID_IDirectSoundFXChorus8,(LPVOID*) &g_pChorus ) ) )
      return ;
     g_pChorus->SetAllParameters (&g_paramsChorus);
    }

      2、压限特技(Compressor )

    按此在新窗口浏览图片

      压限特技的参数通过下面的结构来调整,参数调整界面如上:

    typedef struct _DSFXCompressor
    {
     FLOAT fGain; //压限后输出信号的强度,缺省值是0db
     FLOAT fAttack;//压限达到最大值的时间,缺省是10ms
     FLOAT fRelease;//输入小于fThreshold后,压缩停止的时间,缺省是200ms
     FLOAT fThreshold;//压缩开始的临界点的db值,缺省是-20db
     FLOAT fRatio;//压缩的比率,缺省是3,即3:1
     FLOAT fPredelay;//lThreshold 达到临界点,attack phase开始前的延迟时间
    } DSFXCompressor, *LPDSFXCompressor;

      我们在程序中可以定义这个结构的对象,如下:

    LPDIRECTSOUNDFXCOMPRESSOR8 g_pCompressor = NULL;
    DSFXCompressor g_paramsCompressor;

      通过拖动滑动条,我们可以用下面的代码调整参数:

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_COMPRESSOR;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     hr = g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if(FAILED(hr= _pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_COMPRESSOR, 0, IID_IDirectSoundFXCompressor8,(LPVOID*) &g_pCompressor ) ) )
      return ;
     g_pCompressor->SetAllParameters (&g_paramsCompressor);
    }

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/9/7 15:40:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客3
    发贴心情 
    3、失真特技(Distorion)

    按此在新窗口浏览图片

      失真特技的参数通过下面的结构来调整:

    typedef struct _DSFXDistortion
    {
     FLOAT fGain;//信号失真后的音量的强度变化,缺省是比原来衰减 18db。
     FLOAT fEdge;//失真的强度,用百分比来表示,缺省值是15
     FLOAT fPostEQCenterFrequency;//信号叠加的中心频率,缺省是2400hz
     FLOAT fPostEQBandwidth;//信号的带宽 ,缺省是2400hz
     FLOAT fPreLowpassCutoff;//高通滤波的最高值,缺省是8000hz
    } DSFXDistortion, *LPDSFXDistortion;  

      我们在程序中可以定义这个结构的对象,如下:

    LPDIRECTSOUNDFXDISTORTION8 g_pDistortion = NULL;
    DSFXDistortion g_paramsDistortion;

      通过拖动滑动条,我们可以用下面的代码调整参数:

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_DISTORTION;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( FAILED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_DISTORTION, 0, IID_IDirectSoundFXDistortion8,(LPVOID*) &g_pDistortion ) ) )
      return ;
     g_pDistortion ->SetAllParameters (&g_paramsDistortion);
    }

      4、回声特技( Echo)

    按此在新窗口浏览图片

      回声特技的参数通过下面的结构来调整:

    typedef struct _DSFXEcho
    {
     FLOAT fWetDryMix;处理过的信号和没有处理的信号的比率,缺省值是50
     FLOAT fFeedback;//输出信号反馈到输入信号的百分比, 缺省值是50
     FLOAT fLeftDelay;//左声道延迟的时间,缺省值500ms
     FLOAT fRightDelay;//右声道延迟的时间,缺省值500ms
     LONG lPanDelay;//是否左右声道交替延迟,缺省值 0,左右声道不交替
    } DSFXEcho, *LPDSFXEcho;

      我们在程序中可以定义这个结构的对象,如下:

    LPDIRECTSOUNDFXECHO8 g_pEcho = NULL;
    DSFXEcho g_paramsEcho;

      通过拖动滑动条,我们可以用下面的代码调整参数:

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_ECHO;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( FAILED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_ECHO, 0, IID_IDirectSoundFXEcho8,(LPVOID*) &g_pEcho ) ) )
      return ;
     g_pEcho->SetAllParameters (&g_paramsEcho);
    }

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/9/7 15:41:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客4
    发贴心情 
    5、波浪特技(Flanger)

    按此在新窗口浏览图片

      波浪特技的参数通过下面的结构来调整:

    typedef struct _DSFXFlanger
    {
     FLOAT fWetDryMix;//处理过的信号和没有处理的信号的比率,取值范围 0~~100,缺省值是50
     FLOAT fDepth;//低频振荡器调整延迟时间的百分比,取值范围 0~~100,缺省值 是100
     FLOAT fFeedback;//输出信号反馈到输入信号的百分比,取值范围 -99~~99, 缺省值是-50
     FLOAT fFrequency;//低频振荡器的频率, 缺省值是 0.25
     LONG lWaveform;//低频振荡器的波形,分为三角形,和正弦波形
     FLOAT fDelay;//播放之前的延迟,以毫秒作单位,缺省值是2ms
     LONG lPhase;//相位
    } DSFXFlanger, *LPDSFXFlanger;

      我们在程序中可以定义这个结构的对象,如下:

    LPDIRECTSOUNDFXFLANGER8 g_pFlanger = NULL;
    DSFXFlanger g_paramsFlanger;

      通过拖动滑动条,我们可以用下面的代码调整参数:

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_FLANGER;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( FAILED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_FLANGER, 0, IID_IDirectSoundFXFlanger8,(LPVOID*) &g_pFlanger ) ) )
      return ;
     g_pFlanger->SetAllParameters (&g_paramsFlanger);
    }

      6、咕噜声效特技(Gargle)

    按此在新窗口浏览图片

      咕噜声效特技的参数通过下面的结构来调整:

    typedef struct _DSFXGargle
    {
     DWORD dwRateHz;//调制波频率,取值范围 1 ~~1000 hz,缺省值是20 hz
     DWORD dwWaveShape;//调制波形状,分为三角形和正方形两种,DSFXGARGLE_WAVE_TRIANGLE DSFXGARGLE_WAVE_SQUARE
    } DSFXGargle, *LPDSFXGargle;

      我们在程序中可以定义这个结构的对象,如下:

    LPDIRECTSOUNDFXGARGLE8 g_pGargle = NULL;
    DSFXGargle g_paramsGargle;
    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_GARGLE;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( FAILED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_GARGLE, 0, IID_IDirectSoundFXGargle8,(LPVOID*) &g_pGargle ) ) )
      return ;
     g_pGargle->SetAllParameters (&g_paramsGargle);
    }

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/9/7 15:42:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客5
    发贴心情 
    7、参数平衡特技(ParamEQ)

    按此在新窗口浏览图片

      参数平衡特技的参数通过下面的结构来调整:

    typedef struct _DSFXParamEq
    {
     FLOAT fCenter;//中心的频率 ,单位是hz,取值范围是 80.0f hz~~16000.0f ,缺省值 是 8000hz
     FLOAT fBandwidth;//音的带宽,以半音为单位,取值范围是 1.0f~~36.0f,缺省值 是12
     FLOAT fGain;//音频的音量,以db为单位,取值范围是 -15.0db ~~15.0f db,缺省值是0db
    } DSFXParamEq, *LPDSFXParamEq;

      我们在程序中可以定义这个结构的对象,如下:

    LPDIRECTSOUNDFXPARAMEQ8 g_pParamEq = NULL;
    DSFXParamEq g_paramsParamEq;  

      通过拖动滑动条,我们可以用下面的代码调整参数:

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_PARAMEQ;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( FAILED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_PARAMEQ, 0, IID_IDirectSoundFXParamEq8,(LPVOID*) &g_pParamEq ) ) )
      return ;
     g_pParamEq ->SetAllParameters (&g_paramsParamEq);
    }

      8、混响(Reverb)

    按此在新窗口浏览图片

      混响特技的参数通过下面的结构来调整:

    typedef struct _DSFXWavesReverb
    {
     FLOAT fInGain; //输入信号的音量的大小,即db值,缺省值是 0db。
     FLOAT fReverbMix;//回响混合音量强度大小,用db值来表示,缺省值是 0db。
     FLOAT fReverbTime;//回响的时间,单位是ms,缺省值是 1000.0f ms
     FLOAT fHighFreqR//高频回响所占时间的比率 , 缺省值 0.001f 。TRatio;
    } DSFXWavesReverb, *LPDSFXWavesReverb;

      我们在程序中可以定义这个结构的对象,如下:

    LPDIRECTSOUNDFXWAVESREVERB8 g_pReverb = NULL;
    DSFXWavesReverb g_paramsReverb;

      通过拖动滑动条,我们可以用下面的代码调整参数:

    DSEFFECTDESC effectdesc;
    ZeroMemory( &effectdesc, sizeof( DSEFFECTDESC ) );
    effectdesc.dwSize = sizeof(DSEFFECTDESC);
    effectdesc.dwFlags = 0;
    effectdesc.guidDSFXClass = GUID_DSFX_STANDARD_CHORUS;
    DWORD dwResult;
    if(g_pDSBuffer8)
    {
     g_pDSBuffer8->SetFX(1,&effectdesc,&dwResult);
     if( FAILED( hr = g_pDSBuffer8->GetObjectInPath( GUID_DSFX_STANDARD_CHORUS, 0, IID_IDirectSoundFXChorus8,(LPVOID*) &g_pReverb ) ) )
      return ;
     g_pReverb ->SetAllParameters (&g_paramsReverb);
    }

      结束语

      本文通过一个实例演示了如何使用DirectSound提供的基本音频特技。简单的接口,强大的功能,能给你的程序增色不少。本文的示例代码在windowXP +vc.net下调试通过。

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/9/7 15:43:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/22 21:02:34

    本主题贴数5,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    101.563ms