【VC开源代码栏目提醒】:网学会员--在 VC开源代码编辑为广大网友搜集整理了:echotool.cpp绩等信息,祝愿广大网友取得需要的信息,参考学习。
//-----------------------------------------------------------------------------
// 文件名: EchoTool.cpp
//
// 描 述: 实现一个继承自IDirectMusicTool,并提供回音效果的类
//-----------------------------------------------------------------------------
#include <dmusici.h>
#include "EchoTool.h"
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::CEchoTool()
// 描 述:
//-----------------------------------------------------------------------------
CEchoTool::CEchoTool()
{
m_cRef = 1; // 设置为1,可调用Release()释放
m_dwEchoNum = 3; // 设置缺省情况为每个音符三个回音
m_mtDelay = DMUS_PPQ / 2; // 设置缺省情况为第八音符回音
InitializeCriticalSection(&m_CrSec);
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::~CEchoTool()
// 描 述:
//-----------------------------------------------------------------------------
CEchoTool::~CEchoTool()
{
DeleteCriticalSection(&m_CrSec);
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::QueryInterface()
// 描 述:
//-----------------------------------------------------------------------------
STDMETHODIMP CEchoTool::QueryInterface(const IID &iid, void **ppv)
{
if (iid == IID_IUnknown || iid == IID_IDirectMusicTool)
{
*ppv = static_cast<IDirectMusicTool*>(this);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(this)->AddRef();
return S_OK;
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::AddRef()
// 描 述:
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEchoTool::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::Release()
// 描 述:
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEchoTool::Release()
{
if( 0 == InterlockedDecrement(&m_cRef) )
{
delete this;
return 0;
}
return m_cRef;
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::Init()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CEchoTool::Init( IDirectMusicGraph* pGraph )
{
// 本工具不需要任何初始化
return E_NOTIMPL;
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::GetMsgDeliveryType()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CEchoTool::GetMsgDeliveryType( DWORD* pdwDeliveryType )
{
// 本工具需要立即消息,这是缺省的,因此返回E_NOTIMPL即可。
// 另一种方法是设置*pdwDeliveryType传输类型,如DMUS_PMSGF_TOOL_IMMEDIATE,
// DMUS_PMSGF_TOOL_QUEUE, 或DMUS_PMSGF_TOOL_ATTIME.
*pdwDeliveryType = DMUS_PMSGF_TOOL_IMMEDIATE;
return S_OK;
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::GetMediaTypeArraySize()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CEchoTool::GetMediaTypeArraySize( DWORD* pdwNumElements )
{
// 这个工具只需要note、patch、sysex和MIDI四种消息,
// 所以*pdwNumElements为4.
*pdwNumElements = 4;
return S_OK;
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::GetMediaTypes()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CEchoTool::GetMediaTypes( DWORD** padwMediaTypes,
DWORD dwNumElements )
{
// 用本工具想要处理的消息的类型来填充padwMediaTypes数组。
// 本例中dwNumElements将为3, 因为该数据是从GetMediaTypeArraySize()返回的。
if( dwNumElements == 4 )
{
// 设置数组的元素为DMUS_PMSGT_NOTE,
// DMUS_PMSGT_MIDI, and DMUS_PMSGT_PATCH
(*padwMediaTypes)[0] = DMUS_PMSGT_NOTE;
(*padwMediaTypes)[1] = DMUS_PMSGT_MIDI;
(*padwMediaTypes)[2] = DMUS_PMSGT_PATCH;
(*padwMediaTypes)[3] = DMUS_PMSGT_SYSEX;
return S_OK;
}
else
{
// 这应该不会发生
return E_FAIL;
}
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::ProcessPMsg()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CEchoTool::ProcessPMsg( IDirectMusicPerformance* pPerf,
DMUS_PMSG* pPMsg )
{
DWORD dwCount;
DWORD dwEchoNum;
MUSIC_TIME mtDelay;
// SetEchoNum()和SetDelay()使用这些成员变量,
// 因此使用关键的段使得线程安全。
EnterCriticalSection(&m_CrSec);
dwEchoNum = m_dwEchoNum;
mtDelay = m_mtDelay;
LeaveCriticalSection(&m_CrSec);
// 返回S_FREE释放消息. 如果StampPMsg()失败,没有此消息的目的地,因此释放它
if(( NULL == pPMsg->pGraph ) ||
FAILED(pPMsg->pGraph->StampPMsg(pPMsg)))
{
return DMUS_S_FREE;
}
IDirectMusicPerformance8 *pPerf8;
if (SUCCEEDED(pPerf->QueryInterface(IID_IDirectMusicPerformance8,(void **)&pPerf8)))
{
for( dwCount = 1; dwCount <= dwEchoNum; dwCount++ )
{
DMUS_PMSG *pClone;
if( SUCCEEDED( pPerf8->ClonePMsg( pPMsg,&pClone)))
{
// 增加回音音符的次数
pClone->mtTime += (dwCount * mtDelay);
if (pPMsg->dwType == DMUS_PMSGT_NOTE )
{
DMUS_NOTE_PMSG *pNote = (DMUS_NOTE_PMSG*)pPMsg;
DMUS_NOTE_PMSG *pCloneNote = (DMUS_NOTE_PMSG*)pClone;
pCloneNote->bVelocity = (BYTE) (pNote->bVelocity -
((pNote->bVelocity * (dwCount * 15))/100));
}
// 设置音符,因此仅仅MUSIC_TIME是有效的.
// REFERENCE_TIME将在SendPMsg()中重新计算
pClone->dwFlags = DMUS_PMSGF_MUSICTIME;
pClone->dwPChannel = pPMsg->dwPChannel +
(16*dwCount);
// 排队等待回音的PMsg
pPerf->SendPMsg(pClone );
}
}
pPerf8->Release();
}
//返回DMUS_S_REQUEUE,因此原始消息被重新排列
return DMUS_S_REQUEUE;
}
//-----------------------------------------------------------------------------
// 函数名: CEchoTool::Flush()
// 描 述:
//-----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CEchoTool::Flush( IDirectMusicPerformance* pPerf,
DMUS_PMSG* pDMUS_PMSG,
REFERENCE_TIME rt)
{
// 本工具不需要流
return E_NOTIMPL;
}
//-----------------------------------------------------------------------------
// 函数名: C
上一篇:
DetailsU.pas
下一篇:
雍志祥_基于Ajax的BBS网站_论文正文