⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxaudstr_new.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	HXAudioData audioData ;	audioData.pData = m_piPendingAudioData ;	audioData.pData->AddRef() ;	// use time of incoming packet -- one sample frame is below the	// ms resolution of time stamps.	audioData.ulAudioTime = pInData->ulAudioTime;	// stream type is incoming stream type	audioData.uAudioStreamType = pInData->uAudioStreamType;	theErr = Write2(&audioData) ;	audioData.pData->Release() ;	m_ulPendingAudioBytes = 0 ;	// release the slush buffer	HX_RELEASE(m_piPendingAudioData) ;	if (FAILED(theErr))	    return theErr ;    }    // put partial sample frames from the end of the incoming buffer    // into the slush buffer.    if (ulInBytes % m_ulSampleFrameSize)    {	// the slush buffer should be empty here.	HX_ASSERT(m_ulPendingAudioBytes == 0);	HX_ASSERT(m_piPendingAudioData == 0) ;	// reserve a new slush buffer	theErr = CreateInstance(IID_IHXBuffer, (void**)&m_piPendingAudioData);	if (SUCCEEDED(theErr))	    theErr = m_piPendingAudioData->SetSize(m_ulSampleFrameSize) ;	if (SUCCEEDED(theErr))	{	    m_ulPendingAudioBytes = ulInBytes % m_ulSampleFrameSize ;	    ulInBytes -= m_ulPendingAudioBytes ;	    memcpy(m_piPendingAudioData->GetBuffer(),		   pInData->pData->GetBuffer() + ulCutoffBytes + ulInBytes,		   m_ulPendingAudioBytes) ;	}	if (FAILED(theErr))	    return theErr ;    }    // send any leftover fragment of the incoming buffer.    if (ulInBytes == pInData->pData->GetSize() && !ulCutoffBytes)    /* this is the entire buffer, not a fragment.      * This is the normal case -- let's handle it efficiently. */    {	theErr = Write2(pInData) ;    }    else if (ulInBytes)    /* if anything left in buffer, send it in a fragment */    {	HXAudioData audioData ;	CHXBufferFragment* pFragment = new CHXBufferFragment(	    pInData->pData,	    pInData->pData->GetBuffer() + ulCutoffBytes,	    ulInBytes);	theErr = pFragment->QueryInterface(IID_IUnknown, (void**)&audioData.pData) ;	// this must always succeed, since we know it exports a IHXBuffer	HX_ASSERT(SUCCEEDED(theErr)) ;	// use time of incoming packet -- one sample frame is below the	// ms resolution of time stamps.	audioData.ulAudioTime = pInData->ulAudioTime;	// stream type is incoming stream type if we did not cut anything away,	// and STREAMED_AUDIO if we did (because in that case this is a continuation)	audioData.uAudioStreamType = ulCutoffBytes ? STREAMING_AUDIO : pInData->uAudioStreamType ;	theErr = Write2(&audioData) ;	// we release our hold on pFragment here. When MixIntoBuffer() is done with	// this fragment, it will also release its hold, and the fragment gets	// deleted.	audioData.pData->Release() ;    }#else    theErr = Write2(pInData) ;#endif /* HELIX_FEATURE_AUDIO_INCOMPLETESAMPLE */    return theErr;}/************************************************************************ *  Method: *		IHXAudioStream::Write2 *  Purpose: *      Write audio data to Audio Services. This is a companion/backend *      function to IHXAudioStream::Write * */HX_RESULT CHXAudioStream::Write2(HXAudioData* pInData){    HX_RESULT theErr = HXR_OK;    // 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;    pPreMixHookInfo->pHook   	    = pHook;    pPreMixHookInfo->bDisableWrite  = bDisableWrite;    pPreMixHookInfo->bFinal = FALSE;    pPreMixHookInfo->bIgnoreAudioData = FALSE;    pPreMixHookInfo->bMultiChannelSupport = 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    IHXAudioMultiChannel* pMultiChannel = NULL;    if (pHook && HXR_OK == pHook->QueryInterface(IID_IHXAudioMultiChannel, (void**) &pMultiChannel))    {        pPreMixHookInfo->bMultiChannelSupport = pMultiChannel->GetMultiChannelSupport();    }    HX_RELEASE(pMultiChannel);    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(){    IHXVolume* pRet = NULL;    #ifdef HELIX_FEATURE_VOLUME        if( m_pStreamVolume )    {        m_pStreamVolume->AddRef();        pRet = m_pStreamVolume;    }#endif        return pRet;}#if defined(HELIX_FEATURE_VOLUME)//// IHXVolume methods//STDMETHODIMP CHXAudioStream::OnVolumeChange(const UINT16 uVolume){    m_uVolume = uVolume;#ifdef HELIX_FEATURE_GAINTOOL    if (m_pMixEngine)        m_pMixEngine->SetVolume(m_pMixEngine->HXVolume2TenthOfDB(m_uVolume)) ; #endif    return HXR_OK;}STDMETHODIMP CHXAudioStream::OnMuteChange(const BOOL bMute){    m_bMute = bMute;#ifdef HELIX_FEATURE_GAINTOOL    if (m_pMixEngine)        m_pMixEngine->SetVolume(m_pMixEngine->HXVolume2TenthOfDB(bMute ? HX_MIN_VOLUME : m_uVolume)) ;#endif    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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -