(DirectX系列01)DirectSound 3D语音特效

       近日正在学习DirectX,主要用于视频监控和流媒体方面应用,学习《Visual C++音视频处理技术和工程实践》已经有大半,一直想写些感受,兴趣所致,今天重新学习了下DirectSound 3D语音特效,并编写一些代码,在此分享出来,希望对大家能有所帮助。

       大家都有这种感觉,当我们离发声源越来越远的时候,声音越来越小。DirectSound就是模仿这些现象,从数学理论角度加以描述。当然,影响音效的因素不光只有这些,还有如Doppler效应等,但是DirectSound就是这么神奇,它能模仿大多数的声音特效,这就是神奇的3D语音特效,在游戏等方面有着广泛的应用。

       对于DirectSound中的3D声效的播放,在操作之前需要将创建的主缓冲区设置为DSBCAPS_CTRL3D标志,并由主缓冲区创建一个IDirect3DListener8听者对象,然后调用IDirect3DListener8的接口函数设置听着的位置和方向,从而达到3D语音的效果,接下来介绍下整个特效的处理过程。

     创建DSound对象,并初始化主缓冲区

       在DirectSound中对音频的操作之前都需要创建一个Dsound对象,该对象贯穿这个程序始终,一般创建之后立马创建音频主缓冲区,该对象的创建函数是DirectSoundCreate8,返回一个LPDIRECTSOUND8对象。这部分代码具体如下;

 



 

    //创建Dsound对象
 HRESULT hr;
 if(FAILED(hr = DirectSoundCreate8(NULL,&g_pDsd,NULL)))
  return FALSE;
 if(FAILED(hr = g_pDsd->SetCooperativeLevel(m_hWnd,DSSCL_PRIORITY)))
  return FALSE;
    //初始化Directsound 的主缓冲区,并设置格式
 LPDIRECTSOUNDBUFFER  pDSBPrimary = NULL;
    DSBUFFERDESC   dsbdesc ;
 ZeroMemory(&dsbdesc,sizeof(DSBUFFERDESC));
 dsbdesc.dwSize = sizeof(DSBUFFERDESC);
 dsbdesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
 if(FAILED(hr = g_pDsd->CreateSoundBuffer(&dsbdesc,&pDSBPrimary ,NULL)))
  return FALSE;



 

 

      获取3D缓冲区对象

        IDirectSound3DBuffer8接口通常从DirectSound的次缓冲区获取,次缓冲区获取通过DSBUFFERDESC结构的dwFlags成员设置DSBCAPS_CTRL3D标志创建,具体代码如下;

 



 

 DSBUFFERDESC dsbd;
 ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
 dsbd.dwSize= sizeof(DSBUFFERDESC);

  // 设置DSBCAPS_CTRL3D标志

 dsbd.dwFlags= DSBCAPS_CTRL3D| DSBCAPS_GLOBALFOCUS |  DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2;
 //dsbd.dwBufferBytes   =MAX_AUDIO_BUF * BUFFERNOTIFYSIZE  ;//如果采用流buffer,请将此句放开
 dsbd.dwBufferBytes   =g_pWaveFile->GetSize(); // 如果采用流buffer,请屏蔽掉此句
 dsbd.guid3DAlgorithm = guid3DAlgorithm;
 dsbd.lpwfxFormat     = g_pWaveFile->m_pwfx;

  // 创建次缓冲区
 if(FAILED(hr = g_pDsd->CreateSoundBuffer(&dsbd,&g_pDSBuffer,NULL)))
  return ;
 for(int i =0; i< MAX_AUDIO_BUF;i++)
 {
        g_aPosNotify[i].dwOffset = i* BUFFERNOTIFYSIZE  ;
        g_aPosNotify[i].hEventNotify = g_event[i];
 }

 //获取IDirectSound3DBuffer接口

 if(FAILED(hr = g_pDSBuffer->QueryInterface(IID_IDirectSound3DBuffer, (VOID**)&g_pDS3DBuffer )))

 ........

 // 设置3D缓冲区参数
 g_dsBufferParams.dwMode = DS3DMODE_HEADRELATIVE;
 g_pDS3DBuffer->SetAllParameters( &g_dsBufferParams, DS3D_IMMEDIATE );
  return ; 

    获取听者对象(IDirectSound3DListener8)

 

     获取IDirectSound3DListener8对象其实很简单,首先声明一个LPDIRECTSOUND3DLISTENER对象,然后调用QueryInterface即可。获取的IDirectSound3DListener8后,需要对特效参数进行设置,例如通过SetPosition设置听者的位置,具体的API参照MSDN即可,这部分代码如下;

 



 LPDIRECTSOUND3DLISTENER g_pDSListener = NULL;   // 3D 听者之中呢

 //获取听者对象

 if( FAILED( hr = pDSBPrimary->QueryInterface( IID_IDirectSound3DListener, (VOID**)&g_pDSListener ) ) )
    return FALSE;

 ......

    if(FAILED(hr = g_pDSBuffer->QueryInterface(IID_IDirectSoundNotify,(LPVOID *) &g_pDSNotify )))
  return ;
 g_pDSNotify->SetNotificationPositions(MAX_AUDIO_BUF,g_aPosNotify);
 g_pDSNotify->Release();

 FLOAT fDopplerFactor;
 FLOAT fRolloffFactor;
 FLOAT fMinDistance;
 FLOAT fMaxDistance;

 ......

 g_dsListenerParams.flDopplerFactor = fDopplerFactor;
 g_dsListenerParams.flRolloffFactor = fRolloffFactor;

 if( g_pDSListener )
 {

  // 设置全特性
  g_pDSListener->SetAllParameters( &g_dsListenerParams, DS3D_DEFERRED );

  // 提交延时
     g_pDSListener->CommitDeferredSettings();
 }

 


     读取音频数据,播放

 

     读取WAV音频数据,我们可以直接采用Cwavefile类实现,该类是由微软封装的,专门用于操作wav文件。音频数据的播放直接调用Dsound中的Play函数即可,



