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

📄 oggmultithread.cpp

📁 OggPlay for Symbian 是symbian上的一个媒体播放程序的源码。它支持ogg,wav等等多媒体格式。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	TRequestStatus* status = &iStatus;
	User::RequestComplete(status, KErrCancel);
}

// Playback engine class
// Handles communication with the media server (CMdaAoudioOutputStream) and manages the audio buffering
CStreamingThreadPlaybackEngine* CStreamingThreadPlaybackEngine::NewLC(TStreamingThreadData& aSharedData)
{
	CStreamingThreadPlaybackEngine* self = new(ELeave) CStreamingThreadPlaybackEngine(aSharedData);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
}

CStreamingThreadPlaybackEngine::CStreamingThreadPlaybackEngine(TStreamingThreadData& aSharedData)
: iSharedData(aSharedData), iBufferingThreadPriority(EPriorityNormal)
{
	// Initialise buffer settings
	iSharedData.iBuffersToUse = KNoBuffers;
	iSharedData.iMaxBuffers = KNoBuffers;
	iMaxStreamBuffers = KNoBuffers;
	iBufferLowThreshold = KNoBuffers;
}

void CStreamingThreadPlaybackEngine::ConstructL()
{
	// Open the stream
	iStream = CMdaAudioOutputStream::NewL(*this);
	iStream->Open(&iSettings);

	iStreamingThreadAO = new(ELeave) CStreamingThreadAO(iSharedData, iBufferFlushPending, iBufferingThreadPriority);
	CActiveScheduler::Add(iStreamingThreadAO);
}

CStreamingThreadPlaybackEngine::~CStreamingThreadPlaybackEngine()
{
	if (iStreamingThreadAO)
		iStreamingThreadAO->Cancel();

	iThread.Close();

	delete iStreamingThreadAO;
	delete iStream;
}

void CStreamingThreadPlaybackEngine::SetAudioPropertiesL()
{
	TMdaAudioDataSettings::TAudioCaps ac = TMdaAudioDataSettings::EChannelsMono;
	if (iSharedData.iChannels == 1)
		ac = TMdaAudioDataSettings::EChannelsMono;
	else
		ac = TMdaAudioDataSettings::EChannelsStereo;

	TMdaAudioDataSettings::TAudioCaps rt = TMdaAudioDataSettings::ESampleRate8000Hz;
	switch (iSharedData.iSampleRate)
	{
		case 8000:
			rt = TMdaAudioDataSettings::ESampleRate8000Hz;
			break;

		case 11025:
			rt = TMdaAudioDataSettings::ESampleRate11025Hz;
			break;

		case 16000:
			rt = TMdaAudioDataSettings::ESampleRate16000Hz;
			break;

		case 22050:
			rt = TMdaAudioDataSettings::ESampleRate22050Hz;
			break;

		case 32000:
			rt = TMdaAudioDataSettings::ESampleRate32000Hz;
			break;

		case 44100:
			rt = TMdaAudioDataSettings::ESampleRate44100Hz;
			break;

		case 48000:
			rt = TMdaAudioDataSettings::ESampleRate48000Hz;
			break;

		default:
			User::Leave(KErrNotSupported);
			break;
	}

	iStream->SetAudioPropertiesL(rt, ac);
}

void CStreamingThreadPlaybackEngine::Volume()
{
	iSharedData.iVolume = iStream->Volume();
}

void CStreamingThreadPlaybackEngine::SetVolume()
{
	TInt vol = iSharedData.iVolume;
	if (vol>KMaxVolume)
		vol = KMaxVolume;
	else if (vol<0)
		vol = 0;

	vol = (TInt) (((TReal) vol)/KMaxVolume * iMaxVolume);
	if (vol > iMaxVolume)
		vol = iMaxVolume;
	iStream->SetVolume(vol);
}

