1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmhais/refacladapt/src/tonehwdevice/tonedatapath.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,704 @@
1.4 +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "tonedatapath.h"
1.20 +
1.21 +
1.22 +CToneDataPath* CToneDataPath::NewL()
1.23 + {
1.24 + CToneDataPath* self = new(ELeave) CToneDataPath;
1.25 + CleanupStack::PushL(self);
1.26 + self->ConstructL();
1.27 + CleanupStack::Pop();
1.28 + return self;
1.29 + }
1.30 +
1.31 +
1.32 +void CToneDataPath::ConstructL()
1.33 + {
1.34 + iAudioPlayer = new (ELeave) CToneDataPathPlayer(*this,CActive::EPriorityUserInput);
1.35 + iSoundDeviceErrorReceiver = new (ELeave) CToneSoundDevPlayErrorReceiver(*this, CActive::EPriorityUserInput);
1.36 + }
1.37 +
1.38 +
1.39 +CToneDataPath::~CToneDataPath()
1.40 + {
1.41 + delete iAudioPlayer;
1.42 + delete iSoundDeviceErrorReceiver;
1.43 +
1.44 + iSoundDevice.Close();
1.45 +
1.46 + if (iCodec)
1.47 + {
1.48 + delete iSourceBuffer;
1.49 + if (!iCodec->IsNullCodec())
1.50 + {
1.51 + delete iSoundDeviceBuffer;
1.52 + }
1.53 + }
1.54 +
1.55 +#ifdef __USE_MMF_TRANSFERBUFFERS__
1.56 + delete iTransferWindow;
1.57 +
1.58 + if(iTransferBuffer)
1.59 + {
1.60 + iTransferBuffer->Close();
1.61 + delete iTransferBuffer;
1.62 + }
1.63 +#endif
1.64 +
1.65 +#ifdef __USE_MMF_PTRBUFFERS__
1.66 + delete iPtrBufferMemoryBlock;
1.67 +#endif
1.68 + }
1.69 +
1.70 +
1.71 +TInt CToneDataPath::SetObserver(MMMFHwDeviceObserver& aObserver)
1.72 + {
1.73 + TInt error;
1.74 + if (iHwDeviceObserver)
1.75 + {
1.76 + error = KErrAlreadyExists;
1.77 + }
1.78 + else
1.79 + {
1.80 + iHwDeviceObserver = &aObserver;
1.81 + error = KErrNone;
1.82 + }
1.83 + return error;
1.84 + }
1.85 +
1.86 +
1.87 +TInt CToneDataPath::AddCodec(CToneCodec& aCodec)
1.88 + {
1.89 + if (iCodec)
1.90 + {
1.91 + return KErrNotSupported; //doesn't support multiple codecs
1.92 + }
1.93 +
1.94 + TInt err = KErrNone;
1.95 +
1.96 + iCodec = &aCodec;
1.97 +
1.98 + // Allocate data buffer
1.99 + iSourceBufferSize = iCodec->SourceBufferSize();
1.100 + iSoundDevBufferSize = iCodec->SinkBufferSize();
1.101 +
1.102 + if ((!iSourceBufferSize)||(!iSoundDevBufferSize))
1.103 + {
1.104 + err = KErrArgument; //codec plugin has not specified buffer size
1.105 + }
1.106 +
1.107 + if (err == KErrNone)
1.108 + {
1.109 +#ifdef __USE_MMF_TRANSFERBUFFERS__
1.110 + TRAP(err,iSourceBuffer = CreateTransferBufferL(iSourceBufferSize, static_cast<CMMFTransferBuffer*>(iSourceBuffer)));
1.111 +#endif
1.112 +#ifdef __USE_MMF_PTRBUFFERS__
1.113 + TRAP(err,iSourceBuffer = CreatePtrBufferL(iSourceBufferSize));
1.114 +#else
1.115 + TRAP(err,iSourceBuffer = CMMFDataBuffer::NewL(iSourceBufferSize));
1.116 +#endif
1.117 + }
1.118 +
1.119 + if (err == KErrNone)
1.120 + {
1.121 + if (iCodec->IsNullCodec())
1.122 + {//use source buffer for sound device buffer
1.123 + iSoundDeviceBuffer = NULL;
1.124 + }
1.125 + else
1.126 + {//codec needs separate source and sound device buffers
1.127 + TRAP(err,iSoundDeviceBuffer = CMMFDataBuffer::NewL(iSoundDevBufferSize));
1.128 + }
1.129 + }
1.130 + return err;
1.131 + }
1.132 +
1.133 +TInt CToneDataPath::Start()
1.134 + {
1.135 + TInt startError = KErrNone;
1.136 +
1.137 + if (!iCodec)
1.138 + {//check that a codec has been added
1.139 + startError = KErrNotReady;
1.140 + }
1.141 + if ((!iSoundDevice.Handle())&&(!startError))
1.142 + {//check that the sound drivers can be opened
1.143 + startError = iSoundDevice.Open();
1.144 + }
1.145 +
1.146 + if (iState == EPaused)
1.147 + {//we are paused so need to resume play
1.148 + if (!startError)
1.149 + {
1.150 +#ifdef _SCW_DEBUG
1.151 + RDebug::Print(_L("CToneDataPath::Start-Resume"));
1.152 +#endif
1.153 + iAudioPlayer->ResumePlaying();
1.154 + iState = EPlaying;
1.155 + }
1.156 + }
1.157 + else if (!startError)
1.158 + {
1.159 +#ifdef _SCW_DEBUG
1.160 + RDebug::Print(_L("CToneDataPath::Start-Normal"));
1.161 +#endif
1.162 + // get sample rate and channels from RMdaDevSound
1.163 + RMdaDevSound::TCurrentSoundFormatBuf format;
1.164 + iSoundDevice.GetPlayFormat(format);
1.165 + iSampleRate = format().iRate;
1.166 + iChannels = format().iChannels;
1.167 +
1.168 + iNoMoreSourceData = EFalse;
1.169 + iSourceBuffer->SetLastBuffer(EFalse);
1.170 + iState = EPlaying;
1.171 + iSoundDeviceErrorReceiver->Start();
1.172 + TRAP(startError,FillSourceBufferL()); //get initial buffer of audio data
1.173 + if (startError == KErrNone)
1.174 + {
1.175 + // Start the player objects
1.176 + iAudioPlayer->Start();
1.177 + }
1.178 + else
1.179 + {//failed to start up correctly go back to stopped state
1.180 + iState = EStopped;
1.181 + iSoundDeviceErrorReceiver->Stop();
1.182 + }
1.183 + }
1.184 + return startError;
1.185 + }
1.186 +
1.187 +
1.188 +// *** Main Play Loop ***
1.189 +
1.190 +void CToneDataPath::FillSourceBufferL()
1.191 + {//asks observer to fill the source buffer
1.192 + // Ask immediately for data from the observer
1.193 +#ifdef __CYCLE_MMF_DATABUFFERS__
1.194 + // Create a new buffer to replicate INC021405 Play-EOF-Play on HwAccelerated solution Panics
1.195 + // If the creation fails, we carry on regardless as the original buffer will not have been
1.196 + // destroyed. Must do this as alloc fail tests will not run.
1.197 + if(iSourceBuffer)
1.198 + {
1.199 + iSourceBuffer = CycleAudioBuffer(iSourceBuffer);
1.200 + }
1.201 +#endif // __CYCLE_MMF_DATABUFFERS__
1.202 + User::LeaveIfError(iHwDeviceObserver->FillThisHwBuffer(*iSourceBuffer));
1.203 +
1.204 + }
1.205 +
1.206 +
1.207 +void CToneDataPath::BufferFilledL(CMMFDataBuffer& aBuffer)
1.208 + {//call back from observer to indicate buffer has been filled
1.209 +
1.210 + if (iState == EStopped)
1.211 + {
1.212 + User::Leave(KErrNotReady);//ok if paused?
1.213 + }
1.214 +
1.215 + iSourceBuffer = &aBuffer;
1.216 + iSourceBuffer->SetStatus(EFull);
1.217 +#ifdef _SCW_DEBUG
1.218 + RDebug::Print(_L("CToneDataPath::BufferFilledL"));
1.219 +#endif
1.220 +
1.221 + //need to check that the buffer size is not 0 - if so assume we've reached the end of the data
1.222 + iBuffSize = iSourceBuffer->BufferSize();
1.223 + if (!iBuffSize)
1.224 + {//no buffer - could be end of source or could be that the source has no data??
1.225 + iNoMoreSourceData = ETrue;
1.226 +#ifdef _SCW_DEBUG
1.227 + RDebug::Print(_L("CToneDataPath::BufferFilledL-NoMoreSourceData"));
1.228 +#endif
1.229 + }
1.230 + //even if the buffer size is 0 we still
1.231 + //need to perform the following to get the sound device callback
1.232 + FillSoundDeviceBufferL(); //get buffer in pcm16 format for sound device
1.233 +
1.234 + iAudioPlayer->PlayData(*iSoundDeviceBuffer); //play data to sound drivers
1.235 + }
1.236 +
1.237 +
1.238 +void CToneDataPath::FillSoundDeviceBufferL()
1.239 + {//use CToneCodec to fill the sound device buffer
1.240 +
1.241 + CToneCodec::TCodecProcessResult codecProcessResult;
1.242 +
1.243 + if (iCodec->IsNullCodec())
1.244 + {//no codec so data can be sent direct to sink
1.245 + iSoundDeviceBuffer = iSourceBuffer;
1.246 + iSoundDeviceBuffer->SetStatus(EFull); //sink buffer is full
1.247 + }
1.248 + else
1.249 + {
1.250 + //pass buffer to codec for processing
1.251 + codecProcessResult = iCodec->ProcessL(*iSourceBuffer, *iSoundDeviceBuffer);
1.252 +
1.253 + if (iSourceBuffer->LastBuffer()) //if source is last buffer so is sound dev
1.254 + {
1.255 + iSoundDeviceBuffer->SetLastBuffer(ETrue);
1.256 + }
1.257 + if ((!iSoundDeviceBuffer->BufferSize())&&(codecProcessResult.iDstBytesAdded))
1.258 + {//the codec has added data but not set the buffer length
1.259 + iSoundDeviceBuffer->Data().SetLength(codecProcessResult.iDstBytesAdded);
1.260 + }
1.261 + //only supports EProcessComplete
1.262 + switch (codecProcessResult.iCodecProcessStatus)
1.263 + {
1.264 + case CToneCodec::TCodecProcessResult::EProcessComplete:
1.265 + //finished procesing source data - all data in sink buffer
1.266 + {
1.267 + iSoundDeviceBuffer->SetStatus(EFull); //sink buffer is full
1.268 + }
1.269 + break;
1.270 +#ifdef SYMBIAN_VARIABLE_BITRATE_CODEC
1.271 + case CToneCodec::TCodecProcessResult::EProcessIncomplete:
1.272 + //finished procesing source data - all data in sink buffer
1.273 + {
1.274 + iSoundDeviceBuffer->SetStatus(EFull); //sink buffer is full
1.275 + }
1.276 + break;
1.277 +#endif
1.278 + case CToneCodec::TCodecProcessResult::EDstNotFilled:
1.279 + //could be the last buffer in which case dst might not get filled
1.280 + {
1.281 + iSoundDeviceBuffer->SetStatus(EFull); //sink buffer is full
1.282 + }
1.283 + break;
1.284 + case CToneCodec::TCodecProcessResult::EEndOfData:
1.285 + //no more data - send what we've got to the sink
1.286 + //note we can't always rely on this - in many cases the codec will not know when
1.287 + //it has reached the end of data.
1.288 + {
1.289 + iSoundDeviceBuffer->SetStatus(EFull);//sink buffer may not really be 'full' but its as full as it going to get
1.290 + iNoMoreSourceData = ETrue;
1.291 + //doesn't matter if sink buffer is not full
1.292 + }
1.293 + break;
1.294 + default:
1.295 + //Panic(EMMFSwCodecWrapperBadCodec); //should never get here - bad codec
1.296 + break;
1.297 + }
1.298 + }
1.299 + }
1.300 +
1.301 +
1.302 +void CToneDataPath::BufferEmptiedL(const CMMFDataBuffer& aBuffer)
1.303 + {//call back from CToneDataPathPlayer when the sound device buffer has been emptied
1.304 + if (&aBuffer != iSoundDeviceBuffer)
1.305 + {
1.306 + Panic(EToneBadBuffer);
1.307 + }
1.308 +
1.309 + if (!iNoMoreSourceData)
1.310 + {
1.311 + FillSourceBufferL();
1.312 + }
1.313 + }
1.314 +
1.315 +//*** End of Main Play Loop ***
1.316 +
1.317 +
1.318 +void CToneDataPath::Stop()
1.319 + {
1.320 + iAudioPlayer->Cancel();
1.321 + iSoundDeviceErrorReceiver->Cancel();
1.322 + iSoundDevice.Close();
1.323 +
1.324 +#ifdef __CYCLE_MMF_DATABUFFERS__
1.325 + // Create a new buffer to replicate INC021405 Play-EOF-Play on HwAccelerated solution Panics
1.326 + // If the creation fails, we carry on regardless as the original buffer will not have been
1.327 + // destroyed. Must do this as alloc fail tests will not run.
1.328 + if(iSourceBuffer)
1.329 + {
1.330 + iSourceBuffer = CycleAudioBuffer(iSourceBuffer);
1.331 + }
1.332 +#endif // __CYCLE_MMF_DATABUFFERS__
1.333 +
1.334 + iState = EStopped;
1.335 + }
1.336 +
1.337 +
1.338 +void CToneDataPath::Pause()
1.339 + {
1.340 + //since a pause can happen anyway in the datatransfer -need to set to a known
1.341 + //state so that when play is resumed the behaviour is predictable
1.342 + if (iSoundDevice.Handle())
1.343 + {
1.344 + iSoundDevice.PausePlayBuffer(); //needs new LDD
1.345 + iState = EPaused;
1.346 +#ifdef _SCW_DEBUG
1.347 + RDebug::Print(_L("Pause"));
1.348 +#endif
1.349 + }
1.350 + else
1.351 + {//an error must have occured
1.352 + iState = EStopped;
1.353 + }
1.354 + }
1.355 +
1.356 +
1.357 +TInt CToneDataPath::EmptyBuffers()
1.358 + {
1.359 + TInt error = KErrNone;
1.360 + if (iSoundDevice.Handle() == 0)
1.361 + {
1.362 + error = KErrNotReady;
1.363 + }
1.364 + else
1.365 + {
1.366 + iSoundDevice.FlushPlayBuffer();
1.367 + }
1.368 + return error;
1.369 + }
1.370 +
1.371 +
1.372 +RMdaDevSound& CToneDataPath::Device()
1.373 + {
1.374 + return iSoundDevice;
1.375 + }
1.376 +
1.377 +
1.378 +void CToneDataPath::SoundDeviceException(TInt aError)
1.379 + {
1.380 + if(iIgnoreUnderflow)
1.381 + {
1.382 + if((aError == KErrUnderflow) && (!iNoMoreSourceData))
1.383 + {
1.384 + //ignore underflow
1.385 + return;
1.386 + }
1.387 + }
1.388 +
1.389 + //this sends a request to the hw device observer
1.390 + //to update the bytes played
1.391 + //it is done here so that the sound driver can be closed prior to
1.392 + //updating the policy and sending the error back
1.393 + TUid uidUpdateBytesPlayed;
1.394 + uidUpdateBytesPlayed.iUid = KToneHwDeviceObserverUpdateBytesPlayed;
1.395 + TPtrC8 dummy(0,0);
1.396 +
1.397 + ASSERT(iHwDeviceObserver);
1.398 + iHwDeviceObserver->MsgFromHwDevice(uidUpdateBytesPlayed,dummy);
1.399 +
1.400 + //this closes RMdaDevSound.
1.401 + Stop();
1.402 +
1.403 + //inform devsound so it can update policy
1.404 + iHwDeviceObserver->Stopped();
1.405 +
1.406 + // Inform the observer of the exception condition
1.407 + // We inform the hw device observer after the policy has been
1.408 + // updated incase the observer relied on the error to assume
1.409 + // the policy has been updated
1.410 + iHwDeviceObserver->Error(aError);
1.411 +
1.412 + RDebug::Print(_L("CToneDataPath::iHwDeviceObserver->Error(%d)"),aError);
1.413 + }
1.414 +
1.415 +/**
1.416 +Retrieves a custom interface to the device.
1.417 +The reference CToneDataPath supports three custom interfaces,
1.418 +MEmptyBuffersCustomInterface, MSetVbrFlagCustomInterface and MIgnoreUnderflowEventsCustomInterface
1.419 +
1.420 +@param aInterface
1.421 + Interface UID, defined with the custom interface.
1.422 + aInterface = KMmfUidEmptyBuffersCustomInterface for MEmptyBuffersCustomInterface,
1.423 + KSetVbrFlagCustomInterfaceTypeUid for MSetVbrFlagCustomInterface
1.424 +
1.425 +@return A pointer to the interface implementation, or NULL if the device can not
1.426 + implement the interface requested. The return value must be cast to the
1.427 + correct type by the user.
1.428 +*/
1.429 +TAny* CToneDataPath::CustomInterface(TUid aInterface)
1.430 + {
1.431 + TAny* ret = NULL;
1.432 +
1.433 + if (aInterface == KIgnoreUnderflowCustomInterfaceTypeUid)
1.434 + {
1.435 + MIgnoreUnderflowEventsCustomInterface* result = static_cast<MIgnoreUnderflowEventsCustomInterface*> (this);
1.436 + ret = static_cast<TAny*>(result);
1.437 + }
1.438 + return ret;
1.439 + }
1.440 +
1.441 +
1.442 +void CToneDataPath::IgnoreUnderflowEvents()
1.443 + {
1.444 + iIgnoreUnderflow = ETrue;
1.445 + }
1.446 +
1.447 +
1.448 +
1.449 +/************************************************************************
1.450 + * CDataPathPlayer *
1.451 + ************************************************************************/
1.452 +
1.453 +CToneDataPathPlayer::CToneDataPathPlayer(CToneDataPath& aParent, TInt aPriority)
1.454 +: CActive(aPriority), iParent(aParent)
1.455 + {
1.456 + CActiveScheduler::Add(this);
1.457 + }
1.458 +
1.459 +
1.460 +CToneDataPathPlayer::~CToneDataPathPlayer()
1.461 + {
1.462 + Cancel();
1.463 + }
1.464 +
1.465 +
1.466 +void CToneDataPathPlayer::Start()
1.467 + {
1.468 + // No implementation
1.469 + }
1.470 +
1.471 +
1.472 +void CToneDataPathPlayer::ResumePlaying()
1.473 + {
1.474 + if (iParent.Device().Handle())
1.475 + {
1.476 + //should be ok to call this even if we are active
1.477 + iParent.Device().ResumePlaying();
1.478 + iResumePlaying = ETrue;
1.479 + }
1.480 +#ifdef _SCW_DEBUG
1.481 + RDebug::Print(_L("Playing Resumed"));
1.482 +#endif
1.483 + }
1.484 +
1.485 +
1.486 +void CToneDataPathPlayer::PlayData(const CMMFDataBuffer& aData)
1.487 + {
1.488 + iDataFromSource = &aData;
1.489 + if (!IsActive())
1.490 + {
1.491 +#ifdef _SCW_DEBUG
1.492 + RDebug::Print(_L("CToneDataPathPlayer::PlayData"));
1.493 +#endif
1.494 + iParent.Device().PlayData(iStatus,(static_cast<const CMMFDataBuffer*> (iDataFromSource))->Data());
1.495 + SetActive();
1.496 + }
1.497 + }
1.498 +
1.499 +
1.500 +void CToneDataPathPlayer::Stop()
1.501 + {
1.502 + if (!IsActive())
1.503 + {
1.504 + iParent.Device().FlushPlayBuffer(); // Otherwise won't be flushed
1.505 + }
1.506 + Cancel();
1.507 + iParent.SoundDeviceException(KErrCancel);
1.508 + }
1.509 +
1.510 +
1.511 +void CToneDataPathPlayer::RunL()
1.512 + {
1.513 +#ifdef _SCW_DEBUG
1.514 + RDebug::Print(_L("CToneDataPathPlayer::RunL error[%d]"), iStatus.Int());
1.515 +#endif
1.516 + if (iStatus.Int()!=KErrNone)
1.517 + {
1.518 + iParent.SoundDeviceException(iStatus.Int());
1.519 + }
1.520 + else
1.521 + {
1.522 + iParent.BufferEmptiedL(static_cast<const CMMFDataBuffer&>(*iDataFromSource));
1.523 + iResumePlaying = EFalse;
1.524 + }
1.525 + }
1.526 +
1.527 +
1.528 +TInt CToneDataPathPlayer::RunError(TInt aError)
1.529 + {
1.530 + Error(aError);
1.531 + return KErrNone;
1.532 + }
1.533 +
1.534 +
1.535 +void CToneDataPathPlayer::DoCancel()
1.536 + {
1.537 + if (iParent.Device().Handle())
1.538 + {
1.539 + iParent.Device().CancelPlayData();
1.540 + iParent.Device().FlushPlayBuffer();
1.541 + }
1.542 + }
1.543 +
1.544 +
1.545 +void CToneDataPathPlayer::Error(TInt aError)
1.546 + {
1.547 + iParent.SoundDeviceException(aError);
1.548 + }
1.549 +
1.550 +
1.551 +
1.552 +/************************************************************************
1.553 + * CToneSoundDevPlayErrorReceiver *
1.554 + ************************************************************************/
1.555 +
1.556 +CToneSoundDevPlayErrorReceiver::CToneSoundDevPlayErrorReceiver(CToneDataPath& aParent, TInt aPriority)
1.557 +: CActive(aPriority), iParent(aParent)
1.558 + {
1.559 + CActiveScheduler::Add(this);
1.560 + }
1.561 +
1.562 +CToneSoundDevPlayErrorReceiver::~CToneSoundDevPlayErrorReceiver()
1.563 + {
1.564 + Cancel();
1.565 + }
1.566 +
1.567 +void CToneSoundDevPlayErrorReceiver::Start()
1.568 + {
1.569 + iParent.Device().NotifyPlayError(iStatus);
1.570 + SetActive();
1.571 + }
1.572 +
1.573 +void CToneSoundDevPlayErrorReceiver::Stop()
1.574 + {
1.575 + Cancel();
1.576 + }
1.577 +
1.578 +void CToneSoundDevPlayErrorReceiver::RunL()
1.579 + {
1.580 + TInt reason = iStatus.Int();
1.581 + Start();
1.582 +
1.583 + // An error has been returned
1.584 +#ifdef _SCW_DEBUG
1.585 + RDebug::Print(_L("CToneSoundDevPlayErrorReceiver::RunL[%d]"), reason);
1.586 +#endif
1.587 + iParent.SoundDeviceException(reason);
1.588 + }
1.589 +
1.590 +void CToneSoundDevPlayErrorReceiver::DoCancel()
1.591 + {
1.592 + iParent.Device().CancelNotifyPlayError();
1.593 + }
1.594 +
1.595 +
1.596 +
1.597 +/*
1.598 + * CycleAudioBufferL
1.599 + *
1.600 + * Sets up a usable buffer for passing to MMF
1.601 + *
1.602 + * This method has been written such that it must allocate a new buffer before
1.603 + * replacing the existing one. The purpose of this is to force creation of a
1.604 + * new buffer. Simply deleting and then re-allocing may result in the same
1.605 + * address being used.
1.606 + *
1.607 + * Only cycles if there is enough memory
1.608 + *
1.609 + */
1.610 +#ifdef __CYCLE_MMF_DATABUFFERS__
1.611 +CMMFDataBuffer* CToneDataPath::CycleAudioBuffer(CMMFDataBuffer* aBuffer)
1.612 + {
1.613 + CMMFDataBuffer* buffer = NULL;
1.614 + TUint bufferSize = aBuffer->Data().MaxLength();
1.615 +
1.616 +#ifdef __USE_MMF_TRANSFERBUFFERS__
1.617 + TRAPD(err, buffer = CreateTransferBufferL(bufferSize, static_cast<CMMFTransferBuffer*>(aBuffer)));
1.618 +#else
1.619 + TRAPD(err,buffer = CMMFDataBuffer::NewL(bufferSize));
1.620 +
1.621 + if (err == KErrNone)
1.622 + {
1.623 + delete aBuffer;
1.624 + }
1.625 +#endif
1.626 + if (err != KErrNone)
1.627 + {//there was a problem creating buffer eg OOM so use same buffer
1.628 + buffer = aBuffer;
1.629 + }
1.630 +
1.631 + return buffer;
1.632 +
1.633 + }
1.634 +#endif
1.635 +
1.636 +/*
1.637 + * DoCleanupRHandleBase
1.638 + *
1.639 + * This method will initially Close the handle and then delete it.
1.640 + *
1.641 + */
1.642 +#ifdef __USE_MMF_TRANSFERBUFFERS__
1.643 +inline static void DoCleanupRHandleBase(TAny* aRHandleBase)
1.644 + {
1.645 + ASSERT(aRHandleBase);
1.646 + RHandleBase* rHandleBase = static_cast<RHandleBase*> (aRHandleBase);
1.647 + TRAPD(error, rHandleBase->Close());
1.648 + delete aRHandleBase;
1.649 + }
1.650 +
1.651 +CMMFTransferBuffer* CToneDataPath::CreateTransferBufferL(TUint aBufferSize, CMMFTransferBuffer* aOldBuffer)
1.652 + {
1.653 + CMMFTransferBuffer* buffer = NULL;
1.654 +
1.655 + RTransferBuffer* transBuffer = new (ELeave) RTransferBuffer;
1.656 +
1.657 + TCleanupItem bufferCleanupItem(DoCleanupRHandleBase, transBuffer); //closes and deletes.
1.658 + CleanupStack::PushL(bufferCleanupItem);
1.659 +
1.660 + RTransferWindow* transWindow = new (ELeave) RTransferWindow;
1.661 +
1.662 + TCleanupItem windowCleanupItem(DoCleanupRHandleBase, transWindow); //closes and deletes.
1.663 + CleanupStack::PushL(windowCleanupItem);
1.664 +
1.665 + User::LeaveIfError(transBuffer->Create(aBufferSize));
1.666 + User::LeaveIfError(transWindow->Create(aBufferSize));
1.667 + User::LeaveIfError(transWindow->MapInBuffer(*transBuffer));
1.668 +
1.669 + buffer = CMMFTransferBuffer::NewL(*transWindow);
1.670 +
1.671 + delete aOldBuffer; //closes RTransferWindow
1.672 + delete iTransferWindow;
1.673 +
1.674 + if(iTransferBuffer)
1.675 + {
1.676 + iTransferBuffer->Close();
1.677 + }
1.678 + delete iTransferBuffer;
1.679 +
1.680 + iTransferBuffer = transBuffer;
1.681 + iTransferWindow = transWindow;
1.682 +
1.683 + CleanupStack::Pop(transWindow);
1.684 + CleanupStack::Pop(transBuffer);
1.685 +
1.686 + return buffer;
1.687 + }
1.688 +#endif
1.689 +
1.690 +
1.691 +#ifdef __USE_MMF_PTRBUFFERS__
1.692 +CMMFPtrBuffer* CToneDataPath::CreatePtrBufferL(TUint aBufferSize)
1.693 + {
1.694 + CMMFPtrBuffer* buffer = NULL;
1.695 + if (iPtrBufferMemoryBlock)
1.696 + {
1.697 + delete iPtrBufferMemoryBlock;//incase already exisits
1.698 + }
1.699 + iPtrBufferMemoryBlock = HBufC8::NewL(aBufferSize);
1.700 + TPtr8 ptrMemoryBlock(iPtrBufferMemoryBlock->Des());
1.701 + buffer = CMMFPtrBuffer::NewL(ptrMemoryBlock);
1.702 + return buffer;
1.703 + }
1.704 +#endif // __USE_MMF_PTRBUFFERS__
1.705 +
1.706 +
1.707 +