注册 登录
编程论坛 汇编论坛

MIDI播放库 v1.0

东海一鱼 发布于 2009-10-05 14:55, 1795 次点击
十一闲来无事之作。

原理:
    利用DrictMuisc系统COM接口播放MIDI (游戏制作里面常用到,不过我刚学win32asm,用asm使用COM还是头一遭。哈哈)

工具:
    FASM(MASM32的‘宏’太拉杂,不清爽。顾直接用FASM搞定)。

演示制作:
    MASM32(这个最多人使用,哈哈)。

程序代码:
format MS COFF
  
include 'win32a.inc'
include 'Music.inc'

extrn  '__imp__RtlZeroMemory@8'      as RtlZeroMemory:DWORD
extrn  '__imp__CoInitialize@4'       as CoInitialize:DWORD
extrn  '__imp__CoUninitialize@0'     as CoUninitialize:DWORD
extrn  '__imp__CoCreateInstance@20'  as CoCreateInstance:DWORD
     
  

section '.data' data readable writeable
    CLSID_DirectMusicPerformance    GUID    d2ac2881-b39b-11d1-8704-00600893b1bd
    CLSID_IDirectMusicSegment       GUID    d2ac2882-b39b-11d1-8704-00600893b1bd
    CLSID_DirectMusicLoader            GUID    D2AC2892-B39B-11D1-8704-00600893B1BD   
   
    IID_IDirectMusic                GUID    6536115a-7b2d-11d2-ba18-0000f875ac12
    IID_IDirectMusic8               GUID    2d3629f7-813d-4939-8508-f05c6b75fd97
    IID_IDirectMusicLoader8         GUID    19e7c08c-0a44-4e6a-a116-595a7cd5de8c   
    IID_IDirectMusicSegment8        GUID    c6784488-41a3-418f-aa15-b35093ba42d4   
    IID_IDirectMusicPerformance8    GUID    679c4137-c62e-4147-b2b4-9d569acb254c
    IID_IDirectMusicPort8           GUID    08f2d8c9-37c2-11d2-b9f9-0000f875ac12
    IID_IDirectMusicSegmentState    GUID    a3afdcc7-d3ee-11d1-bc8d-00a0c922e6eb
    IID_IDirectMusicSegmentState8   GUID    a50e4730-0ae4-48a7-9839-bc04bfe07772
    IID_IDirectSound3DBuffer8       GUID    279AFA86-4981-11CE-A521-0020AF0BE560
    IID_IDirectMusicAudioPath8      GUID    c87631f5-23be-4986-8836-05832fcc48f9

    GUID_StandardMIDIFile            GUID    06621075-e92e-11d1-a8c5-00c04fa3726e
    GUID_Download                    GUID    d2ac28a7-b39b-11d1-8704-00600893b1bd
    GUID_Unload                     GUID    d2ac28a8-b39b-11d1-8704-00600893b1bd
    GUID_NULL                       GUID    00000000-0000-0000-0000-000000000000   
        
    pmusic          IDirectMusic
    pmusic8         IDirectMusic8      
    performance     IDirectMusicPerformance8
    psegment        IDirectMusicSegment8
    ploader         IDirectMusicLoader8
    pport           IDirectMusicPort8
    pstate          IDirectMusicSegmentState
    pstate8         IDirectMusicSegmentState8
    p3dbuf          IDirectSound3DBuffer8
    p3dpath         IDirectMusicAudioPath8   
   
section '.code' code readable executable
  
    public MIDI_init    as '_MIDI_init@0'
    public MIDI_play    as '_MIDI_play@0'
    public MIDI_stop    as '_MIDI_stop@0'
    public MIDI_uninit  as '_MIDI_uninit@0'
    public MIDI_load    as '_MIDI_load@8'
   
proc MIDI_init
   
    invoke    CoInitialize,NULL
   
    invoke  CoCreateInstance,CLSID_DirectMusicLoader,0,\
        CLSCTX_INPROC_SERVER or CLSCTX_INPROC_HANDLER,IID_IDirectMusicLoader8,ploader
    cmp eax,0
    jnz @F
        
    invoke    CoCreateInstance,CLSID_DirectMusicPerformance,\
        NULL,CLSCTX_INPROC_SERVER or CLSCTX_INPROC_HANDLER,IID_IDirectMusicPerformance8,performance
    cmp eax,0
    jnz @F
   
    cominvk performance,InitAudio,pmusic,NULL,NULL,DMUS_APATH_DYNAMIC_STEREO,\
        64,DMUS_AUDIOF_ALL,NULL
    cmp eax,0
    jnz @F
   
    cominvk performance,CreateStandardAudioPath,DMUS_APATH_DYNAMIC_3D,\
        64,TRUE,p3dpath
    cmp eax,0
    jnz @F
   
    cominvk p3dpath,GetObjectInPath,DMUS_PCHANNEL_ALL,DMUS_PATH_BUFFER,0,\
        GUID_NULL,0,IID_IDirectSound3DBuffer8,p3dbuf
    cmp eax,0
    jnz @F
   
    cominvk pmusic,QueryInterface,IID_IDirectMusic8,pmusic8   
@@:        
    ret

endp