void CStreamingThreadPlaybackEngine::StartStreaming()
{
	if (iStreaming)
		User::Panic(_L("STPE: StartStream"), 0);

	// Init streaming values
	iBufNum = 0;
	iStreaming = ETrue;

	if (iSharedData.iBufferingMode == ENoBuffering)
	{
		// Fetch the first buffer
		iStreamingThreadAO->PrimeNextBuffer();

		// Stream the first buffer
		SendNextBuffer();
	}
	else
	{
		// Start the streaming thread AO
		iStreamingThreadAO->StartBuffering();

		// Stream the pre buffers
		for (TInt i = 0 ; i<KPreBuffers ; i++)
			SendNextBuffer();
	}
}

void CStreamingThreadPlaybackEngine::PauseStreaming()
{
	// Stop the stream, but don't reset the position
	StopStreaming(EFalse);
}

void CStreamingThreadPlaybackEngine::StopStreaming(TBool aResetPosition)
{
	if (iStreaming)
	{
		// Stop the stream
		iStream->Stop();

		// Stop the AOs
		iStreamingThreadAO->Cancel();

		// Reset streaming data
		iStreaming = EFalse;
		iStreamBuffers = 0;
		iBufferFlushPending = EFalse;

		// Reset shared data
		iSharedData.iNumBuffersRead = 0;
		iSharedData.iNumBuffersPlayed = 0;

		iSharedData.iPrimeBufNum = 0;
		iSharedData.iLastBuffer = NULL;

		iSharedData.iBufferBytesRead = 0;
		iSharedData.iBufferBytesPlayed = 0;

		// Reset the thread priorities
		if ((iBufferingThreadPriority != EPriorityNormal) && (iBufferingThreadPriority != EPriorityAbsoluteForeground))
		{
			iBufferingThreadPriority = (iBufferingThreadPriority == EPriorityMore) ? EPriorityNormal : EPriorityAbsoluteForeground;
			iSharedData.iBufferingThread.SetPriority(iBufferingThreadPriority);
		}
	}

	if (aResetPosition)
		iSharedData.iTotalBufferBytes = 0;
}

void CStreamingThreadPlaybackEngine::SetBufferingMode()
{
	if (iStreaming)
		User::Panic(_L("STPE: SBM1"), 0);

	// Set the buffering values
	switch(iSharedData.iBufferingMode)
	{
		case ENoBuffering:
			iMaxStreamBuffers = KNoBuffers;
			iBufferLowThreshold = KNoBuffers;
			break;

		case EBufferStream:
			iMaxStreamBuffers = KSingleThreadStreamBuffers;
			iBufferLowThreshold = KSingleThreadLowThreshold;
			break;

		case EBufferThread:
			iMaxStreamBuffers = KMultiThreadStreamBuffers;
			iBufferLowThreshold = KMultiThreadLowThreshold;
			break;

		default:
			User::Panic(_L("STPE: SBM2"), 0);
			break;
	}
}

void CStreamingThreadPlaybackEngine::SetThreadPriority()
{
	// Set the thread priorities
	switch(iSharedData.iStreamingThreadPriority)
	{
		case ENormal:
			// Use normal (relative) thread priorities
			if (iBufferingThreadPriority == EPriorityAbsoluteForeground)
				iBufferingThreadPriority = EPriorityNormal;
			else if (iBufferingThreadPriority == EPriorityAbsoluteHigh)
				iBufferingThreadPriority = EPriorityMore;
			else
				break;

			iThread.SetPriority(EPriorityMore);
			iSharedData.iBufferingThread.SetPriority(iBufferingThreadPriority);
			break;

		case EHigh:
			// Use high (absolute) thread priorities
			if (iBufferingThreadPriority == EPriorityNormal)
				iBufferingThreadPriority = EPriorityAbsoluteForeground;
			else if (iBufferingThreadPriority == EPriorityMore)
				iBufferingThreadPriority = EPriorityAbsoluteHigh;
			else
				break;

			iThread.SetPriority(EPriorityAbsoluteHigh);
			iSharedData.iBufferingThread.SetPriority(iBufferingThreadPriority);
			break;

		default:
			User::Panic(_L("STPE: STP"), 0);
			break;
	}
}

