📄 effect.cpp
字号:
//-----------------------------------------------------------------------------
// 名称: CreateDevice.cpp
//
// 功能: 这个文件创建了一个Direct3D对象和一个Direct3D设备,并使用一个窗口作为
// 渲染目标表面。
//
//-----------------------------------------------------------------------------
// 包含DirectMusic头文件
#include <d3d8.h>
#include <dmusicc.h>
#include <dmusici.h>
// Windows类的名称宏定义
#define MY_WINCLASS_NAME "DirectMusic"
// 定义键盘按键的宏
#define MYVK_NUM_01 0x31
#define MYVK_NUM_02 0x32
#define MYVK_NUM_03 0x33
#define MYVK_NUM_04 0x34
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000)? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000)? 0 : 1)
// 定义全局变量
IDirectMusicLoader8* g_pLoader = NULL;
IDirectMusicPerformance8* g_pPerformance = NULL;
IDirectMusicSegment8* g_pSegment = NULL;
IDirectMusicAudioPath* g_pAudioPath = NULL;
IDirectSoundBuffer8* g_pSoundBuffer = NULL;
VOID SoundPlay();
//-----------------------------------------------------------------------------
// 名称: SoundEftEcho()
// 功能: 设置声音的回音效果
// 函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEftEcho()
{
HRESULT hr;
IDirectSoundFXEcho8* pEffectDMO;
DSFXEcho FXParams;
DSEFFECTDESC FXDes;
DWORD dwRes;
ZeroMemory( &FXDes, sizeof(DSEFFECTDESC) );
FXDes.dwSize = sizeof(DSEFFECTDESC);
FXDes.dwFlags = 0;
FXDes.guidDSFXClass = GUID_DSFX_STANDARD_ECHO;
if( g_pAudioPath )
g_pAudioPath->Activate( FALSE );
if( FAILED( hr = g_pSoundBuffer->SetFX( 1, &FXDes, &dwRes ) ) )
return hr;
hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_ECHO,
0,
IID_IDirectSoundFXEcho8,
(LPVOID*) &pEffectDMO);
hr = pEffectDMO->GetAllParameters(&FXParams);
// 设置回音效果的延时为500毫秒,左右两个声道需要单独设置
FXParams. fLeftDelay = 500;
FXParams. fRightDelay= 500;
hr = pEffectDMO->SetAllParameters(&FXParams);
if( g_pAudioPath )
g_pAudioPath->Activate( TRUE );
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: SoundEftDistortion()
// 功能: 设置声音的变形效果
// 函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEftDistortion()
{
HRESULT hr;
IDirectSoundFXDistortion8* pEffectDMO;
DSFXDistortion FXParams;
DSEFFECTDESC FXDes[2];
DWORD dwRes;
ZeroMemory( FXDes, 2*sizeof(DSEFFECTDESC) );
FXDes[0].dwSize = sizeof(DSEFFECTDESC);
FXDes[0].dwFlags = 0;
FXDes[0].guidDSFXClass = GUID_DSFX_STANDARD_ECHO;
FXDes[1].dwSize = sizeof(DSEFFECTDESC);
FXDes[1].dwFlags = 0;
FXDes[1].guidDSFXClass = GUID_DSFX_STANDARD_DISTORTION;
if( g_pAudioPath )
g_pAudioPath->Activate( FALSE );
if( FAILED( hr = g_pSoundBuffer->SetFX( 2, FXDes, &dwRes ) ) )
return hr;
DSFXEcho FXParamsEcho;
IDirectSoundFXEcho8* pEffectDMOEcho;
hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_ECHO,
0,
IID_IDirectSoundFXEcho8,
(LPVOID*) &pEffectDMOEcho);
hr = pEffectDMOEcho->GetAllParameters(&FXParamsEcho);
FXParamsEcho.fWetDryMix = 0;
hr = pEffectDMOEcho->SetAllParameters(&FXParamsEcho);
hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_DISTORTION,
0,
IID_IDirectSoundFXDistortion8,
(LPVOID*) &pEffectDMO);
hr = pEffectDMO->GetAllParameters(&FXParams);
// 设置变形效果中进行增强处理的中心频率为2000Hz
// FXParams. fPostEQCenterFrequency = 2000;
// 设置变形效果中进行增强处理的频率范围,通过频率范围的宽度来决定,
// 这里指定频率宽度为500Hz
// FXParams. fPostEQBandwidth = 5000;
// 设置变形效果中过滤掉的高频部分,指定4000Hz以上的声音频率被过滤掉
// FXParams. fPreLowpassCutoff = 4000;
hr = pEffectDMO->SetAllParameters(&FXParams);
if( g_pAudioPath )
g_pAudioPath->Activate( TRUE );
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: SoundEftReverb()
// 功能: 设置声音的回音效果
// 函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEftReverb()
{
HRESULT hr;
IDirectSoundFXI3DL2Reverb8* pEffectDMO;
DSFXI3DL2Reverb FXParams;
DSEFFECTDESC FXDes[2];
DWORD dwRes;
ZeroMemory( FXDes, 2*sizeof(DSEFFECTDESC) );
FXDes[0].dwSize = sizeof(DSEFFECTDESC);
FXDes[0].dwFlags = 0;
FXDes[0].guidDSFXClass = GUID_DSFX_STANDARD_ECHO;
FXDes[1].dwSize = sizeof(DSEFFECTDESC);
FXDes[1].dwFlags = 0;
FXDes[1].guidDSFXClass = GUID_DSFX_STANDARD_I3DL2REVERB;
if( g_pAudioPath )
g_pAudioPath->Activate( FALSE );
if( FAILED( hr = g_pSoundBuffer->SetFX( 2, FXDes, &dwRes ) ) )
return hr;
DSFXEcho FXParamsEcho;
IDirectSoundFXEcho8* pEffectDMOEcho;
hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_ECHO,
0,
IID_IDirectSoundFXEcho8,
(LPVOID*) &pEffectDMOEcho);
hr = pEffectDMOEcho->GetAllParameters(&FXParamsEcho);
FXParamsEcho.fWetDryMix = 0;
hr = pEffectDMOEcho->SetAllParameters(&FXParamsEcho);
hr = g_pSoundBuffer->GetObjectInPath(GUID_DSFX_STANDARD_I3DL2REVERB,
0,
IID_IDirectSoundFXI3DL2Reverb8,
(LPVOID*) &pEffectDMO);
hr = pEffectDMO->GetAllParameters(&FXParams);
// 设置房间中声音的衰减值,单位是毫分贝
FXParams. lRoom = -500;
// 设置第一次声波反射相对于直达声波的延时时间,单位是秒
FXParams. flReflectionsDelay = 0.01f;
// 设置房间中声音早期反射相对于lRoom变量的衰减值,单位是毫分贝
FXParams. lReflections = -1000;
// 设置早期反射和晚期反射相对于第一次声波反射的延时时间,单位是秒
FXParams. flReverbDelay = 0.011f;
// 设置房间中声音晚期反射相对于lRoom变量的衰减值,单位是毫分贝
FXParams. lReverb = 100;
hr = pEffectDMO->SetAllParameters(&FXParams);
if( g_pAudioPath )
g_pAudioPath->Activate( TRUE );
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: SoundEffectOff()
// 功能: 关闭声音声音的回音效果
// 函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundEffectOff()
{
HRESULT hr;
DWORD dwRes;
if( g_pAudioPath )
g_pAudioPath->Activate( FALSE );
if( FAILED( hr = g_pSoundBuffer->SetFX( 0, NULL, &dwRes ) ) )
return hr;
if( g_pAudioPath )
g_pAudioPath->Activate( TRUE );
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: ProcInput()
// 功能: 处理外部控制设备的输入
//-----------------------------------------------------------------------------
VOID ProcInput()
{
if(KEYDOWN(MYVK_NUM_01))
{
// 设置回音效果
SoundEftEcho();
}
else if(KEYDOWN(MYVK_NUM_02))
{
// 设置变形效果
SoundEftDistortion();
}
else if(KEYDOWN(MYVK_NUM_03))
{
// 设置环境反射效果
SoundEftReverb();
}
else if(KEYDOWN(MYVK_NUM_04))
{
// 关闭所有的声音效果
SoundEffectOff();
}
if(KEYDOWN(VK_SPACE))
{
// 播放声音
SoundPlay();
}
return;
}
//-----------------------------------------------------------------------------
// 名称: SoundInit()
// 功能: 初始化声音播放环境的函数,函数中创建了DirectMusic的载入器对象和
// DirectMusic的演奏对象
// 函数返回E_FAIL表示失败,返回E_OK表示成功。
//-----------------------------------------------------------------------------
HRESULT SoundInit()
{
// 初始化COM
CoInitialize(NULL);
// 创建一个载入器对象
CoCreateInstance( CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC,
IID_IDirectMusicLoader8, (void**)&g_pLoader );
// 创建一个演奏对象
CoCreateInstance( CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC,
IID_IDirectMusicPerformance8, (void**)&g_pPerformance );
// 初始化演奏对象
g_pPerformance->InitAudio( NULL, NULL, NULL,
DMUS_APATH_DYNAMIC_STEREO, 64,
DMUS_AUDIOF_ALL, NULL );
g_pPerformance->GetDefaultAudioPath(&g_pAudioPath);
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: SoundLoad()
// 功能: 载入一个声音文件。文件为:
// \Windows安装目录\media\The Microsoft Sound.wav
//-----------------------------------------------------------------------------
HRESULT SoundLoad()
{
HRESULT hr;
TCHAR strPath[MAX_PATH];
GetCurrentDirectory( MAX_PATH, strPath );
// 下面的代码设置查找目录
WCHAR wstrSearchPath[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, strPath, -1,
wstrSearchPath, MAX_PATH );
g_pLoader->SetSearchDirectory( GUID_DirectMusicAllTypes,
wstrSearchPath,
FALSE);
// 从文件载入声音到一个声音段对象中
WCHAR wstrFileName[MAX_PATH] = L"gun.wav";
if( FAILED( g_pLoader->LoadObjectFromFile( CLSID_DirectMusicSegment,
IID_IDirectMusicSegment8,
wstrFileName,
(LPVOID*) &g_pSegment ) ) )
{
MessageBox( NULL, "Media not found, sample will now quit",
"DirectMusic Tutorial", MB_OK );
return S_FALSE;
}
if( FAILED( hr = g_pAudioPath->GetObjectInPath( DMUS_PCHANNEL_ALL,
DMUS_PATH_BUFFER, 0, GUID_NULL, 0, IID_IDirectSoundBuffer8,
(LPVOID*) &g_pSoundBuffer )))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// 名称: SoundPlay()
// 功能: 播放声音文件
//-----------------------------------------------------------------------------
VOID SoundPlay()
{
// 载入声音段到演奏中
g_pSegment->Download( g_pPerformance );
// 设置这个声音段为循环播放
g_pSegment->SetRepeats(0);
// 播放声音段
g_pPerformance->PlaySegmentEx( g_pSegment, NULL, NULL, 0,
0, NULL, NULL, g_pAudioPath );
}
//-----------------------------------------------------------------------------
// 名称: SoundClean()
// 功能: 释放所有的DirectMusic资源
//-----------------------------------------------------------------------------
VOID SoundClean()
{
// 停止声音播放,并关闭演奏
g_pPerformance->Stop( NULL, NULL, 0, 0 );
g_pPerformance->CloseDown();
// 清除载入器、演奏和声音段对象
g_pLoader->Release();
g_pPerformance->Release();
g_pSegment->Release();
// 关闭COM
CoUninitialize();
return;
}
//-----------------------------------------------------------------------------
// 名称: MsgProc()
// 功能: Windows的消息处理函数
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
ValidateRect( hWnd, NULL );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// 名称: WinMain()
// 功能: Windows主函数,程序启动时,从这里开始执行
//-----------------------------------------------------------------------------
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 定义一个Windows类,指定消息的处理函数为MsgProc
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, (struct HBRUSH__ *)GetStockObject(BLACK_BRUSH), NULL,
MY_WINCLASS_NAME, NULL };
// 注册这个窗口类
RegisterClassEx( &wc );
// 创建应用程序窗口
HWND hWnd = CreateWindow( MY_WINCLASS_NAME, "3D游戏编程——播放声音文件",
WS_OVERLAPPEDWINDOW, 100, 100, 400, 300,
GetDesktopWindow(), NULL, wc.hInstance, NULL );
// 调用SoundInit函数进行DirectMusic对象的创建
if( SUCCEEDED( SoundInit( ) ) )
{
// 显示窗口
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
// 载入声音
SoundLoad();
// 程序主循环,进行窗口消息的分发,消息的处理在MsgProc函数中完成
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
ProcInput();
}
}
// 调用SoundClean函数清除DirectMusic对象
SoundClean();
// 注销窗口类
UnregisterClass( MY_WINCLASS_NAME, wc.hInstance );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -