游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3576|回复: 8

为什么我播放的MIDI文件好象频率不对啊?

[复制链接]

13

主题

25

帖子

27

积分

注册会员

Rank: 2

积分
27
发表于 2005-5-11 21:53:00 | 显示全部楼层 |阅读模式
慢腾腾的,是不是加载的时候要获取文件频率什么的我没做?

132

主题

1341

帖子

1341

积分

金牌会员

Rank: 6Rank: 6

积分
1341
发表于 2005-5-11 21:55:00 | 显示全部楼层

Re:为什么我播放的MIDI文件好象频率不对啊?

DMUSIC or DSOUND?

13

主题

25

帖子

27

积分

注册会员

Rank: 2

积分
27
 楼主| 发表于 2005-5-11 22:07:00 | 显示全部楼层

Re:为什么我播放的MIDI文件好象频率不对啊?

哦,补充一下,是和windows media 比有些不对劲儿,请问这是不是由于经过了DLS处理造成的?
还是我程序压根儿写的有问题?

10

主题

525

帖子

525

积分

高级会员

Rank: 4

积分
525
发表于 2005-5-12 10:46:00 | 显示全部楼层

Re:为什么我播放的MIDI文件好象频率不对啊?

去网上搜搜别人的程序呀

9

主题

106

帖子

106

积分

注册会员

Rank: 2

积分
106
QQ
发表于 2005-5-12 16:26:00 | 显示全部楼层

Re:为什么我播放的MIDI文件好象频率不对啊?

  MIDI还是用DMusic来处理好了……

13

主题

25

帖子

27

积分

注册会员

Rank: 2

积分
27
 楼主| 发表于 2005-5-12 16:39:00 | 显示全部楼层

Re:为什么我播放的MIDI文件好象频率不对啊?

是用DMusic啊,和media播放出来的声音不一样.为什么啊?

132

主题

1341

帖子

1341

积分

金牌会员

Rank: 6Rank: 6

积分
1341
发表于 2005-5-12 18:09:00 | 显示全部楼层

Re:为什么我播放的MIDI文件好象频率不对啊?

放代码

13

主题

25

帖子

27

积分

注册会员

Rank: 2

积分
27
 楼主| 发表于 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-&gtlaySegment(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);                                                                                        //返回
}

9

主题

106

帖子

106

积分

注册会员

Rank: 2

积分
106
QQ
发表于 2005-5-13 08:17:00 | 显示全部楼层

Re:为什么我播放的MIDI文件好象频率不对啊?

  呵呵,C不是很懂……可能是端口的问题?在不同的声卡上各端口表现的效果不同,请使用Microsoft GS Wavetable SW Synth端口,不要随便使用默认端口。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-25 15:18

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表