Midi.cpp
上传用户:garry_shen
上传日期:2015-04-15
资源大小:45647k
文件大小:11k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "XMudClient.h"
  3. #include "midi.h"
  4. #include "MyMusic.h"
  5. BOOL bSelectDefault=FALSE;
  6. extern BOOL g_bSoundPaused;
  7. char g_sFileName[MAX_PATH];
  8. extern rmfullglobals myglobs;
  9. extern void SaveConfigFile(void);
  10. BOOL PlayMidi(char *sFileName)
  11. {
  12.   strcpy(g_sFileName,sFileName);
  13.   return PlayDirectMusic(sFileName);
  14. }
  15. BOOL PauseMidi()
  16. {
  17.   g_bSoundPaused=TRUE;
  18.   SaveConfigFile();
  19.   return PauseDirectMusic();
  20. }
  21. BOOL ResumeMidi()
  22. {
  23.   g_bSoundPaused=FALSE;
  24.   SaveConfigFile();
  25.   return ResumeDirectMusic();
  26. }
  27. BOOL StopMidi()
  28. {
  29.   return StopDirectMusic();
  30. }
  31. BOOL ReplayMidi()
  32. {
  33.   return TRUE;
  34. }
  35. #include <direct.h>
  36. #include <dmusicc.h>
  37. #include <dmusici.h>
  38. BOOL bInitMusicFlag=FALSE;
  39. IDirectMusic* lpMusic=NULL;
  40. IDirectMusicPort *lpPort=NULL;
  41. IDirectMusicPerformance* lpPerf=NULL;
  42. IDirectMusicLoader* lpLoader=NULL;
  43. IDirectMusicCollection* lpCollection=NULL;
  44. IDirectMusicSegment* lpMIDISeg=NULL;
  45. IDirectMusicSegmentState* lpSegState=NULL;
  46. DMUS_PORTCAPS *lpSelectPort=NULL,*lpPreferPort=NULL,*lpDefaultPort=NULL;
  47. MUSIC_TIME  mtStart=0;
  48. MUSIC_TIME  mtOffset=0;
  49. REFERENCE_TIME  rtStart=0;
  50. REFERENCE_TIME  rtOffset=0;
  51. HRESULT SwitchDirectMusicPort(DMUS_PORTCAPS *lpChoicePort)
  52. {
  53.   DWORD LastTickCount;
  54.   DMUS_PORTPARAMS portParams;
  55.   bInitMusicFlag=FALSE;
  56.   if(lpPerf)
  57.   {
  58.     if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
  59.     {
  60.       RegError("Performance stop Error !");
  61.     }
  62.   }
  63.   LastTickCount=timeGetTime();
  64. //  while(timeGetTime()-LastTickCount<100) { }
  65.   Sleep(100);
  66.   if(lpMIDISeg)
  67.   {
  68.     if(FAILED(lpMIDISeg->SetStartPoint(0)))
  69.     {
  70.       RegError("Segment set start point Error !");
  71.     }
  72.     if(FAILED(lpMIDISeg->SetParam(GUID_Unload,-1,0,0,(void*)lpPerf)))
  73.     {
  74.       RegError("Segment set parameter Error !");
  75.     }
  76.     lpMIDISeg->Release();
  77.     lpMIDISeg=NULL;
  78.     if(lpSegState)
  79.     {
  80.       lpSegState->Release();
  81.       lpSegState=NULL;
  82.     }
  83.   }
  84.   if(lpPort)
  85.   {
  86.     if(FAILED(lpPort->Activate(FALSE)))
  87.     {
  88.       RegError("Port deactivate Error !");
  89.     }
  90.     if(FAILED(lpPerf->RemovePort(lpPort)))
  91.     {
  92.       RegError("Remove port Error !");
  93.     }
  94.     lpPort->Release();
  95.     lpPort=NULL;
  96.   }
  97.   ZeroMemory(&portParams, sizeof(portParams));
  98.   portParams.dwSize=sizeof(portParams);
  99.   portParams.dwEffectFlags=DMUS_EFFECT_REVERB;
  100.   portParams.dwChannelGroups=1;
  101.   portParams.dwValidParams=DMUS_PORTPARAMS_CHANNELGROUPS|DMUS_PORTPARAMS_EFFECTS;
  102.   if(!lpMusic||FAILED(lpMusic->CreatePort((REFGUID)lpChoicePort->guidPort,&portParams,&lpPort,NULL)))
  103.   {
  104.     RegError("Port create Error !");
  105.     QuitDirectMusic();
  106.     return FALSE;
  107.   }
  108.   if(FAILED(lpPort->Activate(TRUE)))
  109.   {
  110.     RegError("Port activate Error !");
  111.     QuitDirectMusic();
  112.     return FALSE;
  113.   }
  114.   if(FAILED(lpPerf->AddPort(lpPort)))
  115.   {
  116.     RegError("Port add Error !");
  117.     QuitDirectMusic();
  118.     return FALSE;
  119.   }
  120.   if(FAILED(lpPerf->AssignPChannelBlock(0,lpPort,1)))
  121.   {
  122.     RegError("PChannel assign Error !");
  123.     QuitDirectMusic();
  124.     return FALSE;
  125.   }
  126.   bInitMusicFlag=TRUE;
  127.   return TRUE;
  128. }
  129. HRESULT SwitchMusicPort(void)
  130. {
  131.   if(lpSelectPort==lpPreferPort) { lpSelectPort=lpDefaultPort; return SwitchDirectMusicPort(lpSelectPort); }
  132.   else                           { lpSelectPort=lpPreferPort;  return SwitchDirectMusicPort(lpSelectPort); }
  133. }
  134. HRESULT LoadCollectionByName(IDirectMusicLoader *lpILoader,char *pszFileName,IDirectMusicCollection **lppICollection)
  135. {
  136.   HRESULT hr;
  137.   DMUS_OBJECTDESC Desc;
  138.   mbstowcs(Desc.wszFileName,pszFileName,DMUS_MAX_FILENAME);
  139.   Desc.dwSize=sizeof(DMUS_OBJECTDESC);
  140.   Desc.guidClass=CLSID_DirectMusicCollection;  
  141.   Desc.dwValidData=DMUS_OBJ_CLASS|DMUS_OBJ_FILENAME|DMUS_OBJ_FULLPATH;
  142.   hr=lpILoader->GetObject(&Desc,IID_IDirectMusicCollection,(void **)lppICollection);
  143.   return hr;
  144. }
  145. HRESULT InitDirectMusic(HWND hwnd,LPDIRECTSOUND lpDS)
  146. {
  147.   bInitMusicFlag=FALSE;
  148.   if(FAILED(CoInitialize(NULL))) return FALSE;
  149.   if(FAILED(CoCreateInstance(
  150.     CLSID_DirectMusicPerformance,
  151.     NULL,
  152.     CLSCTX_INPROC, 
  153.     IID_IDirectMusicPerformance2,
  154.     (void**)&lpPerf
  155.     )))
  156.   {
  157.     RegError("Create Instance Error !");
  158.     return FALSE;
  159.   }
  160.   if(!lpPerf||FAILED(lpPerf->Init(&lpMusic,lpDS,hwnd)))
  161.   {
  162.     RegError("Performance create Error !");
  163.     QuitDirectMusic();
  164.     return FALSE;
  165.   };
  166.   EnumDirectMusic();
  167.   if(bSelectDefault) lpSelectPort=lpDefaultPort;
  168.   else               lpSelectPort=lpPreferPort?lpPreferPort:lpDefaultPort;
  169.   if(!SwitchDirectMusicPort(lpSelectPort))
  170.   {
  171.     return FALSE;
  172.   }
  173.   if(FAILED(CoCreateInstance(
  174.     CLSID_DirectMusicLoader,
  175.     NULL,
  176.     CLSCTX_INPROC, 
  177.     IID_IDirectMusicLoader,
  178.     (void**)&lpLoader
  179.     )))
  180.   {
  181.     RegError("Loader create Error !");
  182.     QuitDirectMusic();
  183.     return FALSE;
  184.   }
  185.   char szDir[_MAX_PATH];
  186.   WCHAR wszDir[_MAX_PATH];
  187.   if(_getcwd(szDir,_MAX_PATH)==NULL)
  188.   {
  189.     RegError("Wide get Error !");
  190.     QuitDirectMusic();
  191.     return FALSE;
  192.   }
  193.   MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,szDir,-1,wszDir,_MAX_PATH);
  194.   if(!lpLoader||FAILED(lpLoader->SetSearchDirectory(GUID_DirectMusicAllTypes,wszDir,FALSE)))
  195.   {
  196.     RegError("Search directory set Error !");
  197.     QuitDirectMusic();
  198.     return FALSE;
  199.   }
  200.   if(lpPerf){
  201.     lpPerf->AddNotificationType(GUID_NOTIFICATION_SEGMENT);
  202.   }
  203.   bInitMusicFlag=TRUE;
  204.   return TRUE;
  205. }
  206. HRESULT PlayDirectMusic(char *szMidiFileName)
  207. {
  208.   DMUS_OBJECTDESC ObjDesc;
  209.   if(bInitMusicFlag)
  210.   {
  211.     if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
  212.     {
  213.       RegError("Performance stop Error !");
  214.     }
  215.     if(lpSegState)
  216.     {
  217.       lpSegState->Release();
  218.       lpSegState=NULL;
  219.     }
  220.     rtOffset=0;
  221.     mtOffset=0;
  222.     // Load MIDI Segment
  223.     if(lpMIDISeg)
  224.     {
  225.       if(FAILED(lpMIDISeg->SetStartPoint(0)))
  226.       {
  227.         RegError("Segment set start point Error !");
  228.       }
  229.       lpMIDISeg->Release();
  230.       lpMIDISeg=NULL;
  231.     }
  232.     ObjDesc.dwSize=sizeof(DMUS_OBJECTDESC);
  233.     ObjDesc.guidClass=CLSID_DirectMusicSegment;
  234.     MultiByteToWideChar(CP_ACP,0,szMidiFileName,-1,ObjDesc.wszFileName,sizeof(ObjDesc.wszFileName)/sizeof(ObjDesc.wszFileName[0]));
  235.     ObjDesc.dwValidData=DMUS_OBJ_CLASS|DMUS_OBJ_FILENAME|DMUS_OBJ_FULLPATH;
  236.     lpLoader->GetObject(&ObjDesc,IID_IDirectMusicSegment2,(void**)&lpMIDISeg);
  237.     if(!lpMIDISeg)
  238.     {
  239.       RegError("Segment get Error !");
  240.       QuitDirectMusic();
  241.       return FALSE;
  242.     }
  243.     if(lpCollection)
  244.     {
  245.       lpMIDISeg->SetParam(GUID_ConnectToDLSCollection,0xFFFFFFFF,0,0,(void*)lpCollection);
  246.     }
  247.     lpMIDISeg->SetParam(GUID_StandardMIDIFile,-1,0,0,(void*)lpPerf);
  248.     lpMIDISeg->SetParam(GUID_Download,-1,0,0,(void*)lpPerf);
  249.     lpMIDISeg->SetLoopPoints(0,0);
  250.     lpMIDISeg->SetRepeats(-1);
  251.     lpPerf->PlaySegment(lpMIDISeg,0,0,&lpSegState);
  252.     if(lpSegState)
  253.     {
  254.       lpSegState->GetStartTime(&mtStart);
  255.     }
  256.     lpPerf->MusicToReferenceTime(mtStart,&rtStart);
  257.     return TRUE;
  258.   }
  259.   return FALSE;
  260. }
  261. HRESULT PauseDirectMusic(void)
  262. {
  263.   MUSIC_TIME  mtNow;
  264.   REFERENCE_TIME  rtNow;
  265.   if(bInitMusicFlag)
  266.   {
  267.     lpPerf->Stop(NULL,NULL,0,0);
  268.     lpPerf->GetTime(&rtNow,&mtNow);
  269.     mtOffset=(mtNow-mtStart)+mtOffset; 
  270.     rtOffset=(rtNow-rtStart)+rtOffset;
  271.     if(lpMIDISeg)
  272.     {
  273.       lpMIDISeg->SetStartPoint(mtOffset);
  274.       if(lpSegState)
  275.       {
  276.         lpSegState->Release();
  277.         lpSegState=NULL;
  278.       }
  279.     }
  280.   }
  281.   return TRUE;
  282. }
  283. HRESULT ResumeDirectMusic(void)
  284. {
  285.   if(bInitMusicFlag)
  286.   {
  287.     if(SUCCEEDED(lpPerf->PlaySegment(lpMIDISeg,DMUS_SEGF_BEAT,0,&lpSegState)))
  288.     {
  289.       lpSegState->GetStartTime(&mtStart);
  290.       lpPerf->MusicToReferenceTime(mtStart,&rtStart);
  291.     }
  292.   }
  293.   return TRUE;
  294. }
  295. HRESULT StopDirectMusic(void)
  296. {
  297.   if(bInitMusicFlag)
  298.   {
  299.     if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
  300.     {
  301.       RegError("Performance stop Error !");
  302.     }
  303.     if(lpMIDISeg)
  304.     {
  305.       if(FAILED(lpMIDISeg->SetStartPoint(0)))
  306.       {
  307.         RegError("Segment set start point Error !");
  308.       }
  309.       if(lpSegState)
  310.       {
  311.         lpSegState->Release();
  312.         lpSegState=NULL;
  313.       }
  314.     }
  315.     rtOffset=0;
  316.     mtOffset=0;
  317.   }
  318.   return TRUE;
  319. }
  320. HRESULT QuitDirectMusic(void)
  321. {
  322.   DWORD LastTickCount;
  323.   bInitMusicFlag=FALSE;
  324.   if(lpPerf)
  325.   {
  326.     if(FAILED(lpPerf->Stop(NULL,NULL,0,0)))
  327.     {
  328.       RegError("Performance stop Error !");
  329.     }
  330.   }
  331.   LastTickCount=timeGetTime();
  332. //  while(timeGetTime()-LastTickCount<100) { }
  333.   Sleep(100);
  334.   if(lpMIDISeg)
  335.   {
  336.     if(FAILED(lpMIDISeg->SetStartPoint(0)))
  337.     {
  338.       RegError("Segment set start point Error !");
  339.     }
  340.     if(FAILED(lpMIDISeg->SetParam(GUID_Unload,-1,0,0,(void*)lpPerf)))
  341.     {
  342.       RegError("Segment set parameter Error !");
  343.     }
  344.     lpMIDISeg->Release();
  345.     lpMIDISeg=NULL;
  346.     if(lpSegState)
  347.     {
  348.       lpSegState->Release();
  349.       lpSegState=NULL;
  350.     }
  351.   }
  352.   if(lpLoader)
  353.   {
  354.     lpLoader->Release();
  355.     lpLoader=NULL;
  356.   }
  357.   if(lpPort)
  358.   {
  359.     if(FAILED(lpPort->Activate(FALSE)))
  360.     {
  361.       RegError("Port deactivate Error !");
  362.     }
  363.     if(FAILED(lpPerf->RemovePort(lpPort)))
  364.     {
  365.       RegError("Remove port Error !");
  366.     }
  367.     if(lpDefaultPort)
  368.     {
  369.       LocalFree((HLOCAL)lpDefaultPort);
  370.       lpDefaultPort=NULL;
  371.     }
  372.     if(lpPreferPort)
  373.     {
  374.       LocalFree((HLOCAL)lpPreferPort);
  375.       lpPreferPort=NULL;
  376.     }
  377.     lpPort->Release();
  378.     lpPort=NULL;
  379.   }
  380.   if(lpMusic)
  381.   {
  382.     lpMusic->Release();
  383.     lpMusic=NULL;
  384.   }
  385.   if(lpPerf)
  386.   {
  387.     if(FAILED(lpPerf->CloseDown()))
  388.     {
  389.       RegError("Performance close down Error !");
  390.     }
  391.     lpPerf->Release();
  392.     lpPerf=NULL;
  393.   }
  394.   CoUninitialize();
  395.   return S_OK;
  396. }
  397. HRESULT EnumDirectMusic(void)
  398. {
  399.   long            idx,iDev;
  400.   DMUS_PORTCAPS  *lpPortCaps;
  401.   GUID            guidDefaultPort;
  402.   char            szPortDescription[DMUS_MAX_DESCRIPTION*2];
  403.   HRESULT         hResult=S_OK;
  404.   if((lpPortCaps=(DMUS_PORTCAPS *)LocalAlloc(LPTR,sizeof(DMUS_PORTCAPS)))==NULL)
  405.   {
  406.     return FALSE;
  407.   }
  408.   lpMusic->GetDefaultPort(&guidDefaultPort);
  409.   idx=0;
  410.   iDev=0;
  411.   while(hResult==S_OK)
  412.   {
  413.     lpPortCaps->dwSize=sizeof(DMUS_PORTCAPS);
  414.     hResult=lpMusic->EnumPort(iDev,lpPortCaps);
  415.     if(hResult==S_OK&&lpPortCaps->dwClass==DMUS_PC_OUTPUTCLASS)
  416.     {
  417.       WideCharToMultiByte(CP_ACP,0,lpPortCaps->wszDescription,-1,szPortDescription,sizeof(szPortDescription)/sizeof(szPortDescription[0]),0,0);
  418.       if(IsEqualGUID((REFGUID)lpPortCaps->guidPort,(REFGUID)guidDefaultPort))
  419.       {
  420.         if((lpDefaultPort=(DMUS_PORTCAPS *)LocalAlloc(LPTR,sizeof(DMUS_PORTCAPS)))==NULL)
  421.         {
  422.           LocalFree((HLOCAL)lpPortCaps);
  423.           lpPortCaps=NULL;
  424.           return FALSE;
  425.         }
  426.         memcpy(lpDefaultPort,lpPortCaps,sizeof(DMUS_PORTCAPS));
  427.       }
  428.       if(!strnicmp(szPortDescription,"MIDI Mapper",11))
  429.       {
  430.         if((lpPreferPort=(DMUS_PORTCAPS *)LocalAlloc(LPTR,sizeof(DMUS_PORTCAPS)))==NULL)
  431.         {
  432.           LocalFree((HLOCAL)lpPortCaps);
  433.           lpPortCaps=NULL;
  434.           return FALSE;
  435.         }
  436.         memcpy(lpPreferPort,lpPortCaps,sizeof(DMUS_PORTCAPS));
  437.       }
  438.       idx++;
  439.     }
  440.     else if((hResult==S_FALSE)|(lpPortCaps->dwClass==DMUS_PC_INPUTCLASS))
  441.     {
  442.     }
  443.     else
  444.     {
  445.       LocalFree((HLOCAL)lpPortCaps);
  446.       lpPortCaps=NULL;
  447.       return FALSE;
  448.     }
  449.     iDev++;
  450.   }
  451.   LocalFree((HLOCAL)lpPortCaps);
  452.   lpPortCaps=NULL;
  453.   return TRUE;
  454. }