📄 hxaudses.cpp
字号:
{ GET_IIDHANDLE(IID_IHXAudioDeviceManager2), (IHXAudioDeviceManager2*)this },
{ GET_IIDHANDLE(IID_IHXAudioPushdown), (IHXAudioPushdown*)this },
#ifdef HELIX_FEATURE_VOLUME
{ GET_IIDHANDLE(IID_IHXVolumeAdviseSink), (IHXVolumeAdviseSink*)this },
#endif
#if defined(HELIX_FEATURE_AUDIO_POSTMIXHOOK)
{ GET_IIDHANDLE(IID_IHXAudioHookManager), (IHXAudioHookManager*)this },
#endif
#if defined(HELIX_FEATURE_RESAMPLER) && !defined (HELIX_CONFIG_FIXEDPOINT)
{ GET_IIDHANDLE(IID_IHXAudioResamplerManager), (IHXAudioResamplerManager*)this },
#endif
{ GET_IIDHANDLE(IID_IHXAudioPushdown2), (IHXAudioPushdown2*)this },
};
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) CHXAudioSession::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) CHXAudioSession::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
/************************************************************************
* Method:
* CHXAudioSession::SetVolume
* Purpose:
* Set device volume. This is the audio device volume.
*
*/
void CHXAudioSession::SetVolume( const UINT16 uVolume)
{
m_uVolume = uVolume;
// only set the volume of not muted
if (!m_bMute)
{
HX_ASSERT(m_pCurrentAudioDev || !m_bReplacedDev);
_ConstructIfNeeded();
if (m_pCurrentAudioDev)
{
m_pCurrentAudioDev->SetVolume(uVolume);
}
}
}
void CHXAudioSession::_ConstructIfNeeded()
{
if (!m_pCurrentAudioDev)
{
CreateAudioDevice();
if (!m_bAudioDeviceSupportsVolume)
{
ReleaseAudioDevice();
}
}
}
/************************************************************************
* Method:
* CHXAudioSession::GetVolume
* Purpose:
* Get device volume. This is the audio device volume.
*
*/
UINT16 CHXAudioSession::GetVolume()
{
if(!m_bMute)
{
HX_ASSERT(m_pCurrentAudioDev || !m_bReplacedDev);
_ConstructIfNeeded();
if (m_pCurrentAudioDev)
{
m_uVolume = m_pCurrentAudioDev->GetVolume();
}
}
return m_uVolume;
}
/************************************************************************
* Method:
* CHXAudioSession::SetMute
* Purpose:
* Mute device volume. This is the audio device volume.
*
*/
void CHXAudioSession::SetMute( const BOOL bMute)
{
if (bMute != m_bMute)
{
m_bMute = bMute;
UINT16 volLevel = (m_bMute ? 0 : m_uVolume);
HX_ASSERT(m_pCurrentAudioDev || !m_bReplacedDev);
_ConstructIfNeeded();
if (m_pCurrentAudioDev)
{
m_pCurrentAudioDev->SetVolume( volLevel );
}
}
}
/************************************************************************
* Method:
* CHXAudioSession::Init
* Purpose:
* Setup the Audio Player list.
*/
HX_RESULT CHXAudioSession::Init(IUnknown* pContext)
{
HX_RESULT theErr = HXR_OK;
IHXBuffer* pBuffer = 0;
if (!pContext)
{
theErr = HXR_INVALID_PARAMETER;
goto cleanup;
}
m_pContext = pContext;
m_pContext->AddRef();
#if defined(HELIX_FEATURE_PREFERENCES)
// Get preferences interface and info..
pContext->QueryInterface(IID_IHXPreferences, (void **) &m_pPreferences);
#ifdef _UNIX
//Set up a global so we can read the ESDSupport pref
//when we create the audio device
z_pIHXPrefs = m_pPreferences;
#endif
#endif /* HELIX_FEATURE_PREFERENCES */
if (HXR_OK != pContext->QueryInterface(IID_IHXScheduler,
(void**) &m_pScheduler))
{
theErr = HXR_INVALID_PARAMETER;
goto cleanup;
}
pContext->QueryInterface(IID_IHXInterruptState, (void**) &m_pInterruptState);
// Create audio player list.
m_pPlayerList = new CHXSimpleList;
if (!m_pPlayerList || !m_pPlayerList->IsPtrListValid())
{
theErr = HXR_OUTOFMEMORY;
goto cleanup;
}
#if defined(HELIX_FEATURE_PREFERENCES)
if (m_pPreferences)
{
ReadPrefINT32(m_pPreferences, "MinimumInitalPushdown", m_ulMinimumPushdown);
ReadPrefINT32(m_pPreferences, "IdealMinimumInitalPushdown", m_ulIdealMinimumPushdown);
if (m_ulIdealMinimumPushdown > m_ulMinimumPushdown)
{
m_ulMinimumPushdown = m_ulIdealMinimumPushdown;
}
}
#endif /* HELIX_FEATURE_PREFERENCES */
// Create a device volume interface.
if ( !theErr )
{
#if defined(HELIX_FEATURE_VOLUME)
#if defined(HELIX_FEATURE_PREFERENCES)
if (m_pPreferences)
{
BOOL bOpenAudioDeviceOnPlayback = TRUE;
ReadPrefBOOL(m_pPreferences, "OpenAudioDeviceOnPlayback", bOpenAudioDeviceOnPlayback);
if (!bOpenAudioDeviceOnPlayback)
{
// rgammon 12/17/03
// Create audio device on init if OpenAudioDeviceOnPlayback is
// false. This means that we will be able to query the volume
// successfully on startup. It also means that if there are
// errors opening the audio device, they will show up at
// startup. Some players (the windows player, for example),
// save the system volume at shutdown and use that volume for
// the ui on startup.
CreateAudioDevice();
m_uVolume = GetVolume();
}
}
if (m_pPreferences)
{
if (ReadPrefINT16(m_pPreferences, "Volume", m_uVolume) != HXR_OK)
{
BOOL bUseDS = FALSE;
ReadPrefBOOL(m_pPreferences, "UseDirectSound", bUseDS);
if(bUseDS)
{
m_uVolume = HX_MAX_VOLUME;
}
}
#if defined(HELIX_FEATURE_MUTE_PREFERENCE )
ReadPrefBOOL(m_pPreferences, "Mute", m_bMute);
#endif /* HELIX_FEATURE_MUTE_PREFERENCE */
}
#endif /* HELIX_FEATURE_PREFERENCES */
m_pDeviceVolume = (IHXVolume*)new CHXVolume;
if( m_pDeviceVolume )
{
m_pDeviceVolume->AddRef();
m_pDeviceVolume->SetVolume(m_uVolume);
#if defined(HELIX_FEATURE_MUTE_PREFERENCE )
m_pDeviceVolume->SetMute(m_bMute);
#endif /* HELIX_FEATURE_MUTE_PREFERENCE */
m_pDeviceVolume->AddAdviseSink((IHXVolumeAdviseSink*)this);
}
else
theErr = HXR_OUTOFMEMORY;
#endif /* HELIX_FEATURE_VOLUME */
}
cleanup:
return theErr;
}
/************************************************************************
* Method:
* CHXAudioSession::CreateAudioPlayer
* Purpose:
* The RMA session object calls this to create an audio player. Each
* audio player represents a unique time-line.
*/
HX_RESULT CHXAudioSession::CreateAudioPlayer
(
CHXAudioPlayer** ppAudioPlayer
)
{
m_pMutex->Lock();
HX_RESULT theErr = HXR_OK;
// Create a new audio player.
*ppAudioPlayer= 0;
*ppAudioPlayer = new CHXAudioPlayer( this );
if ( !(*ppAudioPlayer) )
theErr = HXR_OUTOFMEMORY;
// Add new player to player list.
if (!theErr)
{
theErr = _CreateAudioPlayer(ppAudioPlayer);
}
m_pMutex->Unlock();
return theErr;
}
HX_RESULT
CHXAudioSession::_CreateAudioPlayer(CHXAudioPlayer** ppAudioPlayer)
{
HX_RESULT theErr = HXR_OK;
// Add new player to player list.
// Setup internal lists, etc.
theErr = (*ppAudioPlayer)->InitializeStructures();
if (!theErr)
{
// This one to keep it around.
(*ppAudioPlayer)->AddRef();
// This one to return back to the caller of CreateAudioPlayer.
(*ppAudioPlayer)->AddRef();
}
// Add new player to player list.
if ( !theErr && m_pPlayerList )
{
m_pPlayerList->AddTail((void*) *ppAudioPlayer);
}
if (theErr && *ppAudioPlayer)
{
/* Destructor is private. so this is the only way of destructing it */
(*ppAudioPlayer)->AddRef();
(*ppAudioPlayer)->Release();
*ppAudioPlayer = 0;
}
return theErr;
}
/************************************************************************
* Method:
* CHXAudioSession::CreateAudioPlayer
* Purpose:
* The RMA session object calls this to create an audio player. Each
* audio player represents a unique time-line.
*/
HX_RESULT CHXAudioSession::CloseAudioPlayer
(
CHXAudioPlayer* pAudioPlayer
)
{
m_pMutex->Lock();
if ( m_pPlayerList )
{
LISTPOSITION lPosition = NULL;
lPosition = m_pPlayerList->Find(pAudioPlayer);
if (lPosition)
{
m_pPlayerList->RemoveAt(lPosition);
pAudioPlayer->Close();
pAudioPlayer->Release();
}
}
m_pMutex->Unlock();
return HXR_OK;
}
/* ***********************************************************************
* Method:
* CHXAudioSession::Setup
* Purpose:
* Create the audio buffer..
*/
HX_RESULT CHXAudioSession::Setup(BOOL bHasStreams)
{
HX_RESULT theErr = HXR_OK;
// A new audio player may start while an existing player is
// already playing.
if ( m_bInited )
return HXR_OK;
/* Only do all of this if there are audio streams... */
m_bHasStreams = bHasStreams;
if (m_bHasStreams)
{
// Get the audio device format
// NOTE: The order of these function calls is important.
// Specifically, the GetDeviceFormat() must precede any of
// these calls because GetDeviceFormat() determines the
// final device audio format.
if (!theErr)
theErr = GetDeviceFormat();
// Create the playback buffers
/* We still need to create playback buffers since we will use the
* fake timeline if the presentation has atleast one media type other
* than audio
*/
if (!theErr || theErr == HXR_AUDIO_DRIVER)
{
CreatePlaybackBuffer();
}
// Reset the number of blocks we've written
m_ulBlocksWritten = 0;
// Open the audio device only if DisableWrite is OFF
/* This probably needs to be moved at the top so that
* when second player comes in and we are already intialized,
* we check for new value of disablewrite again
*/
CheckDisableWrite();
m_bUseFinalHook = FALSE;
if (!theErr && !m_bDisableWrite)
{
theErr = OpenDevice();
} /* If disable wirte is ON, release the audio device */
else if (!theErr)
{
m_pAudioDev = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -