--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mpserviceplugins/localaudio/src/mpxlocalaudioplayback.cpp Fri Mar 19 09:28:13 2010 +0200
@@ -0,0 +1,1219 @@
+/*
+* Copyright (c) 2006 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: This class plays local audio file
+*
+*/
+
+
+// INCLUDE FILES
+//<branchInfo originator="alakurik" since="26-NOV-2007"/>
+// Including adaptationaudiopreference.h instead of audiopreference.h to
+// bring in needed constants for __HIGH_RESOLUTION_VOLUME
+//</branchInfo>
+//BRANCH 26-NOV-2007
+//#include <audiopreference.h>
+//BRANCH_END
+#if defined(__HIGH_RESOLUTION_VOLUME) && !defined(__LOW_POWER_AUDIO_PLAYBACK)
+#include <adaptationaudiopreference.h>
+#else
+#include <AudioPreference.h>
+#endif
+#include <badesca.h>
+#include <apgcli.h>
+#include <mmf/common/mmfcontrollerframeworkbase.h>
+#include <mmf/common/mmfmeta.h>
+#include <mpxmedia.h>
+#include <mpxdrmmediautility.h>
+#include <mpxmediadrmdefs.h>
+#include <mpxplaybackpluginobserver.h>
+#include <mpxmediaaudiodefs.h>
+#include <mpxmediamusicdefs.h>
+#include <mpxmediageneraldefs.h>
+#include <mpxmediadrmdefs.h>
+#include "mpxaudioeffectengine.h"
+#include <mpxprivatecrkeys.h>
+#include <mpxcenrepwatcher.h>
+
+#include "mpxlocalaudioplayback.h"
+#include "mpxlog.h"
+
+// CONSTANTS
+const TUid KLocalPlaybackUid={0x101FFC06};
+// added because of build warning
+#if defined(__HIGH_RESOLUTION_VOLUME)
+_LIT(KWmaExtension, ".wma");
+_LIT(KRaExtension, ".ra");
+#endif
+
+
+// ============================ LOCAL FUNCTIONS ==============================
+LOCAL_C TInt Balance(TInt aMMFBalance)
+ {
+ return (aMMFBalance-KMMFBalanceCenter) *
+ (EPbBalanceMaxRight-EPbBalanceMaxLeft) /
+ (KMMFBalanceMaxRight-KMMFBalanceMaxLeft);
+ }
+
+LOCAL_C TInt MMFBalance(TInt aBalance)
+ {
+ return KMMFBalanceCenter+(KMMFBalanceMaxRight-KMMFBalanceMaxLeft)/
+ (EPbBalanceMaxRight-EPbBalanceMaxLeft)*aBalance;
+ }
+
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXLocalAudioPlayback* CMPXLocalAudioPlayback::NewL(TAny* /*aInitParams*/)
+ {
+ CMPXLocalAudioPlayback* p=new(ELeave)CMPXLocalAudioPlayback();
+ CleanupStack::PushL(p);
+ p->ConstructL();
+ CleanupStack::Pop(p);
+ return p;
+ }
+
+// ----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::ConstructL()
+ {
+ MPX_FUNC_EX("CMPXLocalAudioPlayback::ConstructL()");
+ iVolumeWatcher = CMPXCenRepWatcher::NewL(KCRUidMPXSettings,
+ KMPXPlaybackVolume,
+ this);
+
+ iMuteWatcher = CMPXCenRepWatcher::NewL(KCRUidMPXSettings,
+ KMPXPlaybackMute,
+ this);
+
+ iPlayer = CMdaAudioPlayerUtility::NewL(*this,
+#ifdef __LOW_POWER_AUDIO_PLAYBACK
+ KAudioPriorityMusicPlayer,
+ TMdaPriorityPreference(KAudioPrefMusicLocalPlayback));
+#else
+#ifdef __HIGH_RESOLUTION_VOLUME
+ KAudioPriorityTwentyStepsVolumeMusicPlayer,
+ TMdaPriorityPreference(KAudioPrefTwentyStepsVolumeMusicPlayerPlayback));
+#else
+ KAudioPriorityRealOnePlayer,
+ TMdaPriorityPreference(KAudioPrefRealOneLocalPlayback));
+#endif // __HIGH_RESOLUTION_VOLUME
+#endif // __LOW_POWER_AUDIO_PLAYBACK
+
+ User::LeaveIfError(iFs.Connect());
+ iFs.ShareProtected();
+ iDrmMediaUtility = CMPXDrmMediaUtility::NewL();
+ iAudioEffects = CMPXAudioEffectEngine::NewL( iPlayer );
+ }
+
+// ----------------------------------------------------------------------------
+// C++ constructor
+// ----------------------------------------------------------------------------
+//
+CMPXLocalAudioPlayback::CMPXLocalAudioPlayback()
+ : iAudioEffectsOn(ETrue), iIsPlaying(EFalse)
+ {}
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CMPXLocalAudioPlayback::~CMPXLocalAudioPlayback()
+ {
+ MPX_FUNC_EX("CMPXLocalAudioPlayback::~CMPXLocalAudioPlayback");
+ delete iMuteWatcher;
+ delete iVolumeWatcher;
+ if ( iDrmMediaUtility )
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EStop ) );
+ iDrmMediaUtility->Close();
+ delete iDrmMediaUtility;
+ }
+ if( iAudioEffects )
+ {
+ iAudioEffects->DestroyAudioEffect();
+ delete iAudioEffects;
+ }
+ if (iPlayer)
+ {
+ iPlayer->Close();
+ delete iPlayer;
+ }
+ iFile.Close();
+ iFs.Close();
+ delete iSong;
+ }
+
+// ----------------------------------------------------------------------------
+// Set observer
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::SetObserver(MMPXPlaybackPluginObserver& aObs)
+ {
+ MPX_FUNC_EX("CMPXLocalAudioPlayback::SetObserver(MMPXPlaybackPluginObserver& aObs)");
+ iObs = &aObs;
+ }
+
+// ----------------------------------------------------------------------------
+// Initializes a song for playback
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::InitialiseL(const TDesC& aSong)
+ {
+ MPX_DEBUG3("-->CMPXLocalAudioPlayback::InitialiseL 0x%08x, (%S)", this, &aSong);
+
+ iDrmMediaUtility->Close();
+ delete iSong;
+ iSong = NULL;
+ iSong = aSong.AllocL();
+ iFile.Close();
+ TInt err( iFile.Open( iFs, aSong, EFileRead | EFileShareReadersOrWriters ));
+ // Remap KErrNotReady to KErrNotFound, because it is referencing a drive
+ // that is not existent
+ if ( KErrNotReady == err )
+ {
+ err = KErrNotFound;
+ }
+ User::LeaveIfError( err );
+
+#if defined(__HIGH_RESOLUTION_VOLUME)
+ TParsePtrC parser(aSong);
+
+ // Merlin twentysteps hack start
+ if (parser.Ext().CompareF(KWmaExtension) == 0 || parser.Ext().CompareF(KRaExtension) == 0)
+ {
+ // This is a wma song, need to delete iPlayer and reset the volume resolution
+ // this is because the volume level 20 is not supported for wma with headphone
+ MPX_DEBUG1("CMPXLocalAudioPlayback::InitialiseL it is a wma file, so set to 10 steps");
+ delete iAudioEffects;
+ iAudioEffects = NULL;
+ delete iPlayer;
+ iPlayer = NULL;
+ iPlayer = CMdaAudioPlayerUtility::NewL(*this,
+ KAudioPriorityRealOnePlayer,
+ TMdaPriorityPreference(KAudioPrefRealOneLocalPlayback));
+ // Also regenerate audio effects
+ iAudioEffects = CMPXAudioEffectEngine::NewL( iPlayer );
+ }
+ // Merlin twentysteps hack end
+#endif // __HIGH_RESOLUTION_VOLUME
+ TMMFileHandleSource source(iFile, KDefaultContentObject, EPlay);
+ iPlayer->OpenFileL(source);
+ iDrmMediaUtility->InitL( iFile );
+ iState = EStateInitialising;
+ iClosedByAudioPolicy = EFalse;
+ iConsumeStarted = EFalse;
+
+ MPX_DEBUG3("<--CMPXLocalAudioPlayback::InitialiseL 0x%08x, (%S)", this, &aSong);
+ }
+
+// ----------------------------------------------------------------------------
+// Initializes a song for playback
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::InitialiseL(RFile& aSong)
+ {
+ MPX_DEBUG2("-->CMPXLocalAudioPlayback::InitialiseL(RFile) 0x%08x", this);
+
+ iDrmMediaUtility->Close();
+ delete iSong;
+ iSong = NULL;
+ iSong = HBufC::NewL(KMaxFileName);
+ TPtr ptr = iSong->Des();
+ aSong.FullName(ptr);
+
+#if defined(__HIGH_RESOLUTION_VOLUME)
+ TParsePtrC parser(ptr);
+
+ // Merlin twentysteps hack start
+ if (parser.Ext().CompareF(KWmaExtension) == 0 || parser.Ext().CompareF(KRaExtension) == 0)
+ {
+ // This is a wma song, need to delete iPlayer and reset the volume resolution
+ // this is because the volume level 20 is not supported for wma with headphone
+ delete iAudioEffects;
+ iAudioEffects = NULL;
+ delete iPlayer;
+ iPlayer = NULL;
+ iPlayer = CMdaAudioPlayerUtility::NewL(*this,
+ KAudioPriorityRealOnePlayer,
+ TMdaPriorityPreference(KAudioPrefRealOneLocalPlayback));
+ // Also regenerate audio effects
+ iAudioEffects = CMPXAudioEffectEngine::NewL( iPlayer );
+ }
+ // Merlin twentysteps hack end
+#endif // __HIGH_RESOLUTION_VOLUME
+ TMMFileHandleSource source(aSong, KDefaultContentObject, EPlay);
+ iPlayer->OpenFileL(source);
+ User::LeaveIfError( iFile.Duplicate( aSong ));
+ iDrmMediaUtility->InitL( iFile );
+ iState = EStateInitialising;
+ iClosedByAudioPolicy = EFalse;
+ iConsumeStarted = EFalse;
+
+ MPX_DEBUG2("<--CMPXLocalAudioPlayback::InitialiseL(RFile) 0x%08x", this);
+ }
+
+// ----------------------------------------------------------------------------
+// Executes a command on the selected song
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::CommandL(TMPXPlaybackCommand aCmd, TInt aData)
+ {
+ MPX_DEBUG3("-->CMPXLocalAudioPlayback::CommandL 0x%08x cmd %d", this, aCmd);
+ switch(aCmd)
+ {
+ case EPbCmdPlay:
+ {
+ // If closed by audio policy, then play command will need to
+ // re-initialise the plugin first.
+ if ( iClosedByAudioPolicy )
+ {
+ HBufC* song( iSong->AllocLC() );
+ InitialiseL( *song );
+ iConsumeStarted = ETrue;
+ CleanupStack::PopAndDestroy( song );
+ iClosedByAudioPolicy = EFalse;
+ }
+ else
+ {
+ // Treat song as play complete if try to play at end of song
+ TTimeIntervalMicroSeconds dur( iPlayer->Duration() );
+ TTimeIntervalMicroSeconds pos( 0 );
+ TInt err( iPlayer->GetPosition( pos ));
+ MPX_DEBUG4("CMPXLocalAudioPlayback::CommandL(): dur=%d, pos=%d, err=%d", I64INT(dur.Int64()), I64INT(pos.Int64()), err);
+ if ( !err &&
+ Abs( dur.Int64() - pos.Int64() ) < KPbMilliMultiplier &&
+ dur.Int64() > KPbMilliMultiplier )
+ {
+ MapcPlayComplete( KErrNone );
+ }
+ else
+ {
+ if (iConsumeStarted)
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EContinue ) );
+ }
+ else
+ {
+ MPX_TRAPD( AEErr, ConsumeRightsL( ContentAccess::EPlay ) );
+ if (AEErr == KErrDiskFull)
+ {
+ iDrmMediaUtility->Close();
+ iPlayer->Stop();
+ iIsPlaying = EFalse;
+ iAudioEffects->DestroyAudioEffect();
+ iPlayer->Close();
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPStopped,
+ 0, KErrDiskFull);
+ iFile.Close();
+ iState = EStateNotInitialised;
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPClosed,
+ EPbCmdStop, KErrDiskFull);
+ iClosedByAudioPolicy = EFalse;
+ break;
+ }
+ iConsumeStarted = ETrue;
+ }
+
+ if ( iAudioEffectsOn )
+ {
+ MPX_TRAP( err, iAudioEffects->CreateAudioEffectsL() );
+ }
+
+ iPlayer->Play();
+ iIsPlaying = ETrue;
+
+ if( iAudioEffectsOn && err != KErrNone )
+ {
+ MPX_TRAP( err, iAudioEffects->CreateAudioEffectsL() );
+ }
+
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPPlaying,
+ 0, KErrNone);
+ }
+ }
+ break;
+ }
+ case EPbCmdPause:
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EPause ) );
+
+ TInt err( iPlayer->Pause() );
+ iIsPlaying = EFalse;
+ iAudioEffects->DestroyAudioEffect();
+
+ MPX_DEBUG2("CMPXLocalAudioPlayback::CommandL(): Pause err = %d", err);
+ // If pause is not supported, resend the play command so plugin
+ // state is correct.
+ // This is for cases like playing .RNG files
+ if ( KErrNotSupported == err )
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPaused,
+ 0,
+ KErrNone);
+ iPlayer->Play();
+ iIsPlaying = ETrue;
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPlaying,
+ 0,
+ KErrNone);
+ }
+ else
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPaused,
+ 0,
+ err);
+ }
+ iClosedByAudioPolicy = EFalse;
+ break;
+ }
+ case EPbCmdStop:
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EStop ));
+ iConsumeStarted = EFalse;
+ iDrmMediaUtility->Close();
+ iPlayer->Stop();
+ iIsPlaying = EFalse;
+ iAudioEffects->DestroyAudioEffect();
+ iPlayer->Close();
+
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPStopped,
+ 0, KErrNone);
+ iFile.Close();
+ iState = EStateNotInitialised;
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPClosed,
+ EPbCmdStop, KErrNone);
+ iClosedByAudioPolicy = EFalse;
+ break;
+ }
+ case EPbCmdClose:
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EStop ));
+ iConsumeStarted = EFalse;
+ iDrmMediaUtility->Close();
+ iAudioEffects->DestroyAudioEffect();
+ iPlayer->Close();
+ iIsPlaying = EFalse;
+ iFile.Close();
+ iState = EStateNotInitialised;
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPClosed,
+ EPbCmdClose, KErrNone);
+ iClosedByAudioPolicy = EFalse;
+ break;
+ }
+ case EPbApplyEffect:
+ {
+ // Re-init audio effects
+ MPX_DEBUG1("CMPXLocalAudioPlayback::CommandL EPbApplyEffect");
+ if( ( aData == KAudioEffectsID || aData == KEqualizerID ) &&
+ ( EStateInitialised == iState ) )
+ {
+ TRAP_IGNORE( iAudioEffects->CreateAudioEffectsL() );
+ iAudioEffectsOn = ETrue;
+ }
+ break;
+ }
+ case EPbCmdCloseItem:
+ {
+ iDrmMediaUtility->Close();
+ iPlayer->Close();
+ iIsPlaying = EFalse;
+ iFile.Close();
+ iState = EStateNotInitialised;
+ iClosedByAudioPolicy = EFalse;
+ break;
+ }
+ case EPbCmdDisableEffect:
+ {
+ iAudioEffectsOn = EFalse;
+ break;
+ }
+ default:
+ break;
+ }
+ MPX_DEBUG3("<--CMPXLocalAudioPlayback::CommandL 0x%08x cmd %d", this, aCmd);
+ }
+
+// ----------------------------------------------------------------------------
+// Sets a property of the plugin
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::SetL(TMPXPlaybackProperty aProperty,TInt aValue)
+ {
+ MPX_DEBUG4("-->CMPXLocalAudioPlayback::SetL 0x%08x, (prop %d, val %d)",
+ this, aProperty, aValue);
+ TBool isSupported=ETrue;
+ switch(aProperty)
+ {
+ case EPbPropertyVolume:
+ {
+ SetVolume( aValue );
+ break;
+ }
+ case EPbPropertyVolumeRamp:
+ iPlayer->SetVolumeRamp(TTimeIntervalMicroSeconds(TInt64(aValue)));
+ break;
+ case EPbPropertyMute:
+ SetMute( aValue );
+ break;
+ case EPbPropertyBalance:
+ iPlayer->SetBalance(MMFBalance(aValue));
+ break;
+ case EPbPropertyPosition:
+ {
+ TInt64 pos(aValue);
+ pos *= KPbMilliMultiplier;
+
+ if (iIsPlaying)
+ {
+ iPlayer->Pause();
+ iPlayer->SetPosition(pos);
+ iPlayer->Play();
+ }
+ else
+ {
+ iPlayer->SetPosition(pos);
+ }
+ }
+ break;
+ default:
+ isSupported=EFalse;
+ }
+
+ if (!isSupported)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPSetComplete,
+ aProperty, KErrNone);
+ MPX_DEBUG4("<--CMPXLocalAudioPlayback::SetL 0x%08x, (prop %d, val %d)",
+ this, aProperty, aValue);
+ }
+
+// ----------------------------------------------------------------------------
+// Gets a property of the plugin (async)
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::PropertyL(TMPXPlaybackProperty aProperty) const
+ {
+ MPX_DEBUG3("-->CMPXLocalAudioPlayback::PropertyL 0x%08x (prop %d)",
+ this, aProperty);
+ TBool isSupported=ETrue;
+ TInt value=KErrNotFound;
+ TInt err(KErrNone);
+ switch(aProperty)
+ {
+ case EPbPropertyVolume:
+ {
+ value = iVolumeWatcher->CurrentValueL();
+ break;
+ }
+ case EPbPropertyMaxVolume:
+ value=iPlayer->MaxVolume();
+ break;
+ case EPbPropertyMute:
+ value = iMuteWatcher->CurrentValueL();
+ break;
+ case EPbPropertyBalance:
+ err = iPlayer->GetBalance(value);
+ value=Balance(value);
+ break;
+ case EPbPropertyDuration:
+ {
+ TTimeIntervalMicroSeconds duration = iPlayer->Duration();
+ value = duration.Int64() / KPbMilliMultiplier;
+ }
+ break;
+ case EPbPropertyPosition:
+ {
+ TTimeIntervalMicroSeconds pos;
+ iPlayer->GetPosition(pos);
+ MPX_DEBUG2("CMPXLocalAudioPlayback::PropertyL position %ld", pos.Int64());
+ value = pos.Int64() / KPbMilliMultiplier;
+ }
+ break;
+ case EPbPropertySupportedFeatures:
+ value = EPbFeatureBalance | EPbFeatureVolumeRamp;
+ break;
+ default:
+ isSupported=EFalse;
+ }
+ if (!isSupported)
+ {
+ User::Leave(KErrNotSupported);
+ }
+ iObs->HandleProperty(aProperty,value,err);
+ MPX_DEBUG3("<--CMPXLocalAudioPlayback::PropertyL 0x%08x (prop %d)",
+ this, aProperty);
+ }
+
+// ----------------------------------------------------------------------------
+// Gets a list of sub players, UPnP only
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::SubPlayerNamesL()
+ {
+ iObs->HandleSubPlayerNames(KLocalPlaybackUid, NULL, ETrue, KErrNone);
+ }
+
+// ----------------------------------------------------------------------------
+// Select a sub player
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::SelectSubPlayerL(TInt /*aIndex*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+// ----------------------------------------------------------------------------
+// Returns current sub player name
+// ----------------------------------------------------------------------------
+//
+const TDesC& CMPXLocalAudioPlayback::SubPlayerName()
+ {
+ return KNullDesC; //No subplayer name for local playback
+ }
+
+// ----------------------------------------------------------------------------
+// Current sub player index
+// ----------------------------------------------------------------------------
+//
+TInt CMPXLocalAudioPlayback::SubPlayerIndex() const
+ {
+ return KErrNotFound;
+ }
+
+// ----------------------------------------------------------------------------
+// Gets media properties
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::MediaL(const TArray<TMPXAttribute>& aAttrs)
+ {
+ MPX_DEBUG2("-->CMPXLocalAudioPlayback::MediaL 0x%08x", this);
+ RArray<TInt> suppIds;
+ CleanupClosePushL(suppIds);
+ suppIds.AppendL(KMPXMediaIdMusic);
+ suppIds.AppendL(KMPXMediaIdGeneral);
+ suppIds.AppendL(KMPXMediaIdAudio);
+ suppIds.AppendL(KMPXMediaIdDrm);
+ CMPXMedia* media=CMPXMedia::NewL(suppIds.Array());
+ CleanupStack::PopAndDestroy(&suppIds);
+ CleanupStack::PushL(media);
+
+ if ( EStateInitialised == iState )
+ {
+ TUint attrG(0); // General attributes
+ TUint attrA(0); // Audio attributes
+ TUint attrM(0); // Music attributes
+ TUint attrD(0); // DRM attributes
+
+ for (TInt i=aAttrs.Count(); --i>=0;)
+ {
+ TMPXAttribute attr(aAttrs[i]);
+ if (attr.ContentId() == KMPXMediaIdGeneral)
+ {
+ attrG |= attr.AttributeId();
+ }
+ else if (attr.ContentId() == KMPXMediaIdMusic)
+ {
+ attrM |= attr.AttributeId();
+ }
+ else if (attr.ContentId() == KMPXMediaIdAudio)
+ {
+ attrA |= attr.AttributeId();
+ }
+ else if ( attr.ContentId() == KMPXMediaIdDrm )
+ {
+ attrD |= attr.AttributeId();
+ }
+ }
+
+ TInt metaCount = 0;
+
+ // Get metadata from MMF
+ TInt error = iPlayer->GetNumberOfMetaDataEntries(metaCount);
+ CMMFMetaDataEntry* metaData = NULL;
+
+ if (!error)
+ {
+ for (TInt i = 0; i < metaCount; ++i)
+ {
+ metaData = iPlayer->GetMetaDataEntryL(i);
+ CleanupStack::PushL(metaData);
+
+ if (metaData->Name().CompareF(KMMFMetaEntrySongTitle()) == 0 &&
+ attrG & EMPXMediaGeneralTitle)
+ { // TODO to check request
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryArtist()) == 0 &&
+ attrM & EMPXMediaMusicArtist)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicArtist),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryAlbum()) == 0 &&
+ attrM & EMPXMediaMusicAlbum)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicAlbum),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryYear()) == 0 &&
+ attrM & EMPXMediaMusicYear)
+ {
+ TInt year;
+ TLex lex( metaData->Value() );
+ lex.Val( year );
+
+ TDateTime dt;
+ dt.SetYear( year );
+ TTime time( dt );
+
+ media->SetTObjectValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicYear),
+ time.Int64());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryComment()) == 0 &&
+ attrG & EMPXMediaGeneralComment)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralComment),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryComposer()) == 0 &&
+ attrM & EMPXMediaMusicComposer)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicComposer),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryAlbumTrack()) == 0 &&
+ attrM & EMPXMediaMusicAlbumTrack)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicAlbumTrack),
+ metaData->Value());
+ }
+ else if (metaData->Name().CompareF(KMMFMetaEntryGenre()) == 0 &&
+ attrM & EMPXMediaMusicGenre)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicGenre),
+ metaData->Value());
+ }
+ //else if (metaData->Name().CompareF(KMMFMetaEntryWOAF()) == 0 &&
+ // attrM & EMPXMediaMusicGenre)
+ // {
+ //media->SetTextValueL(
+ // TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicGenre),
+ // metaData->Value());
+ //}
+ else if (metaData->Name().CompareF(KMMFMetaEntryAPIC()) == 0 &&
+ attrM & EMPXMediaMusicAlbumArtFileName)
+ {
+ // TODO check collection if user defined album art available
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdMusic,EMPXMediaMusicAlbumArtFileName),
+ *iSong);
+ }
+
+ CleanupStack::PopAndDestroy(metaData);
+ metaData = NULL;
+ }
+ if ( attrG & EMPXMediaGeneralTitle )
+ {
+ if ( !media->IsSupported(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle ) ) )
+ {
+ TParsePtrC ptr( *iSong );
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralTitle),
+ ptr.Name() );
+ }
+ }
+ }
+ if (attrG & EMPXMediaGeneralUri)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralUri),
+ *iSong);
+ }
+
+ if (attrG & EMPXMediaGeneralDuration)
+ {
+ TTimeIntervalMicroSeconds duration = iPlayer->Duration();
+ media->SetTObjectValueL<TInt>(
+ TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration),
+ duration.Int64() / KPbMilliMultiplier);
+ }
+
+
+ // Set bitrate TODO
+ TPckgBuf<TMMFAudioConfig> data;
+
+ const TMMFMessageDestinationPckg
+ destinationPckg(KUidInterfaceMMFAudioController);
+
+ if (attrA & EMPXMediaAudioBitrate)
+ {
+ error = iPlayer->CustomCommandSync(destinationPckg,
+ EMMFAudioControllerGetSourceBitRate, KNullDesC8, KNullDesC8, data);
+ if (!error)
+ {
+ media->SetTObjectValueL<TInt>(
+ TMPXAttribute(KMPXMediaIdAudio, EMPXMediaAudioBitrate),
+ data().iSampleRate);
+ }
+ }
+
+ if (attrA & EMPXMediaAudioSamplerate)
+ {
+
+ // Set sampling rate
+ error = iPlayer->CustomCommandSync(destinationPckg,
+ EMMFAudioControllerGetSourceSampleRate, KNullDesC8, KNullDesC8, data);
+ if (!error)
+ {
+ media->SetTObjectValueL<TInt>(
+ KMPXMediaAudioSamplerate,
+ data().iSampleRate);
+ }
+ }
+ if (attrG & EMPXMediaGeneralSize)
+ {
+ TEntry entry;
+ iFs.Entry(iSong->Des(), entry);
+ media->SetTObjectValueL<TInt>(
+ TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralSize),
+ entry.iSize);
+ }
+
+ if (attrG & EMPXMediaGeneralMimeType)
+ {
+ RApaLsSession aps;
+ error = aps.Connect(); // always fail in console test
+ if (KErrNone == error)
+ {
+ CleanupClosePushL(aps);
+ TDataType dataType;
+ TUid ignore;
+ if(aps.AppForDocument(iSong->Des(),ignore,dataType)==KErrNone)
+ {
+ media->SetTextValueL(
+ TMPXAttribute(KMPXMediaIdGeneral,EMPXMediaGeneralMimeType),
+ dataType.Des());
+ }
+ CleanupStack::PopAndDestroy(&aps);
+ } // Notes, STIF console test always fail
+ }
+
+ // Set DRM info
+ const CMPXMedia* drmMedia( iDrmMediaUtility->GetMediaL( attrD ));
+ if ( drmMedia )
+ {
+ TInt count( drmMedia->Count() );
+ for ( TInt i = 0; i < count; i++ )
+ {
+ TUint attrId( drmMedia->Attribute(i).AttributeId() );
+ if ( attrD & attrId )
+ {
+ TMPXAttribute mpxAtt( KMPXMediaIdDrm, attrId );
+ switch ( attrId )
+ {
+ case EMPXMediaDrmType:
+ case EMPXMediaDrmRightsStatus:
+ case EMPXMediaDrmRightsType:
+ case EMPXMediaDrmCount:
+ {
+ TInt val(
+ drmMedia->ValueTObjectL<TInt>( mpxAtt ));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ case EMPXMediaDrmProtected:
+ case EMPXMediaDrmSendingAllowed:
+ case EMPXMediaDrmCanSetAutomated:
+ case EMPXMediaDrmHasInfoUrl:
+ case EMPXMediaDrmHasPreviewUrl:
+ case EMPXMediaDrmAboutToExpire:
+ {
+ TBool val(
+ drmMedia->ValueTObjectL<TBool>( mpxAtt ));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ case EMPXMediaDrmStartTime:
+ case EMPXMediaDrmEndTime:
+ case EMPXMediaDrmIntervalStartTime:
+ case EMPXMediaDrmAccumulatedTime:
+ {
+ TInt64 val(
+ drmMedia->ValueTObjectL<TInt64>( mpxAtt ));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ case EMPXMediaDrmInterval:
+ {
+ TTimeIntervalSeconds val(
+ drmMedia->ValueTObjectL<TTimeIntervalSeconds>(mpxAtt));
+ media->SetTObjectValueL( mpxAtt, val );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ } // end switch (attriId)
+ } // end if ( attrD & attrId )
+ }
+ }
+ }
+
+ iObs->HandleMedia(*media, KErrNone);
+ CleanupStack::PopAndDestroy(media);
+ MPX_DEBUG2("<--CMPXLocalAudioPlayback::MediaL 0x%08x", this);
+ }
+
+// ----------------------------------------------------------------------------
+// Cancel request
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::CancelRequest()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// File open complete event
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::MapcInitComplete(TInt aError,
+ const TTimeIntervalMicroSeconds& aDuration)
+ {
+ MPX_DEBUG4("-->CMPXLocalAudioPlayback::MapcInitComplete 0x%08x err (%d) duration (%Ld)",
+ this, aError, aDuration.Int64());
+ iState = EStateInitialised;
+
+ // Restore volume level
+ if ( KErrNone == aError )
+ {
+ TInt currentVol( 0 );
+ MPX_TRAPD( volError, currentVol = iVolumeWatcher->CurrentValueL() );
+ if ( volError == KErrNone )
+ {
+ SetVolume( currentVol );
+ TBool mute( EFalse);
+ MPX_TRAPD( muteError, mute = iMuteWatcher->CurrentValueL() );
+ if ( muteError == KErrNone && mute )
+ {
+ SetMute(mute);
+ }
+ }
+ }
+
+ // Disable automatic DRM consumption
+ if ( iPlayer )
+ {
+ MMMFDRMCustomCommand* drmCustom = iPlayer->GetDRMCustomCommand();
+ if ( drmCustom )
+ {
+ drmCustom->DisableAutomaticIntent( ETrue );
+ }
+ }
+
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPInitialised,
+ aDuration.Int64()/KPbMilliMultiplier,aError);
+
+ MPX_DEBUG4("<--CMPXLocalAudioPlayback::MapcInitComplete 0x%08x err (%d) duration (%Ld)",
+ this, aError, aDuration.Int64());
+ }
+
+// ----------------------------------------------------------------------------
+// File play complete event
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::MapcPlayComplete(TInt aError)
+ {
+ MPX_DEBUG3("-->CMPXLocalAudioPlayback::MapcPlayComplete 0x%08x (err %d)",
+ this, aError);
+ iState = EStateNotInitialised;
+ iIsPlaying = EFalse;
+ if ( KErrNone != aError )
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EPause ) );
+ }
+ else
+ {
+ TRAP_IGNORE( ConsumeRightsL( ContentAccess::EStop ) );
+ if ( iConsumeStarted )
+ {
+ iConsumeStarted = EFalse;
+ }
+ }
+
+ TRAP_IGNORE( iAudioEffects->DestroyAudioEffect() );
+
+ // If killed by audio policy, mimic a paused state
+ if ( KErrDied == aError || KErrAccessDenied == aError || KErrInUse == aError )
+ {
+ iClosedByAudioPolicy = ETrue;
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPaused,
+ 0,
+ aError );
+ }
+ // If disk removed
+ else if( KErrNotReady == aError )
+ {
+ MPX_DEBUG1("CMPXLocalAudioPlayback::MapcPlayComplete - KErrNotReady");
+
+ iClosedByAudioPolicy = EFalse;
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPStopped,
+ 0,
+ KErrNone );
+ }
+ else
+ {
+ iClosedByAudioPolicy = EFalse;
+ iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPPlayComplete,0,aError);
+ }
+ MPX_DEBUG3("<--CMPXLocalAudioPlayback::MapcPlayComplete 0x%08x (err %d)",
+ this, aError);
+ }
+
+// ----------------------------------------------------------------------------
+// Handle a change in a setting value.
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::HandleSettingChange(
+ const TUid& aRepositoryUid,
+ TUint32 aSettingId )
+ {
+ MPX_DEBUG2("-->CMPXLocalAudioPlayback::HandleSettingChange 0x%08x", this);
+
+ if ( KCRUidMPXSettings == aRepositoryUid &&
+ KMPXPlaybackVolume == aSettingId )
+ {
+ MPX_DEBUG1("CMPXLocalAudioPlayback::HandleSettingChange() Volume setting changed");
+ TInt vol( 0 );
+ MPX_TRAPD( error, vol = iVolumeWatcher->CurrentValueL() );
+ if ( EStateInitialised == iState && error == KErrNone )
+ {
+ SetVolume( vol );
+ }
+ else if ( error == KErrNone )
+ {
+ // Do not need to set volume if not initialised,
+ // just notify observers
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPVolumeChanged,
+ vol,
+ KErrNone);
+ }
+ }
+ else if ( KCRUidMPXSettings == aRepositoryUid &&
+ KMPXPlaybackMute == aSettingId )
+ {
+ MPX_DEBUG1("CMPXLocalAudioPlayback::HandleSettingChange() Mute setting changed");
+ TBool mute( EFalse );
+ MPX_TRAPD( error, mute = static_cast<TBool>(iMuteWatcher->CurrentValueL()) );
+ if ( EStateInitialised == iState && error == KErrNone )
+ {
+ TInt oldVolume( 0 );
+ iPlayer->GetVolume( oldVolume );
+ if ( (mute && oldVolume != 0) || (!mute && oldVolume == 0) )
+ {
+ SetMute( mute );
+ }
+ }
+ else if ( error == KErrNone )
+ {
+ // Do not need to set volume if not initialised,
+ // just notify observers
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPMuteChanged,
+ mute,
+ KErrNone);
+ }
+ }
+ MPX_DEBUG2("<--CMPXLocalAudioPlayback::HandleSettingChange 0x%08x", this);
+ }
+
+// ----------------------------------------------------------------------------
+// Sets the volume level in audio controller
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::SetVolume( TInt aVolume )
+ {
+ MPX_DEBUG3("-->CMPXLocalAudioPlayback::SetVolume 0x%08x vol (%d)", this, aVolume);
+
+ // Ensure that level is within min and max values
+ if ( aVolume > KPbPlaybackVolumeLevelMax )
+ {
+ aVolume = KPbPlaybackVolumeLevelMax;
+ }
+ if ( aVolume < KPbPlaybackVolumeLevelMin )
+ {
+ aVolume = KPbPlaybackVolumeLevelMin;
+ }
+
+ TBool changed( EFalse );
+ // Change MMF Audio player's volume
+ if ( EStateInitialised == iState )
+ {
+ TInt newVolume( aVolume * iPlayer->MaxVolume() / 100 );
+ MPX_DEBUG2("CMPXLocalAudioPlayback::SetVolume(): Setting volume = %d", newVolume);
+
+ // First check if MMF Audio player's volume is changed by new value
+ TInt oldVolume( 0 );
+ iPlayer->GetVolume( oldVolume );
+ if ( newVolume != oldVolume )
+ {
+ iPlayer->SetVolume( newVolume );
+ changed = ETrue;
+ }
+ }
+
+ // Change setting in cenrep
+ TInt currentVol( 0 );
+ MPX_TRAPD( volError, currentVol = iVolumeWatcher->CurrentValueL() );
+ if ( volError == KErrNone && aVolume != currentVol )
+ {
+ MPX_TRAP( volError, iVolumeWatcher->SetValueL( aVolume ) );
+ if( aVolume == 0 )
+ {
+ MPX_TRAP( volError, iMuteWatcher->SetValueL( ETrue ) );
+ }
+ else if( aVolume > 0 )
+ {
+ TBool currentMute( EFalse );
+
+ MPX_TRAP( volError, currentMute = iMuteWatcher->CurrentValueL() );
+ if( volError == KErrNone && currentMute )
+ {
+ MPX_TRAP( volError, iMuteWatcher->SetValueL( EFalse ) );
+ }
+ }
+ }
+
+ // Notify observer if value changed
+ if ( changed )
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPVolumeChanged,
+ aVolume,
+ KErrNone);
+ }
+
+ MPX_DEBUG3("<--CMPXLocalAudioPlayback::SetVolume 0x%08x vol (%d)", this, aVolume);
+ }
+
+// ----------------------------------------------------------------------------
+// Sets the volume level in audio controller
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::SetMute( TBool aMute )
+ {
+ MPX_DEBUG3("-->CMPXLocalAudioPlayback::SetMute 0x%08x vol (%d)", this, aMute);
+
+ TBool changed( EFalse );
+ // Change MMF Audio player's volume
+ if ( EStateInitialised == iState )
+ {
+ TInt currentVolume(0);
+ iPlayer->GetVolume(currentVolume);
+ if ( aMute && currentVolume != 0 )
+ {
+ iVolume = currentVolume;
+ iPlayer->SetVolume(0);
+ changed = ETrue;
+ }
+ else if ( !aMute && currentVolume == 0 ) // UnMute
+ {
+ iPlayer->SetVolume(iVolume);
+ changed = ETrue;
+ }
+ }
+
+ // Change setting in cenrep
+ TBool currentMute( EFalse );
+ MPX_TRAPD( muteError, currentMute = iMuteWatcher->CurrentValueL() );
+ if ( muteError == KErrNone )
+ {
+ if ( aMute && !currentMute )
+ {
+ MPX_TRAP( muteError, iMuteWatcher->SetValueL( aMute ) );
+ }
+ else if ( !aMute && currentMute )
+ {
+ MPX_TRAP( muteError, iMuteWatcher->SetValueL( aMute ) );
+ }
+ }
+
+ // Notify observer if value changed
+ if ( changed )
+ {
+ iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPMuteChanged,
+ aMute,
+ KErrNone);
+ }
+
+ MPX_DEBUG3("<--CMPXLocalAudioPlayback::SetMute 0x%08x vol (%d)", this, aMute);
+ }
+
+// ----------------------------------------------------------------------------
+// Consumes the rights for the current media
+// ----------------------------------------------------------------------------
+//
+void CMPXLocalAudioPlayback::ConsumeRightsL(ContentAccess::TIntent aIntent)
+ {
+ MPX_FUNC("CMPXLocalAudioPlayback::ConsumeRightsL()");
+ // Fix for error: PNUI-7Q8GL6
+ // Normally,this case does not happen.
+ // In EStateInitialising state,consumerights is forbidden.
+ if ( iState == EStateInitialising )
+ {
+ return;
+ }
+ if ( iPlayer )
+ {
+ MMMFDRMCustomCommand* drmCustom = iPlayer->GetDRMCustomCommand();
+ if ( drmCustom )
+ {
+ switch ( aIntent )
+ {
+ case ContentAccess::EPlay:
+ case ContentAccess::EStop:
+ case ContentAccess::EPause:
+ case ContentAccess::EContinue:
+ {
+ break;
+ }
+ default:
+ {
+ aIntent = ContentAccess::EUnknown;
+ iConsumeStarted = EFalse;
+ break;
+ }
+ }
+ TInt returnCode( drmCustom->ExecuteIntent(aIntent) );
+ MPX_DEBUG2("CMPXLocalAudioPlayback::ConsumeRightsL() ExecuteIntent return (%d)", returnCode);
+ User::LeaveIfError(returnCode);
+ }
+ }
+ }
+// End of file