mciSendString не приостанавливает воспроизведение звука из потока

Недавно я уже просил решение, подобное этому:

Есть ли способ приостановить / остановить воспроизведение mp3-файла с помощью mcisendstring с помощью "Подождите" вариант?

Я хочу реализовать функцию в моем аудиоплеере, которая позволяет людям непрерывно воспроизводить звук, в то время как ползунок перемещается в соответствии с текущей секундой, в которой выполняется трек, а также с возможностью перехода к следующему треку после того, как текущий трек завершен. над

После (как вы можете прочитать в ссылке) попытаться сделать это с

mciSendString("play mp3 wait", NULL, 0, NULL);

который потерпел неудачу из-за проблемы, что трек не может быть приостановлен или остановлен, пока он не закончен, я сейчас пытаюсь реализовать это другим способом. В настоящее время, когда я начинаю проигрывать трек, я также запускаю другой поток, который запускает счетчик. Счетчик получает длину дорожки в секундах и отсчитывает время, также предлагая мьютекс для приостановки / возобновления работы счетчика. Чтобы не допустить, чтобы мой MusicCycle просто зациклился, я присоединяюсь к потоку, поэтому жду его завершения.

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
}
}

Обратите внимание, что весь этот метод также создается в потоке:

m_cycleThread = boost::thread(boost::bind(&Music::MusicCycle, this, trackPath));

Поток, запущенный функцией 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 / Resume, которые также вызывают соответствующие функции mciSendString

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

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

Когда я теперь вызываю pause, mciSendString приостанавливает дорожку, а также блокирует счетчик, чтобы он не продолжал обратный отсчет.

Однако проблема в том, что он все еще не работает. Пауза просто не влияет на воспроизведение музыки, несмотря на мои попытки придумать решение без использования опции ожидания в mciSendString

Любой совет?

РЕДАКТИРОВАТЬ: Оказывается, это на самом деле происходит из-за потоков. Я довольно долго занимался C #, и вы могли бы использовать Invokes для решения проблем с потоками. Может быть, это возможно и здесь?

РЕДАКТИРОВАТЬ 2: Я прочитал немного, и кажется, что есть возможность Опубликовать метод в очереди сообщений другого потока через вызов PostMessage WinAPI. Это возможность здесь? Если да, может ли кто-нибудь привести хороший пример? Я немного прочитал, но я до сих пор не очень понимаю

Есть ли что-то подобное в C ++?

4

Решение

РЕДАКТИРОВАТЬ: Оказывается, это на самом деле происходит из-за потоков. Я довольно долго занимался C #, и вы могли бы использовать Invokes для решения проблем с потоками.

Да. Если вам нужен поток пользовательской земли для асинхронных событий затем сообщение в очереди — это ваш курс действий (например, C # (или Java и т. д.) invoke-on-UI-thread). Это тяжелая работа.

РЕДАКТИРОВАТЬ 2: Я прочитал немного, и кажется, что есть возможность Опубликовать метод в очереди сообщений другого потока через вызов PostMessage WinAPI. Это возможность здесь? Если да, может ли кто-нибудь привести хороший пример? Я немного прочитал, но я до сих пор не очень понимаю

Есть ли что-то подобное в C ++?

То, что вы имеете в виду, это просто общий цикл обработки сообщений / событий, который лежит в основе почти всех структур пользовательского интерфейса. C ++ изначально не имеет «GUI», но, безусловно, существуют библиотеки, которые имеют схожие возможности.

Ускорение Асио было одним упоминанием. Если у вас уже есть GUI-фреймворк, у него будет свой собственный цикл обработки событий (он есть у Qt, MFC и т. Д.).

Независимо от того, что используется, все приложения Win32 GUI в конечном итоге используют насос сообщений, о котором вы упоминали, который действительно позволяет отправлять сообщения.
Это почти всегда неправильный уровень абстракции, если вы активно не разрабатываете свою среду GUI².

Вы всегда можете построить свой собственный. Просто есть какая-то (приоритетная) очередь для получения сообщений и главный цикл, обрабатывающий их. Назовите их событиями и быстро: управляемый событиями дизайн.


¹ на данный момент есть волна назад с новомодными назад к основам, как https://github.com/ocornut/imgui

² тот факт, что этот вопрос существует, говорит мне, что вы этого не делаете

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]