MIDI播放库 v1.0
十一闲来无事之作。原理:
利用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
MidiLib&Demo.rar
(19.61 KB)