/*
* 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};
//_LIT(KWmaExtension, ".wma");
//_LIT(KRaExtension, ".ra");
// ============================ 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)
{
TRAPD( drmErr, ConsumeRightsL( ContentAccess::EContinue ) );
if ( drmErr == KErrCANoRights )
{
iDrmMediaUtility->Close();
iPlayer->Stop();
iIsPlaying = EFalse;
iAudioEffects->DestroyAudioEffect();
iPlayer->Close();
iObs->HandlePluginEvent(
MMPXPlaybackPluginObserver::EPStopped, 0,
drmErr);
iFile.Close();
iState = EStateNotInitialised;
iObs->HandlePluginEvent(
MMPXPlaybackPluginObserver::EPClosed,
EPbCmdStop, drmErr);
iClosedByAudioPolicy = EFalse;
break;
}
}
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);
//Handle error of license expired when tapping the progress playing bar
TRAPD( drmErr, ConsumeRightsL( ContentAccess::EContinue ) );
if ( drmErr == KErrCANoRights )
{
iDrmMediaUtility->Close();
iPlayer->Stop();
iIsPlaying = EFalse;
iAudioEffects->DestroyAudioEffect();
iPlayer->Close();
iObs->HandlePluginEvent(
MMPXPlaybackPluginObserver::EPStopped, 0, drmErr);
iFile.Close();
iState = EStateNotInitialised;
iObs->HandlePluginEvent(
MMPXPlaybackPluginObserver::EPClosed, EPbCmdStop,
drmErr);
iClosedByAudioPolicy = EFalse;
return;
}
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