Воспроизвожу звук так:
PlaySound( "C:\\snd.wav" , NULL , SND_FILENAME | SND_ASYNC );
В итоге если звук нужно воспроизвести несколько раз, при каждом воспроизведении старый звук прекращается не доиграв до конца.
Как можно сделать чтобы звуки проигрывались, при этом не завершая предыдущий пока он сам по себе не доиграет?
Первый способ:
Вызывать PlaySound
с флагом SND_SYNC
в цикле столько раз, сколько надо.
int main()
{
for (int i = 0; i < 2; ++i)
{
BOOL ret = PlaySound(L"c:\\Windows\\media\\Alarm01.wav", NULL, SND_FILENAME | SND_SYNC | SND_NOSTOP);
if (ret != TRUE)
{
std::cerr << "Error playing sound :(" << std::endl;
}
}
system("pause");
return 0;
}
Минус такого способа в блокирующем вызове PlaySound, пока проигрывание звука не завершится функция не вернет управление. Можно поместить данный код в поток и управлять
Второй:
Можно вызвать PlaySound
с флагом SND_LOOP
int main()
{
BOOL ret = PlaySound(L"c:\\Windows\\media\\Alarm01.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
if (ret != TRUE)
{
std::cerr << "Error playing sound :(" << std::endl;
}
system("pause");
// Stop playing
PlaySound(NULL, NULL, 0);
return 0;
}
Минус - непонятно как контролировать, сколько раз проигрался звук.
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;
}
К сожалению, проблему невозможно решить, или нужно делать очень дикие костыли.
Сделал проще, подключил библиотеку BASS и все работает как нужно, правда уже без WinAPI функции.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Могут ли возникнуть проблемы с работой со строками если использовать не char* /const char*, а unsigned char*/const unsigned char*? Если все правильно, к примеру, в UTF-8,...
Имеется форма с двумя выпадающими списками и одной кнопкойПо нажатию на кнопку отправляются данные в виде json, на основе этих данных выполняется...