internetradio2.0/uisrc/irmediaclient.cpp
changeset 0 09774dfdd46b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/internetradio2.0/uisrc/irmediaclient.cpp	Mon Apr 19 14:01:53 2010 +0300
@@ -0,0 +1,451 @@
+/*
+* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  ?Description
+*
+*/
+
+
+#include <e32property.h>
+#include "irpubsubkeys.h"
+
+#include "irctrlcmdobserver.h"
+#include "irdebug.h"
+#include "irmediaclient.h"
+#include "irmediaenginebuffer.h"
+#include "irmediaengineinterface.h"
+#include "ircontrolparams.h"
+
+const TInt KZeroVolumeLevel = 0;
+const TInt KIRBitRateDivider = 8;    // To convert bits to bytes.
+const TInt KIRByteMultiplier = 1024; // To convert kilo bytes to bytes.
+const TInt KIRValidBitRate = 0;      // Starting point for valid bit rate.
+const TInt KIRDefBitRate = 64;       // Default bit rate for buffer size calculation.
+const TInt KIRMinBitRate = 8;        // Minimum bit rate for buffer size calculation.
+const TInt KIRMaxBitRate = 192;      // Maximum bit rate for buffer size calculation.
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ---------------------------------------------------------------------------
+// Function : NewL
+// Two Phase Constructor - NewL
+// ---------------------------------------------------------------------------
+//	 
+CIRMediaClient* CIRMediaClient::NewL(CIRCtrlCmdObserver* aChannel)
+	{
+	IRLOG_DEBUG( "CIRMediaClient::NewL - Entering" );
+	CIRMediaClient* self = NewLC(aChannel);
+    CleanupStack::Pop(self);
+    IRLOG_DEBUG( "CIRMediaClient::NewL - Exiting." );
+    return self;	
+	}
+	
+// ---------------------------------------------------------------------------
+// Function : NewLC
+// Two Phase Constructor - NewLC
+// ---------------------------------------------------------------------------
+//
+CIRMediaClient* CIRMediaClient::NewLC(CIRCtrlCmdObserver* aChannel)
+	{
+	IRLOG_DEBUG( "CIRMediaClient::NewLC - Entering" );
+	CIRMediaClient* self = new (ELeave) CIRMediaClient();
+    CleanupStack::PushL(self);
+    self->ConstructL(aChannel);
+	IRLOG_DEBUG( "CIRMediaClient::NewLC - Exiting." );
+    return self;	
+	}
+
+// ---------------------------------------------------------------------------
+// destructor function
+// destructor of the player component
+// ---------------------------------------------------------------------------
+//
+CIRMediaClient::~CIRMediaClient()
+    {
+	IRLOG_DEBUG( "CIRMediaClient::~CIRMediaClient - Entering" );
+	//deletes the player
+	delete iPlayer;
+	//deletes the buffers associated with player
+	delete[] iTempBuffer;
+	delete[] iCurrentBuffer;
+	IRLOG_DEBUG( "CIRMediaClient::~CIRMediaClient - Exiting." );
+    }
+    	
+// ---------------------------------------------------------------------------
+// This is default Constructor
+// for the class CIRMediaClient
+// ---------------------------------------------------------------------------
+//	
+CIRMediaClient::CIRMediaClient():iInputBuffer(NULL,0,0) 
+	{
+	IRLOG_DEBUG( "CIRMediaClient::CIRMediaClient" );
+	}
+
+// ---------------------------------------------------------------------------
+// Two phase ConstructL
+// network component is taken as input
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::ConstructL(CIRCtrlCmdObserver* aChannel)
+    {
+	IRLOG_DEBUG( "CIRMediaClient::ConstructL - Entering" );
+	iChannel = aChannel;
+	IRLOG_DEBUG( "CIRMediaClient::ConstructL - Exiting" );
+	}
+						
+										   //For Play control
+										   
+// ---------------------------------------------------------------------------
+// Function : PlayL
+// Starts to play the stream
+// ---------------------------------------------------------------------------
+//
+TInt CIRMediaClient::Play()
+	{
+	IRLOG_DEBUG( "CIRMediaClient::Play - Entering" );
+	IRLOG_DEBUG( "CIRMediaClient::Play - Exiting" );
+	//sents a play request to media engine
+	if( iPlayer )
+		{
+		iPlayer->Play();
+		IRLOG_DEBUG( "CIRMediaClient::Play - Exiting (1)." );
+		return KErrNone;
+		}
+	else
+		{
+		IRLOG_DEBUG( "CIRMediaClient::Play - Exiting (2)." );
+		return KErrNotFound;
+		}	
+	}
+
+// ---------------------------------------------------------------------------
+// Function : StopL
+// Stops to play the stream
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::Stop()
+	{
+	IRLOG_DEBUG( "CIRMediaClient::Stop - Entering" );
+	//sents a stop request to media engine
+	if( iPlayer )
+		{
+		iPlayer->Stop();
+		}
+	else
+		{
+		iCommand = EStoppedPlaying;
+		iChannel->SentRequest(iCommand,KErrNone);
+		}
+	IRLOG_DEBUG( "CIRMediaClient::Stop - Exiting." );
+	}
+										
+										 //For Volume Control
+// ---------------------------------------------------------------------------
+// Function : SetVolume
+// function to set the volume, 
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::SetVolume(TInt aVolume )
+	{
+	IRLOG_DEBUG( "CIRMediaClient::SetVolume - Entering" );
+	//if player is exists it will set the volume
+	if( iPlayer )
+		{
+		iPlayer->SetVolume(aVolume);	
+		}		
+	IRLOG_DEBUG( "CIRMediaClient::SetVolume - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// Function : MaxVolume
+// ---------------------------------------------------------------------------
+//	
+TInt CIRMediaClient::MaxVolume() const
+	{
+	IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Entering" );
+	IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Exiting" );
+	//if player is created it will sent the max volume else return zero instead of MaxVolume
+	if( iPlayer )
+		{
+		IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Exiting (1)." );
+		//returns maximum volume if player exists
+		return iPlayer->MaxVolume();	
+		}		
+	else
+		{
+		//else zero is returned
+		IRLOG_DEBUG( "CIRMediaClient::MaxVolume - Exiting (2)." );
+		return KZeroVolumeLevel;	
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// Function : Volume
+// function to returns the volume
+// ---------------------------------------------------------------------------
+//		
+TInt CIRMediaClient::Volume() const
+	{
+	IRLOG_DEBUG( "CIRMediaClient::Volume - Entering" );
+	IRLOG_DEBUG( "CIRMediaClient::Volume - Exiting" );
+	//if player is created it will sent the volume else return zero instead of Volume
+	if( iPlayer )
+		{
+		//if player exist it returns the current volume
+		IRLOG_DEBUG( "CIRMediaClient::Volume - Exiting (1)." );
+		return iPlayer->Volume();	
+		}		
+	else
+		{
+		//else will return negative volume
+		IRLOG_DEBUG( "CIRMediaClient::Volume - Exiting (2)." );
+		return KZeroVolumeLevel;	
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// Function: BufferFilled
+// Set the whether a Fill Buffer is currently active
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::BufferFilled()
+	{
+	IRLOG_DEBUG( "CIRMediaClient::BufferFilled - Entering" );
+	if( iFirstTime )
+		{
+		//First all the buffers are filled
+		iInputBufferPtr += iConfig.iPlayBufferSize;	
+		if( (iInputBufferPtr + iConfig.iPlayBufferSize) <= 
+			(iTempBuffer + iConfig.iPlayBufferCount*iConfig.iPlayBufferSize) )
+			{
+			//buffer is not completely filled
+			iInputBuffer.Set(iInputBufferPtr,iConfig.iPlayBufferSize,iConfig.iPlayBufferSize);	
+			
+			if( iStopBuffering )
+				{
+				//if iStopBuffering is true we won't continue in this loop
+				return;		
+				}			
+			else // if not stop buffering is called
+				{
+				//fills the buffer and sents the buffer percentage
+				iChannel->FilltheBuffer(iInputBuffer);			
+				}				
+			}
+		else
+			{
+			//buffer is completely filled
+			iFirstTime = EFalse;
+			iNewPlayer = EFalse;
+			if( iStopBuffering )
+				{
+				//if stop buffering is true we will not proceed further
+				return;	
+				}
+			else
+				{
+                // Error reporting done inside CreatePlayer
+				if ( CreatePlayer() )
+				    {
+				    // Sending this event causes NowPlayingView activation
+				    iBufferPercentage = K100Percentage;				
+				    iChannel->SentRequest( EBufferFillStop, iBufferPercentage );	
+				
+				    //player has already buffered completely for the first time
+				    //so even if StopInitialBuffering is called media client is help less
+				    //to handle this situation iStopBuffering is made ETrue
+				    iStopBuffering = ETrue;
+
+				    //called for intializing a new player
+				    InitializePlayer( iConfig,iChannel );
+				
+				    //calls play for the first time
+				    iPlayer->Play();
+				    }
+				}									
+			}
+		}
+	else
+		{
+		//buffer is already filled for first time
+		//media engine is created and playing so Buffer filled 
+		//function of media Engine should be called
+		iPlayer->BufferFilled();				
+		}			
+	IRLOG_DEBUG( "CIRMediaClient::BufferFilled - Exiting." );
+	}
+	
+// ---------------------------------------------------------------------------
+// Function: StartNewPlayerL
+// Set the whether a Fill Buffer is currently active
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::StartNewPlayerL(TConfig& aConfig,const TDesC8& aFormat
+	)
+	{
+	IRLOG_DEBUG( "CIRMediaClient::StartNewPlayerL - Entering" );
+	//format is copied
+	iFormat.Copy(aFormat);
+
+	//stop of intial buffering from media client is enable
+	iStopBuffering = EFalse;
+	
+	iConfig = aConfig;
+
+	TInt bitRate(0);
+	RProperty::Get ( KUidActiveInternetRadioApp, KIRPSBitrate, bitRate );
+    // Next line will round the bitrate down to be divisible by KIRBitRateDivider.
+	bitRate = bitRate - (bitRate % KIRBitRateDivider);
+	if( bitRate <= KIRValidBitRate )
+	    {
+	    // If invalid bit rate info, use default bit rate for calculating buffer sizes.
+	    bitRate = KIRDefBitRate;
+	    }
+	else if( bitRate < KIRMinBitRate )
+	    {
+	    // If small bit rate info, use minimum bit rate for calculating buffer sizes.
+	    // To make single buffer minimum size 1 kB.
+	    bitRate = KIRMinBitRate;
+	    }
+	else if( bitRate > KIRMaxBitRate )
+	    {
+	    // If large bit rate info, use maximum bit rate for calculating buffer sizes.
+	    // To make single buffer maximum size 24 kB.
+	    bitRate = KIRMaxBitRate;
+	    }
+	else
+	    {
+	    }
+	iConfig.iPlayBufferCount = KIRInputBufferCount;
+    iConfig.iPlayBufferSize = KIRByteMultiplier*bitRate/KIRBitRateDivider;
+	
+	//creates a new instance of media buffer for new player
+	iTempBuffer = new (ELeave) TUint8[iConfig.iPlayBufferCount*iConfig.iPlayBufferSize];
+	iInputBufferPtr = iTempBuffer;
+
+	//initial buffering starts
+	iInputBuffer.Set(iInputBufferPtr,iConfig.iPlayBufferSize,iConfig.iPlayBufferSize);
+	iNewPlayer = ETrue;
+	iFirstTime = ETrue;
+
+	//initial buffering starts
+	iChannel->FilltheBuffer(iInputBuffer);	
+	
+	//starts audio fade out for the previous channel
+	IRLOG_DEBUG( "CIRMediaClient::StartNewPlayerL - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// Function: StopMediaBuffering
+// stops buffering of media engine, the change cannot be reverted 
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::StopMediaBuffering()
+	{
+	IRLOG_DEBUG( "CIRMediaClient::StopMediaBuffering - Entering" );
+	//calls media engine's stop buffering cancels the buffering in media engine
+	if( iPlayer )
+		{
+		iPlayer->StopPlayerBuffering();	
+		}			
+	IRLOG_DEBUG( "CIRMediaClient::StopMediaBuffering - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// Function: StopInitialBuffering
+// stops buffering from media client, media engine is not stopped 
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::StopInitialBuffering()
+	{
+	IRLOG_DEBUG( "CIRMediaClient::StopInitialBuffering - Entering" );
+	//initially buffering is taken care by media client and then 
+	//it shift the responsibility to media engine
+	//this is done because audio fade out has to take place when other channel buffers
+	//if media client is handling the buffer it should be stopped
+	//media client is handling the buffering
+	iStopBuffering = ETrue;
+	
+	delete[] iTempBuffer;
+	iTempBuffer = NULL;
+	
+	iCommand=EStereo;
+	iChannel->SentRequest(iCommand,KErrNone);
+	delete iPlayer;
+	iPlayer = NULL;
+	
+	iStopBuffering = ETrue;
+	//return true to indicate success of cancelling of buffer
+	IRLOG_DEBUG( "CIRMediaClient::StopInitialBuffering - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// Function: SetCodecSettings
+// Creates an instance of the players and initialize it
+// ---------------------------------------------------------------------------
+//
+TBool CIRMediaClient::CreatePlayer()
+	{
+    IRLOG_DEBUG( "CIRMediaClient::CreatePlayer" );
+    TBool createResult( ETrue );
+	//delete the instance of previously created player
+	iCommand=EStereo;
+	iChannel->SentRequest(iCommand,KErrNone);
+    if ( iPlayer )
+    	{
+    	delete iPlayer;
+    	iPlayer = NULL;
+    	}
+		
+	//media engine's instance is created type is stored in iFormat (basically the mime type)
+	TRAPD(error,iPlayer = CIRMediaEngineInterface::NewL(iFormat));
+    if( error )
+        {
+        iChannel->SentRequest( EError, KIRCtrlCmdPlayerNotCreated );
+        createResult = EFalse;
+        }
+    
+    return createResult;    
+	}
+// ---------------------------------------------------------------------------
+// CIRMediaClient::InitializePlayer
+// ---------------------------------------------------------------------------
+//
+void CIRMediaClient::InitializePlayer( TConfig& aConfig,
+	CIRCtrlCmdObserver* aChannel)
+	{
+	IRLOG_DEBUG( "CIRMediaClient::SetCodecSettings" );
+
+	//delete the instance of buffer associated with previously playing player
+	delete[] iCurrentBuffer;
+	iCurrentBuffer = NULL;
+	
+	//current buffer is made same as previous buffer
+	iCurrentBuffer = iTempBuffer;
+	iTempBuffer = NULL;
+		
+	//intialize the media engine
+	iPlayer->Intialize(aConfig,iCurrentBuffer,aChannel);
+	IRLOG_DEBUG( "CIRMediaClient::SetCodecSettings - Exiting." );
+	}
+
+// ---------------------------------------------------------------------------
+// CIRNowPlayingWrapper::GetMediaClientInstance()
+// Returns the Audio Player Instance
+// ---------------------------------------------------------------------------
+//
+CMdaAudioOutputStream* CIRMediaClient::GetPlayerInstance()
+	{
+	IRLOG_DEBUG( "CIRMediaClient::GetMediaClientInstance " );
+	return (iPlayer->GetAudioPlayer());	
+	}