Before exiting, the program must unload the instruments, release all the objects that have been created, and dereference COM (remember, every call to CoInitialize must have a matching call to CoUninitialize).
The following function performs the necessary cleanup:
HRESULT FreeDirectMusic() { // If there is any music playing, stop it. This is // not really necessary, because the music will stop when // the instruments are unloaded or the performance is // closed down. g_pPerf->Stop( NULL, NULL, 0, 0 ); // Unload instruments
–this will cause silence. // CloseDown unloads all instruments, so this call is also not // strictly necessary. g_pMIDISeg->SetParam(GUID_Unload, -1, 0, 0, (void*)g_pPerf); // Release the segment. g_pMIDISeg->Release(); // CloseDown and Release the performance object. g_pPerf->CloseDown(); g_pPerf->Release(); // Release the loader object. g_pLoader->Release(); // Release COM. CoUninitialize(); return S_OK; }