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

📄 audbeos.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

			m_ulNextWriteOffset	+= ulAudioBytesWritten1 + ulAudioBytesWritten2;
			if (pAudioOutData)
				m_bGotAWrite = TRUE;

			if (m_ulNextWriteOffset >= m_ulBufferSize)
			{
				m_ulNextWriteOffset -= m_ulBufferSize;
			}

			if (m_bFirstWrite)
			{
				m_bFirstWrite = FALSE;
			}
		} // lock
		else
		{
			bCanContinue = FALSE;
			if (!m_pPendingBufferList)
			{
				m_pPendingBufferList = new CHXSimpleList;
			}
			
			pBuffer->AddRef();
			m_pPendingBufferList->AddHead((void*) pBuffer);
		}

		pBuffer->Release();
		pBuffer = NULL;

		if (bCanContinue && m_pPendingBufferList && m_pPendingBufferList->GetCount() > 0)
		{
			pBuffer = (IHXBuffer*) m_pPendingBufferList->RemoveHead();
		}
	} // while

	if (m_bPlaying)
	{
		UINT32	ulCurrentTime = HX_GET_TICKCOUNT();
		if (CALCULATE_ELAPSED_TICKS(m_ulLastTimeSync, ulCurrentTime) > 100)
		{
			m_ulLastTimeSync = ulCurrentTime;
			OnTimeSync();
		}
	}

//@ This is an ugly hack, but it seems to work very well.
// Hopefully I can figure it out and fix it properly at some point.
// (mclifton 10/5/99)
/*if (pAudioOutData && m_bPlaying && m_pPendingBufferList && m_pPendingBufferList->GetCount() > 0)
{
snooze(50000);
_Imp_Write(NULL);
}
if (pAudioOutData && m_bPlaying && m_pPendingBufferList && m_pPendingBufferList->GetCount() > 0)
{
snooze(50000);
_Imp_Write(NULL);
}*/

	return theErr;
}

