symbian-qemu-0.9.1-12/libsdl-trunk/src/audio/symbian/streamplayer.cpp
author johnathan.white@2718R8BGH51.accenture.com
Mon, 08 Mar 2010 18:45:03 +0000
changeset 46 b6935a90ca64
parent 1 2fb8b9db1c86
permissions -rw-r--r--
Modify framebuffer and NGA framebuffer to read screen size from board model dtb file. Optimise memory usuage of frame buffer Add example minigui application with hooks to profiler (which writes results to S:\). Modified NGA framebuffer to run its own dfc queue at high priority

#include "streamplayer.h"
#include<mda/common/audio.h>



const TInt KMaxVolume(256);

LOCAL_C TInt GetSampleRate(TInt aRate)
    {
    switch(aRate)
        {
        case 8000: return TMdaAudioDataSettings::ESampleRate8000Hz;
        case 11025: return TMdaAudioDataSettings::ESampleRate11025Hz;
        case 12000: return TMdaAudioDataSettings::ESampleRate12000Hz;
        case 16000: return TMdaAudioDataSettings::ESampleRate16000Hz;
        case 22050: return TMdaAudioDataSettings::ESampleRate22050Hz;
        case 24000: return TMdaAudioDataSettings::ESampleRate24000Hz;
        case 32000: return TMdaAudioDataSettings::ESampleRate32000Hz;
        case 44100: return TMdaAudioDataSettings::ESampleRate44100Hz;
        case 48000: return TMdaAudioDataSettings::ESampleRate48000Hz;
        case 96000: return TMdaAudioDataSettings::ESampleRate96000Hz;
        case 64000: return TMdaAudioDataSettings::ESampleRate64000Hz;
        }
    return KErrNotFound;
    }

LOCAL_C TInt GetChannels(TInt aChannels)
    {
    switch(aChannels)
        {
        case 1: return TMdaAudioDataSettings::EChannelsMono;
        case 2: return TMdaAudioDataSettings::EChannelsStereo;
        }
    return KErrNotFound;
    }
    
TInt CStreamPlayer::ClosestSupportedRate(TInt aRate)
	{
	if(aRate > 96000)
		return 96000;
	TInt rate = aRate;
	while(GetSampleRate(rate) == KErrNotFound)
		{
		++rate;
		}
	return rate;
	}

CStreamPlayer::CStreamPlayer(MStreamProvider& aProvider,  MStreamObs& aObs) :
 iProvider(aProvider), iObs(aObs), iVolume(KMaxVolume)
	{	
	}
		
CStreamPlayer::~CStreamPlayer()
	{
	iState |= EDied;
	if(iState & EInited)
		Close();
	User::After(100000); //wait buffer to be flushed
	ASSERT(iPtr.Length() == 0);
	delete iStream;
	}
		
		
void CStreamPlayer::ConstructL()
	{
	iStream = CMdaAudioOutputStream::NewL(*this, EMdaPriorityMax);
	iSilence.SetMax();
	iSilence.FillZ();
	}
		

TInt CStreamPlayer::OpenStream(TInt aRate, TInt aChannels, TUint32 aType)
	{
	Close();
	
	iType = aType;
	
	iRate = GetSampleRate(aRate);
	if(iRate == KErrNotFound)
		return KErrNotSupported;
	
	iChannels = GetChannels(aChannels);
	if(iChannels == KErrNotFound)
		return KErrNotSupported;
	
	Open();
    
    return KErrNone;
	}


TInt CStreamPlayer::MaxVolume() const
	{
	return KMaxVolume;
	}

void CStreamPlayer::SetVolume(TInt aNew)
    {
    
    const TInt maxi = MaxVolume();
    if(aNew > maxi)
		return;
    if(aNew < 0)
    	return;
    
    iVolume = aNew;
    
    iState |= EVolumeChange;
    }
    
 TInt CStreamPlayer::Volume() const
    {
	return iVolume;
    }

