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

📄 audbeos.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

/*******************************************************************
 *	audbeos.cpp
 *
 *	CLASS: CAudioOutBeOS
 *	
 *	DESCRIPTION: Class implementation for BeOS-specific audio devices 
 *	
 *******************************************************************/

#include "hxtypes.h"
#include "hxresult.h"
#include "hxcom.h"
#include "ihxpckts.h"
#include "hxausvc.h"
#include "auderrs.h"
#include "hxaudev.h"
#include "hxtick.h"
#include "hxthread.h"
#include "hxbuffer.h"
#include "hxslist.h"
#include "hxengin.h"
#include "timeval.h"
#include "hxaudses.h"
#include "audbeos.h"

#include <PushGameSound.h>
#include <MediaDefs.h>

struct IHXCallback;  // forward declaration needed for callback.

CAudioOutBeOS::CAudioOutBeOS()
    : m_player(NULL)
    , m_bFirstWrite(TRUE)
    , m_pPendingBufferList(NULL)
    , m_ulLastPlayCursor(0)
    , m_ulCurrentPlayTime(0)
    , m_ulLastTimeSync(0)
    , m_bPlaying(FALSE)
	, m_ulBufferSize(0)
	, m_ulFrameSize(0)
	, m_ulNextWriteOffset(0)
	, m_ulOldBytesLeft(0)
	, m_ulBlockSize(0)
	, m_bGotAWrite(FALSE)
#if _BEOS_AUDIODEV_CALLBACK
	, m_pPlaybackCountCBTime(NULL)
	, m_bCallbackPending(FALSE)
	, m_PendingCallbackID(0)
#endif
{
#if _BEOS_AUDIODEV_CALLBACK
	m_pPlaybackCountCBTime = new Timeval;
#endif
}		   

CAudioOutBeOS::~CAudioOutBeOS()
{
	_Imp_Close();
#if _BEOS_AUDIODEV_CALLBACK
	delete m_pPlaybackCountCBTime;
#endif
}

