mmfenh/progressivedownload/ProgressiveDownloadUtility/src/AudioPdPlayUtility.cpp
changeset 0 71ca22bcf22a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmfenh/progressivedownload/ProgressiveDownloadUtility/src/AudioPdPlayUtility.cpp	Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,947 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Progressive Download Utility
+*
+*/
+
+#include <bautils.h>
+#include <utf.h>
+#include <mmfpaniccodes.h>
+#include "AudioPdPlayUtility.h"
+#include "AudioPdProperties.h"
+#include "progressivedownloadsourceuids.hrh"
+
+#include <AudioPreference.h>
+
+//void Panic(TInt aPanicCode);
+
+const TUid KUidProgressiveDlSource	= {KProgressiveDownloadSourceUid};
+
+void Panic(TInt aPanicCode)
+	{
+	_LIT(KProgressiveDownloadUtility, "ProgressiveDownloadUtility");
+	User::Panic(KProgressiveDownloadUtility, aPanicCode);
+	}
+
+CAudioPdPlayUtility* CAudioPdPlayUtility::NewL(MAudioPdPlayUtilityCallback& aCallback)
+	{
+    CAudioPdPlayUtility* self = new(ELeave) CAudioPdPlayUtility();
+	CleanupStack::PushL(self);
+
+ 	self->iProperties = CAudioPdProperties::NewL(aCallback);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CAudioPdPlayUtility::~CAudioPdPlayUtility()
+	{
+	delete iProperties;
+	}
+
+CAudioPdPlayUtility::CAudioPdPlayUtility()
+	{
+
+	}
+
+void CAudioPdPlayUtility::ConstructL()
+	{
+
+	}
+
+//For Download Status
+void CAudioPdPlayUtility::HandleDownloadEventL(TUint aTransactionID,
+                                               TBrCtlDownloadEvent aEvent,
+                                               TUint aValue)
+	{
+    iProperties->HandleDownloadEventL(aTransactionID,aEvent,aValue);
+	}
+
+
+void CAudioPdPlayUtility::Play()
+	{
+    iProperties->Play();
+	}
+void CAudioPdPlayUtility::Stop()
+	{
+    iProperties->Stop();
+	}
+TInt CAudioPdPlayUtility::Pause()
+	{
+    return iProperties->Pause();
+	}
+void CAudioPdPlayUtility::SetVolume(TInt aVolume)
+	{
+    iProperties->SetVolume(aVolume);
+	}
+void CAudioPdPlayUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
+	{
+    iProperties->SetRepeats(aRepeatNumberOfTimes,aTrailingSilence);
+	}
+void CAudioPdPlayUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+	{
+    iProperties->SetVolumeRamp(aRampDuration);
+	}
+const TTimeIntervalMicroSeconds& CAudioPdPlayUtility::Duration()
+	{
+	return iProperties->Duration();
+	}
+TInt CAudioPdPlayUtility:: MaxVolume()
+	{
+	return iProperties->MaxVolume();
+	}
+void CAudioPdPlayUtility::Close()
+	{
+    iProperties->Close();
+	}
+TInt CAudioPdPlayUtility::GetPosition(TTimeIntervalMicroSeconds& aPosition)
+	{
+    return iProperties->GetPosition(aPosition);
+	}
+void CAudioPdPlayUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
+	{
+    iProperties->SetPosition(aPosition);
+	}
+
+TInt CAudioPdPlayUtility::SetPriority(TInt aPriority, TMdaPriorityPreference aPref)
+	{
+    return iProperties->SetPriority(aPriority,aPref);
+	}
+TInt CAudioPdPlayUtility::GetVolume(TInt& aVolume)
+	{
+    return iProperties->GetVolume(aVolume);
+	}
+TInt CAudioPdPlayUtility::GetNumberOfMetaDataEntries(TInt& aNumEntries)
+	{
+    return iProperties->GetNumberOfMetaDataEntries(aNumEntries);
+	}
+
+
+CMMFMetaDataEntry* CAudioPdPlayUtility::GetMetaDataEntryL(TInt aMetaDataIndex)
+	{
+	return iProperties->GetMetaDataEntryL(aMetaDataIndex);
+	}
+
+TInt CAudioPdPlayUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aStart,
+								const TTimeIntervalMicroSeconds& aEnd)
+	{
+    return iProperties->SetPlayWindow(aStart,aEnd);
+	}
+
+TInt CAudioPdPlayUtility::ClearPlayWindow()
+	{
+    return iProperties->ClearPlayWindow();
+	}
+TInt CAudioPdPlayUtility::SetBalance(TInt aBalance)
+	{
+    return iProperties->SetBalance(aBalance);
+	}
+TInt CAudioPdPlayUtility::GetBalance(TInt& aBalance)
+	{
+    return iProperties->GetBalance(aBalance);
+	}
+TInt CAudioPdPlayUtility::GetBitRate(TUint& aBitRate)
+	{
+    return iProperties->GetBitRate(aBitRate);
+	}
+
+
+void CAudioPdPlayUtility::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aCallback)
+	{
+    iProperties->RegisterForAudioLoadingNotification(aCallback);
+	}
+
+void CAudioPdPlayUtility::GetAudioLoadingProgressL(TInt& aPercentageProgress)
+	{
+    iProperties->GetAudioLoadingProgressL(aPercentageProgress);
+	}
+
+const CMMFControllerImplementationInformation& CAudioPdPlayUtility::ControllerImplementationInformationL()
+	{
+	return iProperties->ControllerImplementationInformationL();
+	}
+
+
+TInt CAudioPdPlayUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
+	{
+    return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
+	}
+TInt CAudioPdPlayUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
+	{
+    return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
+	}
+void CAudioPdPlayUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
+	{
+	iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
+	}
+void CAudioPdPlayUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
+	{
+	iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
+	}
+
+void CAudioPdPlayUtility::OpenFileL(const TDesC& aFileName)
+	{
+	iProperties->OpenFileL(aFileName);
+	}
+
+
+void CAudioPdPlayUtility::OpenFileL(const RFile& aFile)
+	{
+	RFile& file = const_cast<RFile&>(aFile);
+	iProperties->OpenFileL(file);
+	}
+
+
+void CAudioPdPlayUtility::OpenFileL(const TMMSource& aSource)
+	{
+	iProperties->OpenFileL(aSource);
+	}
+
+void CAudioPdPlayUtility::DlCompleteOpenFileL(const TDesC& aFileName)
+	{
+	iProperties->DlCompleteOpenFileL(aFileName);
+	}
+
+TInt CAudioPdPlayUtility::GetFilePosition(TInt& aFilePosition)
+	{
+	return iProperties->GetFilePosition(aFilePosition);
+	}
+
+TInt CAudioPdPlayUtility::SetFileSize(TInt aFileSize)
+	{
+	return iProperties->SetFileSize(aFileSize);
+	}
+
+TInt CAudioPdPlayUtility::SetBytesDownloaded(TInt aBytesDownloaded, TBool aDownloadComplete)
+	{
+	return iProperties->SetBytesDownloaded(aBytesDownloaded,aDownloadComplete);
+	}
+
+MMMFDRMCustomCommand* CAudioPdPlayUtility::GetDRMCustomCommand()
+	{
+	//ASSERT(iProperties);
+	return iProperties->GetDRMCustomCommand();
+	}
+
+
+TInt CAudioPdPlayUtility::CheckAudioPlayerState()
+	{
+	return iProperties->CheckAudioPlayerState();
+	}
+
+
+//===============================================================
+// CAudioPdProperties implementation begins
+//
+//===============================================================
+CAudioPdProperties* CAudioPdProperties::NewL(MAudioPdPlayUtilityCallback& aCallback)
+	{
+	CAudioPdProperties* self = new(ELeave) CAudioPdProperties(aCallback);
+	CleanupStack::PushL(self);
+	self->ConstructL(aCallback);
+	CleanupStack::Pop(self);
+	return self;
+	}
+CAudioPdProperties* CAudioPdProperties::NewLC(MAudioPdPlayUtilityCallback& /*aCallback*/)
+	{
+	return NULL;
+	}
+
+CAudioPdProperties::~CAudioPdProperties()
+	{
+
+	delete iControllerImplementationInformation;
+	delete iAsyncCallBack;
+	delete iRepeatTrailingSilenceTimer;
+	delete iFindAndOpenController;
+	delete iControllerEventMonitor;
+	iMediaIds.Close();
+	iController.Close();
+	}
+
+CAudioPdProperties::CAudioPdProperties(/*MMdaAudioPlayerCallback*/MAudioPdPlayUtilityCallback& aCallback):
+	iCallback(aCallback),
+	iAudioPlayDeviceCommands(iController),
+	iAudioPlayControllerCommands(iController),
+	iDRMCustomCommands(iController)
+	{
+	iState = EStopped;
+	iPrioritySettings.iPriority = KAudioPriorityRealOnePlayer;//80
+	iPrioritySettings.iPref =(TMdaPriorityPreference) KAudioPrefRealOneLocalPlayback;// 0x01420001;
+	iPlayStart = TTimeIntervalMicroSeconds(0);
+	iPlayEnd = TTimeIntervalMicroSeconds(0);
+	iPlayWindowSet = ENone;
+    iSourceHandle =  NULL;
+	}
+
+void CAudioPdProperties::ConstructL(MAudioPdPlayUtilityCallback& /*aCallback*/)
+	{
+
+	iControllerEventMonitor = CMMFControllerEventMonitor::NewL(*this, iController);
+	iRepeatTrailingSilenceTimer = CRepeatTrailingSilenceTimer::NewL(*this);
+	iAsyncCallBack = CMMFMdaAudioPlayerCallBack::NewL(iCallback);
+	User::LeaveIfError(iMediaIds.Append(KUidMediaTypeAudio));
+	iFindAndOpenController = CMMFFindAndOpenController::NewL(*this);
+	iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings);
+	iFindAndOpenController->ConfigureController(iController, *iControllerEventMonitor, CMMFFindAndOpenController::EPlayback);
+
+	}
+
+void CAudioPdProperties::MfaocComplete(
+		TInt& aError,
+		RMMFController* /*aController*/,
+		TUid aControllerUid,
+		TMMFMessageDestination* aSourceHandle,
+		TMMFMessageDestination* /*aSinkHandle*/)
+	{
+
+	iSourceHandle = aSourceHandle;
+
+	if (aError == KErrNone)
+		{
+		iControllerUid = aControllerUid;
+
+		// Get the clip duration
+		iDuration = TTimeIntervalMicroSeconds(0);
+		aError = iController.GetDuration(iDuration);
+
+		// If an error occurred in any of the above, close the controller.
+		if (aError != KErrNone)
+			{
+			iControllerEventMonitor->Cancel();
+			iController.Close();
+			}
+		}
+
+	iAsyncCallBack->InitComplete(aError, iDuration);
+	}
+
+void CAudioPdProperties::HandleDownloadEventL(TUint aTransactionID,
+                                              TBrCtlDownloadEvent aEvent,
+                                              TUint aValue)
+	{
+	iCallback.HandleDownloadEventL(aTransactionID,aEvent,aValue);
+
+	}
+
+
+void CAudioPdProperties::OpenFileL(const TDesC& aFileName)
+	{
+	TMMFileSource filesource(aFileName, ContentAccess::KDefaultContentObject, ContentAccess::EPlay);
+	OpenFileL(filesource);
+	}
+
+
+void CAudioPdProperties::OpenFileL(const RFile& aFile)
+	{
+	RFile& file = const_cast<RFile&>(aFile);
+	TMMFileHandleSource filesource(file, KNullDesC, ContentAccess::EPlay);
+	OpenFileL(filesource);
+	}
+
+void CAudioPdProperties::OpenFileL(const TMMSource& aSource)
+	{
+	// If iAsyncCallBack is already active, we're still in the process of notifying the client
+	// that a previous request to Open...(...) has completed.
+	if (iAsyncCallBack->IsActive())
+		User::Leave(KErrNotReady);
+
+
+	if (aSource.SourceType()==KUidMMFileHandleSource)
+		{
+
+		RFile& fileHandle = static_cast<const TMMFileHandleSource&>(aSource).Handle();
+
+	    iFindAndOpenController->ConfigureSourceSink(
+	       CMMFFindAndOpenController::TSourceSink(KUidProgressiveDlSource,fileHandle),
+		   CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
+
+		}
+	if (aSource.SourceType()==KUidMMFileSource)
+		{
+		const TDesC& fileName = static_cast<const TMMFileSource&>(aSource).Name();
+
+	    iFindAndOpenController->ConfigureSourceSink(
+	       CMMFFindAndOpenController::TSourceSink(KUidProgressiveDlSource,
+	       CMMFFindAndOpenController::GetConfigFile(fileName)),
+		   CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
+
+		}
+
+	iFindAndOpenController->OpenByFileSource(aSource);
+	}
+
+void CAudioPdProperties::DlCompleteOpenFileL(const TDesC& aFileName)
+	{
+	if (iAsyncCallBack->IsActive())
+		User::Leave(KErrNotReady);
+
+	Close();
+
+	TMMFileSource filesource(aFileName, ContentAccess::KDefaultContentObject, ContentAccess::EPlay);
+
+
+	iFindAndOpenController->ConfigureSourceSink(
+			TMMFileSource(aFileName, filesource.UniqueId(), filesource.Intent(), filesource.IsUIEnabled()),
+			CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
+
+	iFindAndOpenController->OpenByFileSource(filesource);
+
+
+	}
+
+
+void CAudioPdProperties::Play()
+	{
+	// if we're already playing, call the client's callback with KErrNotReady.
+	// This is what the controller would do if we allowed the Play()
+	// to propagate down. Need to do it here too (for consistency)
+	// in case we're in a trailing silence period.
+    if (iState == EPlaying)
+		{
+		iAsyncCallBack->PlayComplete(KErrNotReady);
+		return;
+		}
+
+	// cancel the repeat timer in case the client has called Play()
+	// without waiting for the previous play to complete
+	iRepeatTrailingSilenceTimer->Cancel();
+	// Reset played count
+	iNumberOfTimesPlayed = 0;
+
+	DoPlay();
+	}
+
+void CAudioPdProperties::DoPlay()
+	{
+#if defined(__AUDIO_PROFILING)
+	RDebug::ProfileStart(4);
+#endif  // defined(__AUDIO_PROFILING)
+    TInt err = KErrNone;
+    if (iState != EPaused)
+        {
+		err = iController.Prime();
+
+#if defined(__AUDIO_PROFILING)
+	RDebug::ProfileEnd(4);
+#endif  // defined(__AUDIO_PROFILING)
+
+		// make sure we don't set the position outside the play window -
+		// but allow it to remain unchanged if it's within the window
+		if (iPlayWindowSet == ESet &&
+			(iPosition < iPlayStart || iPosition >= iPlayEnd))
+			iPosition = iPlayStart;
+
+		if (err==KErrNone)
+			err = iController.SetPosition(iPosition);
+        }
+
+	if (err==KErrNone)
+		{
+		if (iPlayWindowSet == ESet)
+			err = iAudioPlayControllerCommands.SetPlaybackWindow(iPlayStart, iPlayEnd);
+		else if (iPlayWindowSet == EClear)
+			{
+			err = iAudioPlayControllerCommands.DeletePlaybackWindow();
+			iPlayWindowSet = ENone;	// assume window will stay cleared
+			}
+		}
+
+	if (err==KErrNone)
+		{
+#if defined(__AUDIO_PROFILING)
+		RDebug::ProfileStart(5);
+#endif  // defined(__AUDIO_PROFILING)
+
+		err = iController.Play();
+
+#if defined(__AUDIO_PROFILING)
+		RDebug::ProfileEnd(5);
+#endif  // defined(__AUDIO_PROFILING)
+		}
+
+	if (err!=KErrNone)
+		iAsyncCallBack->PlayComplete(err);
+	else
+		{
+		iState = EPlaying;
+		iCallback.Playing();
+		}
+	}
+
+
+void CAudioPdProperties::Stop()
+	{
+	if (iState==EPlaying || iState==EPaused)
+		{
+		// cancel the repeat timer in case the client has called Stop()
+		// during the trailing silence period
+		iRepeatTrailingSilenceTimer->Cancel();
+
+		iController.Stop();
+		iPosition = iPlayStart;
+		iState = EStopped;
+		}
+
+	}
+TInt CAudioPdProperties::Pause()
+	{
+    TInt err = KErrNone;
+	if (iState==EPlaying)
+		{
+		err = iController.Pause();
+		if (!err || err==KErrNotReady)
+			err = iController.GetPosition(iPosition);
+		iState = EPaused;
+		iCallback.Paused();
+		}
+	return err;
+	}
+void CAudioPdProperties::SetVolume(TInt aVolume)
+	{
+	TInt err = iAudioPlayDeviceCommands.SetVolume(aVolume);
+
+	__ASSERT_ALWAYS(err==KErrNone, Panic(EMMFMediaClientBadArgument));
+	}
+void CAudioPdProperties::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
+	{
+	iNumberOfTimesToRepeat = aRepeatNumberOfTimes;
+	iTrailingSilence = aTrailingSilence;
+	}
+void CAudioPdProperties::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+	{
+	iAudioPlayDeviceCommands.SetVolumeRamp(aRampDuration);
+	}
+const TTimeIntervalMicroSeconds& CAudioPdProperties::Duration()
+	{
+	TInt err = iController.GetDuration(iDuration);
+	if (err)
+		{
+		iDuration = 0;
+		}
+	return iDuration;
+	}
+TInt CAudioPdProperties:: MaxVolume()
+	{
+		TInt maxVolume = 0;
+#ifdef _DEBUG
+	TInt error =
+#endif
+		iAudioPlayDeviceCommands.GetMaxVolume(maxVolume);
+	__ASSERT_DEBUG(error==KErrNone, Panic(EMMFMediaClientPanicServerCommunicationProblem));
+	return maxVolume;
+	}
+void CAudioPdProperties::Close()
+	{
+	// Reset the audio player state.
+	Stop();
+	iControllerEventMonitor->Cancel();
+	iController.Close();
+	}
+TInt CAudioPdProperties::GetPosition(TTimeIntervalMicroSeconds& aPosition)
+	{
+    TInt error = KErrNone;
+//	if (iState==EPlaying)
+   //For progressivedownload pause and resume I need to get the
+   //last position even if not playing.
+	error = iController.GetPosition(iPosition);
+
+	aPosition = iPosition;
+	return error;
+	}
+void CAudioPdProperties::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
+	{
+	// Clip the position if aPosition is greater than the duration
+	// or if aPosition is negative.
+	const TTimeIntervalMicroSeconds maxPosition(Duration());
+	const TTimeIntervalMicroSeconds minPosition(0);
+
+	if (aPosition > maxPosition)
+		iPosition = maxPosition;
+	else if (aPosition < minPosition)
+		iPosition = minPosition;
+	else
+		iPosition = aPosition;
+
+    if (iState==EPlaying || iState==EPaused || iState == EStopped)
+		{
+		iController.SetPosition(iPosition);
+		}
+//	else if (iState == EPaused)
+//		{
+//		Stop();	// We call stop so that DevSound's internal buffers are reset
+//		}
+	}
+
+TInt CAudioPdProperties::SetPriority(TInt aPriority, TMdaPriorityPreference aPref)
+	{
+    iPrioritySettings.iPref = aPref;
+	iPrioritySettings.iPriority = aPriority;
+	iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings);
+
+	return iController.SetPrioritySettings(iPrioritySettings);
+	}
+TInt CAudioPdProperties::GetVolume(TInt& aVolume)
+	{
+    TInt error = iAudioPlayDeviceCommands.GetVolume(aVolume);
+	return error;
+	}
+TInt CAudioPdProperties::GetNumberOfMetaDataEntries(TInt& aNumEntries)
+	{
+    TInt error = iController.GetNumberOfMetaDataEntries(aNumEntries);
+	return error;
+	}
+
+
+CMMFMetaDataEntry* CAudioPdProperties::GetMetaDataEntryL(TInt aMetaDataIndex)
+	{
+	return iController.GetMetaDataEntryL(aMetaDataIndex);
+	}
+
+TInt CAudioPdProperties::SetPlayWindow(const TTimeIntervalMicroSeconds& aPlayStart,
+								const TTimeIntervalMicroSeconds& aPlayEnd)
+	{
+    TInt error = KErrNone;
+
+	if (aPlayStart >= TTimeIntervalMicroSeconds(0) &&
+		aPlayStart < iDuration &&
+			aPlayStart < aPlayEnd &&
+			aPlayEnd <= iDuration )
+		{
+		iPlayStart = aPlayStart;
+		iPlayEnd = aPlayEnd;
+		iPlayWindowSet = ESet;
+
+		if (iState==EPlaying)
+			error = iAudioPlayControllerCommands.SetPlaybackWindow(aPlayStart, aPlayEnd);
+		}
+	else
+		error = KErrArgument;
+
+	return error;
+	}
+
+TInt CAudioPdProperties::ClearPlayWindow()
+	{
+    	// clear play window start - very important because this is assigned
+	// to iPosition when we stop & is used to set the position on the next Play()
+	iPosition = iPlayStart = iPlayEnd = TTimeIntervalMicroSeconds(0);
+
+	iPlayWindowSet = EClear;
+	TInt err = KErrNone;
+	if (iState==EPlaying)
+		err = iAudioPlayControllerCommands.DeletePlaybackWindow();
+	return err;
+	}
+TInt CAudioPdProperties::SetBalance(TInt aBalance)
+	{
+    TInt err = iAudioPlayDeviceCommands.SetBalance(aBalance);
+	return err;
+	}
+TInt CAudioPdProperties::GetBalance(TInt& aBalance)
+	{
+	TInt err = iAudioPlayDeviceCommands.GetBalance(aBalance);
+	return err;
+	}
+
+TInt CAudioPdProperties::GetBitRate(TUint& aBitRate)
+	{
+	RMMFAudioControllerCustomCommands controller(iController);
+	TInt err = controller.GetSourceBitRate(aBitRate);
+	return err;
+	}
+
+void CAudioPdProperties::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aLoadingObserver)
+	{
+    iLoadingObserver = &aLoadingObserver;
+	}
+
+void CAudioPdProperties::GetAudioLoadingProgressL(TInt& aPercentageProgress)
+	{
+    User::LeaveIfError(iAudioPlayControllerCommands.GetLoadingProgress(aPercentageProgress));
+	}
+
+const CMMFControllerImplementationInformation& CAudioPdProperties::ControllerImplementationInformationL()
+	{
+	if (!iControllerImplementationInformation)
+		{
+		if (iControllerUid==KNullUid)
+			User::Leave(KErrNotReady);
+		iControllerImplementationInformation = CMMFControllerImplementationInformation::NewL(iControllerUid);
+		}
+	return *iControllerImplementationInformation;
+	}
+
+TInt CAudioPdProperties::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
+	{
+    return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
+	}
+TInt CAudioPdProperties::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
+	{
+    return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
+	}
+void CAudioPdProperties::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
+	{
+	iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
+	}
+void CAudioPdProperties::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
+	{
+    iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
+	}
+
+TInt CAudioPdProperties::GetFilePosition(TInt& aFilePosition)
+	{
+  	TInt err = KErrNone;
+  	TPckgBuf<TInt> dataFrom;
+
+	if(iSourceHandle != NULL)
+        {
+    	TMMFMessageDestinationPckg destPckg(*iSourceHandle);
+	    err =CustomCommandSync(destPckg, EGETFILEPOSITION, KNullDesC8, KNullDesC8, dataFrom);
+	    }
+	else
+	    {
+	    err = KErrNotFound;
+	    }
+
+    if(err==KErrNone)
+       aFilePosition = dataFrom();
+
+	return err;
+    }
+
+TInt CAudioPdProperties::SetFileSize(TInt aFileSize)
+	{
+  	TInt err = KErrNone;
+	if(iSourceHandle != NULL)
+        {
+        TMMFMessageDestinationPckg destPckg(*iSourceHandle);
+        TPckgBuf<TInt> data1(aFileSize);
+        err = CustomCommandSync(destPckg, ESETFILESIZE, data1, KNullDesC8);
+        }
+	else
+	    {
+        err = KErrNotFound;
+	    }
+	return err;
+	}
+
+TInt CAudioPdProperties::SetBytesDownloaded(TInt aBytesDownloaded, TBool /*aDownloadComplete*/)
+	{
+  	TInt err = KErrNone;
+	if(iSourceHandle != NULL)
+        {
+        TMMFMessageDestinationPckg destPckg(*iSourceHandle);
+    	TPckgBuf<TInt> data1(aBytesDownloaded);
+        err = CustomCommandSync(destPckg, ESETBYTESDOWNLOADED, data1, KNullDesC8);
+        }
+	else
+	    {
+	    err = KErrNotFound;
+	    }
+
+    return err;
+	}
+
+
+MMMFDRMCustomCommand* CAudioPdProperties::GetDRMCustomCommand()
+	{
+	if (iDRMCustomCommands.IsSupported())
+		{
+		return static_cast<MMMFDRMCustomCommand*>(&iDRMCustomCommands);
+		}
+	else
+		{
+		return NULL;
+		}
+	}
+
+
+TInt CAudioPdProperties::CheckAudioPlayerState()
+	{
+	return iState;
+	}
+void CAudioPdProperties::HandleEvent(const TMMFEvent& aEvent)
+	{
+	// handle loading started/complete messages first, as the later code does not explicitly check the event type
+	if (aEvent.iEventType==KMMFEventCategoryAudioLoadingStarted)
+		{
+		if (iLoadingObserver)
+			iLoadingObserver->MaloLoadingStarted();
+		}
+	else if (aEvent.iEventType==KMMFEventCategoryAudioLoadingComplete)
+		{
+		if (iLoadingObserver)
+			iLoadingObserver->MaloLoadingComplete();
+		}
+	else if (aEvent.iEventType==KMMFEventCategoryPlaybackComplete)
+		{
+		TInt oldState = iState;
+		iPosition = iPlayStart;
+		if (aEvent.iErrorCode == KErrNone)
+			{
+			//If we weren't playing, ignore the event.
+			if(oldState == EPlaying)
+				{
+				//we finished playing the clip so repeat if required
+				iNumberOfTimesPlayed++;
+				if ((iNumberOfTimesPlayed>iNumberOfTimesToRepeat) && (iNumberOfTimesToRepeat!=KMdaRepeatForever))
+					{
+					//we've repeated enough times now
+					iNumberOfTimesPlayed = 0;
+					iState = EStopped;
+					iCallback.MapcPlayComplete(KErrNone);
+					}
+				else
+					{
+					// We need to repeat the clip
+					// we're truncating the trailingsilence here so maximum time is ~37mins
+               		TTimeIntervalMicroSeconds32 silence = I64INT(iTrailingSilence.Int64());
+					iRepeatTrailingSilenceTimer->After(silence);
+					}
+				}
+			}
+		else
+			{ //aEvent.iErrorCode != KErrNone
+			//if we weren't playing, don't advise Client.
+			iState = EStopped;
+			if(oldState == EPlaying)
+				iCallback.MapcPlayComplete(aEvent.iErrorCode);
+			}
+		}
+
+	// else we have an unexpected event that cannot be dealt with by the client.
+	// We will simply ignore this.
+	}
+
+
+void CAudioPdProperties::RepeatTrailingSilenceTimerComplete()
+	{
+	// reset the position for subsequent plays
+	iPosition = iPlayStart;
+	DoPlay();
+	}
+
+
+CRepeatTrailingSilenceTimer* CRepeatTrailingSilenceTimer::NewL(MRepeatTrailingSilenceTimerObs& aObs)
+	{
+	CRepeatTrailingSilenceTimer* s = new(ELeave) CRepeatTrailingSilenceTimer(aObs);
+	CleanupStack::PushL(s);
+	s->ConstructL();
+	CleanupStack::Pop();
+	return s;
+	}
+
+void CRepeatTrailingSilenceTimer::RunL()
+	{
+	iObs.RepeatTrailingSilenceTimerComplete();
+	}
+
+CRepeatTrailingSilenceTimer::CRepeatTrailingSilenceTimer(MRepeatTrailingSilenceTimerObs& aObs) :
+	CTimer(EPriorityHigh),
+	iObs(aObs)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+CMMFMdaAudioPlayerCallBack* CMMFMdaAudioPlayerCallBack::NewL(MAudioPdPlayUtilityCallback& aCallback)
+	{
+	return new(ELeave) CMMFMdaAudioPlayerCallBack(aCallback);
+	}
+
+CMMFMdaAudioPlayerCallBack::CMMFMdaAudioPlayerCallBack(MAudioPdPlayUtilityCallback& aCallback) :
+	CActive(CActive::EPriorityHigh), iCallback(aCallback)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CMMFMdaAudioPlayerCallBack::~CMMFMdaAudioPlayerCallBack()
+	{
+	Cancel();
+	}
+
+void CMMFMdaAudioPlayerCallBack::InitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration)
+	{
+	iError = aError;
+	iDuration = aDuration;
+	iState = ECallbackInitComplete;
+	if (!IsActive())
+		{
+		TRequestStatus* s = &iStatus;
+		SetActive();
+		User::RequestComplete(s, KErrNone);
+		}
+	}
+
+void CMMFMdaAudioPlayerCallBack::PlayComplete(TInt aError)
+	{
+	iError = aError;
+	iState = ECallbackPlayComplete;
+	if (!IsActive())
+		{
+		TRequestStatus* s = &iStatus;
+		SetActive();
+		User::RequestComplete(s, KErrNone);
+		}
+	}
+
+
+void CMMFMdaAudioPlayerCallBack::PlayingCallback()
+	{
+	iState = ECallbackPlaying;
+	if (!IsActive())
+		{
+		TRequestStatus* s = &iStatus;
+		SetActive();
+		User::RequestComplete(s, KErrNone);
+		}
+	}
+
+void CMMFMdaAudioPlayerCallBack::PausedCallback()
+	{
+	iState = ECallbackPaused;
+	if (!IsActive())
+		{
+		TRequestStatus* s = &iStatus;
+		SetActive();
+		User::RequestComplete(s, KErrNone);
+		}
+	}
+
+
+void CMMFMdaAudioPlayerCallBack::RunL()
+	{
+	switch (iState)
+		{
+		case ECallbackInitComplete:
+			iCallback.MapcInitComplete(iError, iDuration);
+			break;
+		case ECallbackPlayComplete:
+			iCallback.MapcPlayComplete(iError);
+			break;
+		case ECallbackPlaying:
+			iCallback.Playing();
+			break;
+		case ECallbackPaused:
+			iCallback.Paused();
+			break;
+
+		}
+	}
+
+void CMMFMdaAudioPlayerCallBack::DoCancel()
+	{
+	// Nothing to cancel
+	}
+