Quote: #include "DSMusic.h" HRESULT Result; IGraphBuilder *g_pGraphBuilder; IMediaControl *g_pMediaControl; IMediaSeeking *g_pMediaSeeking; IMediaEventEx *g_pMediaEventEx; IBaseFilter *g_pTrack; IBaseFilter *LoadAudioFile(LPCWSTR Filename); DSMusic::DSMusic(void) { std::cout << "Setting up DirectShow\n"; ::CoInitialize(NULL); std::cout << "Creating Graph Builder\n"; Result = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&g_pGraphBuilder); if (FAILED(Result)) { // Just an idea about restarting the server on its own when there is a fatal error. Is no good for debugging purposes as the monitored thread is gone std::cout << "***Failed to create Graph Builder\n"; } std::cout << "Creating Media Seeking Interface\n"; Result = g_pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void **)&g_pMediaSeeking); if (FAILED(Result)) { std::cout << "***Failed to create Seek Interface\n"; } std::cout << "Creating Media Control Interface\n"; Result = g_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&g_pMediaControl); if (FAILED(Result)) { std::cout << "***Failed to create Media Control Interface\n"; } std::cout << "Creating Media EventEx Interface\n"; Result = g_pGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&g_pMediaEventEx); if (FAILED(Result)) { std::cout << "***Failed to create Media EventEx Interface\n"; } std::cout << "Setting Event Notify Window\n"; //Result = g_pMediaEventEx->SetNotifyWindow( (OAHWND)hWnd, WM_APP, 0); std::cout << "W**Notify Window not set as we don't have a window handle\n";// may need to create child window for this purpose if (FAILED(Result)) { std::cout << "***Failed to Set Notify Window\n"; } } DSMusic::~DSMusic(void) { g_pMediaEventEx->Release(); g_pMediaEventEx = NULL; g_pMediaControl->Release(); g_pMediaControl = NULL; g_pMediaSeeking->Release(); g_pMediaSeeking = NULL; g_pGraphBuilder->Release(); g_pGraphBuilder = NULL; } int DSMusic::PlayTrack(LPCWSTR FileName) { IPin *pPin = NULL; IEnumFilters *pFilterEnum = NULL; IBaseFilter **ppFilters; IBaseFilter *pFilterTemp = NULL; int iFiltCount; int iPos; g_pTrack = LoadAudioFile(FileName); g_pTrack->FindPin(L"Output", &pPin); ////////////////////////////////////////////////////////////////////// g_pGraphBuilder->EnumFilters(&pFilterEnum); for (iFiltCount = 0; pFilterEnum->Skip(1) == S_OK; iFiltCount++) ; // Allocate space, then pull out all of the ppFilters = (IBaseFilter **)_alloca(sizeof(IBaseFilter *) * iFiltCount); pFilterEnum->Reset(); for (iPos = 0; pFilterEnum->Next(1, &ppFilters[iPos], NULL) == S_OK; iPos++) ; pFilterEnum->Release(); for (iPos = 0; iPos < iFiltCount; iPos++) { g_pGraphBuilder->RemoveFilter(ppFilters[iPos]); //put the filter back? g_pGraphBuilder->AddFilter(ppFilters[iPos], NULL); ppFilters[iPos]->Release(); } //////////////////////////////////////////////////////*/ //We have the new output pin apparently - render it g_pGraphBuilder->Render(pPin); pPin->Release(); //Reseek the graph to the beginning LONGLONG llPos = 0; g_pMediaSeeking->SetPositions(&llPos, AM_SEEKING_AbsolutePositioning, &llPos, AM_SEEKING_NoPositioning); //Start the Graph g_pMediaControl->Run(); return 0; } int DSMusic::StopTrack() { if (g_pMediaControl != NULL) g_pMediaControl->Stop(); return 0; } IBaseFilter *LoadAudioFile(LPCWSTR Filename) { IBaseFilter *pSource; std::cout << "Attempting to load track\n"; Result = g_pGraphBuilder->AddSourceFilter(Filename, Filename, &pSource); if (FAILED(Result)){ printf("Failed to load track with error: %X\n", Result); return NULL; } return pSource; }And this is the header file
Quote: #pragma once #include <iostream> #include <windows.h> #include <windowsx.h> #include <dshow.h> #pragma comment (lib, "strmiids.lib") class DSMusic { public: DSMusic(); ~DSMusic(); int PlayTrack(LPCWSTR FileName); int StopTrack(); private: };The problem is that in my program if I run
Quote: DSMusic Main; // Sets up Direct Show Main.PlayTrack(Library[track].Path); //Loads and plays track DSMusic Second; // Sets up Direct Show Second.PlayTrack(Library[track].Path); //Loads and plays track Main.StopTrack();The program will stop the 2nd track. It always stops the 2nd track even though I told it to stop the first. After loading the second track it seems I have no control over the first. Normally I would presume it is because "IMediaControl *g_pMediaControl;" relates to a pointer and thus when the second track is loaded the memory in the address changes but I thought that because I am using DSMusic as an object there should be 2 separate instances and thus should not affect each other. This is the first time I've attempted to use classes properly. You can tell by my comments that I'm not too sure about the filter graph idea either. I followed a tutorial on that front. [Edited by - Gegenki on August 14, 2009 11:40:20 AM]