WASAPI C++ DLL Темы, висящие в приложении C#

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

У меня есть неуправляемая DLL для аудио-приложения, которое создает поток и ждет события от звуковой карты, чтобы заполнить буфер вывода.

Приложение прекрасно работает со встроенной звуковой картой, но если я переключаюсь на любое USB-аудиоустройство, поток просто зависает.

Вот основные биты кода: я инициализирую свое событие в моей функции инициализации

::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.

0 ответов

Другие вопросы по тегам