0

我必须在我的 UI 中播放多种声音,例如按钮点击、错误、通知等。为此,我编写了以下代码(以前从未在 Windows 中播放过 mp3):

bool ClientHandler::InitSoundAndMusic()
{
    m_pSoundGraph = NULL;
    m_pSoundControl = NULL;

    HRESULT hr = ::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
                                    (void**) &m_pSoundGraph);

    if (!SUCCEEDED(hr) || !m_pSoundGraph)
        return false;

    hr = m_pSoundGraph->QueryInterface(IID_IMediaControl, (void**) &m_pSoundControl);
    if (!SUCCEEDED(hr) || !m_pSoundControl)
        return false;

    return true;
}

void ClientHandler::PlayFile(LPCTSTR file)
{
    if (!m_pSoundGraph)
        return;

    m_pSoundControl->Stop();
    HRESULT hr = m_pSoundGraph->RenderFile(file, NULL);
    if (SUCCEEDED(hr))
        m_pSoundControl->Run();
}

bool ClientHandler::OnEvent(const String& message)
{
    if (message == _T("button"))
    {
        PlayFile(_T(".\\sound\\button.mp3"));
        return true;
    }

    return false;
}

它似乎很慢。当我每秒单击一个按钮约 5 次时,用户界面就会冻结。我想,我不应该每次都调用 Stop/Render/Run,但我不知道如何避免它。我应该如何重写代码?

问候,

4

1 回答 1

0

而不是 DirectShow,我只是尝试了 libzplay (http://libzplay.sourceforge.net/)。

让我引用它的自述文件:

如何在 C++ 中使用 libZPlay

  1. 将 libzplay.h 包含到您的源代码中
  2. 包含 libZPlay 命名空间

    使用命名空间 libZPlay;

  3. 将您的项目与导入库链接。

    libzplay.lib - libzplay.dll 的 VC++ 导入库 libzplay_borland.lib
    - libzplay.dll 的 Borland C++ 导入库
    libzplay.a - libzplay.dll 的 MinGW/GCC 导入库

  4. 创建 ZPlay 类。

    ZPlay *player = CreateZPlay();

  5. 打开文件。

    if(player->OpenFile("mySong.mp3", sfAutodetect) == 0) { // 错误 }

  6. 开始播放

    播放器->播放();

  7. 最后销毁 ZPlay 类

    播放器->释放();

它工作顺利。我可以只打开一次文件,并在每次需要时调用 Play()。在 DirectShow 中调用 Run() 的方式不同。

这就是 The Right Library 必须的:30 分钟从头开始嵌入和坚固的岩石。

于 2012-06-25T20:11:59.967 回答