//打开wav文件

g_pWaveFile = new CWaveFile;
 g_pWaveFile->Open(strFileName,NULL,WAVEFILE_READ);
 WAVEFORMATEX* pwfx  = g_pWaveFile->GetFormat();

....

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

 // 锁定内存
 g_pDSBuffer->Lock(0,0,&lplockbuf,&len,NULL,NULL,DSBLOCK_ENTIREBUFFER);

 // 读取数据
 g_pWaveFile->Read((BYTE*)lplockbuf,len,&dwWrite);

 // 释放到主缓冲区
 g_pDSBuffer->Unlock(lplockbuf,len,NULL,0);

 // 设置播放位置
 g_pDSBuffer->SetCurrentPosition(0);

 //播放
 g_pDSBuffer->Play(0,0,DSBPLAY_LOOPING);

    Close


 if(g_pDSListener)  g_pDSListener->Release();
 if(g_pDsd)  g_pDsd->Release();
    通过上面的几步3D特效处理也并不是很难,进一步学习可以参考MSDN相关文档,www.codeproject.com相关内容也不错。

 

 



 

   

时间: 2024-08-02 13:11:12

(DirectX系列01)DirectSound 3D语音特效的相关文章

Cocos2d-x-v3中3D网格特效动画的应用

Cocos2d-x-v3中3D网格特效动画的应用 一.网格特效的使用原理         基础的动作是对节点整体进行移动,变形等操作,网格特效的原理是将节点分割成多个尺寸相同的网格,根据改变每个网格块的属性使整体节点产生3D的效果. 二.网格特效的基本用法       在cocos2d-x中,v3的版本新引入了一个类NodeGrid,专门用来包装网格的特效,示例如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16     //获取屏幕尺寸     Size v

Css不朽的经典—3D文字特效

css|特效 效果: 3D Text 以下是一个用了blur滤镜而另一个没用的叠加效果 Ttop.cn Ttop.cn Glass Text 这个是两个都用了alpha滤镜的效果 Ttop.cnTtop.cn Inner Shadow 这个是先用了一段白色的文字,再加了mask()滤镜,再用了shadow()滤镜,最后加入chroma()滤镜形成后一段字体,放在前一段文字的相对left: -200px位置上形成的. Ttop.cnTtop.cn Outline Text 用mask, glow