proc SelectPort
    push ebx esi
    locals
      portsec:  DMUS_PORTCAPS
      portparm: DMUS_PORTPARAMS
    endl
   
    lea ebx,[portsec]
    invoke RtlZeroMemory,ebx,sizeof.DMUS_PORTCAPS
    mov [ebx + DMUS_PORTCAPS.dwSize],sizeof.DMUS_PORTCAPS
        
    cominvk pmusic8,EnumPort,2,ebx
   
    lea esi,[portparm]
    invoke RtlZeroMemory,esi,sizeof.DMUS_PORTPARAMS
    mov [esi + DMUS_PORTPARAMS.dwSize],sizeof.DMUS_PORTPARAMS
    mov [esi + DMUS_PORTPARAMS.dwValidParams],DMUS_PORTPARAMS_CHANNELGROUPS
    mov [esi + DMUS_PORTPARAMS.dwChannelGroups],1
   
    test [ebx + DMUS_PORTCAPS.dwFlags],DMUS_PC_AUDIOPATH
    jz @F
   
    mov [esi + DMUS_PORTPARAMS.dwFeatures],DMUS_PORT_FEATURE_AUDIOPATH
@@:   
    lea ecx,[ebx + DMUS_PORTCAPS.guidPort]
    cominvk pmusic8,CreatePort,ecx,esi,pport,NULL
    cmp eax,0
    jnz @F
   
    cominvk pport,Activate,TRUE        
   
@@:
    pop esi ebx
    ret

endp

proc MIDI_load lpData,DataSize
    locals   
      lpMidi: dd ?
      desc: DMUS_OBJECTDESC      
    endl
   
    push ebx esi edi   
   
    lea ebx,[desc]
    invoke RtlZeroMemory,ebx,sizeof.DMUS_OBJECTDESC   
      
    mov [ebx + DMUS_OBJECTDESC.dwSize],sizeof.DMUS_OBJECTDESC
   
    lea edi,[ebx + DMUS_OBJECTDESC.guidClass]      
    mov esi,CLSID_IDirectMusicSegment
    mov ecx,sizeof.stGuid   
    rep movsb   
   
    mov eax,[lpData]
    mov [ebx + DMUS_OBJECTDESC.pbMemData],eax
    mov eax,[DataSize]
    mov [ebx + DMUS_OBJECTDESC.llMemLengthLow],eax
    mov [ebx + DMUS_OBJECTDESC.dwValidData],DMUS_OBJ_CLASS + DMUS_OBJ_MEMORY
   
    call SelectPort   
   
    cominvk ploader,GetObject,ebx,IID_IDirectMusicSegment8,psegment
    cmp eax,0
    jnz @F
   
    cominvk psegment,SetParam,GUID_StandardMIDIFile,-1,0,0,NULL
    cmp eax,0
    jnz @F
   
    cominvk psegment,Download,[performance]
    sub eax,eax
@@:   
    pop edi esi ebx
   
    ret

endp

proc MIDI_play

    cominvk psegment,SetRepeats,DMUS_SEG_REPEAT_INFINITE
    cominvk performance,PlaySegmentEx,[psegment],NULL,NULL,0,0,0,pstate,NULL,[p3dpath]        
    ret

endp

proc MIDI_stop
   
     cominvk psegment,SetStartPoint,0
     cominvk performance,Stop,NULL,NULL,0,0
     ret

endp

proc MIDI_uninit
   
    cmp [ploader],0
    jz @F   
        cominvk ploader,ReleaseObjectByUnknown,[psegment]
        cominvk ploader,Release
        mov [ploader],NULL   
@@:
    cmp [pstate],0
    jz @F
        cominvk pstate,Release
        mov [pstate],NULL   
@@:
    cmp [pstate8],0
    jz @F
        cominvk pstate8,Release
        mov [pstate8],NULL   
@@:
    cmp [p3dpath],0
    jz @F
        cominvk p3dpath,Release
        mov [p3dpath],NULL   
@@:
    cmp [p3dbuf],0
    jz @F
        cominvk p3dbuf,Release
        mov [p3dbuf],NULL   
@@:
    cmp [psegment],0
    jz @F
        cominvk psegment,Release
        mov [psegment],NULL   
@@:
    cmp [pmusic],0
    jz @F
        cominvk pmusic,Release
        mov [pmusic],NULL   
@@:
    cmp [pmusic8],0
    jz @F
        cominvk pmusic8,Release
        mov [pmusic8],NULL   
@@:   
   
    cmp [performance],0
    jz @F   
        cominvk performance,RemovePort,[pport]
        cominvk performance,CloseDown   
@@:   
    cmp [pport],0
    jz @F
        cominvk pport,Release
        mov [pport],NULL   
@@:   
   
    invoke CoUninitialize
   
    ret

endp



只有本站会员才能查看附件,请 登录
6 回复
#2
zklhp2009-10-05 20:03
学习了~~~~~~~
#3
东海一鱼2009-10-05 21:43
刚试了与VC链接,很顺利啊。哈哈。但比用VC实现的库小好多,只有3k

下面是C的调用头文件:

程序代码:
#ifndef __PLAYMIDILIB_H__
#define __PLAYMIDILIB_H__
 
#include <windows.h>
 
#pragma comment(lib,"ole32.lib")
 
#ifdef __cplusplus
extern "C"
{
#endif
 
    HRESULT  __stdcall MIDI_init();
    HRESULT  __stdcall MIDI_load(BYTE* pMidiData,UINT MidiDataSize);
    HRESULT  __stdcall MIDI_play();
    HRESULT  __stdcall MIDI_stop();
    HRESULT  __stdcall MIDI_uninit();
 
#ifdef __cplusplus
}
#endif
 
#endif

以后写keygen要方便了。

[ 本帖最后由 东海一鱼 于 2009-10-5 21:48 编辑 ]
#4
onepc2009-10-06 11:49
深奥~~~~~


         努力ing
#5
Franziska2009-10-11 22:34
看来是为我写的。。。
#6
阿贝2009-10-23 22:52
我还得好好学啊
#7
阿贝2009-10-23 22:53
这就是距离啊
1