|
|

楼主 |
发表于 2005-5-12 22:18:00
|
显示全部楼层
Re:为?Y么??d??IMIDI????D??amp;#39057;??s对&am
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************************************************************************************************//
//* 功能 : 初始化DirectMusic库中用到的接口 *//
//* 处历耘要 : 1.初始化COM接口 *//
//* 2.建立DMusic: erformance对象接口,并初始化Performance接口,并配置其输出端口(默认微鳃?E羝鳎? *//
//* 3.建立DMusic: oader对象接口 *//
//* 4.初始化dm_active_id全局变量,music_fx全局数组变量 *//
//* 函数原形 : int DMusic_Init(void); *//
//* 参数说?E: 无 *//
//* 返回值 : 成功: 1 *//
//* 失败: 0 *//
//* 作者 : 于策 *//
//* 创建时?E: 2005?E月11日 *//
//* ?煮修改时间: 2005?E月11日 *//
//***************************************************************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int DMusic_Init(void)
{
//如果初始化COM失败,则返回失败
if(FAILED(CoInitialize(NULL)))
return(0); //返回失败
//初始化CLSADO,CoCreateInstance()的第一个参数是对象的CLSID(类代?E??飧?E28位的编?Eㄒ坏乇?E读俗榧??瘢?
//?E穆肪逗驮诵胁问?刃畔⒍挤旁谙低匙⒉岜?校坏诙?霾问?话闱榭鱿律栉?ULL;第三个参数用来指明对象的运行环境,?E
//远程或本地,此处设为CLSCTX_INPROC_SERVER,?E魇欠?褡榧?且桓?LL;第四个参数指明用来?E韵笸ㄐ沤涌诘?D,这也是
//一?E28位的编?E坏谖甯霾问?怯美唇邮斩韵蟮慕涌谥刚?E?
//如果创建DirectMusicPerformance接口失败,则返回失败
if(FAILED(CoCreateInstance(CLSID_DirectMusicPerformance,NULL,CLSCTX_INPROC,IID_IDirectMusicPerformance,(void **)&lpdmperf)))
return(0); //返回失败
//如果初始化DirectMusicPerformance接口失败,则返回失败
if(FAILED(lpdmperf->Init(NULL,lpds,main_window_hwnd)))
return(0); //返回失败
//如果指定DirectMusic声音的输出方向失败,则返回失败
if(FAILED(lpdmperf->AddPort(NULL)))
return(0); //返回失败
//如果创建DirectMusicLoader接口失败,则返回失败
if(FAILED(CoCreateInstance(CLSID_DirectMusicLoader,NULL,CLSCTX_INPROC,IID_IDirectMusicLoader,(void **)&lpdmloader)))
return(0); //返回失败
dm_active_id = -1; //重置全局变量
//初始化自定义段
for(int index = 0;index < MAX_MUSICS;index++)
{
music_fx[index].dm_segment = NULL; //初始化dm_segment成员
music_fx[index].dm_segmentstate = NULL; //初始化dm_segmentstate成员
music_fx[index].id = index; //初始化id成员
music_fx[index].state = MUSIC_NULL; //初始化state成员
}
return(1); //返回成功
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************************************************************************************************//
//* 功能 : 载?EIDI音乐文件 *//
//* 处历耘要 : 1.查找可用的段ID *//
//* 2.获取路径名为当前路径名,并将路径名和文件名转换为窥笾符,并设置DirectMusic::Loader的载?E肪? *//
//* 3.帖箱DMUS_OBJECTDESC结构,以建立DirectMusic::Segment对象,并确认是否为?E?IDI文件,并载?E枚文谌? *//
//* 4.重置music_fx全局数组变量的相关成员 *//
//* 函数原形 : int DMusic_Load_MIDI(char * filename); *//
//* 参数说?E: 1.char * filename: 文件?E *//
//* 返回值 : 成功: 对应全局段对象(music_fx)的索引 *//
//* 失败: -1 *//
//* 作者 : 于策 *//
//* 创建时?E: 2005?E月11日 *//
//* ?煮修改时间: 2005?E月11日 *//
//***************************************************************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int DMusic_Load_MIDI(char * filename)
{
DMUS_OBJECTDESC objdesc; //DMusic::Segment段的描述结构
IDirectMusicSegment * psegment = NULL; //临时DMusic::Segment接口指?E?娣旁厝?E?
char szDir[_MAX_PATH]; //文件路径名的普通字符形式
WCHAR wszDir[_MAX_PATH], //文件路径名的窥笾符形式
wfilename[_MAX_PATH]; //文件名的窥笾符形式
int id; //当前操作段对应全局段对象(music_fx)的索引
//查找可用的段
id = -1; //初始化id为无效索引号
//遍历全局段对象(music_fx)
for(int index = 0;index < MAX_MUSICS;index++)
{
//如果存在当前未使用的段,则不再查找
if(MUSIC_NULL == music_fx[index].id)
{
id = index; //设置当前操作的全局段对象(music_fx)的索引
break;
}
}
//如果没找到可用全局段对象(music_fx),则返回失败
if(-1 == id)
return(-1); //返回失败
//如果没有找到当前路径,则返回失败
if(NULL == _getcwd(szDir,_MAX_PATH))
return(-1); //返回失败
MULTI_TO_WIDE(wszDir,szDir); //将获取到的路径转换为窥笾符形式
//设置DMusic::loader对象的搜索路径
if(FAILED(lpdmloader->SetSearchDirectory(GUID_DirectMusicAllTypes,wszDir,FALSE)))
return(-1); //返回失败
MULTI_TO_WIDE(wfilename,filename); //将文件名转换为窥笾符形式
memset((void *)&objdesc,0,sizeof(DMUS_OBJECTDESC)); //开辟DMUS_OBJECTDESC结构内存空?E
objdesc.dwSize = sizeof(DMUS_OBJECTDESC); //设置结构体dwSize成员
objdesc.guidClass = CLSID_DirectMusicSegment; //设置结构体guidClass成员
wcscpy(objdesc.wszFileName,wfilename); //设置结构体wszFileName成员
objdesc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME; //设置结构体dwValidData成员
//如果创建DMusic::Segment对象失败,则返回失败
if(FAILED(lpdmloader->GetObject(&objdesc,IID_IDirectMusicSegment,(void **)&psegment)))
return(-1); //返回失败
//如果?E槲募?О埽?蚍祷厥О?
if(FAILED(psegment->SetParam(GUID_StandardMIDIFile,-1,0,0,(void *)&lpdmperf)))
return(-1); //返回失败
//如果加载Segment内容失败,则返回失败
if(FAILED(psegment->SetParam(GUID_Download,-1,0,0,(void *)lpdmperf)))
return(-1); //返回失败
music_fx[id].dm_segment = psegment; //重置全局段对象(music_fx)的dm_segment成员
music_fx[id].id = id; //重置全局段对象(music_fx)的id成员
music_fx[id].state = MUSIC_LOADED; //重置全局段对象(music_fx)的state成员
return(id); //返回对应全局段对象(music_fx)的索引
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************************************************************************************************//
//* 功能 : 以指定播放次数播放指定段的内容 *//
//* 处历耘要 : 1.设置重复播放次数 *//
//* 2.播放段 *//
//* 3.设置全局段对象(music_fx)对应的成员及全局变量dm_active_id *//
//* 函数原形 : int DMusic_Play(int id,int flag); *//
//* 参数说?E: 1.id: 对应全局段对象(music_fx)的索引 *//
//* 返回值 : 成功: 1 *//
//* 失败: 0 *//
//* 作者 : 于策 *//
//* 创建时?E: 2005?E月12日 *//
//* ?煮修改时间: 2005?E月12日 *//
//***************************************************************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int DMusic_Play(int id,int flag)
{
//如果lpdmperf对象不存在则返回失败
if(lpdmperf)
{
music_fx[id].dm_segment->SetRepeats(flag); //设置重复次数
//如果播放段失败,则返回失败
if(FAILED(lpdmperf-> laySegment(music_fx[id].dm_segment,DMUS_SEGF_REFTIME,0,&music_fx[id].dm_segmentstate)))
return(0); //返回失败
music_fx[id].state = MUSIC_PLAYING; //设置全局段对象(music_fx)对应的成员
dm_active_id = -1; //设置全局激畸琪引
}
return(1); //返回成功
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************************************************************************************************//
//* 功能 : 停止播放指定段 *//
//* 处历耘要 : 1.停止播放指定段 *//
//* 2.设置全局段对象(music_fx)对应的成员及全局变量dm_active_id *//
//* 函数原形 : int DMusic_Stop_Music(int id); *//
//* 参数说?E: 1.id: 对应全局段对象(music_fx)的索引 *//
//* 返回值 : 成功: 1 *//
//* 失败: 0 *//
//* 作者 : 于策 *//
//* 创建时?E: 2005?E月11日 *//
//* ?煮修改时间: 2005?E月11日 *//
//***************************************************************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int DMusic_Stop_Music(int id)
{
//如果全局段对象(music_fx)的dm_segment成员存在切没有被使用,则试图停止段的播放
if(music_fx[id].dm_segment && music_fx[id].state != MUSIC_NULL)
{
//停止播放段内容
if(FAILED(lpdmperf->Stop(music_fx[id].dm_segment,NULL,0,0)))
return(0); //返回失败
music_fx[id].state = MUSIC_STOPPED; //设置全局段对象(music_fx)对应的成员
dm_active_id = -1; //设置全局激畸琪引
return(1); //返回成功
}
else
{
return(0); //返回失败
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************************************************************************************************//
//* 功能 : 删除某个全局段对象(music_fx) *//
//* 处历耘要 : 1.停止播放段,并卸载段内的内容 *//
//* 2.删除段对象和段状态对?E *//
//* 函数原形 : int DMusic_Delete_Music(int id); *//
//* 参数说?E: 1.id: 对应全局段对象(music_fx)的索引 *//
//* 返回值 : 成功: 1 *//
//* 失败: 0 *//
//* 作者 : 于策 *//
//* 创建时?E: 2005?E月11日 *//
//* ?煮修改时间: 2005?E月11日 *//
//***************************************************************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int DMusic_Delete_Music(int id)
{
//如果?E獯??E问?缓戏ǎㄒ蛭?渌???祷刂涤锌赡芪?1),则返回失败
if(-1 == id)
return(0);
//如果全局段对象(music_fx)的dm_segment成员存在,则停止,卸载并释放Segment接口
if(music_fx[id].dm_segment)
{
DMusic_Stop_Music(id); //尝试停止音乐,如果停止没有成功,则继续释放?EΧ韵螅?胁挥跋?E祷刂?
//如果卸载段失败,则返回失败
if(FAILED(music_fx[id].dm_segment->SetParam(GUID_Unload,-1,0,0,lpdmperf)))
return(0); //返回失败
//如果释放Segment接口失败,则返回失败
if(FAILED(music_fx[id].dm_segment->Release()))
return(0); //返回失败
music_fx[id].dm_segment = NULL; //置空指?E
//如果全局段对象(music_fx)的dm_segmentstate成员存在,则停止,卸载并释放SegmentState接口
if(music_fx[id].dm_segmentstate)
{
//如果释放SegmentState接口失败,则返回失败
if(FAILED(music_fx[id].dm_segmentstate->Release()))
return(0); //返回失败
}
music_fx[id].state = NULL; //置空指?E
}
else
{
//如果全局段对象(music_fx)的dm_segmentstate成员存在,则停止,卸载并释放SegmentState接口
if(music_fx[id].dm_segmentstate)
{
//如果释放SegmentState接口失败,则返回失败
if(FAILED(music_fx[id].dm_segmentstate->Release()))
return(0); //返回失败
}
music_fx[id].state = NULL; //置空指?E
}
return(1); //返回成功
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************************************************************************************************//
//* 功能 : 删除全局段对象(music_fx) *//
//* 处历耘要 : 设置全局段对象(music_fx)的索引 *//
//* 函数原形 : int DMusic_Delete_ALL_Music(void); *//
//* 参数说?E: 无 *//
//* 返回值 : 成功: 1 *//
//* 失败: 0 *//
//* 作者 : 于策 *//
//* 创建时?E: 2005?E月11日 *//
//* ?煮修改时间: 2005?E月11日 *//
//***************************************************************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int DMusic_Delete_ALL_Music(void)
{
int success_flag = 1; //存放返回状态
//遍历并删除全局段对象(music_fx)
for(int index =0;index < MAX_MUSICS;index++)
{
if(!DMusic_Delete_Music(index)) //删除全局段对象(music_fx)
success_flag = 0; //设置返回?E疚?О?
}
return(success_flag); //返回
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***************************************************************************************************************************************************//
//* 功能 : 关闭并释放DMusic_Init()函数中创建的所有接口 *//
//* 处历耘要 : 关闭并释放DMusic_Init()函数中创建的所有接口 *//
//* 函数原形 : int DMusic_Shutdown(void); *//
//* 参数说?E: 无 *//
//* 返回值 : 成功: 1 *//
//* 失败: 0 *//
//* 作者 : 于策 *//
//* 创建时?E: 2005?E月11日 *//
//* ?煮修改时间: 2005?E月11日 *//
//***************************************************************************************************************************************************//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int DMusic_Shutdown(void)
{
int success_flag = 1; //存放返回状态
//如果删除全局段对象(music_fx),则设置播放?E疚?О?
if(!DMusic_Delete_ALL_Music())
success_flag = 0; //设置播放?E疚?О?
//如果存在lpdmperf对象,则关闭并释放接口
if(lpdmperf)
{
lpdmperf->CloseDown(); //关闭接口功能
lpdmperf->Release(); //释放接口
}
//如果存在lpdmloader对象,则并释放接口
if(lpdmloader)
{
lpdmloader->Release(); //释放接口
}
CoUninitialize(); //释放COM
return(success_flag); //返回
} |
|