HX_RESULT 
CAudioOutBeOS::_Imp_Reset()
{
    m_ulCurrentPlayTime = 0;
    m_bFirstWrite = TRUE;

	m_ulNextWriteOffset = 0;

	if (m_player)
		m_player->StopPlaying();
	m_bPlaying = FALSE;

    return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_Drain()
{
    return HXR_OK;
}

BOOL 
CAudioOutBeOS::_Imp_SupportsVolume()
{
    return TRUE;
}

UINT16 
CAudioOutBeOS::_Imp_GetVolume()
{
	float	vol = 0.0f;

	if (m_player)
		vol = m_player->Gain();
	return (UINT16)(vol * 100.0f);
}

HX_RESULT 
CAudioOutBeOS::_Imp_SetVolume(const UINT16 uVolume)
{
	float	vol = (float)uVolume / 100.0f;

	if (m_player)
		m_player->SetGain(vol);
    return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_CheckFormat(const HXAudioFormat* pFormat)
{
    return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_GetCurrentTime(ULONG32& ulCurrentTime)
{
	size_t	curPos = 0;

	if (m_player)
	{
		if (m_player->IsPlaying())
			curPos = m_player->CurrentPosition() * m_ulFrameSize;

		// This method of calculating elapsed time was basically copied over from
		// the DirectSound code. The bad news is that it is error-prone. Converting
		// from bytes to milliseconds is prone to roundoff, leading to an accumulation
		// of error, causing a drift of synchronization between audio and video.
		// (That DirectSound code has caused me nothing but headaches...)
		//m_ulCurrentPlayTime +=
		//	CalcMs(CalculateElapsedBytes(m_ulLastPlayCursor, curPos));

		// The more accurate way to do it is to accumulate elapsed bytes, then
		// convert the total to milliseconds. The elapsed bytes is accurate to
		// within a video frame or so. Even though it can't be absolutely accurate,
		// at least it won't drift over time.
		m_ulCurrentPlayTime +=
			CalculateElapsedBytes(m_ulLastPlayCursor, curPos);

		m_ulLastPlayCursor = curPos;
	}
	// old method
	//ulCurrentTime = m_ulCurrentPlayTime;
	// new method
	ulCurrentTime = CalcMs(m_ulCurrentPlayTime);

	return HXR_OK;
}


UINT16
CAudioOutBeOS::_NumberOfBlocksRemainingToPlay(void)
{
	UINT32	res = 0;
	size_t	curPos = 0;

	// add up the number of audio bytes queued up
	if (m_pPendingBufferList)
	{
		LISTPOSITION i = m_pPendingBufferList->GetHeadPosition();

		while (i)
		{
			res += ((IHXBuffer *)m_pPendingBufferList->GetAt(i))->GetSize();
			m_pPendingBufferList->GetNext(i);
		}
	}

	// add in the bytes that are currently in the playback buffer
	if (m_player)
	{
		UINT32	playingBytes = 0;

		if (m_player->IsPlaying())
			curPos = m_player->CurrentPosition() * m_ulFrameSize;

		if (curPos < m_ulNextWriteOffset)
			playingBytes += m_ulNextWriteOffset - curPos;
		else
			playingBytes += (m_ulBufferSize - curPos) + m_ulNextWriteOffset;

		res += playingBytes;
	}

	if (m_bGotAWrite)
		m_ulOldBytesLeft = res;
	else if (res > m_ulOldBytesLeft)
	{
		fprintf(stderr, "Buffer overflow!\n");
		// This is a bad situation - I wish this never happened.
		// But what should I do when it does happen?
		// I used to return 0, since I thought that would force more
		// audio buffers my way, but it also seems to introduce more glitches.
		//res = 0;
	}
	m_bGotAWrite = FALSE;

	res /= m_ulBlockSize;

	return res;
}

void
CAudioOutBeOS::SetFormat(const HXAudioFormat* pFormat)
{
    ::memset(&m_gameSoundFormat, 0, sizeof(gs_audio_format));

	m_gameSoundFormat.frame_rate = pFormat->ulSamplesPerSec;
	m_gameSoundFormat.channel_count = pFormat->uChannels;
	switch (pFormat->uBitsPerSample)
	{
		case 8:
			m_gameSoundFormat.format = gs_audio_format::B_GS_U8;
			break;
		case 16:
			m_gameSoundFormat.format = gs_audio_format::B_GS_S16;
			break;
	}
	m_gameSoundFormat.byte_order = B_MEDIA_LITTLE_ENDIAN;
	m_gameSoundFormat.buffer_size = 2048;

	m_ulFrameSize = m_gameSoundFormat.channel_count * ((m_gameSoundFormat.format==gs_audio_format::B_GS_U8)?1:2);
}

inline UINT32 
CAudioOutBeOS::CalcMs(ULONG32 ulNumBytes)
{
    return ( (ULONG32) (( 1000.0
		/ (m_ulFrameSize
		*  m_gameSoundFormat.frame_rate) )
		*  ulNumBytes) );
}


inline UINT32
CAudioOutBeOS::CalculateElapsedBytes(UINT32 ulLastBytePos, UINT32 ulCurrentBytePos)
{
	 return ((ulCurrentBytePos >= ulLastBytePos) ? (ulCurrentBytePos - ulLastBytePos) : (ulCurrentBytePos + (m_ulBufferSize - ulLastBytePos)));
}

#if _BEOS_AUDIODEV_CALLBACK
void
CAudioOutBeOS::DoTimeSyncs(void)
{
	ReschedPlaybackCheck();
	OnTimeSync();

	return;
}

HX_RESULT
CAudioOutBeOS::ReschedPlaybackCheck()
{
	HX_RESULT theErr = HXR_OK;

	if (m_bCallbackPending)
		return theErr;

	*m_pPlaybackCountCBTime += (int)(m_ulGranularity * 1000) / 2;
	// Put this back in the scheduler.
	HXPlaybackCountCb	*pCallback = 0;
	pCallback = new HXPlaybackCountCb(TRUE);
	if (pCallback)
	{
		pCallback->m_pAudioDeviceObject = this;
		m_bCallbackPending = TRUE;
		m_PendingCallbackID = m_pScheduler->AbsoluteEnter(pCallback, *((HXTimeval *)m_pPlaybackCountCBTime));
	}
	else
		theErr = HXR_OUTOFMEMORY;  // but ignored, why?

	return theErr;
}

CAudioOutBeOS::HXPlaybackCountCb::HXPlaybackCountCb(BOOL timed) 
	: m_lRefCount(0)
	, m_pAudioDeviceObject(0)
	, m_timed(timed)
{
}

CAudioOutBeOS::HXPlaybackCountCb::~HXPlaybackCountCb()
{
}

/*
 * IUnknown methods
 */
/////////////////////////////////////////////////////////////////////////
//      Method:
//              IUnknown::QueryInterface
//      Purpose:
//              Implement this to export the interfaces supported by your 
//              object.
//
STDMETHODIMP CAudioOutBeOS::HXPlaybackCountCb::QueryInterface(REFIID riid, void** ppvObj)
{
	if (IsEqualIID(riid, IID_IHXCallback))
	{
		AddRef();
		*ppvObj = (IHXCallback*)this;
		return HXR_OK;
	}
	else if (IsEqualIID(riid, IID_IUnknown))
	{
		AddRef();
		*ppvObj = this;
		return HXR_OK;
	}

	*ppvObj = NULL;
	return HXR_NOINTERFACE;
}



/////////////////////////////////////////////////////////////////////////
//      Method:
//              IUnknown::AddRef
//      Purpose:
//              Everyone usually implements this the same... feel free to use
//              this implementation.
//
STDMETHODIMP_(ULONG32) CAudioOutBeOS::HXPlaybackCountCb::AddRef()
{
	return InterlockedIncrement(&m_lRefCount);
}

/////////////////////////////////////////////////////////////////////////
//      Method:
//              IUnknown::Release
//      Purpose:
//              Everyone usually implements this the same... feel free to use
//              this implementation.
//
STDMETHODIMP_(ULONG32) CAudioOutBeOS::HXPlaybackCountCb::Release()
{
	if (InterlockedDecrement(&m_lRefCount) > 0)
	{
		return m_lRefCount;
	}

	delete this;
	return 0;
}

/*
 *      IHXPlaybackCountCb methods
 */
STDMETHODIMP CAudioOutBeOS::HXPlaybackCountCb::Func(void)
{
	if (m_pAudioDeviceObject)
	{
		if (!m_timed)
		{
			m_pAudioDeviceObject->_Imp_Write(NULL);
		}
		else
		{
			m_pAudioDeviceObject->_Imp_Write(NULL);
			m_pAudioDeviceObject->m_bCallbackPending = FALSE;
			m_pAudioDeviceObject->DoTimeSyncs();
		}
	}

	return HXR_OK;
}
#endif

⌨️ 快捷键说明

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