internetradio2.0/mediaenginesrc/iraacplayer.cpp
changeset 0 09774dfdd46b
equal deleted inserted replaced
-1:000000000000 0:09774dfdd46b
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  ?Description
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <AudioPreference.h>
       
    20 
       
    21 #include "iraacplayer.h"
       
    22 #include "iraacplayerlocal.h"
       
    23 #include "irbuffercontainer.h"
       
    24 #include "irctrlcmdobserver.h"
       
    25 #include "irdebug.h"
       
    26 #include "irmediaenginebuffer.h"
       
    27 
       
    28 // Constants
       
    29 
       
    30 const TInt KZERO = 0 ;
       
    31 const TInt KONE = 1 ;
       
    32 const TInt KTWO = 2 ;
       
    33 const TInt KTHREE = 3 ;
       
    34 const TInt KFOUR = 4 ;
       
    35 const TInt KFIVE = 5 ;
       
    36 const TInt KSIX = 6 ;
       
    37 const TInt KELEVEN = 11 ;
       
    38 const TInt KTWENTYONE = 21 ;
       
    39 const TInt KTWENTYFOUR = 24 ;
       
    40 const TInt KSIXTEEN = 16 ;
       
    41 const TInt KEIGHT = 8 ;
       
    42 const TInt KONEFIVETHREESIX = 1536 ;
       
    43 
       
    44 
       
    45 
       
    46 
       
    47 
       
    48 // ============================ MEMBER FUNCTIONS ===============================
       
    49 
       
    50 // ---------------------------------------------------------------------------
       
    51 // Function : NewL
       
    52 // function returns an instance of CIRAACPlayer
       
    53 // Two phase constructor
       
    54 // ---------------------------------------------------------------------------
       
    55 //
       
    56 CIRAACPlayer* CIRAACPlayer::NewL()
       
    57 	{
       
    58 	IRLOG_DEBUG( "CIRAACPlayer::NewL" );
       
    59 	CIRAACPlayer* self = CIRAACPlayer::NewLC();
       
    60 	CleanupStack::Pop(self);
       
    61 	IRLOG_DEBUG( "CIRAACPlayer::NewL - Exiting." );
       
    62 	return self;
       
    63 	}
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // Function : NewLC
       
    67 // function creates an instance of CIRAACPlayer
       
    68 // Two phase constructor
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 CIRAACPlayer* CIRAACPlayer::NewLC()
       
    72 	{
       
    73 	IRLOG_DEBUG( "CIRAACPlayer::NewLC" );
       
    74 	CIRAACPlayer* self = new (ELeave) CIRAACPlayer;
       
    75 	CleanupStack::PushL(self);
       
    76 	self->ConstructL();
       
    77 	IRLOG_DEBUG( "CIRAACPlayer::NewLC - Exiting." );
       
    78 	return self;
       
    79 	}
       
    80 
       
    81 // ---------------------------------------------------------------------------
       
    82 // Function : ~CIRAACPlayer
       
    83 // Default Destructor
       
    84 // ---------------------------------------------------------------------------
       
    85 //
       
    86 CIRAACPlayer::~CIRAACPlayer()
       
    87 	{
       
    88 	IRLOG_DEBUG( "CIRAACPlayer::~CIRAACPlayer" );
       
    89 	delete iAudioPlayer;
       
    90 	while(!iSinkBufferQ.IsEmpty())//deleting all the entries in sink buffers queue
       
    91 		{
       
    92 		iTempBufferHolder = iSinkBufferQ.First();
       
    93 		iSinkBufferQ.Remove(*iTempBufferHolder);
       
    94 		delete iTempBufferHolder;
       
    95 		}
       
    96 	while(!iSourceBufferQ.IsEmpty())//deleting all the entries in source buffers queue
       
    97 		{
       
    98 		iTempBufferHolder = iSourceBufferQ.First();
       
    99 		iSourceBufferQ.Remove(*iTempBufferHolder);
       
   100 		delete iTempBufferHolder;
       
   101 		}
       
   102 	IRLOG_DEBUG( "CIRAACPlayer::~CIRAACPlayer - Exiting." );
       
   103 	}
       
   104 
       
   105 
       
   106 									//Function for Play control
       
   107 
       
   108 // ---------------------------------------------------------------------------
       
   109 // Function : Play
       
   110 // function which intiates the player to start playing
       
   111 // ---------------------------------------------------------------------------
       
   112 //
       
   113 void CIRAACPlayer::Play()
       
   114 	{
       
   115 	IRLOG_DEBUG( "CIRAACPlayer::Play" );
       
   116 	if ( EPlaying == iState ) //If the current state is playing
       
   117 		{
       
   118 		//internally stopped before playing so no need of sending
       
   119 		//stop status
       
   120 		iSkipPlayCompleted = ETrue;
       
   121 		iAudioPlayer->Stop(); //then we have to stop it then restart the play from begining
       
   122 		iSkipPlayCompleted = EFalse;
       
   123 		}
       
   124 	iState = ENotReady;
       
   125 	iBufferPercentage = KZeroPercentage;
       
   126 	iHeaderFound = EFalse;
       
   127 	iStopState = EFalse;
       
   128 
       
   129 	//note : using TRAP_IGNORE to suppress a codescanner warning
       
   130 	//"Ignoring the return value from Open() functions"
       
   131 	//this cannot be checked as this symbian API returns void
       
   132 
       
   133 	//opening the current player component
       
   134 	 TRAP_IGNORE(iAudioPlayer->Open(&iSettings); )
       
   135 	iChannel->SentRequest(EPlayingState,KErrNone);			
       
   136 	IRLOG_DEBUG( "CIRAACPlayer::Play - Exiting." );
       
   137 	}
       
   138 
       
   139 // ---------------------------------------------------------------------------
       
   140 // Function : Stop
       
   141 // function which stops the player
       
   142 // ---------------------------------------------------------------------------
       
   143 //
       
   144 void CIRAACPlayer::Stop()
       
   145 	{
       
   146 	IRLOG_DEBUG( "CIRAACPlayer::Stop" );
       
   147 	//If the current state is playing
       
   148 	if ( EPlaying == iState )
       
   149 		{
       
   150 		iAudioPlayer->Stop();
       
   151 		}
       
   152 	else
       
   153 		{
       
   154 		//sending the updated status as stopped
       
   155 		iChannel->SentRequest( EStoppedPlaying, KErrNone );
       
   156 		}
       
   157 	iState = EReadyToPlay;
       
   158 	iStopState = ETrue;
       
   159 	IRLOG_DEBUG( "CIRAACPlayer::Stop - Exiting." );
       
   160 	}
       
   161 
       
   162 										//Functions for Volume Control
       
   163 
       
   164 // ---------------------------------------------------------------------------
       
   165 // Function : SetVolume
       
   166 // function to set the volume
       
   167 // ---------------------------------------------------------------------------
       
   168 //
       
   169 void CIRAACPlayer::SetVolume(TInt aVolume )
       
   170 	{
       
   171 	IRLOG_DEBUG( "CIRAACPlayer::SetVolume" );
       
   172 	//If volume should be less than maximum value and greater than or equal to zero then set the volume
       
   173 	if( KZeroVolume <= aVolume && iAudioPlayer->MaxVolume() >= aVolume )
       
   174 		{
       
   175 		iAudioPlayer->SetVolume((TInt)(aVolume));
       
   176 		iConfig.iVolume = iCurrentVolume = aVolume;
       
   177 		}
       
   178 	IRLOG_DEBUG( "CIRAACPlayer::SetVolume - Exiting." );
       
   179 	}
       
   180 // ---------------------------------------------------------------------------
       
   181 // Function : MaxVolume
       
   182 // function to returns the maximum volume
       
   183 // ---------------------------------------------------------------------------
       
   184 //
       
   185 TInt CIRAACPlayer::MaxVolume() const
       
   186 	{
       
   187 	IRLOG_DEBUG( "CIRAACPlayer::MaxVolume" );
       
   188 	return iAudioPlayer->MaxVolume();
       
   189 	}
       
   190 // ---------------------------------------------------------------------------
       
   191 // Function : Volume
       
   192 // function to returns the volume, integer level of voume is the Output
       
   193 // ---------------------------------------------------------------------------
       
   194 //
       
   195 TInt CIRAACPlayer::Volume() const
       
   196 	{
       
   197 	IRLOG_DEBUG( "CIRAACPlayer::Volume" );
       
   198 	return iAudioPlayer->Volume();
       
   199 	}
       
   200 
       
   201 									//Intialization of Codec Settings
       
   202 
       
   203 // ---------------------------------------------------------------------------
       
   204 // Function: Intialize
       
   205 // Set the codec type and sampling rate channel of stream
       
   206 // This is set to initial settings which is required to start the player
       
   207 // ---------------------------------------------------------------------------
       
   208 //
       
   209 void CIRAACPlayer::Intialize(TConfig& aConfig,TUint8* aInitParams,
       
   210 	CIRCtrlCmdObserver* aChannel)
       
   211 	{
       
   212 	IRLOG_DEBUG( "CIRAACPlayer::Intialize" );
       
   213 	iInputBufferPtr = reinterpret_cast<TUint8*> (aInitParams); //instance of buffer
       
   214 	//Configuration information
       
   215 	iConfig = aConfig; //! Set all the configuration information like volume
       
   216 	iPlayBufferSize = iConfig.iPlayBufferSize;
       
   217 	iInputBufferSize = iConfig.iPlayBufferCount*iPlayBufferSize;
       
   218     iBufferOffset = iPlayBufferSize;
       
   219 	iDataType.Set(KMMFFourCCCodeAAC); //! Set the data type as AAC
       
   220 	iChannel = reinterpret_cast<CIRCtrlCmdObserver*> (aChannel);
       
   221 	iChannel->SentRequest(EPlayerChanged,KErrNone);									//creates an instance of the player
       
   222 	TRAPD(err,CreateBufferL()); //creates the buffer
       
   223 	if( err )
       
   224 		{
       
   225 		iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   226 		return;
       
   227 		}
       
   228 	IRLOG_DEBUG( "CIRAACPlayer::Intialize - Exiting." );
       
   229 	}
       
   230 
       
   231 // ---------------------------------------------------------------------------
       
   232 // Function: StopPlayerBuffering
       
   233 // Function is used to freeze bufferring
       
   234 // ---------------------------------------------------------------------------
       
   235 //
       
   236 void CIRAACPlayer::StopPlayerBuffering()
       
   237 	{
       
   238 	IRLOG_DEBUG( "CIRAACPlayer::StopPlayerBuffering" );
       
   239 	iStopPlayerBuffering = ETrue;
       
   240 	}
       
   241 
       
   242 // ---------------------------------------------------------------------------
       
   243 // Function: BufferFilled
       
   244 // Function which is called when network gets the buffer filled with data
       
   245 // ---------------------------------------------------------------------------
       
   246 //
       
   247 void CIRAACPlayer::BufferFilled()
       
   248 	{
       
   249 	IRLOG_DEBUG( "CIRAACPlayer::BufferFilled" );
       
   250 	if( !iNewPlayer )
       
   251 		{
       
   252 		//if not playing for the first time
       
   253 		if( !iSourceBufferQ.IsEmpty() )
       
   254 			{
       
   255 			//Initially all unfilled buffers are in source buffer Queue
       
   256 			//Once the buffer in the source buffer queue is filled it is moved to queue of buffer
       
   257 			//to the sink
       
   258 			iTempBufferHolder = iSourceBufferQ.First();
       
   259 			iSourceBufferQ.Remove(*iTempBufferHolder);
       
   260 			iSinkBufferQ.AddLast(*iTempBufferHolder);
       
   261 			}
       
   262 		}
       
   263 
       
   264 	if( iFirstTime )
       
   265 		{
       
   266 		//if it is playing for first time or rebuffering
       
   267 		if( !iNewPlayer )
       
   268 			{
       
   269 			//if not playing for the first time
       
   270 			if( !iSourceBufferQ.IsEmpty() )
       
   271 				{
       
   272 				//fill the entire buffer source queue
       
   273 				//if the entire source buffer queue is not filled
       
   274 				if( !iStopPlayerBuffering )
       
   275 					{
       
   276 					iTempBufferHolder = iSourceBufferQ.First();
       
   277 					iTempbuffer = iTempBufferHolder->Des();
       
   278 					iInputBuffer.Set
       
   279 						(iTempbuffer,iPlayBufferSize,iPlayBufferSize);
       
   280 
       
   281 					if( !iStopState )
       
   282 						{
       
   283 						//! Calls the fill the buffer for next subsequent times until the source buffer queue is empty
       
   284 						iChannel->FilltheBuffer(iInputBuffer);
       
   285 						IRLOG_DEBUG( "CIRAACPlayer::BufferFilled - Exiting (1)."  );
       
   286 						return;
       
   287 						}
       
   288 					}
       
   289 				}
       
   290 			else
       
   291 				{
       
   292 				//if the entire source buffer queue is filled
       
   293 				//gets the header informations like sampling rate and channel
       
   294 				//this function here is called to find proper header and
       
   295 				//rearrange buffer accordingly
       
   296 				GetAACAudioProperties();
       
   297 
       
   298 				//buffer is completetly filled and indicates that buffering is completed
       
   299 				iBufferPercentage = K100Percentage;
       
   300 				iChannel->SentRequest( EBufferFillStop, iBufferPercentage );
       
   301 
       
   302 				//takes the first buffer from sink buffer queue
       
   303 				if( !iSinkBufferQ.IsEmpty() )
       
   304 					{
       
   305 					iTempBufferHolder = iSinkBufferQ.First();
       
   306 					}
       
   307 				iTempbuffer = iTempBufferHolder->Des();
       
   308 
       
   309 				iInput.Set(iTempbuffer,iPlayBufferSize,iPlayBufferSize);
       
   310 				iFirstTime = EFalse;
       
   311 				iState = EPlaying;
       
   312 				if( !iStopState )
       
   313 					{
       
   314 					//! Calls the play for the first time
       
   315 					TRAPD(err,iAudioPlayer->WriteL(iInput));
       
   316 					if( err )
       
   317 						{
       
   318 						iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   319                         IRLOG_DEBUG( "CIRAACPlayer::BufferFilled - Exiting (2)." );
       
   320 						return;
       
   321 						}
       
   322 					}
       
   323 				}
       
   324 			}
       
   325 		else
       
   326 			{
       
   327 			//if a new player
       
   328 			TInt err( KErrNone );
       
   329 			//get audio properties like sampling rate and channel
       
   330 			if( !iHeaderFound )
       
   331 				{
       
   332 				GetAACAudioProperties();
       
   333 				}
       
   334 
       
   335 			//sets the audio properties like sampling rate and channel
       
   336 			TRAP(err, iAudioPlayer->SetAudioPropertiesL( iSettings.iSampleRate,
       
   337 														 iSettings.iChannels));
       
   338 			if( err )
       
   339 				{
       
   340 				iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   341                 IRLOG_DEBUG( "CIRAACPlayer::BufferFilled - Exiting (3)." );
       
   342 				return;
       
   343 				}
       
   344 
       
   345 			//indicates that it is ready to play to client
       
   346 			iBufferPercentage = K100Percentage;
       
   347 			iChannel->SentRequest( EBufferFadeInReady, iBufferPercentage );
       
   348 
       
   349 			if( !iSinkBufferQ.IsEmpty() )
       
   350 				{
       
   351 				iTempBufferHolder = iSinkBufferQ.First();
       
   352 				}
       
   353 			iTempbuffer = iTempBufferHolder->Des();
       
   354 
       
   355 			//takes the first buffer from sink buffer queue
       
   356 			iInput.Set(iTempbuffer,iPlayBufferSize,iPlayBufferSize);
       
   357 			iFirstTime = EFalse;
       
   358 			iState = EPlaying;
       
   359 			iNewPlayer = EFalse;
       
   360 			if( !iStopState )
       
   361 				{
       
   362 				//! Calls the play for the first time
       
   363 				TRAP(err,iAudioPlayer->WriteL(iInput));
       
   364 				if( err )
       
   365 					{
       
   366 					iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   367                     IRLOG_DEBUG( "CIRAACPlayer::BufferFilled - Exiting (4)." );
       
   368 					return;
       
   369 					}
       
   370 				}
       
   371 			}
       
   372 		}
       
   373 	IRLOG_DEBUG( "CIRAACPlayer::BufferFilled - Exiting (5)." );
       
   374 	}
       
   375 
       
   376 // ---------------------------------------------------------------------------
       
   377 // Function: CIRAACPlayer
       
   378 // This function is the default constructor
       
   379 // ---------------------------------------------------------------------------
       
   380 //
       
   381 CIRAACPlayer::CIRAACPlayer():iInputBuffer(NULL,0,0),iInput(NULL,0,0)
       
   382 	{
       
   383 	IRLOG_DEBUG( "CIRAACPlayer()::CIRAACPlayer" );
       
   384 	}
       
   385 
       
   386 // ---------------------------------------------------------------------------
       
   387 // Function: ConstructL
       
   388 // Two phase constructor is used to intialize data members
       
   389 // ---------------------------------------------------------------------------
       
   390 //
       
   391 void CIRAACPlayer::ConstructL()
       
   392 	{
       
   393 	IRLOG_DEBUG( "CIRAACPlayer::ConstructL" );
       
   394 
       
   395 
       
   396 	iAudioPlayer = CMdaAudioOutputStream::NewL(*this,KAudioPriorityRealOnePlayer,
       
   397 		(TMdaPriorityPreference)KAudioPrefRealOneStreaming );
       
   398 
       
   399 
       
   400 
       
   401 										//creates an instance of the player
       
   402 
       
   403 	TInt f_off = _FOFF(CIRBufferContainer,iLink); //for the buffer queue which is maintained
       
   404 
       
   405     iSinkBufferQ.SetOffset(f_off);	 //It is Queue of buffer used by media Sink
       
   406     iSourceBufferQ.SetOffset(f_off); // Source of buffer which is ready to fill
       
   407 
       
   408    	iNewPlayer = ETrue;    //indicates that this a newly created player
       
   409 	iStopPlayerBuffering = EFalse; //indicates whether to freeze buffering
       
   410 	iNeedReBuffering = EFalse; //if rebuffering is required this is to set true
       
   411 	iState = ENotReady;//current state not ready
       
   412 	IRLOG_DEBUG( "CIRAACPlayer::ConstructL - Exiting." );
       
   413 
       
   414 	}
       
   415 
       
   416 // ---------------------------------------------------------------------------
       
   417 // Function: CreateBufferL
       
   418 // Allocates memory and  creates buffers of sink queue
       
   419 // ---------------------------------------------------------------------------
       
   420 //
       
   421 void CIRAACPlayer::CreateBufferL()
       
   422 	{
       
   423 	IRLOG_DEBUG( "CIRAACPlayer::CreateBufferL" );
       
   424 	TUint8* bufferaddress = iInputBufferPtr;
       
   425 
       
   426 	//Created memory to buffer and allocates buffers to buffer queues
       
   427 	for(TInt buffercount = 0;buffercount < KIRInputBufferCount; buffercount++)
       
   428 		{
       
   429 		iTempBufferHolder =
       
   430 			CIRBufferContainer::NewL(bufferaddress,iPlayBufferSize);
       
   431 		iSinkBufferQ.AddLast(*iTempBufferHolder);
       
   432 		bufferaddress += iBufferOffset;
       
   433 		}
       
   434 	IRLOG_DEBUG( "CIRAACPlayer::CreateBufferL - Exiting." );
       
   435 	}
       
   436 
       
   437 // ---------------------------------------------------------------------------
       
   438 // Function: ReCreateBufferL
       
   439 // Recreates buffers of source queue
       
   440 // ---------------------------------------------------------------------------
       
   441 //
       
   442 void CIRAACPlayer::ReCreateBufferL()
       
   443 	{
       
   444 	IRLOG_DEBUG( "CIRAACPlayer::ReCreateBufferL" );
       
   445 	while(!iSinkBufferQ.IsEmpty())
       
   446 		{
       
   447 		//Deleting all the entries in sink buffers queue
       
   448 		iTempBufferHolder = iSinkBufferQ.First();
       
   449 		iSinkBufferQ.Remove(*iTempBufferHolder);
       
   450 		delete iTempBufferHolder;
       
   451 		iTempBufferHolder = NULL;
       
   452 		}
       
   453 	while(!iSourceBufferQ.IsEmpty())
       
   454 		{
       
   455 		//deleting all the entries in source buffers queue
       
   456 		iTempBufferHolder = iSourceBufferQ.First();
       
   457 		iSourceBufferQ.Remove(*iTempBufferHolder);
       
   458 		delete iTempBufferHolder;
       
   459 		iTempBufferHolder = NULL;
       
   460 		}
       
   461 	TUint8* bufferaddress = iInputBufferPtr;
       
   462 	for(TInt buffercount = 0;buffercount < KIRInputBufferCount; buffercount++)
       
   463 		{
       
   464 		//reallocates the buffer to source buffer queue
       
   465 		iTempBufferHolder =
       
   466 			CIRBufferContainer::NewL(bufferaddress,iPlayBufferSize);
       
   467 		iSourceBufferQ.AddLast(*iTempBufferHolder);
       
   468 		bufferaddress += iBufferOffset;
       
   469 		}
       
   470 	IRLOG_DEBUG( "CIRAACPlayer::ReCreateBufferL - Exiting." );
       
   471 	}
       
   472 
       
   473 									//Call back functions
       
   474 
       
   475 // ---------------------------------------------------------------------------
       
   476 // Function: MaoscBufferCopied
       
   477 // call back to be implemented for using CMdaAudioOutputStream
       
   478 // Call as callback from the CMdaAudioOutputStream::WriteL
       
   479 // after frame work has copied stream to a buffer * @param Error code
       
   480 // ---------------------------------------------------------------------------
       
   481 //
       
   482 void CIRAACPlayer::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/)
       
   483 	{
       
   484 	IRLOG_DEBUG( "CIRAACPlayer::MaoscBufferCopied" );
       
   485 	if( aError )
       
   486 		{
       
   487 		iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   488 		IRLOG_DEBUG( "CIRAACPlayer::MaoscBufferCopied - Exiting (1)." );
       
   489 		return;
       
   490 		}
       
   491 	else
       
   492 		{
       
   493         if ( iCurrentVolume < iConfig.iVolume )
       
   494             {
       
   495             iCurrentVolume = iConfig.iVolume;
       
   496             IRLOG_INFO2( "CIRAACPlayer::MaoscBufferCopied - Setting volume to %d", iCurrentVolume );
       
   497             iAudioPlayer->SetVolume( iCurrentVolume );
       
   498             }
       
   499 		if( !iSinkBufferQ.IsEmpty() )
       
   500 			{
       
   501 			//removing the previously read buffer
       
   502 			iTempBufferHolder = iSinkBufferQ.First();
       
   503 			iSinkBufferQ.Remove(*iTempBufferHolder);
       
   504 			if(iTempBufferHolder->Size() == iPlayBufferSize)
       
   505 				{
       
   506 				iSourceBufferQ.AddLast(*iTempBufferHolder);
       
   507 				}
       
   508 			else
       
   509 				{
       
   510 				delete iTempBufferHolder;
       
   511 				iTempBufferHolder = NULL;
       
   512 				}
       
   513 			}
       
   514 
       
   515 		if( !iStopPlayerBuffering )
       
   516 			{
       
   517 			if( !iSourceBufferQ.IsEmpty() )
       
   518 				{
       
   519 				//refilling the first empty buffer from the source queue
       
   520 				iFirstTime = EFalse;
       
   521 				iTempBufferHolder = iSourceBufferQ.First();
       
   522 				iTempbuffer = iTempBufferHolder->Des();
       
   523 				iInputBuffer.Set
       
   524 					(iTempbuffer,iPlayBufferSize,iPlayBufferSize);
       
   525 				iChannel->FilltheBuffer(iInputBuffer);
       
   526 				}
       
   527 			}
       
   528 		if( iStopState )
       
   529 			{
       
   530             IRLOG_DEBUG( "CIRAACPlayer::MaoscBufferCopied - Exiting (2)." );
       
   531 			return;
       
   532 			}
       
   533 		//starts to play next buffer
       
   534 		if( !iSinkBufferQ.IsEmpty() )
       
   535 			{
       
   536 			//takes the next buffer and plays
       
   537 			iTempBufferHolder = iSinkBufferQ.First();
       
   538 			iTempbuffer = iTempBufferHolder->Des();
       
   539 			iInput.Set(iTempbuffer,iTempBufferHolder->Size(),
       
   540 				iTempBufferHolder->Size());
       
   541 			//writing to MMF buffer
       
   542 			TRAPD(err,iAudioPlayer->WriteL(iInput));
       
   543 			if( err )
       
   544 				{
       
   545 				iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   546                 IRLOG_DEBUG( "CIRAACPlayer::MaoscBufferCopied - Exiting (3)." );
       
   547 				return;
       
   548 				}
       
   549 			}
       
   550 		else
       
   551 			{
       
   552 			//If no buffer to play so rebuffer
       
   553 			if( !iStopPlayerBuffering )
       
   554 				{
       
   555 				Play();
       
   556 				}
       
   557 			}
       
   558 		}
       
   559 	IRLOG_DEBUG( "CIRAACPlayer::MaoscBufferCopied - Exiting (4)." );
       
   560 	}
       
   561 
       
   562 // ---------------------------------------------------------------------------
       
   563 // Function: MaoscPlayComplete
       
   564 // call back to be implemented for using CMdaAudioOutputStream
       
   565 // after play is completed
       
   566 // ---------------------------------------------------------------------------
       
   567 //
       
   568 void CIRAACPlayer::MaoscPlayComplete(TInt aError)
       
   569 	{
       
   570 	IRLOG_DEBUG( "CIRAACPlayer::MaoscPlayComplete" );
       
   571 	if( !iSkipPlayCompleted )
       
   572 		{
       
   573 		//sending the error code
       
   574 		iChannel->SentRequest( EStoppedPlaying, aError );
       
   575 		}
       
   576 	IRLOG_DEBUG( "CIRAACPlayer::MaoscPlayComplete - Exiting." );
       
   577 	}
       
   578 
       
   579 // ---------------------------------------------------------------------------
       
   580 // Function: MaoscOpenComplete
       
   581 // call back to be implemented for using CMdaAudioOutputStream
       
   582 // Call as callback from the CMdaAudioOutputStream::Open
       
   583 // ---------------------------------------------------------------------------
       
   584 //
       
   585 void CIRAACPlayer::MaoscOpenComplete( TInt aError )
       
   586 	{
       
   587 	IRLOG_DEBUG( "CIRAACPlayer::MaoscOpenComplete" );
       
   588 	if( aError )
       
   589 		{
       
   590 		IRLOG_DEBUG( "CIRAACPlayer::MaoscOpenComplete - Exiting (1)." );
       
   591 		iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   592 		return;
       
   593 		}
       
   594 	else
       
   595 		{
       
   596 		//Setting the data type of player as MP3
       
   597 		TRAPD(err, iAudioPlayer->SetDataTypeL(iDataType.FourCC()));  //set type the data as MP3 type
       
   598 		if ( err )
       
   599 			{
       
   600 			if ( KErrNotSupported == err )
       
   601 				{
       
   602 				iChannel->SentRequest( EError, KErrNotSupported );
       
   603 				}
       
   604 			else
       
   605 				{
       
   606 				iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   607 				}
       
   608             IRLOG_DEBUG( "CIRAACPlayer::MaoscOpenComplete - Exiting (2)." );
       
   609 			return;
       
   610 			}
       
   611 
       
   612 		//during rebuffering current volume is to be taken
       
   613 		if( iNeedReBuffering )
       
   614 			{
       
   615 			iConfig.iVolume = iChannel->FetchVolume();
       
   616 			}
       
   617 		//Computes the current volume and sets the volume
       
   618 		TInt index = iAudioPlayer->MaxVolume()/KNoVolumeLevels;
       
   619 		iConfig.iVolume = iConfig.iVolume * index;
       
   620 		//if volume level given is greater than Maximum volume
       
   621 		//volume is set to maximum volume level
       
   622 		if( iConfig.iVolume > iAudioPlayer->MaxVolume() )
       
   623 			{
       
   624 			iConfig.iVolume = iAudioPlayer->MaxVolume();
       
   625 			}
       
   626 		//if volume level given is lesser than zero
       
   627 		//volume is set to zero volume level
       
   628 		if( iConfig.iVolume < KZeroVolume )
       
   629 			{
       
   630 			iConfig.iVolume = KZeroVolume;
       
   631 			}
       
   632         // The actual setting of the volume is delayed to MaoscBufferCopied method.
       
   633         // This was due to some error in N91 sound subsystem, which caused the
       
   634         // volume not to adjust in some cases. 
       
   635         iCurrentVolume = 0;
       
   636         iAudioPlayer->SetVolume( iCurrentVolume );
       
   637 		iFirstTime = ETrue;
       
   638 		iNeedReBuffering = ETrue;
       
   639 		if( !iNewPlayer )
       
   640 			{
       
   641 			//if rebuffering
       
   642 			TRAP(err,ReCreateBufferL());
       
   643 			if ( err )
       
   644 				{
       
   645 				iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   646                 IRLOG_DEBUG( "CIRAACPlayer::MaoscOpenComplete - Exiting (3)." );
       
   647 				return;
       
   648 				}
       
   649 			if( !iStopPlayerBuffering )
       
   650 				{
       
   651 				//initiates rebuffering for the first time
       
   652 				iTempBufferHolder = iSourceBufferQ.First();
       
   653 				iTempbuffer = iTempBufferHolder->Des();
       
   654 				iInputBuffer.Set(iTempbuffer,iTempBufferHolder->Size(),
       
   655 					iTempBufferHolder->Size());
       
   656 
       
   657 				iChannel->SentRequest( EBufferFillStart, iBufferPercentage );
       
   658 				//! Call FilltheBuffer for first time
       
   659 				iChannel->FilltheBuffer(iInputBuffer);	//start fill the data
       
   660 				}
       
   661 			}
       
   662 		else
       
   663 			{
       
   664 			//First time playing
       
   665 			BufferFilled();
       
   666 			}
       
   667 		}
       
   668 	IRLOG_DEBUG( "CIRAACPlayer::MaoscOpenComplete - Exiting (4)." );
       
   669 	}
       
   670 
       
   671 // ---------------------------------------------------------------------------
       
   672 // Function: GetAACAudioProperties
       
   673 // extract all the information to start the playing from the stream
       
   674 // ---------------------------------------------------------------------------
       
   675 //
       
   676 void CIRAACPlayer::GetAACAudioProperties()
       
   677 	{
       
   678 	IRLOG_DEBUG( "CIRAACPlayer::GetAACAudioProperties" );
       
   679 	//decoding the AAC header
       
   680 	TRAPD(err,DoFindnDecodeAACHeaderL());
       
   681 	if( err )
       
   682 		{
       
   683 		iChannel->SentRequest( EError, KIRCtrlCmdGeneralPlayerError );
       
   684         IRLOG_DEBUG( "CIRAACPlayer::GetAACAudioProperties - Exiting (1)." );
       
   685 		return;
       
   686 		}
       
   687 	switch(iAudioInfo.iSamplingRate)
       
   688 		{
       
   689 		case EAACSamplingFreq8000: //sampling frequency 8000
       
   690 			{
       
   691 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate8000Hz;
       
   692 			}
       
   693 			break;
       
   694 		case EAACSamplingFreq11025: //sampling frequency 11025
       
   695 			{
       
   696 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate11025Hz;
       
   697 			}
       
   698 			break;
       
   699 		case EAACSamplingFreq12000:	//sampling frequency 12000
       
   700 			{
       
   701 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate12000Hz;
       
   702 			}
       
   703 			break;
       
   704 		case EAACSamplingFreq16000:	//sampling frequency 16000
       
   705 			{
       
   706 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate16000Hz;
       
   707 			}
       
   708 			break;
       
   709 		case EAACSamplingFreq22050:	//sampling frequency 22050
       
   710 			{
       
   711 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate22050Hz;
       
   712 			}
       
   713 			break;
       
   714 		case EAACSamplingFreq24000:	//sampling frequency 24000
       
   715 			{
       
   716 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate24000Hz;
       
   717 			}
       
   718 			break;
       
   719 		case EAACSamplingFreq32000:	//sampling frequency 32000
       
   720 			{
       
   721 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate32000Hz;
       
   722 			}
       
   723 			break;
       
   724 		case EAACSamplingFreq44100:	//sampling frequency 44100
       
   725 			{
       
   726 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate44100Hz;
       
   727 			}
       
   728 			break;
       
   729 		case EAACSamplingFreq48000:	//sampling frequency 48000
       
   730 			{
       
   731 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate48000Hz;
       
   732 			}
       
   733 			break;
       
   734 		case EAACSamplingFreq64000:	//sampling frequency 64000
       
   735 			{
       
   736 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate64000Hz;
       
   737 			}
       
   738 			break;
       
   739 		case EAACSamplingFreq96000:	//sampling frequency 96000
       
   740 			{
       
   741 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate96000Hz;
       
   742 			}
       
   743 			break;
       
   744 		default:	//default sampling frequency 22050
       
   745 			{
       
   746 			iSettings.iSampleRate = TMdaAudioDataSettings::ESampleRate22050Hz;
       
   747 			}
       
   748 			break;
       
   749 		}
       
   750 
       
   751 	//sets the channel information
       
   752 	if( KAACChannelMono == iAudioInfo.iChannel ) //if 0 it indicates mono
       
   753 		{
       
   754 		iSettings.iChannels = TMdaAudioDataSettings::EChannelsMono;
       
   755 		}
       
   756 	else //else if it is 1 it indicates stereo
       
   757 		{
       
   758 		iSettings.iChannels = TMdaAudioDataSettings::EChannelsStereo;
       
   759 		}
       
   760 	IRLOG_DEBUG( "CIRAACPlayer::GetAACAudioProperties - Exiting (2)." );
       
   761 	}
       
   762 
       
   763 // ---------------------------------------------------------------------------
       
   764 // Function: DoFindnDecodeAACHeader
       
   765 // Function return a non modifiable pointer descriptor of data buffer
       
   766 // ---------------------------------------------------------------------------
       
   767 //
       
   768 void CIRAACPlayer::DoFindnDecodeAACHeaderL()
       
   769 	{
       
   770 	IRLOG_DEBUG( "CIRAACPlayer::DoFindnDecodeAACHeaderL." );
       
   771 	TUint8* input = iInputBufferPtr;
       
   772 	TUint8* endptr = iInputBufferPtr + iInputBufferSize - KAACHeaderSize;
       
   773 	while ( (endptr > input) && (!iHeaderFound) )
       
   774 		{
       
   775 		//ADIF header is checked
       
   776 		if( ('A' == input[KZERO]) && ('D' == input[KONE]) && ('I' == input[KTWO])	&&
       
   777 			('F' ==input[KTHREE]) )
       
   778 			{
       
   779 			iHeaderFound = ETrue;
       
   780 			}
       
   781 		else
       
   782 			{
       
   783 			//checking for sync bits
       
   784 			if( (0xFF == input[0]) && (0xF0 == (0xF6 & input[1])) )
       
   785 				{
       
   786 				//sync bits are obtained
       
   787 				TInt framelength = 0;
       
   788 				framelength |= (input[KTHREE] & 0x03) << KELEVEN;
       
   789 				framelength |= (input[KFOUR] << KTHREE);
       
   790 				framelength |= (input[KFIVE] >> KFIVE) & 0x07;
       
   791 				if( (0 >= framelength) &&
       
   792 					(endptr > (input + framelength + KFOUR)) )
       
   793 					{
       
   794 					iHeaderFound = EFalse;
       
   795 					}
       
   796 				else
       
   797 					{
       
   798 					//cross checked
       
   799 					TUint8* nextheader = input + framelength;
       
   800 					if( (0xFF == nextheader[0]) &&
       
   801 						(0xF0 == ( 0xF6 & nextheader[1])) )
       
   802 						{
       
   803 					 	iHeaderFound = ETrue;
       
   804 						}
       
   805 					}
       
   806 				}
       
   807 			}
       
   808 		if( iHeaderFound )
       
   809 			{
       
   810 			//header is found
       
   811 			TUint value = 0;
       
   812 			value |= input[0] << KTWENTYFOUR;
       
   813 			value |= input[1] << KSIXTEEN;
       
   814 			value |= input[2] << KEIGHT;
       
   815 			value |= input[KTHREE];
       
   816 			//version information is obtained from 19th bit
       
   817 			//of acc/accp header
       
   818 			TInt index = ( value >> 20 ) & 0x0FFF;
       
   819 			if( 0x0FFF == (index & 0xFFF) )
       
   820 				{
       
   821 				iAudioInfo.iVersion = (value >> 19) & 0x01; //MPEG version
       
   822 														    //0 MPEG 4
       
   823 														    //1 MPEG 2
       
   824 				//selection bits for sampling rate starts with 10th bit
       
   825 				//4 bits are need for getting the sampling rate.
       
   826 				//this bit combination is extracted and stored in index
       
   827 				index = ( value >> 10 ) & 0x00F;
       
   828 				iAudioInfo.iSamplingRate = KAacSamplingRate[index]; //gets the sampling rate
       
   829 				if( 0 == iAudioInfo.iSamplingRate ) //if sampling rate is zero then we consider the header is wrong
       
   830 					{
       
   831 					iHeaderFound = EFalse;
       
   832 					}
       
   833 				else
       
   834 					{
       
   835 					//decoding channel information
       
   836 					index = (value >> 6) & 0x07;
       
   837 					if( index == 0 || index == 2 )
       
   838 						{
       
   839 						iAudioInfo.iChannel = 1; //channel information
       
   840 						}
       
   841 					else if( index == 1 )
       
   842 						{
       
   843 						//1 represents stereo and
       
   844 						iAudioInfo.iChannel = 0; //0 represents mono
       
   845 						}
       
   846 					else
       
   847 						{
       
   848 						iHeaderFound = EFalse;
       
   849 						}
       
   850 
       
   851 					if( iHeaderFound )
       
   852 						{
       
   853 						//additional check is done for validation
       
   854 						//of aac header
       
   855 						index = ( value >> 10 ) & 0x00F;
       
   856 
       
   857 						value = 0;
       
   858 						value |= (input[KFOUR] << KTWENTYFOUR);
       
   859 						value |= (input[KFIVE] << KSIXTEEN);
       
   860 						value |= (input[KSIX] << KEIGHT);
       
   861 
       
   862 						index |= ( (value >> KTWENTYONE ) & 0x07FF );
       
   863 						TInt RawData = ((value >> KEIGHT) &0x03) + 1;
       
   864 						if( index > (KONEFIVETHREESIX * RawData) )
       
   865 							{
       
   866 							iHeaderFound = EFalse;
       
   867 							}
       
   868 						}
       
   869 					}
       
   870 				}
       
   871 			}
       
   872 		//if header is not found we go for next header
       
   873 		if( !iHeaderFound )
       
   874 			{
       
   875 			input++;
       
   876 			}
       
   877 		}
       
   878 	if( iHeaderFound )
       
   879 		{
       
   880 		ReArrangeBufferL(input);
       
   881 		}
       
   882 	IRLOG_DEBUG( "CIRAACPlayer::DoFindnDecodeAACHeaderL - Exiting." );
       
   883 	}
       
   884 
       
   885 // ---------------------------------------------------------------------------
       
   886 // Function: ReArrangeBuffer
       
   887 // Function rearranges the buffer, and should be called after finding the header
       
   888 // from the address of buffers specified, the data buffers are kept in sink queue and
       
   889 // remaining buffers are discarded that is put into source queue.
       
   890 // ---------------------------------------------------------------------------
       
   891 //
       
   892 void CIRAACPlayer::ReArrangeBufferL(TUint8* aInput)
       
   893 	{
       
   894 	IRLOG_DEBUG( "CIRAACPlayer::ReArrangeBufferL" );
       
   895 	//if header is found we are rearranging the buffer
       
   896 	TUint8* input = aInput;
       
   897 	TUint8* endptr = iInputBufferPtr + iInputBufferSize;
       
   898 	TUint8* tempbuffer = input;
       
   899 
       
   900 	while(!iSinkBufferQ.IsEmpty())
       
   901 		{
       
   902 		//removing all the entries in sink buffers queue
       
   903 		iTempBufferHolder = iSinkBufferQ.First();
       
   904 		iSinkBufferQ.Remove(*iTempBufferHolder);
       
   905 		delete iTempBufferHolder;
       
   906 		iTempBufferHolder = NULL;
       
   907 		}
       
   908 
       
   909 	//adds the valid data
       
   910 	for(tempbuffer = input; endptr > (tempbuffer + iBufferOffset);
       
   911 		tempbuffer += iBufferOffset)
       
   912 		{
       
   913 		iTempBufferHolder =
       
   914 			CIRBufferContainer::NewL(tempbuffer,iPlayBufferSize);
       
   915 		iSinkBufferQ.AddLast(*iTempBufferHolder);
       
   916 		}
       
   917 
       
   918 	//adds the valid data
       
   919 	TInt length = endptr - tempbuffer;
       
   920 	if( length > 0 )
       
   921 		{
       
   922 		// this buffer will be removed after first time you play
       
   923 		iTempBufferHolder =
       
   924 			CIRBufferContainer::NewL(tempbuffer,length);
       
   925 		iSinkBufferQ.AddLast(*iTempBufferHolder);
       
   926 		}
       
   927 
       
   928 	//adds the buffers to source buffer queue
       
   929 	for(tempbuffer = iInputBufferPtr;
       
   930 		input > (tempbuffer + iBufferOffset);
       
   931 		tempbuffer += iBufferOffset)
       
   932 		{
       
   933 		iTempBufferHolder =
       
   934 			CIRBufferContainer::NewL(tempbuffer,iPlayBufferSize);
       
   935 		iSourceBufferQ.AddLast(*iTempBufferHolder);
       
   936 		}
       
   937 
       
   938 	IRLOG_DEBUG( "CIRAACPlayer::ReArrangeBufferL - Exiting." );
       
   939 	}
       
   940 
       
   941 // CIRMP3Player::GetMediaClientInstance()
       
   942 // Returns the Audio Player Instance
       
   943 // ---------------------------------------------------------------------------
       
   944 //
       
   945 CMdaAudioOutputStream* CIRAACPlayer::GetAudioPlayer()
       
   946 	{
       
   947 	IRLOG_DEBUG( "CIRMP3Player::GetMediaClientInstance " );
       
   948 	return iAudioPlayer;	
       
   949 	}