Css制作3D文字特效

Css不朽的经典-3D文字特效--这个是先用了一段白色的文字,再加了mask()滤镜,再用了shadow()滤镜,最后加入chroma()滤镜形成后一段字体,放在前一段文字的相对left: -200px位置上形成的. 效果:见附图1 源代码: <style type="text/css"><!--.samplefont-style: italic; font-family: arial black;font-size: 40px; font-weight: bold;

利用AI+PS制作假日热销3D文字特效教程

先说一下开篇的废话.做立体字可以用到的办法有很多,效果最好的,当然还是专业的3D软件来做的好,比如3DS MAX.MAYA等等,可以作出很多特殊的, 逼真的立体效果. 但是在常用的网站专题,一些品面广告用3D,一来一般的3D软件平面和网页设计玩的不是很转, 二来就是一些效果比较耗时..所以现在的AI, CDR等等的都可以做一些简单的3D效果,然后在用PS来处里加工,可以作出一些基础的可以突出显示主题的3D文字特效来,来提高专题页面.平面广告的视觉效果. 好,废话就到这里, 开始正题. 效果图:

jQuery实现3D文字特效的方法

 这篇文章主要介绍了jQuery实现3D文字特效的方法,通过鼠标与css样式来实现文字特效的技巧,需要的朋友可以参考下     本文实例讲述了jQuery实现3D文字特效的方法.分享给大家供大家参考.具体如下: 这款基于jQuery的3D文字特效演示,不是真正的3D,是由多个文字形成的3D效果,如果首次加载网页出错的话,请刷新一下页面,当然在使用中不会出现此问题. 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN&q

(DirectX系列09)DirectShow EDS应用编码分析

(DirectX系列09)DirectShow EDS应用编码分析 DES (DirectShow Editing Services),是一套基于DirectShow核心框架的编程接口.DES的出现,简化了视频编辑任务,弥补了DirectShow对于媒体文件非线性编辑支持的先天性不足.但是,就技术本身而言,DES并没有超越DirectShow Filter架构,而只是DirectShow Filter的一种增强应用. 本章通过DirectX 下timelinetest为例子详细介绍Eds应用编码

(DirectX系列06)DirectShow 字符叠加Filter编码分析

(DirectX系列06)DirectShow 字符叠加Filter编码分析 在很多视频播放的软件当中,字幕的处理是免不了的,有些可能本身已经加载到图像当中未做处理,但大部分都是通过字符叠加来进行处理的.DirectShow 的字符叠加Filter在这些软件中都扮演这绝佳的作用.这一节来介绍DirectShow字符叠加Filter编码的实现,如下详细介绍: 这个Filter的大概作用是在视频流指定的一段时间内进行字符叠加,字符字体.大小.颜色都进行控制,普遍支持RGB 的各种编码格式,同时实现字

2.CCGridAction(3D效果),3D反转特效,凸透镜特效,液体特效,3D翻页特效,水波纹特效,3D晃动的特效,扭曲旋转特效,波动特效,3D波动特效

 1 类图组织 2 实例 CCSprite * spr = CCSprite::create("HelloWorld.png"); spr->setPosition(ccp(winSize.width/2,winSize.height/2)); addChild(spr);   //GridAction //CCFlipX3D * action = CCFlipX3D::create(2); //CCFlipY3D * action = CCFlipY3D::create(2

jquery实现的3D旋转木马特效代码分享_jquery

本文实例讲述了jquery实现的3D旋转木马特效.分享给大家供大家参考.具体如下: 这是一款基于jquery实现的3D旋转木马特效代码,适合用于产品展示,便于用户循环浏览产品细节,是一款非常实用的特效代码. 运行效果图:----------------------查看效果 下载源码----------------------- 小提示:浏览器中如果不能正常运行,可以尝试切换浏览模式. 为大家分享的jquery实现的3D旋转木马特效代码如下 <head> <meta http-equiv=