os/mm/devsound/sounddevbt/src/swcodecwrapper/mmfBtSwCodecPlayDataPath.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// source\server\MmfBtSwCodecPlayDatapath.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "mmfBtSwCodecPlayDataPath.h"
sl@0
    19
#include "mmfbtswcodecwrapper.h"
sl@0
    20
#include "mmfbtswcodecwrappercustominterfacesuids.hrh"
sl@0
    21
#include <mmfpaniccodes.h>
sl@0
    22
#include "mmfBtSwCodecUtility.h"
sl@0
    23
sl@0
    24
#include "MMFBtRoutingSoundDevice.h"
sl@0
    25
#include "A2dpBTHeadsetAudioIfClientServer.h" // for TRange (will be deprecated)
sl@0
    26
sl@0
    27
CMMFSwCodecPlayDataPath* CMMFSwCodecPlayDataPath::NewL(	CRoutingSoundPlayDevice* aSoundDevice,
sl@0
    28
														TUid aDeviceUid)
sl@0
    29
	{
sl@0
    30
	CMMFSwCodecPlayDataPath* self = new(ELeave) CMMFSwCodecPlayDataPath(aSoundDevice,
sl@0
    31
																		aDeviceUid);
sl@0
    32
	CleanupStack::PushL(self);
sl@0
    33
	self->ConstructL();
sl@0
    34
	CleanupStack::Pop();
sl@0
    35
	return self;
sl@0
    36
	}
sl@0
    37
sl@0
    38
sl@0
    39
void CMMFSwCodecPlayDataPath::ConstructL()
sl@0
    40
	{
sl@0
    41
	iAudioPlayer = new (ELeave) CDataPathPlayer(*this,CActive::EPriorityUserInput);
sl@0
    42
	iSoundDeviceErrorReceiver = new (ELeave) CSoundDevPlayErrorReceiver(*this, CActive::EPriorityUserInput);
sl@0
    43
	iUtility = CMMFSwCodecUtility::NewL();
sl@0
    44
	}
sl@0
    45
sl@0
    46
sl@0
    47
CMMFSwCodecPlayDataPath::~CMMFSwCodecPlayDataPath()
sl@0
    48
	{
sl@0
    49
	delete iAudioPlayer;
sl@0
    50
	delete iSoundDeviceErrorReceiver;
sl@0
    51
	delete iUtility;
sl@0
    52
sl@0
    53
	TRequestStatus status;
sl@0
    54
	iSoundDevice->CloseDevice(iDeviceUid, status);
sl@0
    55
	//TODO there should be a timeout for the line below
sl@0
    56
	User::WaitForRequest(status);
sl@0
    57
sl@0
    58
	if (iCodec)
sl@0
    59
		{
sl@0
    60
		delete iSourceBuffer;
sl@0
    61
		if (!iCodec->IsNullCodec()) 
sl@0
    62
			{
sl@0
    63
			delete iSoundDeviceBuffer;
sl@0
    64
			}
sl@0
    65
		}
sl@0
    66
sl@0
    67
#ifdef __USE_MMF_TRANSFERBUFFERS__
sl@0
    68
	delete iTransferWindow;
sl@0
    69
sl@0
    70
	if(iTransferBuffer)
sl@0
    71
		{
sl@0
    72
		iTransferBuffer->Close();
sl@0
    73
		delete iTransferBuffer;
sl@0
    74
		}
sl@0
    75
#endif
sl@0
    76
sl@0
    77
#ifdef __USE_MMF_PTRBUFFERS__
sl@0
    78
	delete iPtrBufferMemoryBlock;
sl@0
    79
#endif
sl@0
    80
	}
sl@0
    81
sl@0
    82
sl@0
    83
TInt CMMFSwCodecPlayDataPath::SetObserver(MMMFHwDeviceObserver& aObserver)
sl@0
    84
	{
sl@0
    85
	TInt error;
sl@0
    86
	if (iHwDeviceObserver)
sl@0
    87
		{
sl@0
    88
		error =  KErrAlreadyExists;
sl@0
    89
		}
sl@0
    90
	else
sl@0
    91
		{
sl@0
    92
		iHwDeviceObserver = &aObserver;
sl@0
    93
		error  = KErrNone;
sl@0
    94
		}
sl@0
    95
	return error;
sl@0
    96
	}
sl@0
    97
sl@0
    98
sl@0
    99
TInt CMMFSwCodecPlayDataPath::AddCodec(CMMFSwCodec& aCodec)
sl@0
   100
	{
sl@0
   101
	if (iCodec)
sl@0
   102
		{
sl@0
   103
		return KErrNotSupported; //doesn't support multiple codecs		
sl@0
   104
		}
sl@0
   105
sl@0
   106
	TInt err = KErrNone;
sl@0
   107
	
sl@0
   108
	iCodec = &aCodec;
sl@0
   109
sl@0
   110
	// Allocate data buffer
sl@0
   111
	iSourceBufferSize = iCodec->SourceBufferSize();
sl@0
   112
	iSoundDevBufferSize = iCodec->SinkBufferSize();
sl@0
   113
sl@0
   114
	if ((!iSourceBufferSize) || (!iSoundDevBufferSize))
sl@0
   115
		{
sl@0
   116
		err = KErrArgument; //codec plugin has not specified buffer size		
sl@0
   117
		}
sl@0
   118
sl@0
   119
	if (err == KErrNone)
sl@0
   120
		{
sl@0
   121
#ifdef __USE_MMF_TRANSFERBUFFERS__
sl@0
   122
		TRAP(err,iSourceBuffer = CreateTransferBufferL(iSourceBufferSize, static_cast<CMMFTransferBuffer*>(iSourceBuffer)));
sl@0
   123
#endif
sl@0
   124
#ifdef __USE_MMF_PTRBUFFERS__
sl@0
   125
		TRAP(err,iSourceBuffer = CreatePtrBufferL(iSourceBufferSize));
sl@0
   126
#else
sl@0
   127
		TRAP(err,iSourceBuffer = CMMFDataBuffer::NewL(iSourceBufferSize));
sl@0
   128
#endif
sl@0
   129
		}
sl@0
   130
	
sl@0
   131
	if (err == KErrNone)
sl@0
   132
		{
sl@0
   133
		if (iCodec->IsNullCodec())
sl@0
   134
			{//use source buffer for sound device buffer	
sl@0
   135
			iSoundDeviceBuffer = NULL;
sl@0
   136
			}
sl@0
   137
		else
sl@0
   138
			{//codec needs separate source and sound device buffers
sl@0
   139
			TRAP(err,iSoundDeviceBuffer = CMMFDataBuffer::NewL(iSoundDevBufferSize));
sl@0
   140
			}
sl@0
   141
		}
sl@0
   142
	return err;
sl@0
   143
	}
sl@0
   144
sl@0
   145
sl@0
   146
TInt CMMFSwCodecPlayDataPath::Start()
sl@0
   147
	{
sl@0
   148
	TInt startError = KErrNone;
sl@0
   149
sl@0
   150
	if (!iCodec || (!iSoundDevice->Handle()))
sl@0
   151
		{
sl@0
   152
		//check that a codec has been added and the sound device is open
sl@0
   153
		startError = KErrNotReady;
sl@0
   154
		}
sl@0
   155
sl@0
   156
	if (iState == EPaused)
sl@0
   157
		{//we are paused so need to resume play
sl@0
   158
		if (!startError)
sl@0
   159
			{
sl@0
   160
#ifdef _SCW_DEBUG
sl@0
   161
			RDebug::Print(_L("CMMFSwCodecPlayDataPath::Start-Resume"));
sl@0
   162
#endif
sl@0
   163
			iAudioPlayer->ResumePlaying();
sl@0
   164
			iState = EPlaying;
sl@0
   165
			}
sl@0
   166
		}
sl@0
   167
	else if (!startError)
sl@0
   168
		{
sl@0
   169
#ifdef _SCW_DEBUG
sl@0
   170
		RDebug::Print(_L("CMMFSwCodecPlayDataPath::Start-Normal"));
sl@0
   171
#endif
sl@0
   172
		if (!startError)
sl@0
   173
			{
sl@0
   174
			iNoMoreSourceData = EFalse;
sl@0
   175
			iSourceBuffer->SetLastBuffer(EFalse);
sl@0
   176
			iState = EPlaying;
sl@0
   177
			iSoundDeviceErrorReceiver->Start();
sl@0
   178
			TRAP(startError, FillSourceBufferL()); //get initial buffer of audio data
sl@0
   179
			if (startError == KErrNone)
sl@0
   180
				{
sl@0
   181
				// Start the player objects
sl@0
   182
				iAudioPlayer->Start();
sl@0
   183
				}
sl@0
   184
			else
sl@0
   185
				{//failed to start up correctly go back to stopped state
sl@0
   186
				iState = EStopped;
sl@0
   187
				iSoundDeviceErrorReceiver->Stop();
sl@0
   188
				}
sl@0
   189
			}
sl@0
   190
   		}
sl@0
   191
	return startError;
sl@0
   192
	}
sl@0
   193
sl@0
   194
sl@0
   195
// *** Main Play Loop ***
sl@0
   196
sl@0
   197
void CMMFSwCodecPlayDataPath::FillSourceBufferL()
sl@0
   198
	{//asks observer to fill the source buffer          
sl@0
   199
    // Ask immediately for data from the observer
sl@0
   200
#ifdef __CYCLE_MMF_DATABUFFERS__
sl@0
   201
	// Create a new buffer to replicate INC021405 Play-EOF-Play on HwAccelerated solution Panics
sl@0
   202
	// If the creation fails, we carry on regardless as the original buffer will not have been 
sl@0
   203
	// destroyed. Must do this as alloc fail tests will not run.
sl@0
   204
	if(iSourceBuffer)
sl@0
   205
		{
sl@0
   206
		iSourceBuffer = CycleAudioBuffer(iSourceBuffer);
sl@0
   207
		}
sl@0
   208
#endif // __CYCLE_MMF_DATABUFFERS__	
sl@0
   209
	User::LeaveIfError(iHwDeviceObserver->FillThisHwBuffer(*iSourceBuffer));
sl@0
   210
	
sl@0
   211
	}
sl@0
   212
sl@0
   213
sl@0
   214
void CMMFSwCodecPlayDataPath::BufferFilledL(CMMFDataBuffer& aBuffer)
sl@0
   215
	{//call back from observer to indicate buffer has been filled
sl@0
   216
	if (iState == EStopped)
sl@0
   217
		User::Leave(KErrNotReady);//ok if paused?
sl@0
   218
sl@0
   219
	iSourceBuffer = &aBuffer;
sl@0
   220
	iSourceBuffer->SetStatus(EFull);
sl@0
   221
#ifdef _SCW_DEBUG
sl@0
   222
	RDebug::Print(_L("CMMFSwCodecPlayDataPath::BufferFilledL"));
sl@0
   223
#endif
sl@0
   224
sl@0
   225
	//need to check that the buffer size is not 0 - if so assume we've reached the end of the data
sl@0
   226
	if (!iSourceBuffer->BufferSize())
sl@0
   227
		{//no buffer  - could be end of source or could be that the source has no data??
sl@0
   228
		iNoMoreSourceData = ETrue;
sl@0
   229
#ifdef _SCW_DEBUG
sl@0
   230
		RDebug::Print(_L("CMMFSwCodecPlayDataPath::BufferFilledL-NoMoreSourceData"));
sl@0
   231
#endif
sl@0
   232
		}
sl@0
   233
	//even if the buffer size is 0 we still 
sl@0
   234
	//need to perform the following to get the sound device callback
sl@0
   235
	FillSoundDeviceBufferL(); //get buffer in pcm16 format for sound device	
sl@0
   236
sl@0
   237
    // attenuate the amplitude of the samples if volume ramping has been changed
sl@0
   238
	// and is non-zero
sl@0
   239
	if (iCustomInterface)
sl@0
   240
		{
sl@0
   241
		TTimeIntervalMicroSeconds volumeRamp = iCustomInterface->VolumeRamp();
sl@0
   242
		if (volumeRamp != iVolumeRamp)
sl@0
   243
			{
sl@0
   244
			iVolumeRamp = volumeRamp;
sl@0
   245
			if (iVolumeRamp.Int64() != 0)
sl@0
   246
				{
sl@0
   247
				iUtility->ConfigAudioRamper(
sl@0
   248
					iVolumeRamp.Int64(), 
sl@0
   249
					iSampleRate, 
sl@0
   250
					iChannels);
sl@0
   251
				iRampAudioSample = ETrue;
sl@0
   252
				}
sl@0
   253
			else
sl@0
   254
				{
sl@0
   255
				iRampAudioSample = EFalse;
sl@0
   256
				}
sl@0
   257
			}
sl@0
   258
			if (iRampAudioSample)
sl@0
   259
				{
sl@0
   260
				iRampAudioSample = iUtility->RampAudio(iSoundDeviceBuffer);
sl@0
   261
				}
sl@0
   262
		}
sl@0
   263
sl@0
   264
	iAudioPlayer->PlayData(*iSoundDeviceBuffer); //play data to sound drivers
sl@0
   265
sl@0
   266
	if (iSourceBuffer->LastBuffer())//check last buffer flag
sl@0
   267
		{
sl@0
   268
		iNoMoreSourceData = ETrue;
sl@0
   269
#ifdef _SCW_DEBUG
sl@0
   270
		RDebug::Print(_L("CMMFSwCodecPlayDataPath::BufferFilledL-LBNoMoreSourceData"));
sl@0
   271
#endif
sl@0
   272
		}
sl@0
   273
	}
sl@0
   274
sl@0
   275
sl@0
   276
void CMMFSwCodecPlayDataPath::FillSoundDeviceBufferL()
sl@0
   277
	{//use CMMFSwCodec to fill the sound device buffer
sl@0
   278
	
sl@0
   279
	CMMFSwCodec::TCodecProcessResult codecProcessResult;
sl@0
   280
sl@0
   281
	if (iCodec->IsNullCodec())
sl@0
   282
		{//no codec so data can be sent direct to sink
sl@0
   283
		iSoundDeviceBuffer = iSourceBuffer;
sl@0
   284
		iSoundDeviceBuffer->SetStatus(EFull);	//sink buffer is full
sl@0
   285
		}	
sl@0
   286
	else 
sl@0
   287
		{	
sl@0
   288
		//pass buffer to codec for processing
sl@0
   289
		codecProcessResult = iCodec->ProcessL(*iSourceBuffer, *iSoundDeviceBuffer);
sl@0
   290
		if (iSourceBuffer->LastBuffer()) //if source is last buffer so is sound dev
sl@0
   291
			iSoundDeviceBuffer->SetLastBuffer(ETrue);
sl@0
   292
		if ((!iSoundDeviceBuffer->BufferSize())&&(codecProcessResult.iDstBytesAdded))
sl@0
   293
			{//the codec has added data but not set the buffer length
sl@0
   294
			iSoundDeviceBuffer->Data().SetLength(codecProcessResult.iDstBytesAdded);
sl@0
   295
			}
sl@0
   296
		//only supports EProcessComplete
sl@0
   297
		switch (codecProcessResult.iCodecProcessStatus)
sl@0
   298
			{
sl@0
   299
		case CMMFSwCodec::TCodecProcessResult::EProcessComplete:
sl@0
   300
		//finished procesing source data - all data in sink buffer
sl@0
   301
			{
sl@0
   302
			iSoundDeviceBuffer->SetStatus(EFull);	//sink buffer is full	
sl@0
   303
			}
sl@0
   304
		break;
sl@0
   305
		case CMMFSwCodec::TCodecProcessResult::EDstNotFilled:
sl@0
   306
		//could be the last buffer in which case dst might not get filled
sl@0
   307
			{
sl@0
   308
			iSoundDeviceBuffer->SetStatus(EFull);	//sink buffer is full	
sl@0
   309
			}
sl@0
   310
		break;
sl@0
   311
		case CMMFSwCodec::TCodecProcessResult::EEndOfData:
sl@0
   312
			//no more data - send what we've got to the sink
sl@0
   313
			//note we can't always rely on this  - in many cases the codec will not know when
sl@0
   314
			//it has reached the end of data.
sl@0
   315
			{
sl@0
   316
			iSoundDeviceBuffer->SetStatus(EFull);//sink buffer may not really be 'full' but its as full as it going to get
sl@0
   317
			iNoMoreSourceData = ETrue;
sl@0
   318
			//doesn't matter if sink buffer is not full
sl@0
   319
			}
sl@0
   320
		break;
sl@0
   321
		default:
sl@0
   322
			Panic(EMMFSwCodecWrapperBadCodec); //should never get here - bad codec
sl@0
   323
			}
sl@0
   324
		}
sl@0
   325
	}
sl@0
   326
sl@0
   327
sl@0
   328
void CMMFSwCodecPlayDataPath::BufferEmptiedL(const CMMFDataBuffer& aBuffer)
sl@0
   329
	{//call back from CDataPathPlayer when the sound device buffer has been emptied
sl@0
   330
	if (&aBuffer != iSoundDeviceBuffer) 
sl@0
   331
		Panic(EMMFSwCodecWrapperBadBuffer);
sl@0
   332
	if (!iNoMoreSourceData) 
sl@0
   333
		FillSourceBufferL();
sl@0
   334
	}
sl@0
   335
sl@0
   336
//*** End of Main Play Loop ***
sl@0
   337
sl@0
   338
sl@0
   339
void CMMFSwCodecPlayDataPath::Stop()
sl@0
   340
	{
sl@0
   341
	iAudioPlayer->Cancel();
sl@0
   342
	iSoundDeviceErrorReceiver->Cancel();
sl@0
   343
	TRequestStatus status;
sl@0
   344
	iSoundDevice->CloseDevice(iDeviceUid, status);
sl@0
   345
	User::WaitForRequest(status);
sl@0
   346
sl@0
   347
#ifdef __CYCLE_MMF_DATABUFFERS__
sl@0
   348
	// Create a new buffer to replicate INC021405 Play-EOF-Play on HwAccelerated solution Panics
sl@0
   349
	// If the creation fails, we carry on regardless as the original buffer will not have been 
sl@0
   350
	// destroyed. Must do this as alloc fail tests will not run.
sl@0
   351
	if(iSourceBuffer)
sl@0
   352
		{
sl@0
   353
		iSourceBuffer = CycleAudioBuffer(iSourceBuffer);
sl@0
   354
		}
sl@0
   355
#endif // __CYCLE_MMF_DATABUFFERS__	
sl@0
   356
sl@0
   357
	iState = EStopped;
sl@0
   358
	}
sl@0
   359
sl@0
   360
sl@0
   361
void CMMFSwCodecPlayDataPath::Pause()
sl@0
   362
	{
sl@0
   363
	//since a pause can happen anyway in the datatransfer -need to set to a known 
sl@0
   364
	//state so that when play is resumed the behaviour is predictable
sl@0
   365
	if (iSoundDevice->Handle())
sl@0
   366
		{
sl@0
   367
		iSoundDevice->PauseBuffer(); // ignores return value?
sl@0
   368
		iState = EPaused;
sl@0
   369
#ifdef _SCW_DEBUG
sl@0
   370
		RDebug::Print(_L("Pause"));
sl@0
   371
#endif
sl@0
   372
		}
sl@0
   373
	else
sl@0
   374
		{//an error must have occured 
sl@0
   375
		iState = EStopped;
sl@0
   376
		}
sl@0
   377
	}
sl@0
   378
sl@0
   379
sl@0
   380
CRoutingSoundPlayDevice* CMMFSwCodecPlayDataPath::Device()
sl@0
   381
	{
sl@0
   382
	return iSoundDevice;
sl@0
   383
	}
sl@0
   384
sl@0
   385
void CMMFSwCodecPlayDataPath::SoundDeviceException(TInt aError)
sl@0
   386
	{
sl@0
   387
	//this sends a request to the hw device observer usually Devsound
sl@0
   388
	//to update the bytes played
sl@0
   389
	//it is done here so that the sound driver can be closed prior to
sl@0
   390
	//updating the plicy and sending the error back
sl@0
   391
	TUid uidUpdateBytesPlayed;
sl@0
   392
	uidUpdateBytesPlayed.iUid = KMmfHwDeviceObserverUpdateBytesPlayed;
sl@0
   393
	TPtrC8 dummy(0,0);
sl@0
   394
	iHwDeviceObserver->MsgFromHwDevice(uidUpdateBytesPlayed,dummy);
sl@0
   395
sl@0
   396
	//this closes RMdaDevSound.
sl@0
   397
	Stop(); 
sl@0
   398
sl@0
   399
	//inform devsound so it can update policy
sl@0
   400
	iHwDeviceObserver->Stopped(); 
sl@0
   401
sl@0
   402
	// Inform the observer of the exception condition
sl@0
   403
	// We inform the hw device observer after the policy has been
sl@0
   404
	// updated incase the observer relied on the error to assume
sl@0
   405
	// the policy has been updated
sl@0
   406
	iHwDeviceObserver->Error(aError);
sl@0
   407
	}
sl@0
   408
sl@0
   409
sl@0
   410
void CMMFSwCodecPlayDataPath::SetPlayCustomInterface(MPlayCustomInterface& aCustomInterface)
sl@0
   411
	{
sl@0
   412
	iCustomInterface = &aCustomInterface;
sl@0
   413
	}
sl@0
   414
	
sl@0
   415
void CMMFSwCodecPlayDataPath::SetConfigForAudioRamp(TUint aSampleRate, TUint aChannels)
sl@0
   416
	{
sl@0
   417
	iSampleRate = aSampleRate;
sl@0
   418
	iChannels = aChannels;
sl@0
   419
	}
sl@0
   420
sl@0
   421
/************************************************************************
sl@0
   422
 *				CDataPathPlayer											*
sl@0
   423
 ************************************************************************/
sl@0
   424
sl@0
   425
CDataPathPlayer::CDataPathPlayer(CMMFSwCodecPlayDataPath& aParent, TInt aPriority)
sl@0
   426
: CActive(aPriority), iParent(aParent)
sl@0
   427
	{
sl@0
   428
	CActiveScheduler::Add(this);
sl@0
   429
	}
sl@0
   430
sl@0
   431
sl@0
   432
CDataPathPlayer::~CDataPathPlayer()
sl@0
   433
	{
sl@0
   434
	Cancel();
sl@0
   435
	}
sl@0
   436
sl@0
   437
sl@0
   438
void CDataPathPlayer::Start()
sl@0
   439
	{
sl@0
   440
	// No implementation
sl@0
   441
	}
sl@0
   442
sl@0
   443
sl@0
   444
void CDataPathPlayer::ResumePlaying()
sl@0
   445
	{
sl@0
   446
	if (iParent.Device()->Handle())
sl@0
   447
		{
sl@0
   448
		//should be ok to call this even if we are active
sl@0
   449
		iParent.Device()->ResumePlaying();
sl@0
   450
		iResumePlaying = ETrue;
sl@0
   451
		}
sl@0
   452
#ifdef _SCW_DEBUG
sl@0
   453
	RDebug::Print(_L("Playing Resumed"));
sl@0
   454
#endif
sl@0
   455
	}
sl@0
   456
sl@0
   457
sl@0
   458
void CDataPathPlayer::PlayData(const CMMFDataBuffer& aData)
sl@0
   459
	{
sl@0
   460
	iDataFromSource = &aData;
sl@0
   461
	if (!IsActive())
sl@0
   462
		{
sl@0
   463
#ifdef _SCW_DEBUG
sl@0
   464
		RDebug::Print(_L("CDataPathPlayer::PlayData"));
sl@0
   465
#endif
sl@0
   466
		iParent.Device()->PlayData(aData.Data(), iStatus);
sl@0
   467
		SetActive();
sl@0
   468
		}
sl@0
   469
	}
sl@0
   470
sl@0
   471
sl@0
   472
void CDataPathPlayer::Stop()
sl@0
   473
	{
sl@0
   474
	if (!IsActive())
sl@0
   475
		{
sl@0
   476
		iParent.Device()->FlushBuffer();
sl@0
   477
		}
sl@0
   478
	Cancel();
sl@0
   479
	iParent.SoundDeviceException(KErrCancel);
sl@0
   480
	}
sl@0
   481
sl@0
   482
sl@0
   483
void CDataPathPlayer::RunL()
sl@0
   484
	{
sl@0
   485
#ifdef _SCW_DEBUG
sl@0
   486
	RDebug::Print(_L("CDataPathPlayer::RunL error[%d]"), iStatus.Int());
sl@0
   487
#endif
sl@0
   488
	if (!iStatus.Int())
sl@0
   489
		{
sl@0
   490
		iParent.BufferEmptiedL(static_cast<const CMMFDataBuffer&>(*iDataFromSource));
sl@0
   491
		iResumePlaying = EFalse;
sl@0
   492
		}
sl@0
   493
	//if we don't have a sound driver handle then we have stopped
sl@0
   494
	//but the client still thinks we are recording so swallow error
sl@0
   495
	else if (iStatus.Int()!= KErrBadHandle)
sl@0
   496
		{ 	
sl@0
   497
		iParent.SoundDeviceException(iStatus.Int());
sl@0
   498
		}
sl@0
   499
	}
sl@0
   500
sl@0
   501
sl@0
   502
TInt CDataPathPlayer::RunError(TInt aError)
sl@0
   503
	{
sl@0
   504
	Error(aError);
sl@0
   505
	return KErrNone;
sl@0
   506
	}
sl@0
   507
sl@0
   508
sl@0
   509
void CDataPathPlayer::DoCancel()
sl@0
   510
	{
sl@0
   511
	if (iParent.Device()->Handle())
sl@0
   512
		{
sl@0
   513
		iParent.Device()->CancelPlayData();
sl@0
   514
		iParent.Device()->FlushBuffer();
sl@0
   515
		}
sl@0
   516
	}
sl@0
   517
sl@0
   518
sl@0
   519
void CDataPathPlayer::Error(TInt aError)
sl@0
   520
	{ 
sl@0
   521
	iParent.SoundDeviceException(aError);
sl@0
   522
	}
sl@0
   523
sl@0
   524
sl@0
   525
/************************************************************************
sl@0
   526
 *				CSoundDevPlayErrorReceiver								*
sl@0
   527
 ************************************************************************/
sl@0
   528
sl@0
   529
CSoundDevPlayErrorReceiver::CSoundDevPlayErrorReceiver(CMMFSwCodecPlayDataPath& aParent, TInt aPriority)
sl@0
   530
: CActive(aPriority), iParent(aParent)
sl@0
   531
	{
sl@0
   532
	CActiveScheduler::Add(this);
sl@0
   533
	}
sl@0
   534
sl@0
   535
CSoundDevPlayErrorReceiver::~CSoundDevPlayErrorReceiver()
sl@0
   536
	{
sl@0
   537
	Cancel();
sl@0
   538
	}
sl@0
   539
sl@0
   540
void CSoundDevPlayErrorReceiver::Start()
sl@0
   541
	{
sl@0
   542
	iParent.Device()->NotifyError(iStatus);
sl@0
   543
	SetActive();
sl@0
   544
	}
sl@0
   545
sl@0
   546
void CSoundDevPlayErrorReceiver::Stop()
sl@0
   547
	{
sl@0
   548
	Cancel();
sl@0
   549
	}
sl@0
   550
sl@0
   551
void CSoundDevPlayErrorReceiver::RunL()
sl@0
   552
	{
sl@0
   553
	// An error has been returned
sl@0
   554
#ifdef _SCW_DEBUG
sl@0
   555
	RDebug::Print(_L("CSoundDevPlayErrorReceiver::RunL[%d]"), iStatus.Int());
sl@0
   556
#endif
sl@0
   557
	iParent.SoundDeviceException(iStatus.Int());
sl@0
   558
	}
sl@0
   559
sl@0
   560
void CSoundDevPlayErrorReceiver::DoCancel()
sl@0
   561
	{
sl@0
   562
	iParent.Device()->CancelNotifyError();
sl@0
   563
	}
sl@0
   564
sl@0
   565