![]() |
#2
zklhp2009-10-05 20:03
|
原理:
利用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
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
只有本站会员才能查看附件,请 登录