📄 hxaudses.cpp
字号:
{ m_bDeferActualResume = FALSE; theErr = ActualResume(); } m_bFirstPlayAudio = FALSE; m_pMutex->Unlock(); return theErr;}HX_RESULTCHXAudioSession::CheckForBufferReuse(){ if (m_pSessionBuf) { m_pSessionBuf->AddRef(); if (m_pSessionBuf->Release() > 1) { /* * Cannot use this buffer the next time * release our reference and create a new one */ m_pSessionBuf->Release(); m_pSessionBuf = (IHXBuffer*) new CHXBuffer; if( m_pSessionBuf ) { m_pSessionBuf->AddRef(); } else { return HXR_OUTOFMEMORY; } } } else { /* create this buffer */ m_pSessionBuf = (IHXBuffer*) new CHXBuffer; if( m_pSessionBuf ) { m_pSessionBuf->AddRef(); } else { return HXR_OUTOFMEMORY; } } if (m_pPlayerBuf) { m_pPlayerBuf->AddRef(); if (m_pPlayerBuf->Release() > 1) { /* * Cannot use this buffer the next time * release our reference and create a new one */ m_pPlayerBuf->Release(); m_pPlayerBuf = (IHXBuffer*) new CHXBuffer; if( m_pSessionBuf ) { m_pPlayerBuf->AddRef(); } else { return HXR_OUTOFMEMORY; } } } return HXR_OK;}void CHXAudioSession::ConvertTo8BitAndOrMono(HXAudioData* pAudioData){ BOOL bChannelConversion = (m_BeforeHookDeviceFmt.uChannels == 1) && (m_DeviceFmt.uChannels == 2); BOOL bBitConversion = m_BeforeHookDeviceFmt.uBitsPerSample == 8; /* Atleast one of them should be true to be in this function */ HX_ASSERT(bChannelConversion || bBitConversion); ULONG32 ulLen = pAudioData->pData->GetSize(); short int* pShortBuf = (short int*) pAudioData->pData->GetBuffer(); UCHAR* pOutUCharBuf = pAudioData->pData->GetBuffer(); short int* pOutShortBuf = (short int*) pAudioData->pData->GetBuffer(); ULONG32 ulLoopCount = ulLen; if (bBitConversion && bChannelConversion) { ulLen = pAudioData->pData->GetSize() / 4; ulLoopCount = pAudioData->pData->GetSize() / 4; } else if (bBitConversion && !bChannelConversion) { ulLen = pAudioData->pData->GetSize() / 2; ulLoopCount = pAudioData->pData->GetSize() / 2; } else /*if (!bBitConversion && bChannelConversion) */ { ulLen = pAudioData->pData->GetSize() / 2; ulLoopCount = pAudioData->pData->GetSize() / 4; } for(ULONG32 j = 0; j < ulLoopCount; j++) { if (bBitConversion && bChannelConversion) { *pOutUCharBuf++ = (UCHAR) ( ((LONG32) ((*pShortBuf++ + 32768L) >> 8) + (LONG32) ((*pShortBuf++ + 32768L) >> 8))/2 ); } else if (bBitConversion && !bChannelConversion) { *pOutUCharBuf++ = (UCHAR)((*pShortBuf++ + 32768L) >> 8); } else /*if (!bBitConversion && bChannelConversion) */ { *pOutShortBuf++ = (short int) (((LONG32) *pShortBuf++ + (LONG32) *pShortBuf++)/2); } } pAudioData->pData->SetSize(ulLen);}/************************************************************************ * Method: * CHXAudioSession::ConvertToEight * Purpose: */void CHXAudioSession::ConvertToEight(){ UCHAR* pSessionBuf = m_pSessionBuf->GetBuffer(); ULONG32 ulLen = m_ulBytesPerGran / sizeof(short); short int* iTmp = (short int*) pSessionBuf; for(ULONG32 j = 0; j < ulLen; j++ ) { pSessionBuf[j] = (UCHAR) ((*iTmp++ + 32768L) >> 8); }}/************************************************************************ * Method: * CHXAudioSession::TryOpenAudio * Purpose: * Try to open the audio device. */HX_RESULT CHXAudioSession::TryOpenAudio(){ HX_RESULT theErr = HXR_OK; BOOL bDeviceOpened = FALSE; // Free the audio device if it is ours so that we can create it on the core thread! if ((!m_bReplacedDev || !m_bUsingReplacedDevice) && m_pCurrentAudioDev) { ReleaseAudioDevice(); RestoreReplacedDevice(); m_pAudioDev = NULL; } theErr = CreateAudioDevice(); if (!theErr && m_pCurrentAudioDev) { m_pAudioDev = m_pCurrentAudioDev; if (!m_bReplacedDev || !m_bUsingReplacedDevice) { ((CHXAudioDevice*)m_pAudioDev)->SetGranularity( m_ulGranularity, m_ulBytesPerGran); } theErr = m_pAudioDev->Open( &m_ActualDeviceFmt, this ); bDeviceOpened = TRUE; m_ulBlocksWritten = 0; /* we always open in a PAUSED state */ if (!theErr) { theErr = m_pAudioDev->Pause(); _NotifyTimelineWatchers(TLW_PAUSE); } if (theErr != HXR_OK) { m_pAudioDev = NULL; } if (!theErr && m_pAudioDev) { /* Set the initial device volume */ m_pAudioDev->SetVolume(m_bMute ? 0 : m_uVolume); } } /* Any error from audio device other than memory error is returned * as HXR_AUDIO_DRIVER */ if (theErr != HXR_OK && theErr != HXR_OUTOFMEMORY) { theErr = HXR_AUDIO_DRIVER; }#ifndef _CARBON if (!theErr && bDeviceOpened && m_bShouldOpenOnCoreThread && m_pInterruptState && !m_pInterruptState->AtInterruptTime()) { // we should re-open on the core thread!!! m_bToBeReOpened = TRUE; if( !m_pDeviceCallback ) { m_pDeviceCallback = new HXDeviceSetupCallback(this); m_pDeviceCallback->AddRef(); } if (!m_pDeviceCallback->PendingID()) { m_pDeviceCallback->PendingID( m_pScheduler->RelativeEnter(m_pDeviceCallback, 0)); } } else#endif { m_bToBeReOpened = FALSE; } return theErr;}HX_RESULTCHXAudioSession::CreateAudioDevice(){ HX_RESULT theErr = HXR_OK; if (!m_pCurrentAudioDev) { // create the audioout object CHXAudioDevice* pAudioDev = CHXAudioDevice::Create(m_pPreferences); if (pAudioDev) { pAudioDev->AddRef(); pAudioDev->Init(m_pContext); if (pAudioDev->InitVolume(0, 100) == TRUE) { m_bAudioDeviceSupportsVolume = TRUE; } else { m_bAudioDeviceSupportsVolume = FALSE; } m_pCurrentAudioDev = (IHXAudioDevice*) pAudioDev; } else { theErr = HXR_OUTOFMEMORY; } } return theErr;}voidCHXAudioSession::ReleaseAudioDevice(){ if (m_pCurrentAudioDev) { ProcessAudioDevice(ACTION_REMOVE, m_pCurrentAudioDev); } m_pCurrentAudioDev->Close(FALSE); _NotifyTimelineWatchers( TLW_CLOSE ); HX_RELEASE(m_pCurrentAudioDev); m_bToBeReOpened = FALSE; if (m_pDeviceCallback && m_pDeviceCallback->PendingID()) { m_pScheduler->Remove(m_pDeviceCallback->PendingID()); m_pDeviceCallback->PendingID(0); }}voidCHXAudioSession::RestoreReplacedDevice(){ if (m_bReplacedDev && !m_bUsingReplacedDevice && !m_pCurrentAudioDev) { m_pCurrentAudioDev = m_pReplacedAudioDev; m_pCurrentAudioDev->AddRef(); m_bUsingReplacedDevice = TRUE; }}/************************************************************************ * Method: * CHXAudioSession::OpenAudio * Purpose: * Open the audio device. */HX_RESULT CHXAudioSession::OpenAudio(){ HX_RESULT theErr = TryOpenAudio(); if (theErr == HXR_AUDIO_DRIVER) { StopAllOtherPlayers(); theErr = TryOpenAudio(); } return theErr;}/************************************************************************ * Method: * CHXAudioSession::CreatePlaybackBuffer * Purpose: * This is the buffer that we mix all player buffers into * and the one we write to the audio device. */HX_RESULT CHXAudioSession::CreatePlaybackBuffer(){ // Calculate the number of bytes per granularity. m_ulBytesPerGran = (ULONG32) (((m_DeviceFmt.uChannels * ((m_DeviceFmt.uBitsPerSample==8)?1:2) * m_DeviceFmt.ulSamplesPerSec) / 1000.0) * m_ulGranularity); /* Number of samples required at output should be a multiple of 8 if * sampling rate is 8K/16K/32K...or a multiple of 11 for 11K/22K... * This is needed since the resamplerequires works reliably ONLY if * this condition is true. Ken is working on this problem. This is * an interim fix */ ULONG32 ulExtraGranularity = 1; if (m_DeviceFmt.ulSamplesPerSec % 8 == 0) { ulExtraGranularity = 8; } else { ulExtraGranularity = 11; } if (m_ulBytesPerGran % (2*m_DeviceFmt.uChannels*ulExtraGranularity) != 0) { m_ulBytesPerGran -= m_ulBytesPerGran % (2*m_DeviceFmt.uChannels*ulExtraGranularity); m_dGranularity = (double) m_ulBytesPerGran / (double) ((double) (m_DeviceFmt.uChannels * ((m_DeviceFmt.uBitsPerSample==8)?1:2) * m_DeviceFmt.ulSamplesPerSec) / 1000.0); } // Readjust the max size of the block m_ActualDeviceFmt.uMaxBlockSize = (UINT16) m_ulBytesPerGran; HX_RELEASE(m_pSessionBuf); HX_RELEASE(m_pPlayerBuf); m_pSessionBuf = new CHXBuffer; m_pSessionBuf->AddRef(); m_pSessionBuf->SetSize(m_ulBytesPerGran); m_DeviceFmt.uMaxBlockSize = (UINT16) m_ulBytesPerGran; m_ActualDeviceFmt.uMaxBlockSize = m_DeviceFmt.uMaxBlockSize; return HXR_OK;}/************************************************************************ * Method: * CHXAudioSession::Pause * Purpose: * Pause playback of this Player's audio. */HX_RESULT CHXAudioSession::Pause( CHXAudioPlayer* p){ m_pMutex->Lock(); BOOL bUseStopInPause = FALSE;#if defined _DEBUG && defined HELIX_FEATURE_AUDIO_MULTIPLAYER_PAUSE bUseStopInPause = HXDebugOptionEnabled("zUseStopInPause");#endif if (!bUseStopInPause && NumberOfResumedPlayers() == 0) { m_bPaused = TRUE; if(m_ulCallbackID) { m_pScheduler->Remove(m_ulCallbackID); m_ulCallbackID = 0; } // Check to see if all audio players are paused, then and only // then will we pause the device if ( m_pAudioDev ) { m_pAudioDev->Pause(); _NotifyTimelineWatchers(TLW_PAUSE); } m_bAtLeastOneTimeReceived = FALSE; m_pLastPausedPlayer = p; } /* * more than one audio player is currently active. * We need to do the following: * 1. get the current time from the device * 2. get the time for data we have already pushed down to the device * 3. flush the au
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -