//Initialization
HRESULT CWASAPIRenderFilter::Init()
{
  if (!m_pSettings->m_bUseWASAPI)
    return S_FALSE;

  if (m_pSettings->m_bWASAPIUseEventMode)
  {
    // Using HW DMA buffer based event notification
    m_hDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    m_dwStreamFlags = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
  }
  else
  {
    // Using rendering thread polling
    m_hDataEvent = CreateWaitableTimer(NULL, TRUE, NULL);
    m_dwStreamFlags = 0;
  }

  m_hDataEvents.push_back(m_hStopThreadEvent);
  m_hDataEvents.push_back(m_hDataEvent);

  m_dwDataWaitObjects.push_back(MPAR_S_THREAD_STOPPING);
  m_dwDataWaitObjects.push_back(MPAR_S_NEED_DATA);

  m_hSampleEvents.push_back(m_hStopThreadEvent);
  m_hSampleEvents.push_back(m_hOOBCommandAvailableEvent);
  m_hSampleEvents.push_back(m_hInputAvailableEvent);

  m_dwSampleWaitObjects.push_back(MPAR_S_THREAD_STOPPING);
  m_dwSampleWaitObjects.push_back(MPAR_S_OOB_COMMAND_AVAILABLE);
  m_dwSampleWaitObjects.push_back(S_OK);

  ResetClockData();

  return CQueuedAudioSink::Init();
}
Пример #2
0
CWASAPIRenderFilter::CWASAPIRenderFilter(AudioRendererSettings* pSettings, CSyncClock* pClock, Logger* pLogger) :
  CQueuedAudioSink(pSettings, pLogger),
  m_pClock(pClock),
  m_hLibAVRT(NULL),
  m_pMMDevice(NULL),
  m_pAudioClient(NULL),
  m_pRenderClient(NULL),
  m_nFramesInBuffer(0),
  m_hTask(NULL),
  m_nBufferSize(0),
  m_hDataEvent(NULL),
  m_pAudioClock(NULL),
  m_nHWfreq(0),
  m_dwStreamFlags(AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST),
  m_state(StateStopped),
  m_bIsAudioClientStarted(false),
  m_bDeviceInitialized(false),
  m_rtNextSampleTime(0),
  m_rtHwStart(0),
  m_nSampleOffset(0),
  m_nDataLeftInSample(0),
  m_llPosError(0),
  m_ullPrevQpc(0),
  m_ullPrevPos(0),
  m_hNeedMoreSamples(NULL),
  m_rtLatency(0),
  m_dOutputBufferSize(m_pSettings->GetOutputBuffer() * 10000),
  m_pLogger(pLogger)
{
  OSVERSIONINFO osvi;
  ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

  GetVersionEx(&osvi);
  bool bWASAPIAvailable = osvi.dwMajorVersion > 5;

  if (!bWASAPIAvailable)
    Log("Disabling WASAPI - OS version earlier than Vista detected");

  // Load Vista specifics DLLs
  m_hLibAVRT = LoadLibrary (_T("AVRT.dll"));
  if (m_hLibAVRT && bWASAPIAvailable)
  {
    pfAvSetMmThreadCharacteristicsW   = (PTR_AvSetMmThreadCharacteristicsW)	GetProcAddress (m_hLibAVRT, "AvSetMmThreadCharacteristicsW");
    pfAvRevertMmThreadCharacteristics	= (PTR_AvRevertMmThreadCharacteristics)	GetProcAddress (m_hLibAVRT, "AvRevertMmThreadCharacteristics");
  }
  else
    pSettings->SetUseWASAPI(false);	// WASAPI not available below Vista

  if (pSettings->GetUseWASAPI())
  {
    IMMDeviceCollection* devices = NULL;
    pSettings->GetAvailableAudioDevices(&devices, NULL, true);
    SAFE_RELEASE(devices); // currently only log available devices
  }

  // We are the end point in the pipeline so we cannot ever have passtru
  m_bNextFormatPassthru = false; 

  m_nOutBufferCount = WASAPI_OUT_BUFFER_COUNT;

  ResetClockData();
}