Show / Hide Table of Contents

MSDN.WhiteKnight - Stack Overflow answers

Ответ на "Проблема с PlaySoundA"

Answer 981885

Link

PlaySound - самый примитивный из звуковых API в Windows, кроме того, устаревший лет 10 назад. Параллельное воспроизведение он действительно не поддерживает (видимо, для отслеживания состояния воспроизведения используется какой-то глобальный объект, который каждый раз сбрасывается). PlaySound нормально использовать для воспроизведения коротких звуков из ресурсов или системных звуков, но для файлов лучше взять что-то более продвинутое, хотя бы DirectShow:

#include <windows.h>
#include <Dshow.h>
#include <stdio.h>

#pragma comment( lib, "winmm.lib" )
#pragma comment( lib, "Strmiids.lib" )

void PlaySoundNew_Impl(const TCHAR* file){ //реализация воспроизведения файла с использованием DirectShow

    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent   *pEvent = NULL;       

    // Create the filter graph manager and query for interfaces.
    HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&pGraph);
    if (FAILED(hr))
    {
        printf("ERROR - Could not create the Filter Graph Manager.");
        return;
    }

    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

    // Build the graph. 
    hr = pGraph->RenderFile(file, NULL);
    if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // Wait for completion.
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);                       
        }
    }
    else printf("RenderFile error 0x%x",(UINT)hr);

    pControl->Release();
    pEvent->Release();
    pGraph->Release();
}

DWORD WINAPI PlaySoundNew_ThreadProc(LPVOID lpThreadParameter){ //функция для фонового потока

    HRESULT hr = CoInitialize(NULL); //для фонового потока также нужна инициализация COM
    if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return 1;
    }

    const TCHAR* file = (const TCHAR*)lpThreadParameter;
    PlaySoundNew_Impl(file);

    CoUninitialize();
    return 0;
}

void PlaySoundNew(const TCHAR* file, bool async){ //воспроизведение файла через DirectShow

    if( async == FALSE){ 
        PlaySoundNew_Impl(file); //синхронно        
    }
    else{ 
        CreateThread(NULL,0,PlaySoundNew_ThreadProc,(LPVOID)file,0,NULL); //асинхронно
    }
}

int main(int argc, char* argv[])
{   
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return 1;
    }

    PlaySoundNew(L"C:\\Music\\Sound1.wav", true);
    Sleep(2000);
    PlaySoundNew(L"C:\\Music\\Sound2.wav", true);   

    getchar();
    CoUninitialize();
    return 0;
}

Content is retrieved from StackExchange API.

Auto-generated by ruso-archive tools.

Back to top Stack Overflow answers (published from sources in GitHub repository). Copyright (c) 2020, MSDN.WhiteKnight. Content licensed under BSD 3-Clause License.
Generated by DocFX