DX Audio und mp3



  • So, ich hab mir den Code ma angesehen und in den ersten 10Zeilen verstehe ich schon nix mehr, jetzt mögen die meisten sagen: Warum macht der c++ und nicht QBasic, aber was soll ich sagen 🙄
    Hier der Code, kann mir den jemand so umarbeiten, das der net so compliziert ist???
    mfg
    Bedanke mich für Antworten

    //------------------------------------------------------------------------------
    // File: BGMusic.cpp
    //
    // Desc: A simple playback applicaiton that plays a cyclic set of media
    //       files of the same type. This is the code required to use DirectShow
    //       to play compressed audio in the background of your title in a
    //       seamless manner.
    //
    // Copyright (c) 1999-2000, Microsoft Corporation. All rights reserved.
    //------------------------------------------------------------------------------
    
    #include <windows.h>
    #include <dshow.h>
    #include <tchar.h>
    #include <malloc.h>
    #define IDI_BGMUSIC    10000
    
    //------------------------------------------------------------------------------
    // Forward Declarations
    //------------------------------------------------------------------------------
    HRESULT GraphInit(void);
    HWND AppInit(HINSTANCE hInstance);
    void AppMessageLoop(void);
    void AppCleanUp(void);
    HRESULT SwapSourceFilter(void); 
    void ShowCurrentFile(HWND hWnd);
    const TCHAR* DXUtil_GetDXSDKMediaPath();
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    VOID CALLBACK MyTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime);
    
    //------------------------------------------------------------------------------
    // Macros
    //------------------------------------------------------------------------------
    #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
    
    //------------------------------------------------------------------------------
    // Constants
    //------------------------------------------------------------------------------
    #define CLASSNAME       TEXT("BGMusicPlayer")
    #define APPNAME         TEXT("BGMusic Player")
    #define APPWIDTH        200
    #define APPHEIGHT       100
    #define MEDIA_TIMEOUT   (15 * 1000)  // 15 seconds, represented in milliseconds
    
    //------------------------------------------------------------------------------
    // Global Variables
    //------------------------------------------------------------------------------
    // DirectShow Graph, Filter & Pins used
    IGraphBuilder *g_pGraphBuilder = NULL;
    IMediaControl *g_pMediaControl = NULL;
    IMediaSeeking *g_pMediaSeeking = NULL;
    IBaseFilter   *g_pSourceCurrent = NULL;
    IBaseFilter   *g_pSourceNext = NULL;
    TCHAR          g_szCurrentFile[128];
    HWND           g_hwndApp;
    
    // File names & variables to track current file
    LPCTSTR pstrFiles[] = 
    {
        TEXT("track2.mp3\0"),
        TEXT("track3.mp3\0"),
        TEXT("track1.mp3\0"),
    };
    
    int g_iNumFiles = 3, g_iNextFile = 0;
    
    //------------------------------------------------------------------------------
    // Name: WinMain()
    // Desc: Main Entry point for the app. Calls the Initialization routines and
    //       then calls the main processing loop.
    //------------------------------------------------------------------------------
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
        // Initialize application window
        if (! AppInit(hInstance))
            return 0;
    
        // Initialize DirectShow components and build initial graph
        if (SUCCEEDED (GraphInit()))
        {
            // Main Message Loop
            AppMessageLoop();
        }
    
        // Clean up
        AppCleanUp();
        return 0;
    }
    
    //------------------------------------------------------------------------------
    // Name: GraphInit()
    // Desc: Initialization of DirectShow components and initial graph
    //------------------------------------------------------------------------------
    HRESULT GraphInit(void)
    {
        HRESULT hr;
        // Initialize COM
        if (FAILED (hr = CoInitialize(NULL)) )
            return hr;
    
        // Create DirectShow Graph
        if (FAILED (hr = CoCreateInstance(CLSID_FilterGraph, NULL,
                                          CLSCTX_INPROC, IID_IGraphBuilder,
                                          reinterpret_cast<void **>(&g_pGraphBuilder))) )
            return hr;
    
        // Get the IMediaControl Interface
        if (FAILED (g_pGraphBuilder->QueryInterface(IID_IMediaControl,
                                     reinterpret_cast<void **>(&g_pMediaControl))))
            return hr;
    
        // Get the IMediaControl Interface
        if (FAILED (g_pGraphBuilder->QueryInterface(IID_IMediaSeeking,
                                     reinterpret_cast<void **>(&g_pMediaSeeking))))
            return hr;
    
        // Create Source Filter for first file
        g_iNextFile = 0;
    
        // Create the intial graph
        if (FAILED (SwapSourceFilter()))
            return hr;
    
        // Set a timer for switching the sources
        SetTimer(g_hwndApp, 0, MEDIA_TIMEOUT, &MyTimerProc);
    
        return S_OK;
    }
    
    //------------------------------------------------------------------------------
    // Name: AppInit()
    // Desc: Initialization of application window
    //------------------------------------------------------------------------------
    HWND AppInit(HINSTANCE hInstance)
    {
        WNDCLASS wc;
    
        // Register the window class
        ZeroMemory(&wc, sizeof wc);
        wc.lpfnWndProc   = WndProc;
        wc.hInstance     = hInstance;
        wc.lpszClassName = CLASSNAME;
        wc.lpszMenuName  = NULL;
        wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BGMUSIC));
        if(!RegisterClass(&wc))
            return 0;
    
        // Create the main window without support for resizing
        g_hwndApp = CreateWindow(CLASSNAME, APPNAME,
                        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU
                                      | WS_MINIMIZEBOX | WS_VISIBLE,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        APPWIDTH, APPHEIGHT,
                        0, 0, hInstance, 0);
    
        return g_hwndApp;
    }
    
    //------------------------------------------------------------------------------
    // Name: WndProcLoop()
    // Desc: Main Message Processor for the Application
    //------------------------------------------------------------------------------
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
            case WM_PAINT:
                ShowCurrentFile(hWnd);
                break;
    
            case WM_CLOSE:
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
        }
    
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    
    //------------------------------------------------------------------------------
    // Name: ShowCurrentFile()
    // Desc: Display the currently playing media file in the main window
    //------------------------------------------------------------------------------
    void ShowCurrentFile(HWND hWnd)
    {
        PAINTSTRUCT ps;
        RECT rc;
        TCHAR szMsg[128];
    
        BeginPaint(hWnd, &ps);
        HDC hdc = GetDC(hWnd);
        GetWindowRect(hWnd, &rc);
    
        // Set the text color to bright green against black background
        SetTextColor(hdc, RGB(80, 255, 80));
        SetBkColor(hdc, RGB(0,0,0));
    
        // Decide where to place the text (centered in window)
        int X = (rc.right - rc.left) / 2;
        int Y = (rc.bottom - rc.top) / 3;
        SetTextAlign(hdc, TA_CENTER | VTA_CENTER);
    
        // Update the text string
        wsprintf(szMsg, _T("Playing %s\0"), g_szCurrentFile);
        ExtTextOut(hdc, X, Y, ETO_OPAQUE, NULL, szMsg, _tcslen(szMsg), 0);
    
        EndPaint(hWnd, &ps);
    }
    
    //------------------------------------------------------------------------------
    // Name: AppMessageLoop()
    // Desc: Main Message Loop for the Application
    //------------------------------------------------------------------------------
    void AppMessageLoop(void)
    {
        MSG msg={0};
    
        // Main message loop:
        while (GetMessage(&msg, NULL, 0, 0))
        {
            if (! TranslateAccelerator(msg.hwnd, NULL, &msg) )
            {
                TranslateMessage(&msg) ;
                DispatchMessage(&msg) ;
            }
        }
    
        return;
    }
    
    //------------------------------------------------------------------------------
    // Name: AppCleanUp)
    // Desc: Clean up the application
    //------------------------------------------------------------------------------
    void AppCleanUp(void)
    {
        // Stop playback
        if (g_pMediaControl)
            g_pMediaControl->Stop();
    
        // Release all remaining pointers
        SAFE_RELEASE( g_pSourceNext);
        SAFE_RELEASE( g_pSourceCurrent);
        SAFE_RELEASE( g_pMediaSeeking);
        SAFE_RELEASE( g_pMediaControl);
        SAFE_RELEASE( g_pGraphBuilder);
    
        // Clean up COM
        CoUninitialize();
        return;
    }
    
    //------------------------------------------------------------------------------
    // MyTimerProc - Callback when the timer goes off
    //------------------------------------------------------------------------------
    VOID CALLBACK MyTimerProc(
      HWND hwnd,     // handle to window
      UINT uMsg,     // WM_TIMER message
      UINT idEvent,  // timer identifier
      DWORD dwTime   // current system time
    )
    {
        SwapSourceFilter();
    
        // Update the "current file" text message
        RECT rc;
        GetWindowRect(hwnd, &rc);
        InvalidateRect(hwnd, &rc, TRUE);
    }
    
    //------------------------------------------------------------------------------
    // Name: SwapSourceFilter()
    // Desc: This routine is used to change the source file in the current graph.
    //       First the graph is stopped, then the current source filter is removed.
    //       The new source filter is added, the output pin on this filter is
    //       rendered, and playback is restarted.
    //
    //       When this routine is called during initialization, there is no
    //       currently running graph. In that case, Stop becomes a no-op. The source
    //       filter is added to an empty graph. Then during the render call, all
    //       necessary filters required to play this source are added to the graph.
    //
    //       On subsequent calls, Stopping the graph allows filters to be removed.
    //       When the old source filter is removed, all other filters are still
    //       left in the graph. The new source filter is added, and then the render
    //       operation reconnects the graph. Since all of the necessary filters for
    //       playback are already in the graph (if the two files have the same file
    //       type), these filters are reused. Existing filters in the graph are
    //       always used first, if possible, during a Render operation. This avoids
    //       having to create new filter instances with each change.
    //------------------------------------------------------------------------------
    HRESULT SwapSourceFilter(void)
    {
        HRESULT hr = S_OK;
        IPin *pPin = NULL;
        TCHAR szFilename[MAX_PATH];
        WCHAR wFileName[MAX_PATH];
    
        // Determine the file to load based on DirectX Media path (from SDK)
        _tcscpy( szFilename, DXUtil_GetDXSDKMediaPath() );
        _tcscat( szFilename, pstrFiles[g_iNextFile % g_iNumFiles]);
        _tcscpy( g_szCurrentFile, pstrFiles[g_iNextFile % g_iNumFiles]);
        g_iNextFile++;
    
        // Make sure that this file exists
        DWORD dwAttr = GetFileAttributes(szFilename);
        if (dwAttr == (DWORD) -1)
            return ERROR_FILE_NOT_FOUND;
    
        #ifndef UNICODE
            MultiByteToWideChar(CP_ACP, 0, szFilename, -1, wFileName, MAX_PATH);
        #else
            lstrcpy(wFileName, szFilename);
        #endif
    
        // OPTIMIZATION OPPORTUNITY
    	// This will open the file, which is expensive. To optimize, this
        // should be done earlier, ideally as soon as we knew this was the
        // next file to ensure that the file load doesn't add to the
        // filter swapping time & cause a hiccup.
        //
        // Add the new source filter to the graph. (Graph can still be running)
        hr = g_pGraphBuilder->AddSourceFilter(wFileName, wFileName, &g_pSourceNext);
    
        // Get the first output pin of the new source filter. Audio sources 
        // typically have only one output pin, so for most audio cases finding 
        // any output pin is sufficient.
        if (SUCCEEDED(hr)) {
            hr = g_pSourceNext->FindPin(L"Output", &pPin);  
        }
    
        // Stop the graph
        if (SUCCEEDED(hr)) {
            hr = g_pMediaControl->Stop();
        }
    
        // Break all connections on the filters. You can do this by adding 
        // and removing each filter in the graph
        if (SUCCEEDED(hr)) {
            IEnumFilters *pFilterEnum = NULL;
            IBaseFilter  *pFilterTemp = NULL;
    
            if (SUCCEEDED(hr = g_pGraphBuilder->EnumFilters(&pFilterEnum))) {
                int iFiltCount = 0;
                int iPos = 0;
    
                // Need to know how many filters. If we add/remove filters during the
                // enumeration we'll invalidate the enumerator
                while (S_OK == pFilterEnum->Skip(1)) {
                    iFiltCount++;
                }
    
                // Allocate space, then pull out all of the 
                IBaseFilter **ppFilters = reinterpret_cast<IBaseFilter **>
                                          (_alloca(sizeof(IBaseFilter *) * iFiltCount));
                pFilterEnum->Reset();
    
                while (S_OK == pFilterEnum->Next(1, &(ppFilters[iPos++]), NULL));
                SAFE_RELEASE(pFilterEnum);
    
                for (iPos = 0; iPos < iFiltCount; iPos++) {
                    g_pGraphBuilder->RemoveFilter(ppFilters[iPos]);
    				// Put the filter back, unless it is the old source
    				if (ppFilters[iPos] != g_pSourceCurrent) {
    					g_pGraphBuilder->AddFilter(ppFilters[iPos], NULL);
                    }
    				SAFE_RELEASE(ppFilters[iPos]);
                }
            }
        }
    
        // We have the new ouput pin. Render it
        if (SUCCEEDED(hr)) {
            hr = g_pGraphBuilder->Render(pPin);
            g_pSourceCurrent = g_pSourceNext;
            g_pSourceNext = NULL;
        }
    
        SAFE_RELEASE(pPin);
        SAFE_RELEASE(g_pSourceNext); // In case of errors
    
        // Re-seek the graph to the beginning
        if (SUCCEEDED(hr)) {
            LONGLONG llPos = 0;
            hr = g_pMediaSeeking->SetPositions(&llPos, AM_SEEKING_AbsolutePositioning,
                                               &llPos, AM_SEEKING_NoPositioning);
        } 
    
        // Start the graph
        if (SUCCEEDED(hr)) {
            hr = g_pMediaControl->Run();
        }
    
        // Release the old source filter.
        SAFE_RELEASE(g_pSourceCurrent)
        return S_OK;   
    }
    
    //-----------------------------------------------------------------------------
    // Name: DXUtil_GetDXSDKMediaPath()
    // Desc: Returns the DirectX SDK media path
    //-----------------------------------------------------------------------------
    const TCHAR* DXUtil_GetDXSDKMediaPath()
    {
        static TCHAR strNull[2] = _T("");
        static TCHAR strPath[MAX_PATH];
        DWORD dwType;
        DWORD dwSize = MAX_PATH;
        HKEY  hKey;
    
        // Open the appropriate registry key
        LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
                                    _T("Software\\Microsoft\\DirectX"),
                                    0, KEY_READ, &hKey );
        if( ERROR_SUCCESS != lResult )
            return strNull;
    
        lResult = RegQueryValueEx( hKey, _T("DX8SDK Samples Path"), NULL,
                                  &dwType, (BYTE*)strPath, &dwSize );
        RegCloseKey( hKey );
    
        if( ERROR_SUCCESS != lResult )
            return strNull;
    
        _tcscat( strPath, _T("\\Media\\") );
    
        return strPath;
    }
    


  • Gott der 2. schrieb:

    Hier der Code, kann mir den jemand so umarbeiten, das der net so compliziert ist???

    Ach geh spielen...

    (@Sgt. Nukem: ist der Umkehrschluss jetzt, das ich 'ne alte Freundin habe?)

    Bye, TGGC (Der Held ist zurück)



  • Gott der 2. schrieb:

    So, ich hab mir den Code ma angesehen und in den ersten 10Zeilen verstehe ich schon nix mehr

    [SNIP - erste 10 Zeilen]

    //------------------------------------------------------------------------------
    // File: BGMusic.cpp
    //
    // Desc: A simple playback applicaiton that plays a cyclic set of media
    //       files of the same type. This is the code required to use DirectShow
    //       to play compressed audio in the background of your title in a
    //       seamless manner.
    //
    // Copyright (c) 1999-2000, Microsoft Corporation. All rights reserved.
    //------------------------------------------------------------------------------
    

    [/SNIP]

    Ich versuch' sie Dir zu erklären! 🤡
    Also: Das '//' leitet in C++ einen (Zeilen-)Kommentar ein, d.h. der Compiler ignoriert die jeweiligen Zeilen, und Du kannst Informationen und anderen Kram in den Code hauen, ohne Compilerfehler zu erhalten!! 🤡 👍

    Gott der 2. schrieb:

    jetzt mögen die meisten sagen: Warum macht der c++ und nicht QBasic, aber was soll ich sagen 🙄

    Warum machst Du kein QBasic?!? 🤡

    TGGC schrieb:

    (@Sgt. Nukem: ist der Umkehrschluss jetzt, das ich 'ne alte Freundin habe?)

    Hehe... ich hoffe Du wirst selber wissen, wie "alt" Deine Freundin ist... 😉
    Ansonsten tut sie mir echt leid. 😞
    Aber so sind die Beziehungen bei Stars nunmal... 🤡 👍



  • *g* euer humor...



  • Man, nicht alt - jung, sondern alt - neu! Du hast dir doch diese Zusammenhänge ausgedacht.

    Bye, TGGC (Der Held ist zurück)



  • Hier der Code, kann mir den jemand so umarbeiten, das der net so compliziert ist???

    Wenn du mp3-Dateien ohne großen Aufwand abspielen willst, solltest du Bibliotheken wie FMOD benutzen. Für sowas brauchst du dann nur 3 Zeilen.



  • echt, wie geht das mit der bib????



  • TGGC schrieb:

    Man, nicht alt - jung, sondern alt - neu!

    Genau DESWEGEN stand das alt in Anführungszeichen!! 🤡



  • Kann mir dan jemand die "3Zeilen" und zeigen was sie machen???



  • ich glaub, wenn du googlst(suchwörter fmod tutorial) findeste 10+ seiten über das thema 😃



  • Genau, lern mal selber denken! Niemand hat Lust dir hier täglich 3 Zeilen zu zeigen.

    Bye, TGGC (Der Held ist zurück)



  • Ihr habt ja recht.
    Dann formoliere ich dir Frage mal anders, welche Formate unterstützt DirectAudio 8? Unterstützt DirectAudio9 mehr Formate?
    Thx für Antworten 🙂


Anmelden zum Antworten