void CStreamPlayer::Open()
	{
	TMdaAudioDataSettings audioSettings;
	audioSettings.Query();
    audioSettings.iCaps = TMdaAudioDataSettings::ERealTime |
     	TMdaAudioDataSettings::ESampleRateFixed; 
    audioSettings.iSampleRate = iRate; 
    audioSettings.iChannels = iChannels;
	audioSettings.iFlags = TMdaAudioDataSettings::ENoNetworkRouting;
	audioSettings.iVolume = 0;
	
	iState &= ~EStopped;
    iStream->Open(&audioSettings);    
	}
	
void CStreamPlayer::Stop()
	{
	if(iState & (EStarted | EInited))
		{
		Close();
		iState |= EStopped;
		}
	}
	
void CStreamPlayer::Start()
	{
	if(iPtr.Length() == 0)
		{
		iState |= EStarted;
		if(iState & EInited)
			{
			Request();
			}
		else if(iState & EStopped)
			{
			Open();
			}
		}
	}

void CStreamPlayer::Close()
	{
	iState &= ~EInited;
	iStream->Stop();
	iState &= ~EStarted;
	}
	
void CStreamPlayer::Request()
	{
	if(iState & EInited)
		{
		iPtr.Set(KNullDesC8);
		
		if(iState & EVolumeChange)
			{
       		const TReal newVol = iVolume;
       		const TReal newMax = MaxVolume();
       		const TInt maxVol = iStream->MaxVolume();
       		const TReal max = static_cast<TReal>(maxVol);
       		const TReal newvolume = (newVol * max) / newMax;
       		const TInt vol = static_cast<TReal>(newvolume);
       		iStream->SetVolume(vol);
			iState &= ~EVolumeChange;
			}
			
		if(iState & EStarted)
			{
	 		iPtr.Set(iProvider.Data());
			}
		if(iPtr.Length() == 0)
			{
			iPtr.Set(iSilence);
			}
		TRAPD(err, iStream->WriteL(iPtr));
		if(err != KErrNone)
			{
			iObs.Complete(MStreamObs::EWrite, err);	
			}
	/*	else
			{
			iProvider.Written(iPtr.Length());
			}*/
		}
	}
	

void CStreamPlayer::SetCapsL()
	{
	iStream->SetDataTypeL(iType);
	iStream->SetAudioPropertiesL(iRate, iChannels);
	}

void CStreamPlayer::MaoscOpenComplete(TInt aError) 
	{
	if(aError == KErrNone)
		{
		TRAPD(err, SetCapsL());
    	if(err == KErrNone)
    		{
    		iStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceTime);
    		iState |= EInited;
    		
    		
        	SetVolume(Volume());	
    		
    		if(iState & EStarted)
    			{
    			Request();
    			}
    			
			}
		aError = err;
		}
	if(!(iState & EDied))
		iObs.Complete(MStreamObs::EInit, aError);
	}
	
void CStreamPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/)
	{
	iPtr.Set(KNullDesC8);
	if(aError == KErrNone)
		{
		if(iState & EInited)
			Request();
		else
			iStream->Stop();
		}
	else if(!(iState & EDied))
		iObs.Complete(MStreamObs::EPlay, aError);
	}
	
void CStreamPlayer::MaoscPlayComplete(TInt aError)
	{	
	iPtr.Set(KNullDesC8);
	iState &= ~EStarted;
	if(!(iState & EDied))
		iObs.Complete(MStreamObs::EClose, aError);
	}
	
TBool CStreamPlayer::Playing() const
	{
	return (iState & EInited) && (iState & EStarted);
	}

TBool CStreamPlayer::Closed() const
	{
	return !(iState & EInited) && !(iState & EDied);
	}
	
	/*
void CStreamPlayer::Request()
	{
	SetActive();
	TRequestStatus* s = &iStatus;
	User::RequestComplete(s, KErrNone);
	}
	//		iTimer.After(0);
	*/