www.pudn.com > XmudOSr.rar > Midi.cpp
#include "stdafx.h"
#include "XMudClient.h"
#include "midi.h"
#include "MyMusic.h"
BOOL bSelectDefault=FALSE;
extern BOOL g_bSoundPaused;
char g_sFileName[MAX_PATH];
extern rmfullglobals myglobs;
extern void SaveConfigFile(void);
BOOL PlayMidi(char *sFileName)
{
strcpy(g_sFileName,sFileName);
return PlayDirectMusic(sFileName);
}
BOOL PauseMidi()
{
g_bSoundPaused=TRUE;
SaveConfigFile();
return PauseDirectMusic();
}
BOOL ResumeMidi()
{
g_bSoundPaused=FALSE;
SaveConfigFile();
return ResumeDirectMusic();
}
BOOL StopMidi()
{
return StopDirectMusic();
}
BOOL ReplayMidi()
{
return TRUE;
}
#include
#include
#include
BOOL bInitMusicFlag=FALSE;
IDirectMusic* lpMusic=NULL;
IDirectMusicPort *lpPort=NULL;
IDirectMusicPerformance* lpPerf=NULL;
IDirectMusicLoader* lpLoader=NULL;
IDirectMusicCollection* lpCollection=NULL;
IDirectMusicSegment* lpMIDISeg=NULL;
IDirectMusicSegmentState* lpSegState=NULL;
DMUS_PORTCAPS *lpSelectPort=NULL,*lpPreferPort=NULL,*lpDefaultPort=NULL;
MUSIC_TIME mtStart=0;
MUSIC_TIME mtOffset=0;
REFERENCE_TIME rtStart=0;
REFERENCE_TIME rtOffset=0;
HRESULT SwitchDirectMusicPort(DMUS_PORTCAPS *lpChoicePort)
{
DWORD LastTickCount;
DMUS_PORTPARAMS portParams;
bInitMusicFlag=FALSE;
if(lpPerf)
{
if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
{
RegError("Performance stop Error !");
}
}
LastTickCount=timeGetTime();
// while(timeGetTime()-LastTickCount<100) { }
Sleep(100);
if(lpMIDISeg)
{
if(FAILED(lpMIDISeg->SetStartPoint(0)))
{
RegError("Segment set start point Error !");
}
if(FAILED(lpMIDISeg->SetParam(GUID_Unload,-1,0,0,(void*)lpPerf)))
{
RegError("Segment set parameter Error !");
}
lpMIDISeg->Release();
lpMIDISeg=NULL;
if(lpSegState)
{
lpSegState->Release();
lpSegState=NULL;
}
}
if(lpPort)
{
if(FAILED(lpPort->Activate(FALSE)))
{
RegError("Port deactivate Error !");
}
if(FAILED(lpPerf->RemovePort(lpPort)))
{
RegError("Remove port Error !");
}
lpPort->Release();
lpPort=NULL;
}
ZeroMemory(&portParams, sizeof(portParams));
portParams.dwSize=sizeof(portParams);
portParams.dwEffectFlags=DMUS_EFFECT_REVERB;
portParams.dwChannelGroups=1;
portParams.dwValidParams=DMUS_PORTPARAMS_CHANNELGROUPS|DMUS_PORTPARAMS_EFFECTS;
if(!lpMusic||FAILED(lpMusic->CreatePort((REFGUID)lpChoicePort->guidPort,&portParams,&lpPort,NULL)))
{
RegError("Port create Error !");
QuitDirectMusic();
return FALSE;
}
if(FAILED(lpPort->Activate(TRUE)))
{
RegError("Port activate Error !");
QuitDirectMusic();
return FALSE;
}
if(FAILED(lpPerf->AddPort(lpPort)))
{
RegError("Port add Error !");
QuitDirectMusic();
return FALSE;
}
if(FAILED(lpPerf->AssignPChannelBlock(0,lpPort,1)))
{
RegError("PChannel assign Error !");
QuitDirectMusic();
return FALSE;
}
bInitMusicFlag=TRUE;
return TRUE;
}
HRESULT SwitchMusicPort(void)
{
if(lpSelectPort==lpPreferPort) { lpSelectPort=lpDefaultPort; return SwitchDirectMusicPort(lpSelectPort); }
else { lpSelectPort=lpPreferPort; return SwitchDirectMusicPort(lpSelectPort); }
}
HRESULT LoadCollectionByName(IDirectMusicLoader *lpILoader,char *pszFileName,IDirectMusicCollection **lppICollection)
{
HRESULT hr;
DMUS_OBJECTDESC Desc;
mbstowcs(Desc.wszFileName,pszFileName,DMUS_MAX_FILENAME);
Desc.dwSize=sizeof(DMUS_OBJECTDESC);
Desc.guidClass=CLSID_DirectMusicCollection;
Desc.dwValidData=DMUS_OBJ_CLASS|DMUS_OBJ_FILENAME|DMUS_OBJ_FULLPATH;
hr=lpILoader->GetObject(&Desc,IID_IDirectMusicCollection,(void **)lppICollection);
return hr;
}
HRESULT InitDirectMusic(HWND hwnd,LPDIRECTSOUND lpDS)
{
bInitMusicFlag=FALSE;
if(FAILED(CoInitialize(NULL))) return FALSE;
if(FAILED(CoCreateInstance(
CLSID_DirectMusicPerformance,
NULL,
CLSCTX_INPROC,
IID_IDirectMusicPerformance2,
(void**)&lpPerf
)))
{
RegError("Create Instance Error !");
return FALSE;
}
if(!lpPerf||FAILED(lpPerf->Init(&lpMusic,lpDS,hwnd)))
{
RegError("Performance create Error !");
QuitDirectMusic();
return FALSE;
};
EnumDirectMusic();
if(bSelectDefault) lpSelectPort=lpDefaultPort;
else lpSelectPort=lpPreferPort?lpPreferPort:lpDefaultPort;
if(!SwitchDirectMusicPort(lpSelectPort))
{
return FALSE;
}
if(FAILED(CoCreateInstance(
CLSID_DirectMusicLoader,
NULL,
CLSCTX_INPROC,
IID_IDirectMusicLoader,
(void**)&lpLoader
)))
{
RegError("Loader create Error !");
QuitDirectMusic();
return FALSE;
}
char szDir[_MAX_PATH];
WCHAR wszDir[_MAX_PATH];
if(_getcwd(szDir,_MAX_PATH)==NULL)
{
RegError("Wide get Error !");
QuitDirectMusic();
return FALSE;
}
MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szDir,-1,wszDir,_MAX_PATH);
if(!lpLoader||FAILED(lpLoader->SetSearchDirectory(GUID_DirectMusicAllTypes,wszDir,FALSE)))
{
RegError("Search directory set Error !");
QuitDirectMusic();
return FALSE;
}
if(lpPerf){
lpPerf->AddNotificationType(GUID_NOTIFICATION_SEGMENT);
}
bInitMusicFlag=TRUE;
return TRUE;
}
HRESULT PlayDirectMusic(char *szMidiFileName)
{
DMUS_OBJECTDESC ObjDesc;
if(bInitMusicFlag)
{
if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
{
RegError("Performance stop Error !");
}
if(lpSegState)
{
lpSegState->Release();
lpSegState=NULL;
}
rtOffset=0;
mtOffset=0;
// Load MIDI Segment
if(lpMIDISeg)
{
if(FAILED(lpMIDISeg->SetStartPoint(0)))
{
RegError("Segment set start point Error !");
}
lpMIDISeg->Release();
lpMIDISeg=NULL;
}
ObjDesc.dwSize=sizeof(DMUS_OBJECTDESC);
ObjDesc.guidClass=CLSID_DirectMusicSegment;
MultiByteToWideChar(CP_ACP,0,szMidiFileName,-1,ObjDesc.wszFileName,sizeof(ObjDesc.wszFileName)/sizeof(ObjDesc.wszFileName[0]));
ObjDesc.dwValidData=DMUS_OBJ_CLASS|DMUS_OBJ_FILENAME|DMUS_OBJ_FULLPATH;
lpLoader->GetObject(&ObjDesc,IID_IDirectMusicSegment2,(void**)&lpMIDISeg);
if(!lpMIDISeg)
{
RegError("Segment get Error !");
QuitDirectMusic();
return FALSE;
}
if(lpCollection)
{
lpMIDISeg->SetParam(GUID_ConnectToDLSCollection,0xFFFFFFFF,0,0,(void*)lpCollection);
}
lpMIDISeg->SetParam(GUID_StandardMIDIFile,-1,0,0,(void*)lpPerf);
lpMIDISeg->SetParam(GUID_Download,-1,0,0,(void*)lpPerf);
lpMIDISeg->SetLoopPoints(0,0);
lpMIDISeg->SetRepeats(-1);
lpPerf->PlaySegment(lpMIDISeg,0,0,&lpSegState);
if(lpSegState)
{
lpSegState->GetStartTime(&mtStart);
}
lpPerf->MusicToReferenceTime(mtStart,&rtStart);
return TRUE;
}
return FALSE;
}
HRESULT PauseDirectMusic(void)
{
MUSIC_TIME mtNow;
REFERENCE_TIME rtNow;
if(bInitMusicFlag)
{
lpPerf->Stop(NULL,NULL,0,0);
lpPerf->GetTime(&rtNow,&mtNow);
mtOffset=(mtNow-mtStart)+mtOffset;
rtOffset=(rtNow-rtStart)+rtOffset;
if(lpMIDISeg)
{
lpMIDISeg->SetStartPoint(mtOffset);
if(lpSegState)
{
lpSegState->Release();
lpSegState=NULL;
}
}
}
return TRUE;
}
HRESULT ResumeDirectMusic(void)
{
if(bInitMusicFlag)
{
if(SUCCEEDED(lpPerf->PlaySegment(lpMIDISeg,DMUS_SEGF_BEAT,0,&lpSegState)))
{
lpSegState->GetStartTime(&mtStart);
lpPerf->MusicToReferenceTime(mtStart,&rtStart);
}
}
return TRUE;
}
HRESULT StopDirectMusic(void)
{
if(bInitMusicFlag)
{
if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
{
RegError("Performance stop Error !");
}
if(lpMIDISeg)
{
if(FAILED(lpMIDISeg->SetStartPoint(0)))
{
RegError("Segment set start point Error !");
}
if(lpSegState)
{
lpSegState->Release();
lpSegState=NULL;
}
}
rtOffset=0;
mtOffset=0;
}
return TRUE;
}
HRESULT QuitDirectMusic(void)
{
DWORD LastTickCount;
bInitMusicFlag=FALSE;
if(lpPerf)
{
if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
{
RegError("Performance stop Error !");
}
}
LastTickCount=timeGetTime();
// while(timeGetTime()-LastTickCount<100) { }
Sleep(100);
if(lpMIDISeg)
{
if(FAILED(lpMIDISeg->SetStartPoint(0)))
{
RegError("Segment set start point Error !");
}
if(FAILED(lpMIDISeg->SetParam(GUID_Unload,-1,0,0,(void*)lpPerf)))
{
RegError("Segment set parameter Error !");
}
lpMIDISeg->Release();
lpMIDISeg=NULL;
if(lpSegState)
{
lpSegState->Release();
lpSegState=NULL;
}
}
if(lpLoader)
{
lpLoader->Release();
lpLoader=NULL;
}
if(lpPort)
{
if(FAILED(lpPort->Activate(FALSE)))
{
RegError("Port deactivate Error !");
}
if(FAILED(lpPerf->RemovePort(lpPort)))
{
RegError("Remove port Error !");
}
if(lpDefaultPort)
{
LocalFree((HLOCAL)lpDefaultPort);
lpDefaultPort=NULL;
}
if(lpPreferPort)
{
LocalFree((HLOCAL)lpPreferPort);
lpPreferPort=NULL;
}
lpPort->Release();
lpPort=NULL;
}
if(lpMusic)
{
lpMusic->Release();
lpMusic=NULL;
}
if(lpPerf)
{
if(FAILED(lpPerf->CloseDown()))
{
RegError("Performance close down Error !");
}
lpPerf->Release();
lpPerf=NULL;
}
CoUninitialize();
return S_OK;
}
HRESULT EnumDirectMusic(void)
{
long idx,iDev;
DMUS_PORTCAPS *lpPortCaps;
GUID guidDefaultPort;
char szPortDescription[DMUS_MAX_DESCRIPTION*2];
HRESULT hResult=S_OK;
if((lpPortCaps=(DMUS_PORTCAPS *)LocalAlloc(LPTR,sizeof(DMUS_PORTCAPS)))==NULL)
{
return FALSE;
}
lpMusic->GetDefaultPort(&guidDefaultPort);
idx=0;
iDev=0;
while(hResult==S_OK)
{
lpPortCaps->dwSize=sizeof(DMUS_PORTCAPS);
hResult=lpMusic->EnumPort(iDev,lpPortCaps);
if(hResult==S_OK&&lpPortCaps->dwClass==DMUS_PC_OUTPUTCLASS)
{
WideCharToMultiByte(CP_ACP,0,lpPortCaps->wszDescription,-1,szPortDescription,sizeof(szPortDescription)/sizeof(szPortDescription[0]),0,0);
if(IsEqualGUID((REFGUID)lpPortCaps->guidPort,(REFGUID)guidDefaultPort))
{
if((lpDefaultPort=(DMUS_PORTCAPS *)LocalAlloc(LPTR,sizeof(DMUS_PORTCAPS)))==NULL)
{
LocalFree((HLOCAL)lpPortCaps);
lpPortCaps=NULL;
return FALSE;
}
memcpy(lpDefaultPort,lpPortCaps,sizeof(DMUS_PORTCAPS));
}
if(!strnicmp(szPortDescription,"MIDI Mapper",11))
{
if((lpPreferPort=(DMUS_PORTCAPS *)LocalAlloc(LPTR,sizeof(DMUS_PORTCAPS)))==NULL)
{
LocalFree((HLOCAL)lpPortCaps);
lpPortCaps=NULL;
return FALSE;
}
memcpy(lpPreferPort,lpPortCaps,sizeof(DMUS_PORTCAPS));
}
idx++;
}
else if((hResult==S_FALSE)|(lpPortCaps->dwClass==DMUS_PC_INPUTCLASS))
{
}
else
{
LocalFree((HLOCAL)lpPortCaps);
lpPortCaps=NULL;
return FALSE;
}
iDev++;
}
LocalFree((HLOCAL)lpPortCaps);
lpPortCaps=NULL;
return TRUE;
}