?? hxaudstr.cpp
字號:
m_Owner->AudioFormatNowKnown(); } if (!theErr && m_bSetupDone && !m_bInited) { theErr = ProcessInfo(); } return theErr;}/************************************************************************ * Method: * IHXAudioStream::Write * Purpose: * Write audio data to Audio Services. * * NOTE: If the renderer loses packets and there is no loss * correction, then the renderer should write the next packet * using a meaningful start time. Audio Services will play * silence where packets are missing. */STDMETHODIMP CHXAudioStream::Write( HXAudioData* pInData){ HX_RESULT theErr = HXR_OK; if (!pInData) { return HXR_INVALID_PARAMETER; } if (!m_bInited) { return HXR_NOT_INITIALIZED; } // Init pre-mix hooks. Call this once to set up hook info. if ( !m_bHooksInitialized ) { InitHooks(); } // Process any "hooks"; Add the data to the data list. /* If buffer is NULL, it means that the user just * wants to know what timestamp should be placed in the next * STREAMED/TIMED audio data */ if ( !m_bGotHooks || !pInData->pData) { theErr = AddData( pInData ); } else { HXAudioData outData; outData.pData = 0; outData.ulAudioTime = 0; theErr = ProcessHooks( pInData, &outData ); if (!theErr && !m_bDisableWrite ) { theErr = AddData( &outData ); } if (outData.pData) { outData.pData->Release(); } } return theErr;}/************************************************************************ * Method: * IHXAudioStream::AddPreMixHook * Purpose: * Use this method to add a pre-mix audio data hook. */STDMETHODIMP CHXAudioStream::AddPreMixHook( IHXAudioHook* pHook, const BOOL bDisableWrite){#if defined(HELIX_FEATURE_AUDIO_PREMIXHOOK) void* pTmp = 0; /* Does one already exists */ if (m_PreMixHookMap.Lookup((void*)pHook, pTmp)) { return HXR_INVALID_PARAMETER; } HXAudioHookInfo* pPreMixHookInfo = (HXAudioHookInfo*) new HXAudioHookInfo; if(!pPreMixHookInfo) { return HXR_OUTOFMEMORY; } pPreMixHookInfo->pHook = pHook; pPreMixHookInfo->bDisableWrite = bDisableWrite; pPreMixHookInfo->bIgnoreAudioData = FALSE; IHXValues* pValues = NULL; if (pHook && pHook->QueryInterface(IID_IHXValues, (void**) &pValues) == HXR_OK) { UINT32 ulValue = 0; pValues->GetPropertyULONG32("IgnoreAudioData", ulValue); pPreMixHookInfo->bIgnoreAudioData = (ulValue == 1); HX_RELEASE(pValues); } pHook->AddRef(); // Released in destructor m_PreMixHookMap.SetAt(pHook, pPreMixHookInfo); m_bGotHooks = TRUE; /* If any one of them is Disabled, we do not write */ if (bDisableWrite) { m_bDisableWrite = TRUE; } ProcessAudioHook(ACTION_ADD, pHook); /* If we are already initialized, send the audio format */ if (m_bHooksInitialized) { if (pPreMixHookInfo->bIgnoreAudioData || HXR_OK == ProcessAudioHook(ACTION_CHECK, pHook)) { pHook->OnInit( &m_AudioFmt ); } } return HXR_OK;#else return HXR_NOTIMPL;#endif /* HELIX_FEATURE_AUDIO_PREMIXHOOK */}/************************************************************************ * Method: * IHXAudioStream::RemovePreMixHook * Purpose: * Use this method to remove a pre-mix audio data hook. */STDMETHODIMP CHXAudioStream::RemovePreMixHook( IHXAudioHook* pHook){#if defined(HELIX_FEATURE_AUDIO_PREMIXHOOK) HXAudioHookInfo* pPreMixHookInfo = 0; BOOL bCheckForDisableWrite = FALSE; if (!m_PreMixHookMap.Lookup((void*)pHook, (void*&) pPreMixHookInfo)) { return HXR_INVALID_PARAMETER; } m_PreMixHookMap.RemoveKey(pHook); /* If we are removing a hook which had disable write, * we need to re-determine if any of the remaining hooks * has DisableWrite set to TRUE */ if (pPreMixHookInfo->bDisableWrite) { bCheckForDisableWrite = TRUE; m_bDisableWrite = FALSE; } ProcessAudioHook(ACTION_REMOVE, pHook); pPreMixHookInfo->pHook->Release(); delete pPreMixHookInfo; if (m_PreMixHookMap.GetCount() == 0) { m_bGotHooks = FALSE; m_bDisableWrite = FALSE; } else if (bCheckForDisableWrite) { CHXMapPtrToPtr::Iterator lIter = m_PreMixHookMap.Begin(); for (; lIter != m_PreMixHookMap.End(); ++lIter) { HXAudioHookInfo* pPreMixHook = (HXAudioHookInfo*) (*lIter); /* atleast one has Disable Write ON */ if (pPreMixHook->bDisableWrite) { m_bDisableWrite = TRUE; break; } } }#endif /* HELIX_FEATURE_AUDIO_PREMIXHOOK */ return HXR_OK;}/************************************************************************* Method:* IHXAudioStream::AddDryNotification* Purpose:* Use this to add a notification response object to get notifications* when audio stream is running dry.*/STDMETHODIMP CHXAudioStream::AddDryNotification ( IHXDryNotification* /*IN*/ pNotification ){ if (!pNotification) { return HXR_INVALID_PARAMETER; } void* pTmp = 0; /* Does one already exists */ if (m_DryNotificationMap.Lookup((void*)pNotification, pTmp)) { return HXR_INVALID_PARAMETER; } pNotification->AddRef(); m_DryNotificationMap.SetAt((void*)pNotification, (void*)pNotification); return HXR_OK;}/************************************************************************* Method:* IHXAudioStream2::RemoveDryNotification* Purpose:* Use this to remove itself from the notification response object* during the stream switching.*/STDMETHODIMP CHXAudioStream::RemoveDryNotification ( IHXDryNotification* /*IN*/ pNotification ){ HX_RESULT hr = HXR_OK; void* pTmp = 0; if (!pNotification) { hr = HXR_INVALID_PARAMETER; goto cleanup; } // remove only if it is exists if (m_DryNotificationMap.Lookup((void*)pNotification, pTmp)) { m_DryNotificationMap.RemoveKey((void*)pNotification); HX_RELEASE(pNotification); } else { hr = HXR_INVALID_PARAMETER; goto cleanup; }cleanup: return hr;}/************************************************************************* Method:* IHXAudioStream2::GetAudioFormat* Purpose:* Returns the input audio format of the data written by the * renderer. This function will fill in the pre-allocated * HXAudioFormat structure passed in.*/STDMETHODIMPCHXAudioStream::GetAudioFormat(HXAudioFormat* /*IN/OUT*/pAudioFormat){ HX_ASSERT(pAudioFormat); if (!pAudioFormat) { return HXR_INVALID_PARAMETER; } if (!m_bInited) { return HXR_UNEXPECTED; } pAudioFormat->uChannels = m_AudioFmt.uChannels; pAudioFormat->uBitsPerSample = m_AudioFmt.uBitsPerSample; pAudioFormat->ulSamplesPerSec = m_AudioFmt.ulSamplesPerSec; pAudioFormat->uMaxBlockSize = m_AudioFmt.uMaxBlockSize; return HXR_OK;} /************************************************************************ * Method: * IHXAudioStream::GetAudioVolume * Purpose: * Return this stream's IRMA volume interface. */STDMETHODIMP_(IHXVolume*) CHXAudioStream::GetAudioVolume(){ if ( m_pStreamVolume ) { m_pStreamVolume->AddRef(); return m_pStreamVolume; } else { return 0; }}#if defined(HELIX_FEATURE_VOLUME)/* * IHXVolumeAdviseSink methods */STDMETHODIMP CHXAudioStream::OnVolumeChange( const UINT16 uVolume){ m_uVolume = uVolume; return HXR_OK;}STDMETHODIMP CHXAudioStream::OnMuteChange( const BOOL bMute){ m_bMute = bMute; return HXR_OK;}#endif /* HELIX_FEATURE_VOLUME *//************************************************************************ * Method: * IHXAudioStream::AddData * Purpose: * Add audio data to list. * NOTE: Mark Streamed data also as Timed data IF we don't write a streamed packet * since it was LATE!!! */HX_RESULT CHXAudioStream::AddData( HXAudioData* pAudioData){ HX_RESULT theErr = HXR_OK; BOOL bInTSRollOver = FALSE; HXAudioInfo* pAinfo = 0; /* If buffer is NULL, it means that the user just * wants to know what timestamp should be placed in the next * STREAMED/TIMED audio data */ if (!pAudioData->pData) { HXAudioInfo* pInfo = NULL; if (!m_pDataList->IsEmpty() && NULL != (pInfo = (HXAudioInfo*) m_pDataList->GetTail())) { pAudioData->ulAudioTime = pInfo->ulStartTime + CalcMs(pInfo->pBuffer->GetSize()); } else { pAudioData->ulAudioTime = INT64_TO_UINT32(m_llLastWriteTime - CAST_TO_INT64 m_ulTSRollOver * CAST_TO_INT64 MAX_UINT32); } return HXR_OK; } // make sure the renderer does not pass NULL data!! HX_ASSERT(pAudioData->pData->GetBuffer() != NULL && pAudioData->pData->GetSize() != 0); if (pAudioData->pData->GetBuffer() == NULL || pAudioData->pData->GetSize() == 0) { return HXR_INVALID_PARAMETER; } if (m_bIsFirstPacket) { m_bIsFirstPacket = FALSE; IHXErrorMessages* pErrMsg = NULL; if (HXR_OK == m_Owner->m_pContext->QueryInterface(IID_IHXErrorMessages, (void**)&pErrMsg)) { DEBUG_OUT(pErrMsg, DOL_GENERIC, (s,"AudioFormatIn: %lu channels %lu SamplesPerSec", m_AudioFmt.uChannels, m_AudioFmt.ulSamplesPerSec)); DEBUG_OUT(pErrMsg, DOL_GENERIC, (s,"AudioFormatOut: %lu channels %lu SamplesPerSec", m_DeviceFmt.uChannels, m_DeviceFmt.ulSamplesPerSec)); } HX_RELEASE(pErrMsg); if (m_bIsLive)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -