mmhais/refacladapt/src/tonehwdevice/tonedatapath.cpp
changeset 0 79dd3e2336a0
equal deleted inserted replaced
-1:000000000000 0:79dd3e2336a0
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "tonedatapath.h"
       
    17 
       
    18 
       
    19 CToneDataPath* CToneDataPath::NewL()
       
    20 	{
       
    21 	CToneDataPath* self = new(ELeave) CToneDataPath;
       
    22 	CleanupStack::PushL(self);
       
    23 	self->ConstructL();
       
    24 	CleanupStack::Pop();
       
    25 	return self;
       
    26 	}
       
    27 
       
    28 
       
    29 void CToneDataPath::ConstructL()
       
    30 	{
       
    31 	iAudioPlayer = new (ELeave) CToneDataPathPlayer(*this,CActive::EPriorityUserInput);
       
    32 	iSoundDeviceErrorReceiver = new (ELeave) CToneSoundDevPlayErrorReceiver(*this, CActive::EPriorityUserInput);
       
    33 	}
       
    34 
       
    35 
       
    36 CToneDataPath::~CToneDataPath()
       
    37 	{
       
    38 	delete iAudioPlayer;
       
    39 	delete iSoundDeviceErrorReceiver;
       
    40 	
       
    41 	iSoundDevice.Close();
       
    42 
       
    43 	if (iCodec)
       
    44 		{
       
    45 		delete iSourceBuffer;
       
    46 		if (!iCodec->IsNullCodec()) 
       
    47 			{
       
    48 			delete iSoundDeviceBuffer;
       
    49 			}
       
    50 		}
       
    51 
       
    52 #ifdef __USE_MMF_TRANSFERBUFFERS__
       
    53 	delete iTransferWindow;
       
    54 
       
    55 	if(iTransferBuffer)
       
    56 		{
       
    57 		iTransferBuffer->Close();
       
    58 		delete iTransferBuffer;
       
    59 		}
       
    60 #endif
       
    61 
       
    62 #ifdef __USE_MMF_PTRBUFFERS__
       
    63 	delete iPtrBufferMemoryBlock;
       
    64 #endif
       
    65 	}
       
    66 
       
    67 
       
    68 TInt CToneDataPath::SetObserver(MMMFHwDeviceObserver& aObserver)
       
    69 	{
       
    70 	TInt error;
       
    71 	if (iHwDeviceObserver)
       
    72 		{
       
    73 		error =  KErrAlreadyExists;
       
    74 		}
       
    75 	else
       
    76 		{
       
    77 		iHwDeviceObserver = &aObserver;
       
    78 		error  = KErrNone;
       
    79 		}
       
    80 	return error;
       
    81 	}
       
    82 
       
    83 
       
    84 TInt CToneDataPath::AddCodec(CToneCodec& aCodec)
       
    85 	{
       
    86 	if (iCodec)
       
    87 		{
       
    88 		return KErrNotSupported; //doesn't support multiple codecs
       
    89 		}
       
    90 
       
    91 	TInt err = KErrNone;
       
    92 	
       
    93 	iCodec = &aCodec;
       
    94 
       
    95 	// Allocate data buffer
       
    96 	iSourceBufferSize = iCodec->SourceBufferSize();
       
    97 	iSoundDevBufferSize = iCodec->SinkBufferSize();
       
    98 
       
    99 	if ((!iSourceBufferSize)||(!iSoundDevBufferSize))
       
   100 		{
       
   101 		err = KErrArgument; //codec plugin has not specified buffer size
       
   102 		}
       
   103 
       
   104 	if (err == KErrNone)
       
   105 		{
       
   106 #ifdef __USE_MMF_TRANSFERBUFFERS__
       
   107 		TRAP(err,iSourceBuffer = CreateTransferBufferL(iSourceBufferSize, static_cast<CMMFTransferBuffer*>(iSourceBuffer)));
       
   108 #endif
       
   109 #ifdef __USE_MMF_PTRBUFFERS__
       
   110 		TRAP(err,iSourceBuffer = CreatePtrBufferL(iSourceBufferSize));
       
   111 #else
       
   112 		TRAP(err,iSourceBuffer = CMMFDataBuffer::NewL(iSourceBufferSize));
       
   113 #endif
       
   114 		}
       
   115 	
       
   116 	if (err == KErrNone)
       
   117 		{
       
   118 		if (iCodec->IsNullCodec())
       
   119 			{//use source buffer for sound device buffer	
       
   120 			iSoundDeviceBuffer = NULL;
       
   121 			}
       
   122 		else
       
   123 			{//codec needs separate source and sound device buffers
       
   124 			TRAP(err,iSoundDeviceBuffer = CMMFDataBuffer::NewL(iSoundDevBufferSize));
       
   125 			}
       
   126 		}
       
   127 	return err;
       
   128 	}
       
   129 
       
   130 TInt CToneDataPath::Start()
       
   131 	{
       
   132 	TInt startError = KErrNone;
       
   133 
       
   134 	if (!iCodec) 
       
   135 		{//check that a codec has been added
       
   136 		startError = KErrNotReady;
       
   137 		}
       
   138 	if ((!iSoundDevice.Handle())&&(!startError))
       
   139     	{//check that the sound drivers can be opened
       
   140    		startError = iSoundDevice.Open();
       
   141 		}
       
   142 
       
   143 	if (iState == EPaused)
       
   144 		{//we are paused so need to resume play
       
   145 		if (!startError)
       
   146 			{
       
   147 #ifdef _SCW_DEBUG
       
   148 			RDebug::Print(_L("CToneDataPath::Start-Resume"));
       
   149 #endif
       
   150 			iAudioPlayer->ResumePlaying();
       
   151 			iState = EPlaying;
       
   152 			}
       
   153 		}
       
   154 	else if (!startError)
       
   155 		{
       
   156 #ifdef _SCW_DEBUG
       
   157 		RDebug::Print(_L("CToneDataPath::Start-Normal"));
       
   158 #endif
       
   159 		// get sample rate and channels from RMdaDevSound
       
   160 		RMdaDevSound::TCurrentSoundFormatBuf format;
       
   161 		iSoundDevice.GetPlayFormat(format);
       
   162 		iSampleRate = format().iRate;
       
   163 		iChannels = format().iChannels;
       
   164 		
       
   165 		iNoMoreSourceData = EFalse;
       
   166 		iSourceBuffer->SetLastBuffer(EFalse);
       
   167 		iState = EPlaying;
       
   168 		iSoundDeviceErrorReceiver->Start();
       
   169 		TRAP(startError,FillSourceBufferL()); //get initial buffer of audio data
       
   170 		if (startError == KErrNone)
       
   171 			{
       
   172 			// Start the player objects
       
   173 			iAudioPlayer->Start();
       
   174 			}
       
   175 		else
       
   176 			{//failed to start up correctly go back to stopped state
       
   177 			iState = EStopped;
       
   178 			iSoundDeviceErrorReceiver->Stop();
       
   179 			}
       
   180    		}
       
   181 	return startError;
       
   182 	}
       
   183 
       
   184 
       
   185 // *** Main Play Loop ***
       
   186 
       
   187 void CToneDataPath::FillSourceBufferL()
       
   188 	{//asks observer to fill the source buffer          
       
   189     // Ask immediately for data from the observer
       
   190 #ifdef __CYCLE_MMF_DATABUFFERS__
       
   191 	// Create a new buffer to replicate INC021405 Play-EOF-Play on HwAccelerated solution Panics
       
   192 	// If the creation fails, we carry on regardless as the original buffer will not have been 
       
   193 	// destroyed. Must do this as alloc fail tests will not run.
       
   194 	if(iSourceBuffer)
       
   195 		{
       
   196 		iSourceBuffer = CycleAudioBuffer(iSourceBuffer);
       
   197 		}
       
   198 #endif // __CYCLE_MMF_DATABUFFERS__	
       
   199 	User::LeaveIfError(iHwDeviceObserver->FillThisHwBuffer(*iSourceBuffer));
       
   200 	
       
   201 	}
       
   202 
       
   203 
       
   204 void CToneDataPath::BufferFilledL(CMMFDataBuffer& aBuffer)
       
   205 	{//call back from observer to indicate buffer has been filled
       
   206 	
       
   207 	if (iState == EStopped)
       
   208 		{
       
   209 		User::Leave(KErrNotReady);//ok if paused?
       
   210 		}
       
   211 
       
   212 	iSourceBuffer = &aBuffer;
       
   213 	iSourceBuffer->SetStatus(EFull);
       
   214 #ifdef _SCW_DEBUG
       
   215 	RDebug::Print(_L("CToneDataPath::BufferFilledL"));
       
   216 #endif
       
   217 
       
   218 	//need to check that the buffer size is not 0 - if so assume we've reached the end of the data
       
   219 	iBuffSize = iSourceBuffer->BufferSize();
       
   220 	if (!iBuffSize)
       
   221 		{//no buffer  - could be end of source or could be that the source has no data??
       
   222 		iNoMoreSourceData = ETrue;
       
   223 #ifdef _SCW_DEBUG
       
   224 		RDebug::Print(_L("CToneDataPath::BufferFilledL-NoMoreSourceData"));
       
   225 #endif
       
   226 		}
       
   227 	//even if the buffer size is 0 we still 
       
   228 	//need to perform the following to get the sound device callback
       
   229 	FillSoundDeviceBufferL(); //get buffer in pcm16 format for sound device	
       
   230 	
       
   231 	iAudioPlayer->PlayData(*iSoundDeviceBuffer); //play data to sound drivers
       
   232 	}
       
   233 
       
   234 
       
   235 void CToneDataPath::FillSoundDeviceBufferL()
       
   236 	{//use CToneCodec to fill the sound device buffer
       
   237 	
       
   238 	CToneCodec::TCodecProcessResult codecProcessResult;
       
   239 
       
   240 	if (iCodec->IsNullCodec())
       
   241 		{//no codec so data can be sent direct to sink
       
   242 		iSoundDeviceBuffer = iSourceBuffer;
       
   243 		iSoundDeviceBuffer->SetStatus(EFull);	//sink buffer is full
       
   244 		}
       
   245 	else 
       
   246 		{
       
   247 		//pass buffer to codec for processing
       
   248 		codecProcessResult = iCodec->ProcessL(*iSourceBuffer, *iSoundDeviceBuffer);
       
   249 		
       
   250 		if (iSourceBuffer->LastBuffer()) //if source is last buffer so is sound dev
       
   251 			{
       
   252 			iSoundDeviceBuffer->SetLastBuffer(ETrue);
       
   253 			}
       
   254 		if ((!iSoundDeviceBuffer->BufferSize())&&(codecProcessResult.iDstBytesAdded))
       
   255 			{//the codec has added data but not set the buffer length
       
   256 			iSoundDeviceBuffer->Data().SetLength(codecProcessResult.iDstBytesAdded);
       
   257 			}
       
   258 		//only supports EProcessComplete
       
   259 		switch (codecProcessResult.iCodecProcessStatus)
       
   260 			{
       
   261 		case CToneCodec::TCodecProcessResult::EProcessComplete:
       
   262 		//finished procesing source data - all data in sink buffer
       
   263 			{
       
   264 			iSoundDeviceBuffer->SetStatus(EFull);	//sink buffer is full	
       
   265 			}
       
   266 		break;
       
   267 #ifdef SYMBIAN_VARIABLE_BITRATE_CODEC
       
   268 		case CToneCodec::TCodecProcessResult::EProcessIncomplete:
       
   269 		//finished procesing source data - all data in sink buffer
       
   270 			{
       
   271 			iSoundDeviceBuffer->SetStatus(EFull);	//sink buffer is full	
       
   272 			}
       
   273 		break;
       
   274 #endif
       
   275 		case CToneCodec::TCodecProcessResult::EDstNotFilled:
       
   276 		//could be the last buffer in which case dst might not get filled
       
   277 			{
       
   278 			iSoundDeviceBuffer->SetStatus(EFull);	//sink buffer is full	
       
   279 			}
       
   280 		break;
       
   281 		case CToneCodec::TCodecProcessResult::EEndOfData:
       
   282 			//no more data - send what we've got to the sink
       
   283 			//note we can't always rely on this  - in many cases the codec will not know when
       
   284 			//it has reached the end of data.
       
   285 			{
       
   286 			iSoundDeviceBuffer->SetStatus(EFull);//sink buffer may not really be 'full' but its as full as it going to get
       
   287 			iNoMoreSourceData = ETrue;
       
   288 			//doesn't matter if sink buffer is not full
       
   289 			}
       
   290 		break;
       
   291 		default:
       
   292 			//Panic(EMMFSwCodecWrapperBadCodec); //should never get here - bad codec
       
   293 			break;
       
   294 			}
       
   295 		}
       
   296 	}
       
   297 
       
   298 
       
   299 void CToneDataPath::BufferEmptiedL(const CMMFDataBuffer& aBuffer)
       
   300 	{//call back from CToneDataPathPlayer when the sound device buffer has been emptied
       
   301 	if (&aBuffer != iSoundDeviceBuffer) 
       
   302 		{
       
   303 		Panic(EToneBadBuffer);
       
   304 		}
       
   305 
       
   306 	if (!iNoMoreSourceData) 
       
   307 		{
       
   308 		FillSourceBufferL();
       
   309 		}
       
   310 	}
       
   311 
       
   312 //*** End of Main Play Loop ***
       
   313 
       
   314 
       
   315 void CToneDataPath::Stop()
       
   316 	{
       
   317 	iAudioPlayer->Cancel();
       
   318 	iSoundDeviceErrorReceiver->Cancel();
       
   319     iSoundDevice.Close();
       
   320 
       
   321 #ifdef __CYCLE_MMF_DATABUFFERS__
       
   322 	// Create a new buffer to replicate INC021405 Play-EOF-Play on HwAccelerated solution Panics
       
   323 	// If the creation fails, we carry on regardless as the original buffer will not have been 
       
   324 	// destroyed. Must do this as alloc fail tests will not run.
       
   325 	if(iSourceBuffer)
       
   326 		{
       
   327 		iSourceBuffer = CycleAudioBuffer(iSourceBuffer);
       
   328 		}
       
   329 #endif // __CYCLE_MMF_DATABUFFERS__	
       
   330 
       
   331 	iState = EStopped;
       
   332 	}
       
   333 
       
   334 
       
   335 void CToneDataPath::Pause()
       
   336 	{
       
   337 	//since a pause can happen anyway in the datatransfer -need to set to a known 
       
   338 	//state so that when play is resumed the behaviour is predictable
       
   339 	if (iSoundDevice.Handle())
       
   340 		{
       
   341 		iSoundDevice.PausePlayBuffer(); //needs new LDD
       
   342 		iState = EPaused;
       
   343 #ifdef _SCW_DEBUG
       
   344 		RDebug::Print(_L("Pause"));
       
   345 #endif
       
   346 		}
       
   347 	else
       
   348 		{//an error must have occured 
       
   349 		iState = EStopped;
       
   350 		}
       
   351 	}
       
   352 	
       
   353 	
       
   354 TInt CToneDataPath::EmptyBuffers()
       
   355 	{
       
   356 	TInt error = KErrNone;
       
   357 	if (iSoundDevice.Handle() == 0)
       
   358 		{
       
   359 		error = KErrNotReady;		
       
   360 		}
       
   361 	else
       
   362 		{
       
   363 		iSoundDevice.FlushPlayBuffer();
       
   364 		}
       
   365 	return error;
       
   366 	}	
       
   367 
       
   368 
       
   369 RMdaDevSound& CToneDataPath::Device()
       
   370 	{
       
   371 	return iSoundDevice;
       
   372 	}
       
   373 
       
   374 
       
   375 void CToneDataPath::SoundDeviceException(TInt aError)
       
   376 	{
       
   377 	if(iIgnoreUnderflow)
       
   378 		{
       
   379 		if((aError == KErrUnderflow) && (!iNoMoreSourceData))
       
   380 			{
       
   381 			//ignore underflow
       
   382 			return;
       
   383 			}
       
   384 		}
       
   385 
       
   386 	//this sends a request to the hw device observer
       
   387 	//to update the bytes played
       
   388 	//it is done here so that the sound driver can be closed prior to
       
   389 	//updating the policy and sending the error back
       
   390 	TUid uidUpdateBytesPlayed;
       
   391 	uidUpdateBytesPlayed.iUid = KToneHwDeviceObserverUpdateBytesPlayed;
       
   392 	TPtrC8 dummy(0,0);
       
   393 	
       
   394 	ASSERT(iHwDeviceObserver);
       
   395 	iHwDeviceObserver->MsgFromHwDevice(uidUpdateBytesPlayed,dummy);
       
   396 
       
   397 	//this closes RMdaDevSound.
       
   398 	Stop(); 
       
   399 
       
   400 	//inform devsound so it can update policy
       
   401 	iHwDeviceObserver->Stopped(); 
       
   402 
       
   403 	// Inform the observer of the exception condition
       
   404 	// We inform the hw device observer after the policy has been
       
   405 	// updated incase the observer relied on the error to assume
       
   406 	// the policy has been updated
       
   407 	iHwDeviceObserver->Error(aError);
       
   408 	
       
   409 	RDebug::Print(_L("CToneDataPath::iHwDeviceObserver->Error(%d)"),aError);
       
   410 	}
       
   411 
       
   412 /**
       
   413 Retrieves a custom interface to the device.
       
   414 The reference CToneDataPath supports three  custom interfaces,
       
   415 MEmptyBuffersCustomInterface, MSetVbrFlagCustomInterface and MIgnoreUnderflowEventsCustomInterface
       
   416 
       
   417 @param	aInterface
       
   418 		Interface UID, defined with the custom interface.
       
   419 		aInterface = KMmfUidEmptyBuffersCustomInterface for MEmptyBuffersCustomInterface,
       
   420 					 KSetVbrFlagCustomInterfaceTypeUid for MSetVbrFlagCustomInterface
       
   421 		
       
   422 @return A pointer to the interface implementation, or NULL if the device can not
       
   423 		implement the interface requested. The return value must be cast to the
       
   424 		correct type by the user.
       
   425 */
       
   426 TAny* CToneDataPath::CustomInterface(TUid aInterface)
       
   427 	{
       
   428 	TAny* ret = NULL;
       
   429 
       
   430 	if (aInterface == KIgnoreUnderflowCustomInterfaceTypeUid)
       
   431 		{
       
   432 		MIgnoreUnderflowEventsCustomInterface* result = static_cast<MIgnoreUnderflowEventsCustomInterface*> (this);
       
   433 		ret = static_cast<TAny*>(result);
       
   434 		}
       
   435 	return ret;
       
   436 	}
       
   437 
       
   438 
       
   439 void CToneDataPath::IgnoreUnderflowEvents()
       
   440 	{
       
   441 	iIgnoreUnderflow = ETrue;
       
   442 	}
       
   443 
       
   444 
       
   445 
       
   446 /************************************************************************
       
   447  *				CDataPathPlayer											*
       
   448  ************************************************************************/
       
   449 
       
   450 CToneDataPathPlayer::CToneDataPathPlayer(CToneDataPath& aParent, TInt aPriority)
       
   451 : CActive(aPriority), iParent(aParent)
       
   452 	{
       
   453 	CActiveScheduler::Add(this);
       
   454 	}
       
   455 
       
   456 
       
   457 CToneDataPathPlayer::~CToneDataPathPlayer()
       
   458 	{
       
   459 	Cancel();
       
   460 	}
       
   461 
       
   462 
       
   463 void CToneDataPathPlayer::Start()
       
   464 	{
       
   465 	// No implementation
       
   466 	}
       
   467 
       
   468 
       
   469 void CToneDataPathPlayer::ResumePlaying()
       
   470 	{
       
   471 	if (iParent.Device().Handle())
       
   472 		{
       
   473 		//should be ok to call this even if we are active
       
   474 		iParent.Device().ResumePlaying(); 
       
   475 		iResumePlaying = ETrue;
       
   476 		}
       
   477 #ifdef _SCW_DEBUG
       
   478 	RDebug::Print(_L("Playing Resumed"));
       
   479 #endif
       
   480 	}
       
   481 
       
   482 
       
   483 void CToneDataPathPlayer::PlayData(const CMMFDataBuffer& aData)
       
   484 	{
       
   485 	iDataFromSource = &aData;
       
   486 	if (!IsActive())
       
   487 		{
       
   488 #ifdef _SCW_DEBUG
       
   489 		RDebug::Print(_L("CToneDataPathPlayer::PlayData"));
       
   490 #endif
       
   491 		iParent.Device().PlayData(iStatus,(static_cast<const CMMFDataBuffer*> (iDataFromSource))->Data());
       
   492 		SetActive();
       
   493 		}
       
   494 	}
       
   495 
       
   496 
       
   497 void CToneDataPathPlayer::Stop()
       
   498 	{
       
   499 	if (!IsActive())
       
   500 		{
       
   501 		iParent.Device().FlushPlayBuffer(); // Otherwise won't be flushed
       
   502 		}
       
   503 	Cancel();
       
   504 	iParent.SoundDeviceException(KErrCancel);
       
   505 	}
       
   506 
       
   507 
       
   508 void CToneDataPathPlayer::RunL()
       
   509 	{
       
   510 #ifdef _SCW_DEBUG
       
   511 	RDebug::Print(_L("CToneDataPathPlayer::RunL error[%d]"), iStatus.Int());
       
   512 #endif
       
   513 	if (iStatus.Int()!=KErrNone)
       
   514 		{
       
   515 		iParent.SoundDeviceException(iStatus.Int());
       
   516 		}
       
   517 	else
       
   518 		{
       
   519 		iParent.BufferEmptiedL(static_cast<const CMMFDataBuffer&>(*iDataFromSource));
       
   520 		iResumePlaying = EFalse;
       
   521 		}
       
   522 	}
       
   523 
       
   524 
       
   525 TInt CToneDataPathPlayer::RunError(TInt aError)
       
   526 	{
       
   527 	Error(aError);
       
   528 	return KErrNone;
       
   529 	}
       
   530 
       
   531 
       
   532 void CToneDataPathPlayer::DoCancel()
       
   533 	{
       
   534 	if (iParent.Device().Handle())
       
   535 		{
       
   536 		iParent.Device().CancelPlayData();
       
   537 		iParent.Device().FlushPlayBuffer();
       
   538 		}
       
   539 	}
       
   540 
       
   541 
       
   542 void CToneDataPathPlayer::Error(TInt aError)
       
   543 	{ 
       
   544 	iParent.SoundDeviceException(aError);
       
   545 	}
       
   546 
       
   547 
       
   548 
       
   549 /************************************************************************
       
   550  *				CToneSoundDevPlayErrorReceiver							*
       
   551  ************************************************************************/
       
   552 
       
   553 CToneSoundDevPlayErrorReceiver::CToneSoundDevPlayErrorReceiver(CToneDataPath& aParent, TInt aPriority)
       
   554 : CActive(aPriority), iParent(aParent)
       
   555 	{
       
   556 	CActiveScheduler::Add(this);
       
   557 	}
       
   558 
       
   559 CToneSoundDevPlayErrorReceiver::~CToneSoundDevPlayErrorReceiver()
       
   560 	{
       
   561 	Cancel();
       
   562 	}
       
   563 
       
   564 void CToneSoundDevPlayErrorReceiver::Start()
       
   565 	{
       
   566 	iParent.Device().NotifyPlayError(iStatus);
       
   567 	SetActive();
       
   568 	}
       
   569 
       
   570 void CToneSoundDevPlayErrorReceiver::Stop()
       
   571 	{
       
   572 	Cancel();
       
   573 	}
       
   574 
       
   575 void CToneSoundDevPlayErrorReceiver::RunL()
       
   576 	{
       
   577 	TInt reason = iStatus.Int();
       
   578 	Start();
       
   579 
       
   580 	// An error has been returned
       
   581 #ifdef _SCW_DEBUG
       
   582 	RDebug::Print(_L("CToneSoundDevPlayErrorReceiver::RunL[%d]"), reason);
       
   583 #endif
       
   584 	iParent.SoundDeviceException(reason);
       
   585 	}
       
   586 
       
   587 void CToneSoundDevPlayErrorReceiver::DoCancel()
       
   588 	{
       
   589 	iParent.Device().CancelNotifyPlayError();
       
   590 	}
       
   591 
       
   592 
       
   593 
       
   594 /*
       
   595  * CycleAudioBufferL
       
   596  *
       
   597  * Sets up a usable buffer for passing to MMF
       
   598  *	
       
   599  * This method has been written such that it must allocate a new buffer before
       
   600  * replacing the existing one. The purpose of this is to force creation of a 
       
   601  * new buffer. Simply deleting and then re-allocing may result in the same 
       
   602  * address being used.
       
   603  * 
       
   604  * Only cycles if there is enough memory
       
   605  *
       
   606  */
       
   607 #ifdef __CYCLE_MMF_DATABUFFERS__
       
   608 CMMFDataBuffer* CToneDataPath::CycleAudioBuffer(CMMFDataBuffer* aBuffer)
       
   609 	{
       
   610 	CMMFDataBuffer* buffer = NULL;
       
   611 	TUint bufferSize = aBuffer->Data().MaxLength();
       
   612 
       
   613 #ifdef __USE_MMF_TRANSFERBUFFERS__
       
   614 	TRAPD(err, buffer = CreateTransferBufferL(bufferSize, static_cast<CMMFTransferBuffer*>(aBuffer)));
       
   615 #else
       
   616 	TRAPD(err,buffer = CMMFDataBuffer::NewL(bufferSize));
       
   617 
       
   618 	if (err == KErrNone)
       
   619 		{
       
   620 		delete aBuffer;
       
   621 		}
       
   622 #endif
       
   623 	if (err != KErrNone)
       
   624 		{//there was a problem creating buffer eg OOM so use same buffer
       
   625 		buffer = aBuffer;
       
   626 		}
       
   627 
       
   628 	return buffer;
       
   629 
       
   630 	}
       
   631 #endif
       
   632 
       
   633 /*
       
   634  * DoCleanupRHandleBase
       
   635  *
       
   636  * This method will initially Close the handle and then delete it.
       
   637  *
       
   638  */
       
   639 #ifdef __USE_MMF_TRANSFERBUFFERS__
       
   640 inline static void DoCleanupRHandleBase(TAny* aRHandleBase)
       
   641 	{
       
   642 	ASSERT(aRHandleBase);
       
   643 	RHandleBase* rHandleBase = static_cast<RHandleBase*> (aRHandleBase);
       
   644 	TRAPD(error, rHandleBase->Close());
       
   645 	delete aRHandleBase;
       
   646 	}
       
   647 
       
   648 CMMFTransferBuffer* CToneDataPath::CreateTransferBufferL(TUint aBufferSize, CMMFTransferBuffer* aOldBuffer)
       
   649 	{
       
   650 	CMMFTransferBuffer* buffer = NULL;
       
   651 
       
   652 	RTransferBuffer* transBuffer = new  (ELeave) RTransferBuffer;
       
   653 	
       
   654 	TCleanupItem bufferCleanupItem(DoCleanupRHandleBase, transBuffer); //closes and deletes.
       
   655 	CleanupStack::PushL(bufferCleanupItem);
       
   656 
       
   657 	RTransferWindow* transWindow = new (ELeave) RTransferWindow;
       
   658 	
       
   659 	TCleanupItem windowCleanupItem(DoCleanupRHandleBase, transWindow); //closes and deletes.
       
   660 	CleanupStack::PushL(windowCleanupItem);
       
   661 
       
   662 	User::LeaveIfError(transBuffer->Create(aBufferSize));
       
   663 	User::LeaveIfError(transWindow->Create(aBufferSize));
       
   664 	User::LeaveIfError(transWindow->MapInBuffer(*transBuffer));
       
   665 
       
   666 	buffer = CMMFTransferBuffer::NewL(*transWindow);
       
   667 
       
   668 	delete aOldBuffer; //closes RTransferWindow
       
   669 	delete iTransferWindow;
       
   670 
       
   671 	if(iTransferBuffer)
       
   672 		{
       
   673 		iTransferBuffer->Close();
       
   674 		}
       
   675 	delete iTransferBuffer;
       
   676 
       
   677 	iTransferBuffer = transBuffer;
       
   678 	iTransferWindow = transWindow;
       
   679 
       
   680 	CleanupStack::Pop(transWindow); 
       
   681 	CleanupStack::Pop(transBuffer); 
       
   682 
       
   683 	return buffer;
       
   684 	}
       
   685 #endif
       
   686 
       
   687 
       
   688 #ifdef __USE_MMF_PTRBUFFERS__
       
   689 CMMFPtrBuffer* CToneDataPath::CreatePtrBufferL(TUint aBufferSize)
       
   690 	{
       
   691 	CMMFPtrBuffer* buffer = NULL;
       
   692 	if (iPtrBufferMemoryBlock)
       
   693 		{
       
   694 		delete iPtrBufferMemoryBlock;//incase already exisits
       
   695 		}
       
   696 	iPtrBufferMemoryBlock = HBufC8::NewL(aBufferSize);
       
   697 	TPtr8 ptrMemoryBlock(iPtrBufferMemoryBlock->Des());
       
   698 	buffer = CMMFPtrBuffer::NewL(ptrMemoryBlock);
       
   699 	return buffer;
       
   700 	}
       
   701 #endif  // __USE_MMF_PTRBUFFERS__
       
   702 
       
   703 
       
   704