Я довольно тщательно искал похожий вопрос, но не нашел точного случая, который у меня есть.
У меня есть неуправляемая DLL для аудио-приложения, которое создает поток и ждет события от звуковой карты, чтобы заполнить выходной буфер.
Приложение прекрасно работает со встроенной звуковой картой, но если я переключаюсь на любое USB-аудиоустройство, поток просто зависает.
Вот основные биты кода:
Я инициализирую свое Событие в моей функции Initialize
::Initialize()
{
_AudioSamplesReadyEvent = CreateEventEx(NULL, L"InputReady", 0, EVENT_MODIFY_STATE | SYNCHRONIZE);
}
И передать его звуковому устройству после его инициализации
::InitiAudioEngine()
{
hr = _AudioClient->SetEventHandle(_AudioSamplesReadyEvent);
}
Вот нить
//HRESULT hr = CoInitializeEx(NULL, COINIT_SPEED_OVER_MEMORY); //gets called in the constructor of my renderthread class
DWORD DoRenderThread()
{
HANDLE waitArray[2] = {_ShutdownEvent, _AudioSamplesReadyEvent};
HANDLE mmcssHandle = NULL;
DWORD mmcssTaskIndex = 0;
mmcssHandle = AvSetMmThreadCharacteristics(L"Audio", &mmcssTaskIndex);
while (_StillPlaying)
{
HRESULT hr;
DWORD waitResult = WaitForMultipleObjects(2, waitArray, FALSE, INFINITE);
switch (waitResult)
{
case WAIT_OBJECT_0 + 0: // _ShutdownEvent
_StillPlaying = false; // We're done, exit the loop.
break;
case WAIT_OBJECT_0 + 1: // _AudioSamplesReadyEvent
// We need to provide the next buffer of samples to the audio renderer.
BYTE *pData;
//invoke the callback to the managed app to fill our buffer
_Handler(NULL, 0);
hr = _RenderClient->GetBuffer(_BufferSizePerPeriod, &pData);
if (SUCCEEDED(hr))
{
// Copy data from the render buffer to the output buffer and bump our render pointer.
if(_FrameSize == QUAD_FRAME)
{
//we have to remux the stream data in to an L,R,LR,RR frame
//inserting silence for the rear channels
const int bufmuxsz = FIXED_FRAME_SIZE * QUAD_FRAME;
BYTE muxarray[bufmuxsz] = {0};
BYTE tempbuffer[FIXED_FRAME_SIZE * STEREO_FRAME];
CopyMemory(tempbuffer, _Buffer, FIXED_FRAME_SIZE * STEREO_FRAME);
int i = 0;
for(int x = 0; x < bufmuxsz; ++x)
{
muxarray[x++] = tempbuffer[i++];
muxarray[x++] = tempbuffer[i++];
muxarray[x++] = tempbuffer[i++];
muxarray[x++] = tempbuffer[i++];
x += 3; //the array is initialized to '0' so skip the assignments
}
CopyMemory(pData, muxarray, _BufferSizePerPeriod*_FrameSize);
}
else
{
CopyMemory(pData, _Buffer, _BufferSizePerPeriod * _FrameSize);
}
hr = _RenderClient->ReleaseBuffer(_BufferSizePerPeriod, 0);
if (!SUCCEEDED(hr))
{
printf("Playback Failed!!\n");
_StillPlaying = false;
}
}
else
{
_StillPlaying = false;
}
break;
}
}
AvRevertMmThreadCharacteristics(mmcssHandle);
CoUninitialize();
return 0;
}
Мои 2 события, которые я жду, — это событие завершения работы и событие samplesready со звуковой карты. Это всегда бьет один раз, но потом зависает. Опять же, это только с аудио интерфейсами USB.
Задача ещё не решена.
Других решений пока нет …