12 #ifdef WIN32_ENABLE_DIRECTMUSIC_SUPPORT 
   15 #include "../stdafx.h" 
   16 #ifdef WIN32_LEAN_AND_MEAN 
   17   #undef WIN32_LEAN_AND_MEAN // Don't exclude rarely-used stuff from Windows headers 
   20 #include "../os/windows/win32.h" 
   21 #include "../core/mem_func.hpp" 
   25 #undef FACILITY_DIRECTMUSIC // Needed for newer Windows SDK version. 
   31 #include "../safeguards.h" 
   36 static IDirectMusic *music = NULL;
 
   39 static IDirectMusicPerformance *performance = NULL;
 
   42 static IDirectMusicLoader *loader = NULL;
 
   45 static IDirectMusicSegment *segment = NULL;
 
   47 static bool seeking = 
false;
 
   51 static const char ole_files[] =
 
   61   unsigned long (WINAPI * CoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
 
   62   HRESULT (WINAPI * CoInitialize)(LPVOID pvReserved);
 
   63   void (WINAPI * CoUninitialize)();
 
   71   if (performance != NULL) 
return NULL;
 
   73   if (proc.CoCreateInstance == NULL) {
 
   75       return "ole32.dll load failed";
 
   80   if (FAILED(proc.CoInitialize(NULL))) {
 
   81     return "COM initialization failed";
 
   85   if (FAILED(proc.CoCreateInstance(
 
   86         CLSID_DirectMusicPerformance,
 
   89         IID_IDirectMusicPerformance,
 
   92     return "Failed to create the performance object";
 
   96   if (FAILED(performance->Init(&music, NULL, NULL))) {
 
   97     return "Failed to initialize performance object";
 
  102 #ifndef NO_DEBUG_MESSAGES 
  103   if (_debug_driver_level > 0) {
 
  105     char desc[DMUS_MAX_DESCRIPTION];
 
  109     caps.dwSize = 
sizeof(DMUS_PORTCAPS);
 
  111     DEBUG(driver, 1, 
"Detected DirectMusic ports:");
 
  112     for (
int i = 0; music->EnumPort(i, &caps) == S_OK; i++) {
 
  113       if (caps.dwClass == DMUS_PC_OUTPUTCLASS) {
 
  121   IDirectMusicPort *music_port = NULL; 
 
  127     caps.dwSize = 
sizeof(DMUS_PORTCAPS);
 
  128     if (FAILED(music->EnumPort(port, &caps))) 
return "Supplied port parameter is not a valid port";
 
  129     if (caps.dwClass != DMUS_PC_OUTPUTCLASS) 
return "Supplied port parameter is not an output port";
 
  132     DMUS_PORTPARAMS params;
 
  134     params.dwSize          = 
sizeof(DMUS_PORTPARAMS);
 
  135     params.dwValidParams   = DMUS_PORTPARAMS_CHANNELGROUPS;
 
  136     params.dwChannelGroups = 1;
 
  138     if (FAILED(music->CreatePort(caps.guidPort, ¶ms, &music_port, NULL))) {
 
  139       return "Failed to create port";
 
  143     if (FAILED(music_port->Activate(TRUE))) {
 
  144       music_port->Release();
 
  145       return "Failed to activate port";
 
  150   if (FAILED(performance->AddPort(music_port))) {
 
  151     if (music_port != NULL) music_port->Release();
 
  152     return "AddPort failed";
 
  157   if (music_port != NULL) {
 
  158     if (FAILED(performance->AssignPChannelBlock(0, music_port, 1))) {
 
  159       music_port->Release();
 
  160       return "Failed to assign PChannel block";
 
  163     music_port->Release();
 
  167   if (FAILED(proc.CoCreateInstance(
 
  168         CLSID_DirectMusicLoader,
 
  171         IID_IDirectMusicLoader,
 
  174     return "Failed to create loader object";
 
  181 MusicDriver_DMusic::~MusicDriver_DMusic()
 
  191   if (performance != NULL) performance->Stop(NULL, NULL, 0, 0);
 
  193   if (segment != NULL) {
 
  194     segment->SetParam(GUID_Unload, 0xFFFFFFFF, 0, 0, performance);
 
  204   if (performance != NULL) {
 
  205     performance->CloseDown();
 
  206     performance->Release();
 
  210   if (loader != NULL) {
 
  215   proc.CoUninitialize();
 
  222   DMUS_OBJECTDESC obj_desc;
 
  223   ZeroMemory(&obj_desc, 
sizeof(obj_desc));
 
  224   obj_desc.dwSize = 
sizeof(obj_desc);
 
  225   obj_desc.guidClass = CLSID_DirectMusicSegment;
 
  226   obj_desc.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME | DMUS_OBJ_FULLPATH;
 
  228     CP_ACP, MB_PRECOMPOSED,
 
  230     obj_desc.wszFileName, 
lengthof(obj_desc.wszFileName)
 
  234   if (segment != NULL) {
 
  240   if (FAILED(loader->GetObject(
 
  241         &obj_desc, IID_IDirectMusicSegment, (LPVOID*)&segment
 
  243     DEBUG(driver, 0, 
"DirectMusic: GetObject failed");
 
  248   if (FAILED(segment->SetParam(
 
  249         GUID_StandardMIDIFile, 0xFFFFFFFF, 0, 0, performance
 
  251     DEBUG(driver, 0, 
"DirectMusic: SetParam (MIDI file) failed");
 
  256   if (FAILED(segment->SetParam(GUID_Download, 0xFFFFFFFF, 0, 0, performance))) {
 
  257     DEBUG(driver, 0, 
"DirectMusic: failed to download instruments");
 
  262   if (FAILED(performance->PlaySegment(segment, 0, 0, NULL))) {
 
  263     DEBUG(driver, 0, 
"DirectMusic: PlaySegment failed");
 
  273   if (FAILED(performance->Stop(segment, NULL, 0, 0))) {
 
  274     DEBUG(driver, 0, 
"DirectMusic: StopSegment failed");
 
  284   if (performance->IsPlaying(segment, NULL) == S_OK) {
 
  295   long db = vol * 2000 / 127 - 2000; 
 
  296   performance->SetGlobalParam(GUID_PerfMasterVolume, &db, 
sizeof(db));