void CStreamingThreadPlaybackEngine::Position()
{
	iSharedData.iStreamingPosition = iStream->Position();
}

TBool CStreamingThreadPlaybackEngine::PrepareToFlushBuffers()
{
	// Mark that a buffer flush is pending (this inhibits requests to the buffering thread)
	iBufferFlushPending = ETrue;

	// Return streaming status
	return iStreaming;
}

TBool CStreamingThreadPlaybackEngine::FlushBuffers()
{
	// Return the streaming status
	// (Get the value before we flush the buffers and possibly change it)
	TBool ret = iStreaming;

	// Reset the buffer flush pending flag 
	iBufferFlushPending = EFalse;

	// Reset the audio stream (move position / change volume gain)
	const TInt64 KConst500 = TInt64(500);
	switch (iSharedData.iFlushBufferEvent)
	{
		case EPlaybackPaused:
		case EBufferingModeChanged:
		{
			// Flush all of the data
			TInt bufferBytes = iSharedData.BufferBytes();
			if (bufferBytes)
			{
				iSharedData.iTotalBufferBytes-= bufferBytes;
				TInt64 newPositionMillisecs = (KConst500*iSharedData.iTotalBufferBytes)/TInt64(iSharedData.iSampleRate*iSharedData.iChannels);
				iSharedData.iOggPlayback.SetDecoderPosition(newPositionMillisecs);
			}

			// Pause the stream
			PauseStreaming();
			break;
		}

		case EVolumeGainChanged:
		{
			// Calculate how much data needs to be flushed
			// Don't flush buffers that are already in the stream and leave another KPreBuffers unflushed
			TInt availBuffers = iSharedData.NumBuffers() - iStreamBuffers;
			TBool buffersToFlush = availBuffers>KPreBuffers;
			TInt numFlushBuffers = (buffersToFlush) ? availBuffers-KPreBuffers : 0;
			iSharedData.iNumBuffersRead -= numFlushBuffers;

			TInt bytesFlushed = 0;
			if (buffersToFlush)
			{
				TInt bufNum = iBufNum + KPreBuffers;
				if (bufNum>=iSharedData.iMaxBuffers)
					bufNum -= iSharedData.iMaxBuffers;
				iSharedData.iPrimeBufNum = bufNum;

				for (TInt i = 0 ; i<numFlushBuffers ; i++)
				{
					bytesFlushed += iSharedData.iOggPlayback.iBuffer[bufNum]->Length();
					bufNum++;
					if (bufNum == iSharedData.iMaxBuffers)
						bufNum = 0;
				}
				iSharedData.iBufferBytesRead-= bytesFlushed;
			}

			// Reset the decoder position
			if (bytesFlushed)
			{
				iSharedData.iTotalBufferBytes-= bytesFlushed;
				TInt64 newPositionMillisecs = (KConst500*iSharedData.iTotalBufferBytes)/TInt64(iSharedData.iSampleRate*iSharedData.iChannels);
				iSharedData.iOggPlayback.SetDecoderPosition(newPositionMillisecs);
			}

			// Set the new volume gain (and carry on as if nothing had happened)
			iSharedData.iOggPlayback.SetSampleRateConverterVolumeGain(iSharedData.iNewGain);
			break;
		}

		case EPositionChanged:
			// Recalculate the number of buffer bytes
			iSharedData.iTotalBufferBytes = (iSharedData.iNewPosition*TInt64(iSharedData.iSampleRate*iSharedData.iChannels))/KConst500;

			// Set the new position
			iSharedData.iOggPlayback.SetDecoderPosition(iSharedData.iNewPosition);

			// Pause the stream
			PauseStreaming();
			break;

		default:
			User::Panic(_L("STPE: Flush"), 0);		

⌨️ 快捷键说明

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