HX_RESULT 
CAudioOutBeOS::_Imp_Open(const HXAudioFormat* pFormat)
{
	size_t	bufSize;
	void	*basePtr;

    SetFormat(pFormat);

#if _BEOS_AUDIODEV_CALLBACK
	if (m_pOwner)
	{
		m_pOwner->GetScheduler(&m_pScheduler);
		m_pScheduler->AddRef();
	}
#endif

	// set up the player with enough buffer space for about 4 seconds of audio
//	m_player = new BPushGameSound(m_gameSoundFormat.frame_rate, &m_gameSoundFormat, 4);

	// BPushGameSound->CurrentPosition is accurate to within a buffer
	// Therefore, to keep good synchronization between audio and video, a single
	// buffer should not have a longer duration than a frame of video. We don't
	// know here what the video framerate (if any) may be, but we can assume that it
	// isn't over 30fps. Thus, each audio buffer should be no longer than about 30 ms.
	// To store about 3 seconds of audio, we'll need 100 buffers.
	bufSize = (size_t)(m_gameSoundFormat.frame_rate * 0.03f);
	m_player = new BPushGameSound(bufSize, &m_gameSoundFormat, 100);

	if (m_player->InitCheck() != B_OK)
	{
		delete m_player;
		m_player = NULL;
		return RA_AOE_BADOPEN;
	}
	if (m_player->LockForCyclic(&basePtr, &bufSize) != BPushGameSound::lock_ok)
		m_player->UnlockCyclic();
	m_ulBufferSize = bufSize;
	m_ulBlockSize = m_ulBytesPerGran;

	return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_Close()
{
#if _BEOS_AUDIODEV_CALLBACK
	if (m_pScheduler)
	{
		// Remove callback from scheduler
		if (m_bCallbackPending)
		{
			m_pScheduler->Remove(m_PendingCallbackID);
			m_bCallbackPending = FALSE;
		}
		m_pScheduler->Release();
		m_pScheduler = NULL;
	}
#endif

	if (m_pPendingBufferList)
	{
		while (!m_pPendingBufferList->IsEmpty())
		{
			IHXBuffer	*pBuffer = (IHXBuffer *)m_pPendingBufferList->RemoveHead();
			pBuffer->Release();
			pBuffer = NULL;
		}

		delete m_pPendingBufferList;
		m_pPendingBufferList = NULL;
	}

	if (m_player)
	{
		m_player->StopPlaying();
		delete m_player;
		m_player = NULL;
	}
	m_bPlaying = FALSE;
    return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_Seek(ULONG32 ulSeekTime)
{
    return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_Pause()
{
	if (m_player)
	{
		size_t	curPos = m_player->CurrentPosition() * m_ulFrameSize;
		uint8	*pAudioPtr;
		size_t	i, ulAudioBytes;

		m_player->StopPlaying();
		if (m_player->LockForCyclic((void **)&pAudioPtr, &ulAudioBytes) == BPushGameSound::lock_ok && pAudioPtr)
		{
			// shift the audio data all back to the beginning of the buffer
			if (m_ulNextWriteOffset > curPos)
			{
				for (i = curPos; i < m_ulNextWriteOffset; i++)
				{
					pAudioPtr[i - curPos] = pAudioPtr[i];
				}
				m_ulNextWriteOffset = m_ulNextWriteOffset - curPos;
			}
			else
			{ // wrap-around
				uint32	remaining = ulAudioBytes - curPos;
				uint8	*tempBuf = new uint8[m_ulNextWriteOffset];

				for (i = 0; i < m_ulNextWriteOffset; i++)
				{
					tempBuf[i] = pAudioPtr[i];
				}
				for (i = curPos; i < ulAudioBytes; i++)
				{
					pAudioPtr[i - curPos] = pAudioPtr[i];
				}
				for (i = 0; i < m_ulNextWriteOffset; i++)
				{
					pAudioPtr[i + remaining] = tempBuf[i];
				}

				delete [] tempBuf;
				m_ulNextWriteOffset = remaining + m_ulNextWriteOffset;
			}
			m_player->UnlockCyclic();
			m_bGotAWrite = TRUE;
			m_ulLastPlayCursor = 0;
		}
	}

	m_bPlaying = FALSE;
	return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_Resume()
{
	if (m_player)
		m_player->StartPlaying();

	m_ulLastPlayCursor = 0;
	m_bPlaying = TRUE;
	m_ulLastTimeSync = HX_GET_TICKCOUNT();
	OnTimeSync();

	return HXR_OK;
}

HX_RESULT 
CAudioOutBeOS::_Imp_Write(const HXAudioData* pAudioOutData)
{
	HX_RESULT	theErr = HXR_OK;
	IHXBuffer	*pBuffer = NULL;

#if _BEOS_AUDIODEV_CALLBACK
	if (m_bFirstWrite && pAudioOutData)
	{
		/*  Initialize the playback callback time. */
		HXTimeval lTime = m_pScheduler->GetCurrentSchedulerTime();
		m_pPlaybackCountCBTime->tv_sec = lTime.tv_sec;
		m_pPlaybackCountCBTime->tv_usec = lTime.tv_usec;

		m_bFirstWrite = FALSE;
		ReschedPlaybackCheck();
	}
#endif

	if (pAudioOutData && pAudioOutData->pData)
	{
		pAudioOutData->pData->AddRef();
	}

	if (m_pPendingBufferList && m_pPendingBufferList->GetCount() > 0)
	{
		if (pAudioOutData && pAudioOutData->pData)
			m_pPendingBufferList->AddTail(pAudioOutData->pData);
		pBuffer = (IHXBuffer *)m_pPendingBufferList->RemoveHead();
	}
	else
	{
		if (pAudioOutData && pAudioOutData->pData)
			pBuffer = pAudioOutData->pData;
	}

    BOOL    bCanContinue = TRUE;

	while (bCanContinue && pBuffer)
	{
		UINT32 ulBufferSize = pBuffer->GetSize();

		uint8* pAudioPtr1	= NULL;
		uint8* pAudioPtr2	= NULL;
		size_t curPos;
		size_t ulAudioBytes1 = 0;
		size_t ulAudioBytes2 = 0;
		size_t ulAudioBytesWritten1 = 0;
		size_t ulAudioBytesWritten2 = 0;

		if (m_player->LockForCyclic((void **)&pAudioPtr1, &ulAudioBytes1) == BPushGameSound::lock_ok && pAudioPtr1)
		{
			size_t	ulSizeToWrite, curPos;

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

			if (m_ulNextWriteOffset >= curPos)
			{
				pAudioPtr2 = pAudioPtr1;
				ulAudioBytes1 -= m_ulNextWriteOffset;
			}
			else
			{
				pAudioPtr2 = NULL;
				ulAudioBytes1 = curPos - m_ulNextWriteOffset - 1;
			}
			pAudioPtr1 += m_ulNextWriteOffset;

			if (ulAudioBytes1 < 0)
				ulAudioBytes1 = 0;

			ulSizeToWrite = ulBufferSize;
			if (ulSizeToWrite > ulAudioBytes1)
			{
				ulSizeToWrite = ulAudioBytes1;
			}

			if (ulSizeToWrite > 0)
			{
				::memcpy(pAudioPtr1, (void*) pBuffer->GetBuffer(), ulSizeToWrite); /* Flawfinder: ignore */
			}
			ulAudioBytesWritten1 = ulSizeToWrite;

			size_t	ulRemainingToWrite = ulBufferSize - ulSizeToWrite;

			ulAudioBytes2 = curPos - 1;
			if (ulRemainingToWrite > 0 && pAudioPtr2 && ulAudioBytes2 > 0)
			{
				ulSizeToWrite = ulRemainingToWrite;
				if (ulSizeToWrite > ulAudioBytes2)
				{
					ulSizeToWrite = ulAudioBytes2;
				}
				::memcpy(pAudioPtr2, (void*) (pBuffer->GetBuffer() + ulAudioBytesWritten1), ulSizeToWrite);
				ulAudioBytesWritten2 = ulSizeToWrite;
				ulRemainingToWrite -= ulSizeToWrite;
			}

			if (ulRemainingToWrite > 0)
			{
				IHXBuffer* pNewBuffer = (IHXBuffer*) new CHXBuffer;
				pNewBuffer->AddRef();
				pNewBuffer->Set(pBuffer->GetBuffer() + (ulBufferSize - ulRemainingToWrite), ulRemainingToWrite);

				if (!m_pPendingBufferList)
				{
					m_pPendingBufferList = new CHXSimpleList;
				}

				m_pPendingBufferList->AddHead((void*) pNewBuffer);

				// no more space in the secondary buffer
				bCanContinue = FALSE;
			}

			m_player->UnlockCyclic();

⌨️ 快捷键说明

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