C++ mciSendString不';t暂停从线程播放的声音

C++ mciSendString不';t暂停从线程播放的声音,c++,boost,boost-thread,mcisendstring,C++,Boost,Boost Thread,Mcisendstring,最近我已经提出了类似于以下问题的解决方案: 我想在我的音频播放器中实现一个功能,允许人们连续播放声音,同时滑块根据当前曲目运行的秒数移动,并且还具有在当前曲目结束后转到下一个曲目的功能 在(正如你在链接中看到的)尝试使用 mciSendString("play mp3 wait", NULL, 0, NULL); 由于在完成之前无法暂停或停止音轨的问题,它失败了,我现在尝试以另一种方式实现它。目前,当我开始播放曲目时,我还启动了另一个线程,即启动计数器。计数器以秒为单位获取曲目的长度,并倒计

最近我已经提出了类似于以下问题的解决方案:

我想在我的音频播放器中实现一个功能,允许人们连续播放声音,同时滑块根据当前曲目运行的秒数移动,并且还具有在当前曲目结束后转到下一个曲目的功能

在(正如你在链接中看到的)尝试使用

mciSendString("play mp3 wait", NULL, 0, NULL);
由于在完成之前无法暂停或停止音轨的问题,它失败了,我现在尝试以另一种方式实现它。目前,当我开始播放曲目时,我还启动了另一个线程,即启动计数器。计数器以秒为单位获取曲目的长度,并倒计时,还提供一个用于暂停/恢复计数器的互斥锁。为了阻止我的音乐循环不受控制地循环,我加入了线程,因此等待它的终止

void Music::MusicCycle(std::wstring trackPath)
{
    while (true)
    {
        OpenMP3(trackPath);
        mciSendString("play mp3", NULL, 0, NULL);

        m_counterThread = boost::thread(boost::bind(&Counter::StartCount, m_counter, <length of track in seconds>));
        m_counterThread.join();

        //... Get new track here
    }
}
MusicCycle函数启动的线程如下所示:

void Counter::StartCount(int seconds)
{
    boost::mutex::scoped_lock lock(m_mutex);

    for (int i = 0; i < seconds; i++)
    {
        while (m_counterLock)
        {
            m_condVar.wait(lock);
        }

        boost::this_thread::sleep(boost::posix_time::seconds(1));
    }
}
当我调用pause now时,mciSendString将暂停曲目,并锁定计数器,使其不会继续倒计时

然而,问题是它仍然不起作用。暂停根本不会影响音乐的播放,尽管我努力想出了一个解决方案,但没有使用mciSendString中的wait选项

有什么建议吗

编辑:事实证明,这实际上是由于线程造成的。我已经做了很长时间的C#,您可以使用调用来解决线程问题。也许这在这里也是可能的

EDIT2:我读了一点,似乎有一个选项可以通过PostMessage WinAPI调用在另一个线程的消息队列中发布一个方法。这有可能吗?如果有,谁能提供一个好的例子?我读了一点,但到目前为止我还不太明白

< C++中也有类似的事情吗?

编辑:事实证明,这实际上是由于线程造成的。我已经做了很长时间的C#,您可以使用调用来解决线程问题

对。如果您需要一个用于异步事件的用户登录线程,那么排队消息就是您的操作过程(比如在UI线程上调用C#(或Java等)。这是一项艰苦的工作

EDIT2:我读了一点,似乎有一个选项可以通过PostMessage WinAPI调用在另一个线程的消息队列中发布一个方法。这有可能吗?如果有,谁能提供一个好的例子?我读了一点,但到目前为止我还不太明白

< C++中也有类似的事情吗?

您所指的只是几乎所有UI框架下的一般消息泵/事件循环。C++没有“GUI”,但肯定存在类似的库。

Boost Asio是值得一提的。如果您已经有一个GUI框架,它将有自己的事件循环(Qt、MFC等)

不管使用什么,所有Win32 GUI应用程序最终都会使用您提到的消息泵,它确实允许发布消息。 这几乎总是错误的抽象级别,除非您正在积极开发GUI框架

你总是可以建立自己的。只需使用某种(优先级)队列来接收消息,并使用一个主循环来处理这些消息。将它们称为事件和pronto:事件驱动设计


目前,有一股潮流卷土重来,新的时尚回归到了基本元素,如


²这个问题的存在告诉我你没有这样做

你能简化吗?MCI命令是否在更简单的应用程序中工作?为什么你总是产生一个新的线程?你是否考虑过使用Boost ASIO和一个合适的时钟来测量时间(也许MCI有一个传输接口可以告诉你实际的轨道位置,所以你不需要做所有的英雄)。@ Seh一个线程是这样做的,即当我有连续播放时,UI不会挂起,而另一个用于计数器,这样它就不会阻碍歌曲的播放。是的,如果我不尝试跨线程执行它,它就会工作。我可能需要研究asio,但计数器现在并没有真正妨碍我,而是跨线程的mcisendstring问题。如果没有线程问题,你就不需要计数器。另外,我问“为什么你总是产生一个新的线程?”。你只回答了第一部分(明显的)哦,对了,我现在明白你的意思了。我已经修好了,我会尽快更新我的电脑。
void Counter::StartCount(int seconds)
{
    boost::mutex::scoped_lock lock(m_mutex);

    for (int i = 0; i < seconds; i++)
    {
        while (m_counterLock)
        {
            m_condVar.wait(lock);
        }

        boost::this_thread::sleep(boost::posix_time::seconds(1));
    }
}
mciSendString("resume mp3", NULL, 0, NULL);

mciSendString("pause mp3", NULL, 0, NULL);