os/mm/mmhais/refacladapt/src/tonehwdevice/tonedatapath.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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