Add William's draft of mediaclientaudio stub.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/MediaClientAudio.mmp Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,60 @@
+// Copyright (c) 2002-2009 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:
+// mediaclientaudio.dll Media Server audio compatibility library
+//
+//
+
+/**
+ @file
+*/
+
+#define KSharedLibraryUidDefine 268435597
+#define KUidMediaServerClientAudioDllUnicodeDefine 268450194
+
+target stem_mediaclientaudio.dll
+NOEXPORTLIBRARY
+CAPABILITY ALL -TCB
+targettype DLL
+UID KSharedLibraryUidDefine KUidMediaServerClientAudioDllUnicodeDefine
+VENDORID 0x70000001
+UNPAGED
+
+USERINCLUDE .
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+// Real source /sf/os/mm/mmlibs/mmfw/src/Client/Audio/mmfclienttoneplayer.cpp
+SOURCEPATH .
+source mmfclienttoneplayer.cpp
+//source mmfclientaudioplayer.cpp
+
+library euser.lib
+
+#ifdef EABI
+DEFFILE MediaClientAudio.def
+#endif
+
+#ifdef WINSCW
+DEFFILE MEDIACLIENTAUDIO.DEF
+#endif
+
+nostrictdef
+
+start wins
+ baseaddress 0x4F2A0000
+end
+
+
+
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/mmfclientaudioplayer.cpp Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,2133 @@
+// Copyright (c) 2002-2009 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:
+//
+
+#include <bautils.h>
+#include <utf.h>
+#include <mmf/common/mmfpaniccodes.h>
+#include "mmfclientaudioplayer.h"
+#include "mmfclientutility.h"
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <mmf/common/mmfdurationinfocustomcommandsimpl.h>
+#include <mmf/common/mmfdurationinfocustomcommandsenums.h>
+#endif
+
+using namespace ContentAccess;
+
+// declared in the recorder module
+void Panic(TInt aPanicCode);
+
+void TMMFMessage::Complete(TInt aReason)
+ {
+ iMessage.Complete(aReason);
+ iAmCompleted = ETrue;
+ }
+
+/**
+Constructs and initialises a new instance of the audio player utility.
+
+The function leaves if the audio player utility object cannot be created.
+
+No callback notification is made upon completion of NewL().
+
+@param aCallback
+ The audio player observer interface.
+@param aPriority
+ The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
+ EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
+@param aPref
+ The Priority Preference - an additional audio policy parameter. The suggested default is
+ EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
+ values may be supported by given phones and/or platforms, but should not be depended upon by
+ portable code.
+
+@return A pointer to the new audio player utility object.
+
+Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
+several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
+the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
+Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
+vary between different phones. Portable applications are advised not to assume any specific behaviour.
+*/
+EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewL(MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority,
+ TInt aPref)
+ {
+ CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
+ CleanupStack::PushL(self);
+ self->iProperties = CMMFMdaAudioPlayerUtility::NewL(aCallback, aPriority, aPref);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Constructs and initialises a new instance of the audio player utility for playing sampled audio data
+from a file. The audio data must be in a supported format (e.g. WAV and AU).
+
+The function leaves if the audio player utility object cannot be created.
+
+When initialisation of the audio player utility is complete, successfully or otherwise, the callback
+function MMdaAudioPlayerCallback::MapcInitComplete() is called.
+
+@param aFileName
+ The full path name of the file containing the audio data.
+@param aCallback
+ The audio player observer interface.
+@param aPriority
+ The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
+ EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
+@param aPref
+ The Priority Preference - an additional audio policy parameter. The suggested default is
+ EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
+ values may be supported by given phones and/or platforms, but should not be depended upon by
+ portable code.
+@param aServer
+ Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
+
+@return A pointer to the new audio player utility object.
+
+Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
+several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
+the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
+Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
+vary between different phones. Portable applications are advised not to assume any specific behaviour.
+*/
+EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewFilePlayerL(const TDesC& aFileName,
+ MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority,
+ TInt aPref,
+ CMdaServer* /*aServer*/)
+ {
+ CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
+ CleanupStack::PushL(self);
+ self->iProperties = CMMFMdaAudioPlayerUtility::NewFilePlayerL(aFileName, aCallback, aPriority, aPref);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Constructs and initialises a new instance of the audio player utility for playing sampled audio data
+from a descriptor.
+
+The audio data must be in a supported format (e.g. WAV and AU).
+
+The function leaves if the audio player utility object cannot be created. When initialisation of the
+audio player utility is complete, successfully or otherwise, the callback function
+MMdaAudioPlayerCallback::MapcInitComplete() is called.
+
+@param aData
+ A descriptor containing the audio data. This descriptor must remain in existence for the
+ lifetime of this audio player utility object.
+@param aCallback
+ The audio player observer interface.
+@param aPriority
+ The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
+ EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
+@param aPref
+ The Priority Preference - an additional audio policy parameter. The suggested default is
+ EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
+ values may be supported by given phones and/or platforms, but should not be depended upon by
+ portable code.
+@param aServer
+ Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
+
+@return A pointer to the new audio player utility object.
+
+Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
+several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
+the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
+Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
+vary between different phones. Portable applications are advised not to assume any specific behaviour.
+*/
+EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewDesPlayerL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
+ {
+ CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
+ CleanupStack::PushL(self);
+ self->iProperties = CMMFMdaAudioPlayerUtility::NewDesPlayerL(aData, aCallback, aPriority, aPref);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Constructs and initialises a new instance of the audio player utility for playing sampled audio data
+from a read only descriptor.
+
+The audio data must be in a supported format (e.g. WAV and AU).
+
+The function leaves if the audio player utility object cannot be created. When initialisation of
+the audio player utility is complete, successfully or otherwise, the callback function
+MMdaAudioPlayerCallback::MapcInitComplete() is called.
+
+@param aData
+ A read only descriptor containing the audio data. This descriptor must remain in existence
+ for the lifetime of this audio player utility object.
+@param aCallback
+ The audio player observer interface.
+@param aPriority
+ The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
+ EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
+@param aPref
+ The Priority Preference - an additional audio policy parameter. The suggested default is
+ EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
+ values may be supported by given phones and/or platforms, but should not be depended upon by
+ portable code.
+@param aServer
+ Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
+
+@return A pointer to a new audio player utility.
+
+Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
+several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
+the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
+Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
+vary between different phones. Portable applications are advised not to assume any specific behaviour.
+*/
+EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
+ {
+ CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
+ CleanupStack::PushL(self);
+ self->iProperties = CMMFMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(aData, aCallback, aPriority, aPref);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CMdaAudioPlayerUtility::CMdaAudioPlayerUtility()
+ {
+ }
+
+/**
+Destructor.
+
+Frees all resources owned by the object prior to its destruction.
+*/
+CMdaAudioPlayerUtility::~CMdaAudioPlayerUtility()
+ {
+ delete iProperties;
+ }
+
+/**
+Ensures that any subsequent calls to OpenXYZ() will create controllers that
+share a heap.
+
+The default behaviour is that for each player utility a controller with its own heap
+is created. Each heap uses a chunk, so using this function avoids situations where
+the number of chunks per process is limited.
+The default behaviour is generally to be preferred, and should give lower overall
+memory usage. However, if many controllers are to be created for a particular thread,
+then this function should be used to prevent running out of heaps or chunks.
+
+@since 9.1
+*/
+EXPORT_C void CMdaAudioPlayerUtility::UseSharedHeap()
+ {
+ ASSERT(iProperties);
+ iProperties->UseSharedHeap();
+ }
+
+// 5.0 functions
+
+/**
+Begins playback of audio sample data at the current playback position using the current volume,
+gain and priority settings.
+
+When playing of the audio sample is complete, successfully or
+otherwise, the callback function
+MMdaAudioPlayerCallback::MapcPlayComplete() is
+called.
+
+If this function is called whilst already playing then
+MMdaAudioPlayerCallback::MapcPlayComplete will return with the
+error code KErrNotReady.
+
+@since 5.0
+*/
+void CMdaAudioPlayerUtility::Play()
+ {
+ ASSERT(iProperties);
+ iProperties->Play();
+ }
+
+/**
+Stops playback of the audio sample as soon as possible.
+
+If the audio sample is playing, playback is stopped as soon as
+possible. If playback is already complete, nothing further happens as
+a result of calling this function. The callback function
+MMdaAudioPlayerCallback::MapcPlayComplete() is not
+called.
+
+@since 5.0
+*/
+void CMdaAudioPlayerUtility::Stop()
+ {
+ ASSERT(iProperties);
+ iProperties->Stop();
+ }
+
+
+/**
+Changes the current playback volume to a specified value.
+
+The volume can be changed before or during playback and is effective
+immediately. The volume can be set to any value between zero (mute) and
+the maximum permissible volume (determined using MaxVolume()).
+
+@param aVolume
+ The volume setting. This can be any value from zero to
+ the value returned by a call to
+ CMdaAudioPlayerUtility::MaxVolume().
+ Setting a zero value mutes the sound. Setting the maximum
+ value results in the loudest possible sound. Values less
+ than zero would be set to zero and the values greater than
+ the maximum permitted volume would be set to the maximum volume.
+@return An error code indicating if the function call was successful. KErrNone on success,
+ otherwise another of the system-wide error codes.
+@panic EMMFMediaClientBadArgument is raised when the audio player utility is not initialised.
+
+@since 5.0
+*/
+TInt CMdaAudioPlayerUtility::SetVolume(TInt aVolume)
+ {
+ ASSERT(iProperties);
+ return iProperties->SetVolume(aVolume);
+ }
+
+/**
+Sets the number of times the audio sample is to be repeated during the
+playback operation.
+
+A period of silence can follow each playing of the sample. The audio
+sample can be repeated indefinitely.
+
+@param aRepeatNumberOfTimes
+ The number of times the audio sample, together with
+ the trailing silence, is to be repeated. If this is
+ set to KMdaRepeatForever, then the audio
+ sample, together with the trailing silence, is
+ repeated indefinitely or until Stop() is
+ called. If this is set to zero, then the audio sample
+ is not repeated.
+@param aTrailingSilence
+ The time interval of the trailing silence in microseconds.
+
+@since 5.0
+*/
+void CMdaAudioPlayerUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
+ {
+ ASSERT(iProperties);
+ iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
+ }
+
+/**
+Defines the period over which the volume level is to rise smoothly
+from nothing to the normal volume level.
+
+@param aRampDuration
+ The period over which the volume is to rise. A zero
+ value causes the audio sample to be played at the
+ normal level for the full duration of the playback. A
+ value which is longer than the duration of the audio
+ sample means that the sample never reaches its normal
+ volume level.
+
+@since 5.0
+*/
+void CMdaAudioPlayerUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+ {
+ ASSERT(iProperties);
+ iProperties->SetVolumeRamp(aRampDuration);
+ }
+
+/**
+Returns the duration of the audio sample in microseconds.
+
+@return The duration of the sample in microseconds.
+
+@since 5.0
+*/
+const TTimeIntervalMicroSeconds& CMdaAudioPlayerUtility::Duration()
+ {
+ ASSERT(iProperties);
+ return iProperties->Duration();
+ }
+
+/**
+Returns the duration of the audio sample in microseconds, and the duration state.
+
+@param aDuration
+ The duration of the sample in microseconds.
+@return The duration state
+
+@since 9.1
+*/
+EXPORT_C TMMFDurationInfo CMdaAudioPlayerUtility::Duration(TTimeIntervalMicroSeconds& aDuration)
+{
+ ASSERT(iProperties);
+ return iProperties->Duration(aDuration);
+}
+
+/**
+Returns an integer representing the maximum volume.
+
+This is the maximum value which can be passed to
+CMdaAudioPlayerUtility::SetVolume(). This value is platform
+independent, but is always greater than or equal to one.
+
+@return The maximum volume setting.
+@panic EMMFMediaClientPanicServerCommunicationProblem is raised when the audio player utility is not initialised.
+
+@since 5.0
+*/
+TInt CMdaAudioPlayerUtility::MaxVolume()
+ {
+ ASSERT(iProperties);
+ return iProperties->MaxVolume();
+ }
+
+// 7.0s functions
+
+/**
+Opens an audio clip from a file.
+
+The audio data must be in a supported format (for example, WAV or AU).
+
+This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
+
+@param aFileName
+ The file to open.
+@leave KErrNotReady
+ If a previous open statement is awaiting notification of completion.
+ opening the file
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const TDesC& aFileName)
+ {
+ ASSERT(iProperties);
+ iProperties->OpenFileL(aFileName);
+ }
+
+/**
+Opens an audio clip from a file.
+
+The audio data must be in a supported format (for example, WAV or AU).
+
+This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
+
+Note: it is generally advisable that the RFile is shared through the call RFs::ShareProtected().
+This allows the adaptation to pass it to another process, if that is required. This is particularly
+true of playing DRM encrypted files.
+
+@param aFile
+ The open shared session file handle to use
+@leave KErrBadHandle
+ If the file handle is not shared through the call RFs::ShareProtected(), and the adaptation needs it to be.
+@leave KErrNotReady
+ If a previous open statement is awaiting notification of completion.
+ opening the file
+*/
+EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const RFile& aFile)
+ {
+ ASSERT(iProperties);
+ RFile& file = const_cast<RFile&>(aFile);
+ TMMFileHandleSource tfs(file, KDefaultContentObject, EPlay);
+ iProperties->OpenFileL(tfs);
+ }
+
+/**
+Opens an audio clip from a file.
+
+The audio data must be in a supported format (for example, WAV or AU).
+
+This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
+
+@param aSource
+ The file to open or an open file handle to use
+@leave KErrNotReady
+ If a previous open statement is awaiting notification of completion.
+ opening the file
+*/
+EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const TMMSource& aSource)
+ {
+ ASSERT(iProperties);
+ iProperties->OpenFileL(aSource);
+ }
+
+/**
+Opens an audio clip from a descriptor.
+
+The audio data must be in a supported format (for example, WAV or AU).
+
+@param aDescriptor
+ A descriptor containing the audio clip.
+@leave KErrInUse
+ If a previous open statement is awaiting notification of completion.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::OpenDesL(const TDesC8& aDescriptor)
+ {
+ ASSERT(iProperties);
+ iProperties->OpenDesL(aDescriptor);
+ }
+
+/**
+Opens an audio clip from a URL.
+
+The audio data must be in a supported format (for example, WAV or AU).
+
+@param aUrl
+ The URL to open.
+@param aIapId
+ Internet access point(IAP) ID to use. KUseDefaultIap selects the default IAP.
+@param aMimeType
+ MIME type of the URL source.
+
+@leave KErrInUse
+ If a previous open statement is awaiting notification of completion.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::OpenUrlL(const TDesC& aUrl, const TInt aIapId /*=KUseDefaultIap*/, const TDesC8& aMimeType /*=KNullDesC8*/)
+ {
+ ASSERT(iProperties);
+ iProperties->OpenUrlL(aUrl, aIapId, aMimeType);
+ }
+
+/**
+Pauses the playback of the audio clip.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::Pause()
+ {
+ ASSERT(iProperties);
+ return iProperties->Pause();
+ }
+
+/**
+Closes the current audio clip (allowing another clip to be opened).
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::Close()
+ {
+ ASSERT(iProperties);
+ iProperties->Close();
+ }
+
+/**
+Returns the current playback position in microseconds from the start of the clip.
+
+@param aPosition
+ The current time position in microseconds from the start of the clip to the current
+ play position.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::GetPosition(TTimeIntervalMicroSeconds& aPosition)
+ {
+ ASSERT(iProperties);
+ return iProperties->GetPosition(aPosition);
+ }
+
+/**
+Sets the current playback position in microseconds from the start of the clip.
+
+@param aPosition
+ The position to move to in microseconds from the start of the clip.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
+ {
+ ASSERT(iProperties);
+ iProperties->SetPosition(aPosition);
+ }
+
+/**
+Sets the priority for playback. This is used to arbitrate between multiple
+objects trying to access a single sound device.
+
+@param aPriority
+ The Priority Value.
+@param aPref
+ The Priority Preference.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+
+@see CMdaAudioPlayerUtility::NewL()
+
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::SetPriority(TInt aPriority, TInt aPref)
+ {
+ ASSERT(iProperties);
+ return iProperties->SetPriority(aPriority, aPref);
+ }
+
+/**
+Returns the current playback volume.
+
+@param aVolume
+ A value between 0 and the maximum volume settings returned by MaxVolume().
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::GetVolume(TInt& aVolume)
+ {
+ ASSERT(iProperties);
+ return iProperties->GetVolume(aVolume);
+ }
+
+/**
+Returns the number of meta data entries in the current audio clip.
+
+@param aNumEntries
+ The number of meta data entries in the header of the current clip.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::GetNumberOfMetaDataEntries(TInt& aNumEntries)
+ {
+ ASSERT(iProperties);
+ return iProperties->GetNumberOfMetaDataEntries(aNumEntries);
+ }
+
+/**
+Returns the requested meta data entry.
+
+@param aMetaDataIndex
+ The index number of the meta data to retrieve.
+
+@return The requested meta data entry.
+@leave KErrNotFound
+ The meta data entry does not exist.
+@leave KErrNotImplemented
+ The controller does not support meta data information for this format.
+
+@since 7.0s
+*/
+EXPORT_C CMMFMetaDataEntry* CMdaAudioPlayerUtility::GetMetaDataEntryL(TInt aMetaDataIndex)
+ {
+ ASSERT(iProperties);
+ return iProperties->GetMetaDataEntryL(aMetaDataIndex);
+ }
+
+/**
+Defines a window on the audio sample data.
+
+The window is defined in terms of a start and end position.
+When the current playback position reaches the window end position, or Stop() is called, the
+current playback position is set to the window start position and playback stops.
+
+The current playback position is not affected by a call to SetPlayWindow() unless it is outside
+the new playback window, in which case it is set to the window start or end position depending
+on which one is closer.
+
+The window persists until ClearPlayWindow() is called.
+Loading new audio sample data without adjusting or clearing the window will result in
+playback errors if the window is outside the new data.
+
+@param aStart
+ The position defining the start of the window, measured in microseconds. If this value is less
+ than zero, it is set to zero. If this value is greater than aEnd, then it is swapped with aEnd.
+@param aEnd
+ The position defining the end of the window, measured in microseconds. If this value is greater
+ than the value returned by Duration(), it is set to the value of Duration(). If this value is
+ less than aStart, then it is swapped with aStart.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aStart,
+ const TTimeIntervalMicroSeconds& aEnd)
+ {
+ ASSERT(iProperties);
+ return iProperties->SetPlayWindow(aStart, aEnd);
+ }
+
+/**
+Clears the current playback window.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::ClearPlayWindow()
+ {
+ ASSERT(iProperties);
+ return iProperties->ClearPlayWindow();
+ }
+
+/**
+Sets the current playback balance.
+
+@param aBalance
+ A value between KMMFBalanceMaxLeft
+ and KMMFBalanceMaxRight. The default value is
+ KMMFBalanceCenter.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::SetBalance(TInt aBalance /*= KMMFBalanceCenter*/)
+ {
+ ASSERT(iProperties);
+ return iProperties->SetBalance(aBalance);
+ }
+
+/**
+ * Returns The current playback balance. This function may not return the same value
+ * as passed to SetBalance depending on the internal implementation in
+ * the underlying components.
+ *
+ * @param aBalance
+ * A value between KMMFBalanceMaxLeft
+ * and KMMFBalanceMaxRight.
+ *
+ * @return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ * another of the system-wide error codes.
+ *
+ * @since 7.0s
+ */
+EXPORT_C TInt CMdaAudioPlayerUtility::GetBalance(TInt& aBalance)
+ {
+ ASSERT(iProperties);
+ return iProperties->GetBalance(aBalance);
+ }
+
+/**
+Returns the controller implementation information associated with the current controller.
+
+@return The controller implementation structure
+
+@since 7.0s
+*/
+EXPORT_C const CMMFControllerImplementationInformation& CMdaAudioPlayerUtility::ControllerImplementationInformationL()
+ {
+ ASSERT(iProperties);
+ return iProperties->ControllerImplementationInformationL();
+ }
+
+/**
+Registers callback object to receive notifications of audio loading/rebuffering.
+
+@param aCallback
+ The object to receive audio loading notifications.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aCallback)
+ {
+ ASSERT(iProperties);
+ iProperties->RegisterForAudioLoadingNotification(aCallback);
+ }
+
+/**
+Returns the current progress of audio loading.
+
+@param aPercentageProgress
+ The percentage of the audio clip loaded.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::GetAudioLoadingProgressL(TInt& aPercentageProgress)
+ {
+ ASSERT(iProperties);
+ iProperties->GetAudioLoadingProgressL(aPercentageProgress);
+ }
+
+/**
+Sends a synchronous custom command to the controller.
+
+@param aDestination
+ The destination of the message, consisting of the UID of
+ the interface of this message.
+@param aFunction
+ The function number to indicate which function is to be called
+ on the interface defined in the aDestination parameter.
+@param aDataTo1
+ A reference to the first chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+@param aDataTo2
+ A reference to the second chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+@param aDataFrom
+ A reference to an area of memory to which the controller framework will
+ write any data to be passed back to the client. Can't be KNullDesC8.
+
+@return The result of the request. Exact range of values is dependent on the interface.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
+ {
+ ASSERT(iProperties);
+ return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
+ }
+
+/**
+Sends a synchronous custom command to the controller.
+
+@param aDestination
+ The destination of the message, consisting of the UID of
+ the interface of this message.
+@param aFunction
+ The function number to indicate which function is to be called
+ on the interface defined in the aDestination parameter.
+@param aDataTo1
+ A reference to the first chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+@param aDataTo2
+ A reference to the second chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+
+@return The result of the request. Exact range of values is dependent on the interface.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
+ {
+ ASSERT(iProperties);
+ return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
+ }
+
+/**
+Sends an asynchronous custom command to the controller.
+
+Note:
+This method will return immediately. The RunL of the active object owning the
+aStatus parameter will be called when the command is completed by the
+controller framework.
+
+@param aDestination
+ The destination of the message, consisting of the uid of
+ the interface of this message.
+@param aFunction
+ The function number to indicate which function is to be called
+ on the interface defined in the aDestination parameter.
+@param aDataTo1
+ A reference to the first chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+@param aDataTo2
+ A reference to the second chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+@param aDataFrom
+ A reference to an area of memory to which the controller framework will
+ write any data to be passed back to the client. Can't be KNullDesC8."
+@param aStatus
+ The TRequestStatus of an active object. This will contain the
+ result of the request on completion. The exact range of
+ result values is dependent on the interface.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
+ {
+ ASSERT(iProperties);
+ iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
+ }
+
+/**
+Sends an asynchronous custom command to the controller.
+
+Note:
+This method will return immediately. The RunL of the active object owning the
+aStatus parameter will be called when the command is completed by the
+controller framework.
+
+@param aDestination
+ The destination of the message, consisting of the uid of
+ the interface of this message.
+@param aFunction
+ The function number to indicate which function is to be called
+ on the interface defined in the aDestination parameter.
+@param aDataTo1
+ A reference to the first chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+@param aDataTo2
+ A reference to the second chunk of data to be copied to the controller
+ framework. The exact contents of the data are dependent on the
+ interface being called. Can be KNullDesC8.
+@param aStatus
+ The TRequestStatus of an active object. This will contain the
+ result of the request on completion. The exact range of
+ result values is dependent on the interface.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
+ {
+ ASSERT(iProperties);
+ iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
+ }
+
+/**
+Returns the bit rate of the audio clip.
+
+@param aBitRate
+ The bit rate of the audio clip
+
+@return An error code indicating if the function call was successful. KErrNone on success,
+ otherwise another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::GetBitRate(TUint& aBitRate)
+ {
+ ASSERT(iProperties);
+ return iProperties->GetBitRate(aBitRate);
+ }
+
+/**
+Gets a controller's DRM custom command implementation.
+
+@return A pointer to a controller's DRM custom command implementation, or NULL if the
+controller does not support it.
+*/
+EXPORT_C MMMFDRMCustomCommand* CMdaAudioPlayerUtility::GetDRMCustomCommand()
+ {
+ ASSERT(iProperties);
+ return iProperties->GetDRMCustomCommand();
+ }
+
+/**
+Registers the Event for Notification when resource is avaliable.
+
+@param aCallback
+ The audio outputstream observer interface..
+
+@param aNotificationEventUid
+ The Event for which the client is registered.
+
+@param aNotificationRegistrationData
+ Notification registration specific data.
+
+@return An error code indicating if the registration was successful. KErrNone on success,
+ otherwise another of the system-wide error codes.
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,TUid aNotificationEventUid,const TDesC8& aNotificationRegistrationData)
+ {
+ ASSERT(iProperties);
+ return iProperties->RegisterAudioResourceNotification(aCallback,aNotificationEventUid,aNotificationRegistrationData);
+ }
+
+/**
+Cancels the registered notification event.
+
+@param aNotificationEventUid
+ The Event to notify the client.
+
+@return An error code indicating if the registration was successful. KErrNone on success,
+ otherwise another of the system-wide error codes.
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::CancelRegisterAudioResourceNotification(TUid aNotificationEventUid)
+ {
+ ASSERT(iProperties);
+ return iProperties->CancelRegisterAudioResourceNotification(aNotificationEventUid);
+ }
+
+/**
+Waits for the client to resume the play even after the default timer expires.
+
+@return An error code indicating if the registration was successful. KErrNone on success,
+ otherwise another of the system-wide error codes.
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::WillResumePlay()
+ {
+ ASSERT(iProperties);
+ return iProperties->WillResumePlay();
+ }
+
+
+/**
+Set the priority of the controller's sub thread.
+
+This can be used to increase the responsiveness of the audio plugin to minimise
+any lag in processing. This function should be used with care as it may have knock-on
+effects elsewhere in the system.
+
+@param aPriority
+ The TThreadPriority that the thread should run under. The default is EPriorityNormal.
+@return TInt
+ A standard error code: KErrNone if successful, KErrNotReady if the thread does not have a
+ valid handle.
+*/
+EXPORT_C TInt CMdaAudioPlayerUtility::SetThreadPriority(const TThreadPriority& aPriority) const
+ {
+ ASSERT(iProperties);
+ return iProperties->SetThreadPriority(aPriority);
+ }
+
+
+
+
+CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewL(MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority,
+ TInt aPref)
+ {
+ CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewFilePlayerL(const TDesC& aFileName,
+ MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority,
+ TInt aPref,
+ CMdaServer* /*aServer*/)
+ {
+ CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ TMMFileSource filesource(aFileName, KDefaultContentObject, EPlay);
+ self->OpenFileL(filesource);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewDesPlayerL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
+ {
+ CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ self->OpenDesL(aData);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
+ {
+ CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ self->OpenDesL(aData);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CMMFMdaAudioPlayerUtility::UseSharedHeap()
+ {
+ iFindAndOpenController->UseSharedHeap();
+ }
+
+// CMMFMdaAudioPlayerUtility
+CMMFMdaAudioPlayerUtility::~CMMFMdaAudioPlayerUtility()
+ {
+
+ delete iControllerImplementationInformation;
+ delete iAsyncCallBack;
+ delete iRepeatTrailingSilenceTimer;
+ delete iFindAndOpenController;
+ delete iControllerEventMonitor;
+ iMediaIds.Close();
+ iController.Close();
+ }
+
+CMMFMdaAudioPlayerUtility::CMMFMdaAudioPlayerUtility(MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref) :
+ iCallback(aCallback),
+ iAudioPlayDeviceCommands(iController),
+ iAudioPlayControllerCommands(iController),
+ iNotificationRegistrationCommands(iController),
+ iDRMCustomCommands(iController),
+ iAudioPlayControllerSetRepeatsCommands(iController)
+ {
+ iState = EStopped;
+ iPrioritySettings.iPriority = aPriority;
+ iPrioritySettings.iPref = aPref;
+ iPlayStart = TTimeIntervalMicroSeconds(0);
+ iPlayEnd = TTimeIntervalMicroSeconds(0);
+ iPlayWindowSet = ENone;
+ iEventHolder = KNullUid;
+ }
+
+void CMMFMdaAudioPlayerUtility::ConstructL()
+ {
+ 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 CMMFMdaAudioPlayerUtility::MfaocComplete(
+ TInt& aError,
+ RMMFController* /*aController*/,
+ TUid aControllerUid,
+ TMMFMessageDestination* /*aSourceHandle*/,
+ TMMFMessageDestination* /*aSinkHandle*/)
+ {
+ if (aError == KErrNone)
+ {
+ iControllerUid = aControllerUid;
+
+ // Get the clip duration
+ iDuration = TTimeIntervalMicroSeconds(0);
+ aError = iController.GetDuration(iDuration);
+
+ // If an error occurred during GetDuration, may try for next controller, if present.
+ if (aError != KErrNone)
+ {
+ iControllerEventMonitor->Cancel();
+
+ if (iFindAndOpenController)
+ {
+ if(iFindAndOpenController-> ControllerIndex() < (iFindAndOpenController->ControllerCount())-1)
+ {
+ return; //actually tries to load next controllers, if there are other controllers selected in the controller list
+ }
+ }
+
+ iController.Close(); // otherwise close the controller
+ }
+
+ if (iFindAndOpenController)
+ {
+ iFindAndOpenController->Close();
+ }
+ }
+
+ iAsyncCallBack->InitComplete(aError, iDuration);
+ }
+
+/**
+ Open an audio clip from a file
+ @param "const TFileSource& aFileSource" "the file to open"
+ @leave "" "Leaves on an error opening the file
+ @since version 5.0
+*/
+void CMMFMdaAudioPlayerUtility::OpenFileL(const TDesC& aFileName)
+ {
+ TMMFileSource filesource(aFileName, KDefaultContentObject, EPlay);
+ OpenFileL(filesource);
+ }
+
+/**
+ Open an audio clip from a file
+ @param "const RFile& aFile" "the shared session file handle to open"
+ @leave "" "KErrBadHandle if the file handle is not shared through the call RFs::ShareProtected(), and the underlying CAF layer needs it to be.
+ @leave "" "Leaves on an error opening the file
+ @since version 5.0
+*/
+void CMMFMdaAudioPlayerUtility::OpenFileL(const RFile& aFile)
+ {
+ RFile& file = const_cast<RFile&>(aFile);
+ TMMFileHandleSource filesource(file, KDefaultContentObject, EPlay);
+ OpenFileL(filesource);
+ }
+
+void CMMFMdaAudioPlayerUtility::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(
+ TMMFileHandleSource(fileHandle, aSource.UniqueId(), aSource.Intent(), aSource.IsUIEnabled()),
+ CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
+
+ }
+ if (aSource.SourceType()==KUidMMFileSource)
+ {
+ const TDesC& fileName = static_cast<const TMMFileSource&>(aSource).Name();
+ iFindAndOpenController->ConfigureSourceSink(
+ TMMFileSource(fileName, aSource.UniqueId(), aSource.Intent(), aSource.IsUIEnabled()),
+ CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
+ }
+
+ iFindAndOpenController->OpenByFileSource(aSource);
+ }
+
+/**
+ Open an audio clip from a descriptor
+ @param "const TDesC8& aDescriptor" "the descriptor containing the clip"
+ @leave "" "Leaves on an error opening the descriptor"
+ @since version 5.0
+*/
+void CMMFMdaAudioPlayerUtility::OpenDesL(const TDesC8& aDescriptor)
+ {
+ // 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(KErrInUse);
+
+ iFindAndOpenController->ConfigureSourceSink(
+ CMMFFindAndOpenController::TSourceSink(KUidMmfDescriptorSource,
+ CMMFFindAndOpenController::GetConfigDescriptor(aDescriptor)),
+ CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
+ iFindAndOpenController->OpenByDescriptor(aDescriptor);
+ }
+
+/**
+ Open an audio clip from a Url
+ @param "const TDesC& aUrl" "the url reference to the clip"
+ @leave "" "Leaves on an error opening the url"
+ @since version 7.0s
+*/
+void CMMFMdaAudioPlayerUtility::OpenUrlL(const TDesC& aUrl, const TInt aIapId, const TDesC8& aMimeType)
+ {
+ // 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(KErrInUse);
+
+ CBufFlat* urlCfgBuffer = NULL;
+ CMMFFindAndOpenController::GetConfigUrlL(urlCfgBuffer, aUrl, aIapId);
+
+ iFindAndOpenController->ConfigureSourceSink(
+ CMMFFindAndOpenController::TSourceSink(KUidMmfUrlSource, urlCfgBuffer->Ptr(0)),
+ CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
+ iFindAndOpenController->OpenByUrl(aUrl, aIapId, aMimeType);
+ delete urlCfgBuffer;
+ }
+
+/**
+Begins playback of the initialised audio sample at the current volume
+and priority levels.
+
+When playing of the audio sample is complete, successfully or
+otherwise, the callback function
+MMdaAudioPlayerCallback::MapcPlayComplete() is
+called.
+
+If this function is called whilst already playing then
+MMdaAudioPlayerCallback::MapcPlayComplete will return with the
+error code KErrNotReady.
+
+@since 5.0
+*/
+void CMMFMdaAudioPlayerUtility::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
+ if(iState != EPaused)
+ {
+ iNumberOfTimesPlayed = 0;
+ if(iNumberOfTimesToRepeat>0 || iNumberOfTimesToRepeat == KMdaRepeatForever)
+ {
+ TInt err = iAudioPlayControllerSetRepeatsCommands.SetRepeats(iNumberOfTimesToRepeat, iTrailingSilence);
+ if(err==KErrNone)
+ {
+ iNumberOfTimesToRepeat = 0;
+ iTrailingSilence = 0;
+ }
+ //Controller not supporting setrepeats custom command is not a real error
+ //we revert back to playerutility's loop play implementation in that case
+ }
+ }
+
+ DoPlay();
+ }
+
+void CMMFMdaAudioPlayerUtility::DoPlay()
+ {
+#if defined(__AUDIO_PROFILING)
+ RDebug::ProfileStart(4);
+#endif // defined(__AUDIO_PROFILING)
+ TInt err = KErrNone;
+ if (iState != EPaused || iRepeatCancelled)
+ {
+ err = iController.Prime();
+ iRepeatCancelled = EFalse;
+
+#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;
+
+ if(iEventHolder != KNullUid)
+ {
+ err = iNotificationRegistrationCommands.RegisterAsClient(iEventHolder,iNotificationDataHolder);
+ iEventHolder = KNullUid;
+ iNotificationDataHolder = KNullDesC8;
+ if(err == KErrNotSupported)
+ {
+ return;
+ }
+ if(err != KErrNone)
+ {
+ iController.Stop();
+ iAsyncCallBack->PlayComplete(err);
+ }
+ }
+ }
+
+/**
+Stops playback of the audio sample as soon as possible.
+
+If the audio sample is playing, playback is stopped as soon as
+possible. If playback is already complete, nothing further happens as
+a result of calling this function. The callback function
+MMdaAudioPlayerCallback::MapcPlayComplete() is not
+called.
+
+@since 5.0
+*/
+void CMMFMdaAudioPlayerUtility::Stop()
+ {
+
+ if (iState==EStopped)
+ {
+ // resetting the position to the start.
+ //if any position change in stoped state
+ iPosition = iPlayStart;
+ return;
+ }
+
+ 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;
+ }
+
+ }
+
+/**
+ *
+ * Pauses playback of the audio clip
+ * @return One of the system-wide error codes
+ * @since 7.0s
+ */
+TInt CMMFMdaAudioPlayerUtility::Pause()
+ {
+ TInt err = KErrNone;
+ if(iRepeatTrailingSilenceTimer->IsActive())
+ {
+ iRepeatTrailingSilenceTimer->Cancel();
+ iRepeatCancelled = ETrue;
+ iState = EPaused;
+ return KErrNone;
+ }
+ if (iState==EPlaying)
+ {
+ err = iController.Pause();
+ if (!err || err==KErrNotReady)
+ err = iController.GetPosition(iPosition);
+ iState = EPaused;
+ }
+ return err;
+ }
+
+/**
+ *
+ * Closes the current audio clip (allowing another clip to be opened)
+ *
+ * @since 7.0s
+ */
+void CMMFMdaAudioPlayerUtility::Close()
+ {
+ // Reset the audio player state.
+ Stop();
+ iControllerEventMonitor->Cancel();
+ iController.Close();
+ if (iFindAndOpenController)
+ iFindAndOpenController->Close();
+ if(iControllerImplementationInformation)
+ {
+ delete iControllerImplementationInformation;
+ iControllerImplementationInformation = NULL;
+ }
+ iControllerUid = KNullUid;
+ }
+
+
+/**
+Changes the current playback volume to a specified value.
+
+The volume can be changed before or during playback and is effective
+immediately.
+
+@param aVolume
+ The volume setting. This can be any value from zero to
+ the value returned by a call to
+ CMdaAudioPlayerUtility::MaxVolume().
+ Setting a zero value mutes the sound. Setting the
+ maximum value results in the loudest possible sound.
+@return An error code indicating if the function call was successful. KErrNone on success,
+ otherwise another of the system-wide error codes.
+@panic EMMFMediaClientBadArgument is raised when the audio player utility is not initialised.
+
+@since 5.0
+*/
+TInt CMMFMdaAudioPlayerUtility::SetVolume(TInt aVolume)
+ {
+ TInt err = iAudioPlayDeviceCommands.SetVolume(aVolume);
+ if (err == KErrArgument)
+ {
+ TInt maxVolume = MaxVolume();
+ if (aVolume < 0)
+ {
+ aVolume = 0;
+ }
+ else if (aVolume > maxVolume)
+ {
+ aVolume = maxVolume;
+ }
+ err = iAudioPlayDeviceCommands.SetVolume(aVolume);
+ }
+
+ return err;
+ }
+
+/**
+Sets the number of times the audio sample is to be repeated during the
+playback operation.
+
+A period of silence can follow each playing of the sample. The audio
+sample can be repeated indefinitely.
+
+@param aRepeatNumberOfTimes
+ The number of times the audio sample, together with
+ the trailing silence, is to be repeated. If this is
+ set to KMdaRepeatForever, then the audio
+ sample, together with the trailing silence, is
+ repeated indefinitely or until Stop() is
+ called. If this is set to zero, then the audio sample
+ is not repeated. The behaviour is undefined for
+ negative values (other than KMdaRepeatForever).
+@param aTrailingSilence
+ The time interval of the training silence.
+ Negative values will produce a panic USER 87.
+@since 5.0
+*/
+void CMMFMdaAudioPlayerUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
+ {
+ TInt err = iAudioPlayControllerSetRepeatsCommands.SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
+
+ if(err!=KErrNone)
+ {
+ iNumberOfTimesToRepeat = aRepeatNumberOfTimes;
+ iTrailingSilence = aTrailingSilence;
+ }
+ }
+
+/**
+Defines the period over which the volume level is to rise smoothly
+from nothing to the normal volume level.
+
+@param aRampDuration
+ The period over which the volume is to rise. A zero
+ value causes the audio sample to be played at the
+ normal level for the full duration of the playback. A
+ value which is longer than the duration of the audio
+ sample means that the sample never reaches its normal
+ volume level.
+
+@since 5.0
+*/
+void CMMFMdaAudioPlayerUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+ {
+ iAudioPlayDeviceCommands.SetVolumeRamp(aRampDuration);
+ }
+
+TInt CMMFMdaAudioPlayerUtility::SetPriority(TInt aPriority, TInt aPref)
+ {
+ iPrioritySettings.iPref = aPref;
+ iPrioritySettings.iPriority = aPriority;
+ iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings);
+
+ return iController.SetPrioritySettings(iPrioritySettings);
+ }
+
+/**
+Returns the duration of the audio sample.
+
+@return The duration in microseconds.
+
+@since 5.0
+*/
+const TTimeIntervalMicroSeconds& CMMFMdaAudioPlayerUtility::Duration()
+ {
+ TInt err = iController.GetDuration(iDuration);
+ if (err)
+ {
+ iDuration = 0;
+ }
+ return iDuration;
+ }
+
+/**
+Returns the duration of the audio sample in microseconds, and the duration state.
+
+@param aDuration
+ The duration of the sample in microseconds.
+@return The duration state
+
+@since 9.1
+*/
+TMMFDurationInfo CMMFMdaAudioPlayerUtility::Duration(TTimeIntervalMicroSeconds& aDuration)
+{
+ TPckgBuf<TMMFDurationInfo> pckg;
+ TMMFDurationInfo result = EMMFDurationInfoValid;
+
+ TMMFMessageDestinationPckg iDestinationPckg(TMMFMessageDestination(KUidInterfaceMMFDurationInfoControl, KMMFObjectHandleController));
+
+ TInt err = iController.CustomCommandSync(iDestinationPckg,
+ EMMFGetDurationInfo,
+ KNullDesC8,
+ KNullDesC8,
+ pckg );
+
+ switch ( err )
+ {
+ case KErrNone:
+ result = pckg();
+ break;
+
+ case KErrNotSupported:
+ // Custom command not implemented return EMMFDurationInfoValid as the default value
+ break;
+
+ default:
+ // Unknown error
+ result = EMMFDurationInfoUnknown;
+ break;
+ }
+
+ // Get the duration information to return in aDuration
+ // This is the intended behaviour regardless of what value err has
+ aDuration = Duration();
+ return result;
+}
+
+/**
+Returns an integer representing the maximum volume.
+
+This is the maximum value which can be passed to
+CMdaAudioPlayerUtility::SetVolume().
+
+@return The maximum volume. This value is platform dependent but is always greater than or equal
+ to one.
+@panic EMMFMediaClientPanicServerCommunicationProblem is raised when the audio player utility is not initialised.
+
+@since 5.0
+*/
+TInt CMMFMdaAudioPlayerUtility::MaxVolume()
+ {
+ TInt maxVolume = 0;
+#ifdef _DEBUG
+ TInt error =
+#endif
+ iAudioPlayDeviceCommands.GetMaxVolume(maxVolume);
+ __ASSERT_DEBUG(error==KErrNone, Panic(EMMFMediaClientPanicServerCommunicationProblem));
+ return maxVolume;
+ }
+
+void CMMFMdaAudioPlayerUtility::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 == KMMFEventCategoryAudioResourceAvailable)
+ {
+ if (iAudioResourceNotificationCallBack != NULL)
+ {
+ TBuf8<TMMFAudioConfig::KNotificationDataBufferSize> notificationData;
+ if (KErrNone != iNotificationRegistrationCommands.GetResourceNotificationData(aEvent.iEventType, notificationData))
+ {
+ notificationData.SetLength(0);
+ }
+ iAudioResourceNotificationCallBack->MarncResourceAvailable(aEvent.iEventType, notificationData);
+ }
+ }
+ else if (aEvent.iEventType == KMMFEventCategoryPlaybackComplete)
+ {
+ TInt oldState = iState;
+ //DevCR KEVN-7T5EHA: In case of pre-emption, we need to get the position from Controller, if that fails we reset the position to keep the original behaviour.
+ if(aEvent.iErrorCode == KErrInUse ||aEvent.iErrorCode == KErrDied ||aEvent.iErrorCode == KErrAccessDenied )
+ {
+ TInt err= iController.GetPosition(iPosition);
+ if(err != KErrNone)
+ {
+ iPosition = iPlayStart;
+ }
+ }
+ else
+ {
+ 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 play silence, then repeat the clip
+ iTrailingSilenceLeftToPlay = iTrailingSilence;
+ PlaySilence();
+ }
+ }
+ }
+ else
+ { //aEvent.iErrorCode != KErrNone
+ //if we weren't playing, don't advise Client.
+ iState = EStopped;
+ if (oldState == EPlaying)
+ {
+ iCallback.MapcPlayComplete(aEvent.iErrorCode);
+ }
+ }
+ }
+ else if(aEvent.iEventType == KMMFErrorCategoryControllerGeneralError)
+ {
+ TInt oldState = iState;
+ iPosition = iPlayStart;
+ 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 CMMFMdaAudioPlayerUtility::PlaySilence()
+ {
+ // iRepeatTrailingSilenceTimer->After() takes a TTimeIntervalMicroSeconds32
+ // so for longer periods of silence call it repeatedly with KMaxTInt lengths
+ TTimeIntervalMicroSeconds32 silence;
+ if (iTrailingSilenceLeftToPlay.Int64() > KMaxTInt)
+ {
+ silence = KMaxTInt;
+ iTrailingSilenceLeftToPlay = iTrailingSilenceLeftToPlay.Int64() - KMaxTInt;
+ }
+ else
+ {
+ silence = I64INT(iTrailingSilenceLeftToPlay.Int64());
+ iTrailingSilenceLeftToPlay = 0;
+ }
+ iRepeatTrailingSilenceTimer->After(silence);
+ }
+
+void CMMFMdaAudioPlayerUtility::RepeatTrailingSilenceTimerComplete()
+ {
+ if (iTrailingSilenceLeftToPlay.Int64() > 0)
+ {
+ PlaySilence();
+ }
+ else
+ {
+ // reset the position for subsequent plays
+ iPosition = iPlayStart;
+ DoPlay();
+ }
+ }
+
+/**
+ *
+ * Returns the current playback position in microseconds
+ *
+ * @param "TTimeIntervalMicroSeconds& aPosition"
+ * The current time position in microseconds from the start of the file
+ * @return "TInt" One of the global error codes
+ *
+ * @since 7.0s
+ */
+TInt CMMFMdaAudioPlayerUtility::GetPosition(TTimeIntervalMicroSeconds& aPosition)
+ {
+ TInt error = KErrNone;
+ if (iState==EPlaying)
+ error = iController.GetPosition(iPosition);
+ aPosition = iPosition;
+ return error;
+ }
+
+/**
+ *
+ * Set the current playback position in microseconds from the start of the file
+ *
+ * @param "TTimeIntervalMicroSeconds& aPosition"
+ * The position to move to in microseconds from the start of the file.
+ * If aPosition is negative, the position is set to the start of the file.
+ * If aPosition is greater than the file duration, the position is set to the
+ * end of the file.
+ *
+ * @since 7.0s
+ */
+void CMMFMdaAudioPlayerUtility::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)
+ {
+ iController.SetPosition(iPosition);
+ }
+// else if (iState == EPaused)
+// {
+// Stop(); // We call stop so that DevSound's internal buffers are reset
+// }
+ }
+
+/**
+Returns the current playback volume
+
+@param aVolume
+ A volume value between 0 and the value returned by MaxVolume().
+
+@return One of the global error codes.
+
+@since 7.0s
+*/
+TInt CMMFMdaAudioPlayerUtility::GetVolume(TInt& aVolume)
+ {
+ TInt error = iAudioPlayDeviceCommands.GetVolume(aVolume);
+ return error;
+ }
+
+/**
+ *
+ * Returns the number of meta data entries in the current clip
+ *
+ * @param "TInt& aNumEntries"
+ * The number of meta data entries in the header of the current clip
+ * @return "TInt" One of the global error codes
+ *
+ * @since 7.0s
+ */
+TInt CMMFMdaAudioPlayerUtility::GetNumberOfMetaDataEntries(TInt& aNumEntries)
+ {
+ TInt error = iController.GetNumberOfMetaDataEntries(aNumEntries);
+ return error;
+ }
+
+/**
+ *
+ * Returns the requested meta data entry
+ *
+ * @param "TInt aMetaDataIndex"
+ * The index number of the meta data to retrieve
+ * @return "CMMFMetaDataEntry*" The meta data entry to return
+ * @leave Leaves with KErrNotFound if the meta data entry does not exist or
+ * KErrNotImplemented if the controller does not support meta data
+ * information for this format. Other errors indicate more general system
+ * failure.
+ *
+ * @since 7.0s
+ */
+CMMFMetaDataEntry* CMMFMdaAudioPlayerUtility::GetMetaDataEntryL(TInt aMetaDataIndex)
+ {
+ return iController.GetMetaDataEntryL(aMetaDataIndex);
+ }
+
+/**
+ *
+ * Set the current playback window
+ *
+ * @param "const TTimeIntervalMicroSeconds& aStart"
+ * Start time of playback window relative to start of file
+ * @param "const TTimeIntervalMicroSeconds& aEnd"
+ * End time of playback window relative to start of file
+ *
+ * @return "TInt" One of the global error codes
+ *
+ * @since 7.0s
+ */
+TInt CMMFMdaAudioPlayerUtility::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;
+ }
+
+/**
+ *
+ * Clear the current playback window
+ *
+ * @return "TInt" One of the global error codes
+ *
+ * @since 7.0s
+ */
+TInt CMMFMdaAudioPlayerUtility::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;
+ }
+
+/**
+Sets the current playback balance
+
+@param aBalance
+ A value between KMMFBalanceMaxLeft and KMMFBalanceMaxRight. The default value is
+ KMMFBalanceCenter.
+
+@return One of the global error codes.
+
+@since 7.0s
+*/
+TInt CMMFMdaAudioPlayerUtility::SetBalance(TInt aBalance)
+ {
+ TInt err = iAudioPlayDeviceCommands.SetBalance(aBalance);
+ return err;
+ }
+
+/**
+Returns the bit rate of the audio clip.
+
+@param aBitRate
+ Bit rate of the audio clip.
+
+@return One of the global error codes.
+
+@since 7.0s
+*/
+TInt CMMFMdaAudioPlayerUtility::GetBitRate(TUint& aBitRate)
+ {
+ RMMFAudioControllerCustomCommands controller(iController);
+ TInt err = controller.GetSourceBitRate(aBitRate);
+ return err;
+ }
+
+const CMMFControllerImplementationInformation& CMMFMdaAudioPlayerUtility::ControllerImplementationInformationL()
+ {
+ if (!iControllerImplementationInformation)
+ {
+ if (iControllerUid==KNullUid)
+ User::Leave(KErrNotReady);
+ iControllerImplementationInformation = CMMFControllerImplementationInformation::NewL(iControllerUid);
+ }
+ return *iControllerImplementationInformation;
+ }
+
+void CMMFMdaAudioPlayerUtility::GetAudioLoadingProgressL(TInt& aPercentageProgress)
+ {
+ User::LeaveIfError(iAudioPlayControllerCommands.GetLoadingProgress(aPercentageProgress));
+ }
+
+TInt CMMFMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
+ {
+ return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
+ }
+
+TInt CMMFMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
+ {
+ return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
+ }
+
+void CMMFMdaAudioPlayerUtility::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 CMMFMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
+ {
+ iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
+ }
+
+/**
+Returns the current playback balance
+
+@param aBalance
+ A value between KMMFBalanceMaxLeft and KMMFBalanceMaxRight
+
+@return One of the global error codes.
+
+@since 7.0s
+*/
+TInt CMMFMdaAudioPlayerUtility::GetBalance(TInt& aBalance)
+ {
+ TInt err = iAudioPlayDeviceCommands.GetBalance(aBalance);
+ return err;
+ }
+
+MMMFDRMCustomCommand* CMMFMdaAudioPlayerUtility::GetDRMCustomCommand()
+ {
+ // TODO: check controller supports MMMFDRMCustomCommandImplementor
+ if (iDRMCustomCommands.IsSupported())
+ {
+ return static_cast<MMMFDRMCustomCommand*>(&iDRMCustomCommands);
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+void CMMFMdaAudioPlayerUtility::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aLoadingObserver)
+ {
+ iLoadingObserver = &aLoadingObserver;
+ }
+
+TInt CMMFMdaAudioPlayerUtility::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,
+ TUid aNotificationEventUid,
+ const TDesC8& aNotificationRegistrationData)
+ {
+ iAudioResourceNotificationCallBack = &aCallback;
+ TInt err = iNotificationRegistrationCommands.RegisterAsClient(aNotificationEventUid, aNotificationRegistrationData);
+ if(err == KErrNotReady)
+ {
+ iEventHolder = aNotificationEventUid;
+ iNotificationDataHolder = aNotificationRegistrationData;
+ return KErrNone;
+ }
+ iNotificationDataHolder = KNullDesC8;
+ iEventHolder = KNullUid;
+ return err;
+ }
+
+TInt CMMFMdaAudioPlayerUtility::CancelRegisterAudioResourceNotification(TUid aNotificationEventId)
+ {
+ TInt err = iNotificationRegistrationCommands.CancelRegisterAsClient(aNotificationEventId);
+ if(err == KErrNotReady)
+ {
+ if(aNotificationEventId != KMMFEventCategoryAudioResourceAvailable)
+ {
+ return KErrNotSupported;
+ }
+ if(iEventHolder == KNullUid)
+ {
+ return KErrCancel;
+ }
+ iEventHolder = KNullUid;
+ iNotificationDataHolder = KNullDesC8;
+ return KErrNone;
+ }
+ return err;
+ }
+
+TInt CMMFMdaAudioPlayerUtility::WillResumePlay()
+ {
+ return iNotificationRegistrationCommands.WillResumePlay();
+ }
+
+TInt CMMFMdaAudioPlayerUtility::SetThreadPriority(const TThreadPriority& aThreadPriority) const
+ {
+ return iController.SetThreadPriority(aThreadPriority);
+ }
+
+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(MMdaAudioPlayerCallback& aCallback)
+ {
+ return new(ELeave) CMMFMdaAudioPlayerCallBack(aCallback);
+ }
+
+CMMFMdaAudioPlayerCallBack::CMMFMdaAudioPlayerCallBack(MMdaAudioPlayerCallback& 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::RunL()
+ {
+ switch (iState)
+ {
+ case ECallbackInitComplete:
+ iCallback.MapcInitComplete(iError, iDuration);
+ break;
+ case ECallbackPlayComplete:
+ iCallback.MapcPlayComplete(iError);
+ break;
+ }
+ }
+
+void CMMFMdaAudioPlayerCallBack::DoCancel()
+ {
+ // Nothing to cancel
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/mmfclientaudioplayer.h Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,261 @@
+// Copyright (c) 2002-2009 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:
+//
+
+
+#ifndef MMFCLIENTAUDIOPLAY_H
+#define MMFCLIENTAUDIOPLAY_H
+
+#include <e32std.h>
+#include <e32base.h>
+#include <mdaaudiosampleplayer.h>
+#include <mmf/common/mmfcontroller.h>
+#include <mmf/server/mmffile.h>
+#include <mmf/server/mmfdes.h>
+#include <mmfcontrollerimplementationuids.hrh>
+#include <mmf/common/mmfstandardcustomcommands.h>
+#include <mmf/common/mmfdrmcustomcommands.h>
+#include "mmfclientutility.h"
+#include <mmf/common/mmfdurationinfocustomcommands.h>
+
+static const TUid KUidMmfAudioController = {KMmfUidControllerAudio};
+
+/**
+Mixin class to allow notification that the timed silence has finished.
+*/
+class MRepeatTrailingSilenceTimerObs
+ {
+public:
+ virtual void RepeatTrailingSilenceTimerComplete() = 0;
+ };
+
+/**
+CTimer-based active object that waits the requested time before notifying its observer.
+*/
+class CRepeatTrailingSilenceTimer : public CTimer
+ {
+public:
+ static CRepeatTrailingSilenceTimer* NewL(MRepeatTrailingSilenceTimerObs& aObs);
+ void RunL();
+private:
+ CRepeatTrailingSilenceTimer(MRepeatTrailingSilenceTimerObs& aObs);
+private:
+ MRepeatTrailingSilenceTimerObs& iObs;
+ };
+
+/**
+Active object utility class to allow the callback to be called asynchronously.
+This should help prevent re-entrant code in clients of the mediaframework.
+*/
+class CMMFMdaAudioPlayerCallBack : public CActive
+ {
+public:
+ enum TCallbackState {
+ ECallbackInitComplete,
+ ECallbackPlayComplete
+ };
+
+
+public:
+ static CMMFMdaAudioPlayerCallBack* NewL(MMdaAudioPlayerCallback& aCallback);
+ ~CMMFMdaAudioPlayerCallBack();
+ void InitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration);
+ void PlayComplete(TInt aError);
+private:
+ CMMFMdaAudioPlayerCallBack(MMdaAudioPlayerCallback& aCallback);
+ void RunL();
+ void DoCancel();
+private:
+ MMdaAudioPlayerCallback& iCallback;
+ TInt iError;
+ TTimeIntervalMicroSeconds iDuration;
+ TCallbackState iState;
+ };
+
+/**
+Concrete implementation of the CMdaAudioPlayerUtility API.
+@see CMdaAudioPlayerUtility
+*/
+class CMMFMdaAudioPlayerUtility;
+NONSHARABLE_CLASS( CMMFMdaAudioPlayerUtility ): public CBase,
+ public MMMFControllerEventMonitorObserver,
+ public MRepeatTrailingSilenceTimerObs,
+ public MMMFFindAndOpenControllerObserver
+ {
+friend class CMdaAudioPlayerUtility;
+// friends for Unit testing only
+friend class CTestStepUnitMMFAudClient;
+
+public:
+ enum TMMFAudioPlayerState
+ {
+ EStopped,
+ EOpening,
+ EPaused,
+ EPlaying
+ };
+public:
+ static CMMFMdaAudioPlayerUtility* NewFilePlayerL(const TDesC& aFileName,
+ MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority = EMdaPriorityNormal,
+ TInt aPref = EMdaPriorityPreferenceTimeAndQuality,
+ CMdaServer* aServer = NULL);
+ static CMMFMdaAudioPlayerUtility* NewDesPlayerL(const TDesC8& aData,
+ MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority = EMdaPriorityNormal,
+ TInt aPref = EMdaPriorityPreferenceTimeAndQuality,
+ CMdaServer* aServer = NULL);
+ static CMMFMdaAudioPlayerUtility* NewDesPlayerReadOnlyL(const TDesC8& aData,
+ MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority = EMdaPriorityNormal,
+ TInt aPref = EMdaPriorityPreferenceTimeAndQuality,
+ CMdaServer* aServer = NULL);
+
+ static CMMFMdaAudioPlayerUtility* NewL(MMdaAudioPlayerCallback& aCallback,
+ TInt aPriority = EMdaPriorityNormal,
+ TInt aPref = EMdaPriorityPreferenceTimeAndQuality);
+
+/**
+ Destructor
+*/
+ ~CMMFMdaAudioPlayerUtility();
+
+ void UseSharedHeap();
+
+ void OpenFileL(const TDesC& aFileName);
+ void OpenFileL(const RFile& aFile);
+ void OpenFileL(const TMMSource& aSource);
+
+ void OpenDesL(const TDesC8& aDescriptor);
+ void OpenUrlL(const TDesC& aUrl, TInt aIapId=KUseDefaultIap, const TDesC8& aMimeType = KNullDesC8);
+ void Play();
+ void Stop();
+ TInt SetVolume(TInt aVolume);
+ void SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence);
+ void SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration);
+ const TTimeIntervalMicroSeconds& Duration();
+ TInt MaxVolume();
+
+ // API Additions since version 7.0
+ TInt Pause();
+ void Close();
+ TInt GetPosition(TTimeIntervalMicroSeconds& aPosition);
+ void SetPosition(const TTimeIntervalMicroSeconds& aPosition);
+
+ TInt SetPriority(TInt aPriority, TInt aPref);
+ TInt GetVolume(TInt& aVolume);
+ TInt GetNumberOfMetaDataEntries(TInt& aNumEntries);
+ CMMFMetaDataEntry* GetMetaDataEntryL(TInt aMetaDataIndex);
+ TInt SetPlayWindow(const TTimeIntervalMicroSeconds& aStart,
+ const TTimeIntervalMicroSeconds& aEnd);
+ TInt ClearPlayWindow();
+ TInt SetBalance(TInt aBalance = KMMFBalanceCenter);
+ TInt GetBalance(TInt& aBalance);
+ TInt GetBitRate(TUint& aBitRate);
+
+ void RegisterForAudioLoadingNotification(MAudioLoadingObserver& aCallback);
+ void GetAudioLoadingProgressL(TInt& aPercentageProgress);
+ const CMMFControllerImplementationInformation& ControllerImplementationInformationL();
+
+ TInt RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,TUid aNotificationEventUid,const TDesC8& aNotificationRegistrationData = KNullDesC8);
+ TInt CancelRegisterAudioResourceNotification(TUid aNotificationEventId);
+ TInt WillResumePlay();
+ TInt CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom);
+ TInt CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2);
+ void CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus);
+ void CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus);
+
+ MMMFDRMCustomCommand* GetDRMCustomCommand();
+
+ TInt SetThreadPriority(const TThreadPriority& aThreadPriority) const;
+
+ TMMFDurationInfo Duration(TTimeIntervalMicroSeconds& aDuration);
+
+ // from MMMFControllerEventMonitorObserver
+ virtual void HandleEvent(const TMMFEvent& aEvent);
+ // from MRepeatTrailingSilenceTimerObs
+ virtual void RepeatTrailingSilenceTimerComplete();
+
+ // from MMMFFindAndOpenControllerObserver
+ virtual void MfaocComplete(
+ TInt& aError,
+ RMMFController* aController,
+ TUid aControllerUid,
+ TMMFMessageDestination* aSourceHandle,
+ TMMFMessageDestination* aSinkHandle);
+
+protected:
+ CMMFMdaAudioPlayerUtility(MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref);
+ void ConstructL();
+ void DoPlay();
+
+private:
+ void PlaySilence();
+
+private:
+ // last play window command
+ enum TPlayWindowCommand
+ {
+ ENone,
+ ESet,
+ EClear
+ };
+
+ MMdaAudioPlayerCallback& iCallback;
+ CMMFMdaAudioPlayerCallBack* iAsyncCallBack;
+ MAudioLoadingObserver* iLoadingObserver;
+ MMMFAudioResourceNotificationCallback* iAudioResourceNotificationCallBack;
+ RMMFController iController;
+ CMMFControllerEventMonitor* iControllerEventMonitor;
+ TMMFAudioPlayerState iState;
+ TTimeIntervalMicroSeconds iDuration; // Needed because of api "Duration()" that returns a reference
+ TMMFPrioritySettings iPrioritySettings;
+
+ TInt iNumberOfTimesPlayed;
+ TInt iNumberOfTimesToRepeat;
+ TTimeIntervalMicroSeconds iTrailingSilence;
+ TTimeIntervalMicroSeconds iTrailingSilenceLeftToPlay;
+ CRepeatTrailingSilenceTimer* iRepeatTrailingSilenceTimer;
+
+ // Source and sink handle info
+ TMMFMessageDestination iSourceHandle;
+ TMMFMessageDestination iSinkHandle;
+
+ // Custom command handlers
+ RMMFAudioPlayDeviceCustomCommands iAudioPlayDeviceCommands;
+ RMMFAudioPlayControllerCustomCommands iAudioPlayControllerCommands;
+ RMMFResourceNotificationCustomCommands iNotificationRegistrationCommands;
+ RMMFDRMCustomCommands iDRMCustomCommands;
+ RMMFAudioPlayControllerSetRepeatsCustomCommands iAudioPlayControllerSetRepeatsCommands;
+
+ // Current playback time so we can resume from where we were stopped
+ TTimeIntervalMicroSeconds iPosition;
+
+ // Play window start and end times and whether it has been set
+ TTimeIntervalMicroSeconds iPlayStart;
+ TTimeIntervalMicroSeconds iPlayEnd;
+ TPlayWindowCommand iPlayWindowSet;
+ RArray<TUid> iMediaIds;
+
+ CMMFControllerImplementationInformation* iControllerImplementationInformation;
+ TUid iControllerUid;
+
+ // utility class to find and open a suitable controller asynchronously
+ CMMFFindAndOpenController* iFindAndOpenController;
+ TUid iEventHolder;
+ TBuf8<256> iNotificationDataHolder;
+ TBool iRepeatCancelled;
+ };
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/mmfclienttoneplayer.cpp Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,1059 @@
+// Copyright (c) 2002-2009 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:
+//
+
+#include <mmf/common/mmfpaniccodes.h>
+
+#include "mmfclienttoneplayer.h"
+using namespace ContentAccess;
+enum TMmfMdaAudioToneUtility
+ {
+ EBadArgument,
+ EPostConditionViolation,
+ EPlayStartedCalledWithError
+ };
+
+void Panic(TInt aPanicCode)
+ {
+ _LIT(KMMFMediaClientAudioPanicCategory, "Stem_MMFAudioClient");
+ User::Panic(KMMFMediaClientAudioPanicCategory, aPanicCode);
+ }
+
+// Dummy DevSound class
+
+CDummyDevSound::CDummyDevSound()
+ : CTimer(EPriorityStandard)
+ {}
+
+CDummyDevSound* CDummyDevSound::NewL()
+ {
+ CDummyDevSound* self = new(ELeave) CDummyDevSound();
+ return self;
+ }
+
+void CDummyDevSound::InitializeL(MDevSoundObserver& aDevSoundObserver)
+ {
+ iObserver = &aDevSoundObserver;
+ iObserver->InitializeComplete(KErrNone);
+ }
+
+void CDummyDevSound::Play(const TTimeIntervalMicroSeconds& aDuration)
+ {
+ if (IsActive())
+ {
+ // currently playing - ignore the request?
+ return;
+ }
+ TTimeIntervalMicroSeconds32 d = I64LOW(aDuration.Int64());
+ if (d <= TTimeIntervalMicroSeconds32(0))
+ {
+ d = 10;
+ }
+ After(d);
+ }
+
+void CDummyDevSound::RunL()
+ {
+ RDebug::Printf("!Beep!\n");
+ iObserver->ToneFinished(KErrNone);
+ }
+
+/**
+Creates a new instance of the tone player utility.
+The default volume is set to MaxVolume() / 2.
+
+@param aObserver
+ A class to receive notifications from the tone player.
+@param aServer
+ This parameter is no longer used and should be NULL.
+
+@return A pointer to the new audio tone player utility object.
+
+@since 5.0
+*/
+EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* aServer /*= NULL*/)
+ {
+ return CMdaAudioToneUtility::NewL(aObserver, aServer, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality);
+ }
+
+/**
+Creates a new instance of the tone player utility.
+The default volume is set to MaxVolume() / 2.
+
+@param aObserver
+ A class to receive notifications from the tone player
+@param aServer
+ This parameter is no longer used and should be NULL
+@param aPriority
+ The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
+ EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
+@param aPref
+ The Priority Preference - an additional audio policy parameter. The suggested default is
+ EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
+ values may be supported by given phones and/or platforms, but should not be depended upon by
+ portable code.
+
+@return A pointer to the new audio tone player utility object.
+
+@since 5.0
+
+Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
+several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
+the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
+Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
+vary between different phones. Portable applications are advised not to assume any specific behaviour.
+*/
+EXPORT_C CMdaAudioToneUtility* CMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/,
+ TInt aPriority /*= EMdaPriorityNormal*/,
+ TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/)
+ {
+ CMdaAudioToneUtility* self = new(ELeave) CMdaAudioToneUtility();
+ CleanupStack::PushL(self);
+ self->iProperties = CMMFMdaAudioToneUtility::NewL(aObserver, NULL, aPriority, aPref);
+ CleanupStack::Pop(); //self
+ return self;
+ }
+
+/**
+Destructor. Frees any resources held by the tone player
+
+@since 5.0
+*/
+CMdaAudioToneUtility::~CMdaAudioToneUtility()
+ {
+ delete iProperties;
+ }
+
+/**
+Returns the current state of the audio tone utility.
+
+@return The state of the audio tone utility.
+
+@since 5.0
+*/
+TMdaAudioToneUtilityState CMdaAudioToneUtility::State()
+ {
+ ASSERT(iProperties);
+ return iProperties->State();
+ }
+
+/**
+Returns the maximum volume supported by the device. This is the maximum value which can be
+passed to CMdaAudioToneUtility::SetVolume().
+
+@return The maximum volume. This value is platform dependent but is always greater than or equal to one.
+
+@since 5.0
+*/
+TInt CMdaAudioToneUtility::MaxVolume()
+ {
+ ASSERT(iProperties);
+ return iProperties->MaxVolume();
+ }
+
+/**
+Returns an integer representing the current volume of the audio device.
+
+@return The current volume.
+
+@since 5.0
+*/
+TInt CMdaAudioToneUtility::Volume()
+ {
+ ASSERT(iProperties);
+ return iProperties->Volume();
+ }
+
+/**
+Changes the volume of the audio device.
+
+The volume can be changed before or during play and is effective
+immediately.
+
+@param aVolume
+ The volume setting. This can be any value from zero to
+ the value returned by a call to
+ CMdaAudioToneUtility::MaxVolume().
+ Setting a zero value mutes the sound. Setting the
+ maximum value results in the loudest possible sound.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::SetVolume(TInt aVolume)
+ {
+ ASSERT(iProperties);
+ iProperties->SetVolume(aVolume);
+ }
+
+/**
+Changes the clients priority.
+
+@param aPriority
+ The Priority Value.
+@param aPref
+ The Priority Preference.
+
+@see CMdaAudioToneUtility::NewL()
+
+@since 5.0
+
+*/
+void CMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref)
+ {
+ ASSERT(iProperties);
+ iProperties->SetPriority(aPriority, aPref);
+ }
+
+/**
+Changes the duration of DTMF tones, the gaps between DTMF tones and the
+pauses.
+
+@param aToneLength
+ The duration of the DTMF tone in microseconds.
+@param aToneOffLength
+ The gap between DTFM tones in microseconds.
+@param aPauseLength
+ Pauses in microseconds
+*/
+void CMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength,
+ TTimeIntervalMicroSeconds32 aToneOffLength,
+ TTimeIntervalMicroSeconds32 aPauseLength)
+ {
+ ASSERT(iProperties);
+ iProperties->SetDTMFLengths(aToneLength, aToneOffLength, aPauseLength);
+ }
+
+/**
+Sets the number of times the tone sequence is to be repeated during
+the play operation.
+
+A period of silence can follow each playing of the tone sequence. The
+tone sequence can be repeated indefinitely.
+
+@param aRepeatNumberOfTimes
+ The number of times the tone sequence, together with
+ the trailing silence, is to be repeated. If this is
+ set to KMdaRepeatForever, then the tone
+ sequence, together with the trailing silence, is
+ repeated indefinitely. The behaviour is undefined for values other than
+ KMdaRepeatForever, zero and positive.
+@param aTrailingSilence
+ The time interval of the training silence. The behaviour is undefined
+ for values other than zero and positive.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes,
+ const TTimeIntervalMicroSeconds& aTrailingSilence)
+ {
+ ASSERT(iProperties);
+ iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
+ }
+
+/**
+Defines the period over which the volume level is to rise smoothly
+from nothing to the normal volume level.
+
+@param aRampDuration
+ The period over which the volume is to rise. A zero
+ value causes the tone to be played at the normal level
+ for the full duration of the playback. A value which
+ is longer than the duration of the tone sequence means
+ that the tone never reaches its normal volume level.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+ {
+ ASSERT(iProperties);
+ iProperties->SetVolumeRamp(aRampDuration);
+ }
+
+/**
+Returns the number of available pre-defined tone sequences.
+
+@return The number of tone sequences. This value is implementation
+ dependent but is always greater than or equal to zero.
+
+@since 5.0
+*/
+TInt CMdaAudioToneUtility::FixedSequenceCount()
+ {
+ ASSERT(iProperties);
+ return iProperties->FixedSequenceCount();
+ }
+
+/**
+Returns the name assigned to a specific pre-defined tone sequence.
+
+@param aSequenceNumber
+ The index identifying the specific pre-defined tone sequence.
+ Index values are relative to zero. This can be any value from
+ zero to the value returned by a call to FixedSequenceCount() - 1.
+ The function raises a panic if sequence number is not within this
+ range.
+
+@see CMMFDevSound::FixedSequenceName(TInt aSequenceNumber)
+@see FixedSequenceCount()
+
+@return The name assigned to the tone sequence.
+
+@since 5.0
+*/
+const TDesC& CMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber)
+ {
+ ASSERT(iProperties);
+ return iProperties->FixedSequenceName(aSequenceNumber);
+ }
+
+/**
+Configures the audio tone player utility to play a single tone.
+
+This function is asynchronous. On completion, the observer callback
+function MMdaAudioToneObserver::MatoPrepareComplete() is
+called, indicating the success or failure of the configuration
+operation.The configuration operation can be cancelled by calling
+CMdaAudioToneUtility::CancelPrepare(). The configuration
+operation cannot be started if a play operation is in progress.
+
+@param aFrequency
+ The frequency (pitch) of the tone in Hz.
+@param aDuration
+ The duration of the tone in microseconds.
+@since 5.0
+*/
+void CMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
+ {
+ ASSERT(iProperties);
+ iProperties->PrepareToPlayTone(aFrequency, aDuration);
+ }
+
+/**
+Configures the audio tone player utility to play a dual tone.
+The generated tone consists of two sine waves of different
+frequencies summed together.
+
+This function is asynchronous. On completion, the observer callback
+function MMdaAudioToneObserver::MatoPrepareComplete() is
+called, indicating the success or failure of the configuration
+operation. The configuration operation can be cancelled by calling
+CMdaAudioToneUtility::CancelPrepare(). The configuration
+operation cannot be started if a play operation is in progress.
+
+@param aFrequencyOne
+ The first frequency (pitch) of the tone.
+@param aFrequencyTwo
+ The second frequency (pitch) of the tone.
+@param aDuration
+ The duration of the tone in microseconds.
+
+@since 7.0sy
+*/
+EXPORT_C void CMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
+ {
+ ASSERT(iProperties);
+ iProperties->PrepareToPlayDualTone(aFrequencyOne, aFrequencyTwo, aDuration);
+ }
+
+/**
+Configures the audio tone utility player to play a DTMF (Dual-Tone
+Multi-Frequency) string.
+
+This function is asynchronous. On completion, the observer callback
+function MMdaAudioToneObserver::MatoPrepareComplete() is
+called, indicating the success or failure of the configuration
+operation. The configuration operation can be cancelled by calling
+CMdaAudioToneUtility::CancelPrepare(). The configuration
+operation cannot be started if a play operation is in progress.
+
+@param aDTMF
+ A descriptor containing the DTMF string.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF)
+ {
+ ASSERT(iProperties);
+ iProperties->PrepareToPlayDTMFString(aDTMF);
+ }
+
+/**
+Configures the audio tone player utility to play a tone sequence
+contained in a descriptor.
+
+This function is asynchronous. On completion, the observer callback
+function MMdaAudioToneObserver::MatoPrepareComplete() is
+called, indicating the success or failure of the configuration
+operation. The configuration operation can be cancelled by calling
+CMdaAudioToneUtility::CancelPrepare(). The configuration
+operation cannot be started if a play operation is in progress.
+
+@param aSequence
+ The descriptor containing the tone sequence. The
+ format of the data is unspecified but is expected to
+ be platform dependent. A device might support more
+ than one form of sequence data.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence)
+ {
+ ASSERT(iProperties);
+ iProperties->PrepareToPlayDesSequence(aSequence);
+ }
+
+/**
+Configures the audio tone player utility to play a tone sequence
+contained in a file.
+
+This function is asynchronous. On completion, the observer callback
+function MMdaAudioToneObserver::MatoPrepareComplete() is
+called, indicating the success or failure of the configuration
+operation. The configuration operation can be cancelled by calling
+CMdaAudioToneUtility::CancelPrepare(). The configuration
+operation cannot be started if a play operation is in progress.
+
+@param aFileName
+ The full path name of the file containing the tone
+ sequence. The format of the data is unspecified but is
+ expected to be platform dependent. A device might
+ support more than one form of sequence data.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName)
+ {
+ ASSERT(iProperties);
+ iProperties->PrepareToPlayFileSequence(aFileName);
+ }
+
+/**
+Configures the audio tone player utility to play a tone sequence
+contained in a file.
+
+This function is asynchronous. On completion, the observer callback
+function MMdaAudioToneObserver::MatoPrepareComplete() is
+called, indicating the success or failure of the configuration
+operation. The configuration operation can be cancelled by calling
+CMdaAudioToneUtility::CancelPrepare(). The configuration
+operation cannot be started if a play operation is in progress.
+
+@param aFile
+ A handle to an open file containing the tone
+ sequence. The format of the data is unspecified but is
+ expected to be platform dependent. A device might
+ support more than one form of sequence data.
+
+@since 5.0
+*/
+EXPORT_C void CMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFile)
+ {
+ ASSERT(iProperties);
+ iProperties->PrepareToPlayFileSequence(aFile);
+ }
+
+
+/**
+Configures the audio tone player utility to play the specified
+pre-defined tone sequence.
+
+This function is asynchronous. On completion, the observer callback
+function MMdaAudioToneObserver::MatoPrepareComplete() is
+called, indicating the success or failure of the configuration
+operation. The configuration operation can be cancelled by calling
+CMdaAudioToneUtility::CancelPrepare(). The configuration
+operation cannot be started if a play operation is in progress.
+
+@param aSequenceNumber
+ An index into the set of pre-defined tone sequences.
+ This can be any value from zero to the value returned by a
+ call to FixedSequenceCount() - 1.
+ If the sequence number is not within this range, a panic will be
+ raised when Play() is called later.
+
+@see FixedSequenceCount()
+@see CMMFDevSound::PlayFixedSequenceL(TInt aSequenceNumber)
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber)
+ {
+ ASSERT(iProperties);
+ iProperties->PrepareToPlayFixedSequence(aSequenceNumber);
+ }
+
+/**
+Cancels the configuration operation.
+
+The observer callback function
+MMdaAudioToneObserver::MatoPrepareComplete() is not
+called.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::CancelPrepare()
+ {
+ ASSERT(iProperties);
+ iProperties->CancelPrepare();
+ }
+
+/**
+Plays the tone.
+
+The tone played depends on the current configuration.This function is
+asynchronous. On completion, the observer callback function
+MMdaAudioToneObserver::MatoPlayComplete() is called,
+indicating the success or failure of the play operation.The play
+operation can be cancelled by
+calling CMdaAudioToneUtility::CancelPlay().
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::Play()
+ {
+ ASSERT(iProperties);
+ iProperties->Play();
+ }
+
+EXPORT_C TInt CMdaAudioToneUtility::Pause()
+ {
+ ASSERT(iProperties);
+ return iProperties->Pause();
+ }
+
+EXPORT_C TInt CMdaAudioToneUtility::Resume()
+ {
+ ASSERT(iProperties);
+ return iProperties->Resume();
+ }
+
+/**
+Cancels the tone playing operation.
+
+The observer callback
+function MMdaAudioToneObserver::MatoPlayComplete() is not
+called.
+
+@since 5.0
+*/
+void CMdaAudioToneUtility::CancelPlay()
+ {
+ ASSERT(iProperties);
+ iProperties->CancelPlay();
+ }
+
+/**
+Sets the stereo balance for playback.
+
+@param aBalance
+ The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight.
+
+@return An error code indicating if the function call was successful. KErrNone on success, otherwise
+ another of the system-wide error codes.
+
+@since 7.0s
+*/
+EXPORT_C void CMdaAudioToneUtility::SetBalanceL(TInt aBalance /*=KMMFBalanceCenter*/)
+ {
+ ASSERT(iProperties);
+ iProperties->SetBalanceL(aBalance);
+ }
+
+/**
+ * Returns The current playback balance.This function may not return the same value
+ * as passed to SetBalanceL depending on the internal implementation in
+ * the underlying components.
+ *
+ * @return The balance. Should be between KMMFBalanceMaxLeft and KMMFBalanceMaxRight.
+ *
+ * @since 7.0s
+ */
+EXPORT_C TInt CMdaAudioToneUtility::GetBalanceL()
+ {
+ ASSERT(iProperties);
+ return iProperties->GetBalanceL();
+ }
+
+/**
+Retrieves a custom interface to the underlying device.
+
+@param aInterfaceId
+ The interface UID, defined with the custom interface.
+
+@return A pointer to the interface implementation, or NULL if the device does not
+ implement the interface requested. The return value must be cast to the
+ correct type by the user.
+*/
+EXPORT_C TAny* CMdaAudioToneUtility::CustomInterface(TUid aInterfaceId)
+ {
+ ASSERT(iProperties);
+ return 0;
+ }
+
+EXPORT_C void CMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver)
+ {
+ ASSERT(iProperties);
+ iProperties->RegisterPlayStartCallback(aObserver);
+ }
+
+
+
+CMMFMdaAudioToneUtility* CMMFMdaAudioToneUtility::NewL(MMdaAudioToneObserver& aObserver, CMdaServer* /*aServer = NULL*/,
+ TInt aPriority /*= EMdaPriorityNormal*/,
+ TInt aPref /*= EMdaPriorityPreferenceTimeAndQuality*/)
+
+ {
+ CMMFMdaAudioToneUtility* self = new(ELeave) CMMFMdaAudioToneUtility(aObserver, aPriority, aPref);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+
+CMMFMdaAudioToneUtility::CMMFMdaAudioToneUtility(MMdaAudioToneObserver& aCallback, TInt aPriority, TInt aPref) :
+ iCallback(aCallback)
+ {
+ iPrioritySettings.iPref = aPref;
+ iPrioritySettings.iPriority = aPriority;
+ iState = EMdaAudioToneUtilityNotReady;
+ iInitialized = EFalse;
+ iPlayCalled = EFalse;
+
+#ifdef _DEBUG
+ iPlayCalledBeforeInitialized = EFalse;
+#endif
+ }
+
+void CMMFMdaAudioToneUtility::ConstructL()
+ {
+ iAsyncCallback = CMMFMdaAudioToneObserverCallback::NewL(*this, *this);
+
+ // iDevSound = CMMFDevSound::NewL();
+ // iDevSound->InitializeL(*this,EMMFStateTonePlaying);
+
+ iTimer = CDummyDevSound::NewL();
+ iTimer->InitializeL(*this);
+
+ SetVolume(MaxVolume()/2 ); // set the volume to an intermediate value
+ }
+
+CMMFMdaAudioToneUtility::~CMMFMdaAudioToneUtility()
+ {
+ delete iAsyncCallback;
+ }
+
+
+
+void CMMFMdaAudioToneUtility::InitializeComplete(TInt aError)
+ {
+#ifdef _DEBUG
+ __ASSERT_ALWAYS(!iPlayCalledBeforeInitialized, User::Panic(_L("PlayInitialized called before InitializeComplete"), 0));
+#endif
+ iInitialized = ETrue;
+
+ if (iPlayCalled)
+ {
+ // Play() is called before InitializeComplete()
+ if (aError == KErrNone)
+ {
+ PlayAfterInitialized();
+ }
+ else
+ {
+ // InitializeComplete() with error other than KErrNone
+ iState = EMdaAudioToneUtilityNotReady;
+ iAsyncCallback->MatoPlayComplete(aError);
+ }
+ iPlayCalled = EFalse;
+ }
+ iInitializeState = aError;
+ }
+
+void CMMFMdaAudioToneUtility::ToneFinished(TInt aError)
+ {
+ if (aError != KErrCancel)
+ {
+ if (aError == KErrUnderflow)
+ {
+ aError = KErrNone;
+ }
+
+ iAsyncCallback->MatoPlayComplete(aError);
+ }
+ // else don't want to callback after a cancel
+ }
+
+
+TMdaAudioToneUtilityState CMMFMdaAudioToneUtility::State()
+ {
+ return iState;
+ }
+
+TInt CMMFMdaAudioToneUtility::MaxVolume()
+ {
+ return 100;
+ }
+
+TInt CMMFMdaAudioToneUtility::Volume()
+ {
+ return iDevSoundVolume;
+ }
+
+void CMMFMdaAudioToneUtility::SetVolume(TInt aVolume)
+ {
+ iDevSoundVolume = aVolume;
+ }
+
+void CMMFMdaAudioToneUtility::SetPriority(TInt aPriority, TInt aPref)
+ {
+ iPrioritySettings.iPref = aPref;
+ iPrioritySettings.iPriority = aPriority;
+ }
+
+void CMMFMdaAudioToneUtility::SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength,
+ TTimeIntervalMicroSeconds32 aToneOffLength,
+ TTimeIntervalMicroSeconds32 aPauseLength)
+ {
+ }
+
+void CMMFMdaAudioToneUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
+ {
+ // iDevSound->SetToneRepeats(aRepeatNumberOfTimes, aTrailingSilence);
+ }
+
+void CMMFMdaAudioToneUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+ {
+ }
+
+TInt CMMFMdaAudioToneUtility::FixedSequenceCount()
+ {
+ return 1; // iDevSound->FixedSequenceCount();
+ }
+
+_LIT(KFixedSequenceName, "FixedSequenceName");
+const TDesC& CMMFMdaAudioToneUtility::FixedSequenceName(TInt aSequenceNumber)
+ {
+ return KFixedSequenceName;
+ }
+
+void CMMFMdaAudioToneUtility::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const
+ {
+ }
+
+
+void CMMFMdaAudioToneUtility::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const
+ {
+ }
+
+
+void CMMFMdaAudioToneUtility::SetBalanceL(TInt aBalance)
+ {
+ iDevSoundBalance = aBalance;
+ }
+
+TInt CMMFMdaAudioToneUtility::GetBalanceL()
+ {
+ return iDevSoundBalance;
+ }
+
+void CMMFMdaAudioToneUtility::PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
+ {
+ iDuration = aDuration;
+ iAsyncCallback->MatoPrepareComplete(KErrNone);
+ }
+
+void CMMFMdaAudioToneUtility::PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
+ {
+ iDuration = aDuration;
+ iAsyncCallback->MatoPrepareComplete(KErrNone);
+ }
+
+void CMMFMdaAudioToneUtility::PrepareToPlayDTMFString(const TDesC& aDTMF)
+ {
+ iDuration = TTimeIntervalMicroSeconds(100);
+ iAsyncCallback->MatoPrepareComplete(KErrNone);
+ }
+
+void CMMFMdaAudioToneUtility::PrepareToPlayDesSequence(const TDesC8& aSequence)
+ {
+ iDuration = TTimeIntervalMicroSeconds(100);
+ iAsyncCallback->MatoPrepareComplete(KErrNone);
+ }
+
+void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(const TDesC& aFileName)
+ {
+ iDuration = TTimeIntervalMicroSeconds(100);
+ iAsyncCallback->MatoPrepareComplete(KErrNone);
+ }
+
+void CMMFMdaAudioToneUtility::PrepareToPlayFileSequence(RFile& aFileName)
+ {
+ iDuration = TTimeIntervalMicroSeconds(100);
+ iAsyncCallback->MatoPrepareComplete(KErrNone);
+ }
+
+
+
+
+void CMMFMdaAudioToneUtility::PrepareToPlayFixedSequence(TInt aSequenceNumber)
+ {
+ iDuration = TTimeIntervalMicroSeconds(100);
+ iSequenceNumber = aSequenceNumber;
+ iAsyncCallback->MatoPrepareComplete(KErrNone);
+ }
+
+void CMMFMdaAudioToneUtility::CancelPrepare()
+ {
+ if (iState == EMdaAudioToneUtilityPrepared)
+ {
+ iState = EMdaAudioToneUtilityNotReady;
+ }
+ // Cancel the AO
+ iAsyncCallback->Cancel();
+ }
+
+TInt CMMFMdaAudioToneUtility::Pause()
+ {
+ // Handle scenario when Pause is called before playback has started
+ if (iState != EMdaAudioToneUtilityPlaying || (iState == EMdaAudioToneUtilityPlaying && !iInitialized))
+ {
+ return KErrNotReady;
+ }
+
+ iState = EMdaAudioToneUtilityPaused;
+ return KErrNone;
+ }
+
+TInt CMMFMdaAudioToneUtility::Resume()
+ {
+ if (iState != EMdaAudioToneUtilityPaused)
+ {
+ return KErrNotReady;
+ }
+
+ iState = EMdaAudioToneUtilityPlaying;
+ return KErrNone;
+ }
+
+void CMMFMdaAudioToneUtility::Play()
+ {
+ TInt error = KErrNone;
+
+ if ((iState == EMdaAudioToneUtilityPlaying) || (iState == EMdaAudioToneUtilityPaused) || iPlayCalled)
+ {
+ iState = EMdaAudioToneUtilityNotReady;
+ iAsyncCallback->MatoPlayComplete(error);
+ return;
+ }
+
+ iState = EMdaAudioToneUtilityPlaying;
+
+ if (iInitialized)
+ {
+ // Play() is called after InitializeComplete()
+ if (iInitializeState)
+ {
+ // InitializeComplete() with error other than KErrNone
+ iState = EMdaAudioToneUtilityNotReady;
+ iAsyncCallback->MatoPlayComplete(iInitializeState);
+ }
+ else
+ {
+ PlayAfterInitialized();
+ }
+ }
+ else
+ {
+ // Play() is called before InitializeComplete()
+ iPlayCalled = ETrue;
+ }
+ }
+
+void CMMFMdaAudioToneUtility::PlayAfterInitialized()
+ {
+#ifdef _DEBUG
+ if (iInitialized == EFalse)
+ {
+ iPlayCalledBeforeInitialized = ETrue;
+ }
+#endif
+
+ // Really play something!
+ // TRAP(error, iDevSound->PlayToneL(c->Frequency(), c->Duration()));
+ iTimer->Play(iDuration);
+
+#if 0 // the error case
+ iState = EMdaAudioToneUtilityNotReady;
+ iAsyncCallback->MatoPlayComplete(error);
+ return;
+#endif
+
+ if(iPlayStartObserver)
+ {
+ iAsyncCallback->MatoPlayStarted(KErrNone);
+ }
+ }
+
+void CMMFMdaAudioToneUtility::CancelPlay()
+ {
+ iTimer->Cancel();
+ if(iState == EMdaAudioToneUtilityPlaying || iState == EMdaAudioToneUtilityPaused)
+ {
+ iState = EMdaAudioToneUtilityPrepared;
+ }
+ // Cancel the AO
+ iAsyncCallback->Cancel();
+ iPlayCalled = EFalse;
+ }
+
+
+void CMMFMdaAudioToneUtility::SendEventToClient(const TMMFEvent& /*aEvent*/)
+ {
+ if(iState == EMdaAudioToneUtilityPlaying)
+ {
+ iState = EMdaAudioToneUtilityPrepared;
+ }
+
+ iAsyncCallback->MatoPlayComplete(KErrInUse);
+ }
+
+
+void CMMFMdaAudioToneUtility::RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver)
+ {
+ iPlayStartObserver = &aObserver;
+ }
+
+void CMMFMdaAudioToneUtility::MatoPrepareComplete(TInt aError)
+ {
+ if (!aError)
+ {
+ iState = EMdaAudioToneUtilityPrepared;
+ }
+ else
+ {
+ iState = EMdaAudioToneUtilityNotReady;
+ }
+
+ iCallback.MatoPrepareComplete(aError);
+ }
+
+void CMMFMdaAudioToneUtility::MatoPlayComplete(TInt aError)
+ {
+ iState = EMdaAudioToneUtilityPrepared;
+ iCallback.MatoPlayComplete(aError);
+ }
+
+void CMMFMdaAudioToneUtility::MatoPlayStarted(TInt aError)
+ {
+ __ASSERT_DEBUG(aError==KErrNone, Panic(EPlayStartedCalledWithError));
+
+ // Not always there is an observer registered
+ if(iPlayStartObserver)
+ {
+ iPlayStartObserver->MatoPlayStarted(aError);
+ }
+ }
+
+// CustomInferface - just pass on to DevSound.
+TAny* CMMFMdaAudioToneUtility::CustomInterface(TUid aInterfaceId)
+ {
+ return 0;
+ }
+
+
+CMMFMdaAudioToneObserverCallback* CMMFMdaAudioToneObserverCallback::NewL(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback)
+ {
+ return new(ELeave) CMMFMdaAudioToneObserverCallback(aCallback, aPlayStartCallback);
+ }
+
+CMMFMdaAudioToneObserverCallback::CMMFMdaAudioToneObserverCallback(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback) :
+ CActive(CActive::EPriorityHigh),
+ iCallback(aCallback),
+ iPlayStartCallback(aPlayStartCallback)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CMMFMdaAudioToneObserverCallback::~CMMFMdaAudioToneObserverCallback()
+ {
+ Cancel();
+ }
+
+void CMMFMdaAudioToneObserverCallback::MatoPrepareComplete(TInt aError)
+ {
+ iAction = EPrepareComplete;
+ iErrorCode = aError;
+
+ TRequestStatus* s = &iStatus;
+ SetActive();
+ User::RequestComplete(s, KErrNone);
+ }
+
+void CMMFMdaAudioToneObserverCallback::MatoPlayComplete(TInt aError)
+ {
+ if(!IsActive())
+ {
+ iAction = EPlayComplete;
+ iErrorCode = aError;
+
+ TRequestStatus* s = &iStatus;
+ SetActive();
+ User::RequestComplete(s, KErrNone);
+ }
+ }
+
+void CMMFMdaAudioToneObserverCallback::MatoPlayStarted(TInt aError)
+ {
+ iAction = EPlayStarted;
+ iErrorCode = aError;
+
+ TRequestStatus* s = &iStatus;
+ SetActive();
+ User::RequestComplete(s, KErrNone);
+ }
+
+void CMMFMdaAudioToneObserverCallback::RunL()
+ {
+ switch (iAction)
+ {
+ case EPrepareComplete:
+ {
+ iCallback.MatoPrepareComplete(iErrorCode);
+ break;
+ }
+ case EPlayComplete:
+ {
+ iCallback.MatoPlayComplete(iErrorCode);
+ break;
+ }
+ case EPlayStarted:
+ iPlayStartCallback.MatoPlayStarted(iErrorCode);
+ break;
+ }
+ }
+
+void CMMFMdaAudioToneObserverCallback::DoCancel()
+ {
+ //nothing to cancel
+ }
+
+void MMMFClientUtility::ReservedVirtual1() {}
+void MMMFClientUtility::ReservedVirtual2() {}
+void MMMFClientUtility::ReservedVirtual3() {}
+void MMMFClientUtility::ReservedVirtual4() {}
+void MMMFClientUtility::ReservedVirtual5() {}
+void MMMFClientUtility::ReservedVirtual6() {}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/mmfclienttoneplayer.h Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,189 @@
+// Copyright (c) 2002-2009 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:
+//
+
+
+#ifndef __MMFCLIENTTONEPLAY_H__
+#define __MMFCLIENTTONEPLAY_H__
+
+
+#include <e32std.h>
+#include <e32base.h>
+#include <mdaaudiotoneplayer.h>
+#include <mmf/server/sounddevice.h>
+//Panic category and codes
+_LIT(KMMFMdaAudioToneUtilityPanicCategory, "MMFMdaAudioToneUtility");
+enum TMMFMdaAudioToneUtilityPanicCodes
+ {
+ EMMFMdaAudioToneUtilityAlreadyPrepared,
+ EMMFMdaAudioToneUtilityBadToneConfig,
+ EMMFMdaAudioToneUtilityBadMixinCall
+ };
+
+/**
+Active object utility class to allow the callback to be called asynchronously.
+This should help prevent re-entrant code in clients of the mediaframework.
+*/
+class CMMFMdaAudioToneObserverCallback : public CActive, public MMdaAudioToneObserver, public MMdaAudioTonePlayStartObserver
+ {
+public:
+ static CMMFMdaAudioToneObserverCallback* NewL(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback);
+ ~CMMFMdaAudioToneObserverCallback();
+// From MMdaAudioToneObserver
+ virtual void MatoPrepareComplete(TInt aError);
+ virtual void MatoPlayComplete(TInt aError);
+// From MMdaAudioTonePlayStartObserver
+ virtual void MatoPlayStarted(TInt aError);
+private:
+ CMMFMdaAudioToneObserverCallback(MMdaAudioToneObserver& aCallback, MMdaAudioTonePlayStartObserver& aPlayStartCallback);
+ void RunL();
+ void DoCancel();
+private:
+ enum TMMFAudioToneObserverCallbackAction {EPrepareComplete, EPlayComplete, EPlayStarted};
+ MMdaAudioToneObserver& iCallback;
+ MMdaAudioTonePlayStartObserver& iPlayStartCallback;
+ TMMFAudioToneObserverCallbackAction iAction;
+ TInt iErrorCode;
+ };
+
+class CMMFToneConfig;
+
+/**
+Timer class used instead of actual CMMFDevSound - the interface isn't the same either!
+*/
+NONSHARABLE_CLASS( CDummyDevSound ) : public CTimer
+ {
+ public:
+ static CDummyDevSound* NewL();
+
+ void InitializeL(MDevSoundObserver& aDevSoundObserver);
+ void RunL();
+ void Play(const TTimeIntervalMicroSeconds& aDuration);
+
+ private:
+ CDummyDevSound();
+
+ private:
+ MDevSoundObserver* iObserver;
+ };
+
+/**
+Concrete implementation of the CMdaAudioToneUtility API.
+@see CMdaAudioToneUtility
+*/
+class CMMFMdaAudioToneUtility;
+NONSHARABLE_CLASS( CMMFMdaAudioToneUtility ): public CBase,
+ public MMdaAudioToneObserver,
+ public MDevSoundObserver,
+ public MMdaAudioTonePlayStartObserver
+ {
+friend class CMdaAudioToneUtility;
+// only for testing purposes
+friend class CTestStepUnitMMFAudClient;
+
+public:
+ static CMMFMdaAudioToneUtility* NewL(MMdaAudioToneObserver& aObserver, CMdaServer* aServer = NULL,
+ TInt aPriority = EMdaPriorityNormal,
+ TInt aPref = EMdaPriorityPreferenceTimeAndQuality);
+
+ ~CMMFMdaAudioToneUtility();
+
+ TMdaAudioToneUtilityState State();
+ TInt MaxVolume();
+ TInt Volume();
+ void SetVolume(TInt aVolume);
+ void SetPriority(TInt aPriority, TInt aPref);
+ void SetDTMFLengths(TTimeIntervalMicroSeconds32 aToneLength,
+ TTimeIntervalMicroSeconds32 aToneOffLength,
+ TTimeIntervalMicroSeconds32 aPauseLength);
+ void SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence);
+ void SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration);
+ TInt FixedSequenceCount();
+ const TDesC& FixedSequenceName(TInt aSequenceNumber);
+ void PrepareToPlayTone(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration);
+ void PrepareToPlayDualTone(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration);
+ void PrepareToPlayDTMFString(const TDesC& aDTMF);
+ void PrepareToPlayDesSequence(const TDesC8& aSequence);
+ void PrepareToPlayFileSequence(const TDesC& aFileName);
+ void PrepareToPlayFileSequence(RFile& aFile);
+ void PrepareToPlayFixedSequence(TInt aSequenceNumber);
+ void CancelPrepare();
+ void Play();
+ void CancelPlay();
+ TInt Pause();
+ TInt Resume();
+
+ void SetBalanceL(TInt aBalance=KMMFBalanceCenter);
+ TInt GetBalanceL();
+// From MMdaAudioToneObserver
+ void MatoPrepareComplete(TInt aError);
+ void MatoPlayComplete(TInt aError);
+
+// From DevSoundObserver
+ void InitializeComplete(TInt aError);
+ void ToneFinished(TInt aError);
+ void BufferToBeFilled(CMMFBuffer* /*aBuffer*/) {User::Panic(KMMFMdaAudioToneUtilityPanicCategory,EMMFMdaAudioToneUtilityBadMixinCall);}
+ void PlayError(TInt /*aError*/) {User::Panic(KMMFMdaAudioToneUtilityPanicCategory,EMMFMdaAudioToneUtilityBadMixinCall);}
+ void BufferToBeEmptied(CMMFBuffer* /*aBuffer*/) {User::Panic(KMMFMdaAudioToneUtilityPanicCategory,EMMFMdaAudioToneUtilityBadMixinCall);}
+ void RecordError(TInt /*aError*/) {User::Panic(KMMFMdaAudioToneUtilityPanicCategory,EMMFMdaAudioToneUtilityBadMixinCall);}
+ void ConvertError(TInt /*aError*/) {User::Panic(KMMFMdaAudioToneUtilityPanicCategory,EMMFMdaAudioToneUtilityBadMixinCall);}
+ void DeviceMessage(TUid /*aMessageId*/, const TDesC8& /*aMsg*/) {User::Panic(KMMFMdaAudioToneUtilityPanicCategory,EMMFMdaAudioToneUtilityBadMixinCall);}
+ void SendEventToClient(const TMMFEvent& /*aEvent*/);
+
+ TAny* CustomInterface(TUid aInterfaceId);
+
+ void PlayAfterInitialized();
+
+ void RegisterPlayStartCallback(MMdaAudioTonePlayStartObserver& aObserver);
+
+// From MMdaAudioTonePlayStartObserver
+ void MatoPlayStarted(TInt aError);
+
+protected:
+ CMMFMdaAudioToneUtility(MMdaAudioToneObserver& aCallback, TInt aPriority, TInt aPref);
+ void ConstructL();
+private:
+ // functions to convert between MediaServer Balance and SoundDev balance
+ void CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) const;
+ void CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) const;
+
+private:
+ CDummyDevSound* iTimer;
+ MMdaAudioToneObserver& iCallback;
+ CMMFMdaAudioToneObserverCallback* iAsyncCallback;
+
+ TMdaAudioToneUtilityState iState;
+
+ TMMFPrioritySettings iPrioritySettings;
+
+ TInt iInitializeState;
+
+ TInt iSequenceNumber;
+ TBool iPlayCalled;
+
+ TBool iInitialized;
+
+ MMdaAudioTonePlayStartObserver* iPlayStartObserver;
+
+#ifdef _DEBUG
+ TBool iPlayCalledBeforeInitialized;
+#endif
+
+ TInt iDevSoundVolume;
+ TInt iDevSoundBalance;
+ TTimeIntervalMicroSeconds iDuration;
+ };
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/mmfclientutility.cpp Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,2531 @@
+// Copyright (c) 2002-2009 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:
+// Audio, MIDI and Video client utility functions.
+//
+//
+
+#include <e32std.h>
+#include <f32file.h>
+#include <bautils.h>
+#include <mmf/server/mmfdrmpluginserverproxy.h>
+#include <caf/content.h>
+#include <caf/data.h>
+using namespace ContentAccess;
+
+#include "mmfclientutility.h"
+#include <mmf/common/mmfpaniccodes.h>
+
+const TInt KMaxMimeLength = 256;
+const TInt KMaxHeaderSize = 256;
+const TInt KExpandSize = 100;
+
+#ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
+ const TInt KDefaultScreenNo = 0;
+#endif
+
+void CUPanic(TInt aCUPanicCode)
+ {
+ _LIT(KMMFMediaClientUtilityPaanicCategory, "MMFClientUtility");
+ User::Panic(KMMFMediaClientUtilityPaanicCategory, aCUPanicCode);
+ }
+
+/**
+ * @internalComponent
+ */
+EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMWrite(TUid aMdaFormatUid)
+ {
+ TUid ECOMUid = KNullUid;
+ if (aMdaFormatUid == KUidMdaClipFormatWav)
+ ECOMUid = TUid::Uid(KMmfUidFormatWAVWrite);
+ else if (aMdaFormatUid == KUidMdaClipFormatAu)
+ ECOMUid = TUid::Uid(KMmfUidFormatAUWrite);
+ else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)
+ ECOMUid = TUid::Uid(KMmfUidFormatRAWWrite);
+ else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)
+ ECOMUid = TUid::Uid(KAdvancedUidFormatAMRWrite);
+
+ return ECOMUid;
+ }
+
+/**
+ * @internalComponent
+ */
+EXPORT_C TUid CMMFClientUtility::ConvertMdaFormatUidToECOMRead(TUid aMdaFormatUid)
+ {
+ TUid ECOMUid = KNullUid;
+ if (aMdaFormatUid == KUidMdaClipFormatWav)
+ ECOMUid = TUid::Uid(KMmfUidFormatWAVRead);
+ else if (aMdaFormatUid == KUidMdaClipFormatAu)
+ ECOMUid = TUid::Uid(KMmfUidFormatAURead);
+ else if (aMdaFormatUid == KUidMdaClipFormatRawAudio)
+ ECOMUid = TUid::Uid(KMmfUidFormatRAWRead);
+ else if (aMdaFormatUid == KUidMdaClipFormatRawAmr)
+ ECOMUid = TUid::Uid(KAdvancedUidFormatAMRRead);
+
+ return ECOMUid;
+ }
+
+/**
+ * @internalComponent
+ */
+EXPORT_C TInt CMMFClientUtility::GetFileHeaderData(const TDesC& aFileName, TDes8& aHeaderData, TInt aMaxLength)
+ {
+ RFs fsSession;
+ RFile file;
+ TInt error = KErrNone;
+
+ if ((error = fsSession.Connect()) == KErrNone)
+ {
+ if ((error = file.Open(fsSession, aFileName, EFileShareReadersOrWriters)) == KErrNone)
+ {
+ TInt size = 0;
+
+ if ((error = file.Size(size)) == KErrNone)
+ {
+ if (size > 0)
+ {
+ if (size > aMaxLength)
+ size = aMaxLength;
+
+ error = file.Read(aHeaderData, size);
+ }
+ }
+ file.Close();
+ }
+ fsSession.Close();
+ }
+
+ return error;
+ }
+
+/**
+ * @internalComponent
+ */
+EXPORT_C TFourCC CMMFClientUtility::ConvertMdaCodecToFourCC(TMdaPackage& aCodec)
+ {
+ TFourCC dataType = KMMFFourCCCodeNULL;
+ switch (aCodec.Uid().iUid)
+ {
+ case KUidMdaWavPcmCodecDefine:
+ {
+ TMdaPcmWavCodec* pcmWavCodec = (TMdaPcmWavCodec*)&aCodec;
+ if (pcmWavCodec->iBits == TMdaPcmWavCodec::E8BitPcm)
+ dataType = KMMFFourCCCodePCMU8; //8 bit PCM
+ else
+ dataType = KMMFFourCCCodePCM16; //16 bit PCM
+ break;
+ }
+ case KUidMdaAu8PcmCodecDefine:
+ dataType = KMMFFourCCCodePCM8;
+ break;
+ case KUidMdaAuCodecDefine:
+ case KUidMdaAu16PcmCodecDefine:
+ dataType = KMMFFourCCCodePCM16B;
+ break;
+
+ case KUidMdaAuMulawCodecDefine:
+ case KUidMdaWavMulawCodecDefine:
+ case KUidMdaRawAudioMulawCodecDefine: //uLAW
+ dataType = KMMFFourCCCodeMuLAW;
+ break;
+ case KUidMdaAuAlawCodecDefine:
+ case KUidMdaWavAlawCodecDefine:
+ case KUidMdaRawAudioAlawCodecDefine: //ALAW
+ dataType = KMMFFourCCCodeALAW;
+ break;
+ case KUidMdaRawAudioS8PcmCodecDefine: // P8
+ dataType = KMMFFourCCCodePCM8;
+ break;
+ case KUidMdaRawAudioU8PcmCodecDefine: // PU8
+ dataType = KMMFFourCCCodePCMU8;
+ break;
+ case KUidMdaRawAudioSL16PcmCodecDefine: // P16
+ dataType = KMMFFourCCCodePCM16;
+ break;
+ case KUidMdaRawAudioSB16PcmCodecDefine: //P16B
+ dataType = KMMFFourCCCodePCM16B;
+ break;
+ case KUidMdaRawAudioUL16PcmCodecDefine: //PU16
+ dataType = KMMFFourCCCodePCMU16;
+ break;
+ case KUidMdaRawAudioUB16PcmCodecDefine: //PU6B
+ dataType = KMMFFourCCCodePCMU16B;
+ break;
+ case KUidMdaGsmWavCodecDefine: //GSM6
+ dataType = KMMFFourCCCodeGSM610;
+ break;
+ case KUidMdaWavImaAdpcmCodecDefine:
+ dataType = KMMFFourCCCodeIMAD;
+ break;
+ case KUidMdaRawAmrCodecDefine:
+ dataType = KMMFFourCCCodeAMR;
+ break;
+ default: // Not a Uid we recognise
+ dataType = KMMFFourCCCodeNULL;
+ break;
+ }
+ return dataType;
+ }
+
+
+CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewL(TMMSource& aSource, TBool aSecureDRMMode)
+ {
+ CMMFUtilityFileInfo* self = CMMFUtilityFileInfo::NewLC(aSource, aSecureDRMMode);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+CMMFUtilityFileInfo* CMMFUtilityFileInfo::NewLC(TMMSource& aSource, TBool aSecureDRMMode)
+ {
+ CMMFUtilityFileInfo* self = new (ELeave) CMMFUtilityFileInfo;
+ CleanupStack::PushL(self);
+ self->ConstructL(aSource, aSecureDRMMode);
+ return self;
+ }
+
+
+void CMMFUtilityFileInfo::ConstructL(const TMMSource& aSource, TBool aSecureDRMMode)
+ {
+ if (!aSecureDRMMode)
+ {
+ if (aSource.SourceType()==KUidMMFileSource)
+ {
+ const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+ iData = CData::NewL(TVirtualPathPtr(fileSource.Name(), fileSource.UniqueId()),
+ EContentShareReadWrite);
+ }
+
+ if (aSource.SourceType()==KUidMMFileHandleSource)
+ {
+ const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+ iData = CData::NewL(fileHandleSource.Handle(), fileHandleSource.UniqueId());
+ }
+
+ TInt err = iData->SetProperty(EAgentPropertyAgentUI, aSource.IsUIEnabled());
+ if (err != KErrNone && err != KErrCANotSupported)
+ {
+ // KErrCANotSupported isn't a problem for us so eat the error code.
+ User::Leave(err);
+ }
+
+ err = iData->EvaluateIntent(aSource.Intent());
+ User::LeaveIfError(err);
+ }
+ else
+ {
+ // Use RMMFDRMPluginServerProxy as medium
+ iDrmPluginServer = new (ELeave) RMMFDRMPluginServerProxy;
+ User::LeaveIfError(iDrmPluginServer->Open());
+
+ CBufFlat* dataBuffer = CBufFlat::NewL(KExpandSize);
+ CleanupStack::PushL(dataBuffer);
+ RBufWriteStream stream;
+ stream.Open(*dataBuffer);
+ CleanupClosePushL(stream);
+
+ stream.WriteInt32L(aSource.UniqueId().Length());
+ stream.WriteL(aSource.UniqueId());
+ stream.WriteInt32L(aSource.IsUIEnabled());
+ TPckgBuf<ContentAccess::TIntent> intentPckg(aSource.Intent());
+ stream.WriteL(intentPckg);
+ stream.CommitL();
+
+ CleanupStack::PopAndDestroy(&stream);
+ if (aSource.SourceType()==KUidMMFileSource)
+ {
+ const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+ iDrmPluginServer->OpenDataContentL(fileSource.Name(), dataBuffer->Ptr(0));
+ }
+ if (aSource.SourceType()==KUidMMFileHandleSource)
+ {
+ const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+ iDrmPluginServer->OpenDataContentL(fileHandleSource.Handle(), dataBuffer->Ptr(0));
+ }
+ CleanupStack::PopAndDestroy(dataBuffer);
+ }
+ }
+
+TInt CMMFUtilityFileInfo::EvaluateIntent(TIntent aIntent)
+ {
+ if (iData)
+ {
+ return iData->EvaluateIntent(aIntent);
+ }
+ else
+ {
+ ASSERT(iDrmPluginServer);
+ return iDrmPluginServer->EvaluateDataContentIntent(aIntent);
+ }
+ }
+/**
+ * @internalComponent
+ */
+TBool CMMFUtilityFileInfo::GetFileMimeTypeL(TDes8& aMimeType)
+ {
+ if (iData)
+ {
+ return iData->GetMimeTypeL(aMimeType);
+ }
+ else
+ {
+ ASSERT(iDrmPluginServer);
+ return iDrmPluginServer->GetDataContentMimeTypeL(aMimeType);
+ }
+ }
+
+/**
+ * @internalComponent
+ */
+void CMMFUtilityFileInfo::GetFileHeaderDataL(TDes8& aHeaderData, TInt aMaxLength)
+ {
+ if (iData)
+ {
+ TInt size = 0;
+ iData->DataSizeL(size);
+ if (size > 0)
+ {
+ if (size > aMaxLength)
+ size = aMaxLength;
+ TInt pos = 0;
+ User::LeaveIfError(iData->Seek(ESeekStart, pos));
+ User::LeaveIfError(iData->Read(aHeaderData, size));
+ }
+ }
+ else
+ {
+ ASSERT(iDrmPluginServer);
+ iDrmPluginServer->GetDataContentFileHeaderL(aHeaderData, aMaxLength);
+ }
+ }
+
+/**
+ * @internalComponent
+ */
+EXPORT_C HBufC8* CMMFClientUtility::GetFileExtensionL(const TDesC& aFileName)
+ {
+ TParse fileName;
+ fileName.Set(aFileName,NULL,NULL);
+ HBufC8* fileSuffix = NULL;
+ if(fileName.ExtPresent())
+ {
+ TPtrC fileSuffixPtr(fileName.Ext());
+ fileSuffix = HBufC8::NewL(fileSuffixPtr.Length());
+ fileSuffix->Des().Copy(fileSuffixPtr);
+ }
+ else
+ {
+ fileSuffix = KNullDesC8().AllocL();
+ }
+ return fileSuffix;
+ }
+
+
+/**
+ * @internalComponent
+ */
+CMMFUtilityFileInfo::~CMMFUtilityFileInfo()
+ {
+ if (iData)
+ {
+ delete iData;
+ }
+ if (iDrmPluginServer)
+ {
+ iDrmPluginServer->Close();
+ delete iDrmPluginServer;
+ }
+ }
+
+/*
+ * @internalComponent
+ *
+ * Returns an integer rating indicating how well the supplied format matches
+ * the header data and file extension supplied.
+ * 3 brownie points awarded for data & suffix match.
+ * 2 brownie points awarded for data match alone.
+ * 1 brownie point awarded for suffix match alone.
+ */
+TInt CMMFClientUtility::GetBestMatchL(const CMMFFormatImplementationInformation* format, const TDesC8& aHeaderData, const TDesC8& aFileExtension)
+ {
+ TInt browniePoints = 0;
+
+ if (aHeaderData.Length() > 0) // Non empty file
+ {
+ if (aFileExtension.Length() > 0) // With a file extension
+ {
+ if (format->SupportsHeaderDataL(aHeaderData) &&
+ format->SupportsFileExtension(aFileExtension))
+ {
+ browniePoints = 3;
+ }
+ else if (format->SupportsHeaderDataL(aHeaderData))
+ {
+ browniePoints = 2;
+ }
+ else
+ {
+ // See if this format has any 'empty' match data or no match data, indicating
+ // that this format will match extension alone even if data present.
+ // (A format may have more than one match data string.)
+ const CDesC8Array& supportedHeaderData = format->SupportedHeaderData();
+
+ if (supportedHeaderData.Count() == 0)
+ {
+ // No header data indicated.
+ if (format->SupportsFileExtension(aFileExtension))
+ {
+ browniePoints = 1;
+ }
+ }
+ else
+ {
+ for (register TInt i = 0; i < supportedHeaderData.Count(); i++)
+ {
+ if ((supportedHeaderData[i].Length() == 0) &&
+ format->SupportsFileExtension(aFileExtension))
+ {
+ browniePoints = 1;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // No file suffix, so must match header data alone.
+ if (format->SupportsHeaderDataL(aHeaderData))
+ {
+ browniePoints = 2;
+ }
+ }
+ }
+ else // Empty File
+ {
+ // We have no choice but to match extension, if there is one.
+ if ((aFileExtension.Length() > 0) && format->SupportsFileExtension(aFileExtension))
+ {
+ browniePoints = 1;
+ }
+ }
+
+ return browniePoints;
+}
+
+/**
+ * @internalComponent
+ *
+ * This function parses all the play & record formats in the given list of controllers,
+ * looking for controllers & formats that best match the requirements.
+ * Play controllers will be returned before record controllers, and
+ * in cases of equal priority between formats, ECom order will be maintained.
+ *
+ * @param "aControllers"
+ * A reference to a user supplied list of controllers retrieved from ECom.
+ * This list may be have been filtered for audio/video/play/record.
+ * @param "aHeaderDataPlayback"
+ * A descriptor reference containing the file's header data.
+ * for matching against a controller's play formats. May be KNullDesC8
+ * @param "aFileExtensionPlayback"
+ * A descriptor reference containing the filename's extension.
+ * for matching against a controller's play formats. May be KNullDesC8
+ * @param "aHeaderDataRecord"
+ * A descriptor reference containing the file's header data.
+ * for matching against a controller's record formats. May be KNullDesC8
+ * @param "aFileExtensionRecord"
+ * A descriptor reference containing the filename's extension.
+ * for matching against a controller's record formats. May be KNullDesC8
+ * @param "aPrioritisedControllers"
+ * A reference to a user supplied list through which the list of
+ * prioritised controllers will be returned.
+ * @since 7.0s
+ */
+void CMMFClientUtility::PrioritiseControllersL(
+ const RMMFControllerImplInfoArray& aControllers,
+ const TDesC8& aHeaderDataPlayback,
+ const TDesC8& aFileExtensionPlayback,
+ const TDesC8& aHeaderDataRecord,
+ const TDesC8& aFileExtensionRecord,
+ RMMFControllerImplInfoArray& prioritisedControllers)
+ {
+ RMMFControllerImplInfoArray fullMatchControllers; // data AND suffix
+ CleanupClosePushL(fullMatchControllers);
+ RMMFControllerImplInfoArray partMatchControllers; // data OR suffix
+ CleanupClosePushL(partMatchControllers);
+
+ TBool checkingPlaybackFormats = EFalse;
+ TBool checkingRecordFormats = EFalse;
+
+ if (aHeaderDataPlayback != KNullDesC8 || aFileExtensionPlayback != KNullDesC8)
+ checkingPlaybackFormats = ETrue;
+ if (aHeaderDataRecord != KNullDesC8 || aFileExtensionRecord != KNullDesC8)
+ checkingRecordFormats = ETrue;
+
+ // Examine each format for each controller. We only want to know at this stage
+ // if the controller has suitable formats, so as soon as we know it has, we can
+ // add it to out list, ranked by how well it matched.
+ for (register TInt i = 0; i < aControllers.Count(); i++)
+ {
+ const CMMFControllerImplementationInformation* controller = aControllers[i];
+ TInt savedBrowniePointsPlayback = 0;
+ TInt savedBrowniePointsRecord = 0;
+
+ if (checkingPlaybackFormats)
+ {
+ for (register TInt p = 0; p < controller->PlayFormats().Count(); p++)
+ {
+ const CMMFFormatImplementationInformation* format = controller->PlayFormats()[p];
+
+ TInt browniePoints = GetBestMatchL(format, aHeaderDataPlayback, aFileExtensionPlayback);
+
+ if (browniePoints >= savedBrowniePointsPlayback)
+ savedBrowniePointsPlayback = browniePoints;
+ }
+ }
+
+ if (checkingRecordFormats)
+ {
+ for (register TInt r = 0; r < controller->RecordFormats().Count(); r++)
+ {
+ const CMMFFormatImplementationInformation* format = controller->RecordFormats()[r];
+
+ TInt browniePoints = GetBestMatchL(format, aHeaderDataRecord, aFileExtensionRecord);
+
+ if (browniePoints >= savedBrowniePointsRecord)
+ savedBrowniePointsRecord = browniePoints;
+ }
+ }
+
+ TInt savedBrowniePoints = 0;
+ // if we're checking both playback & record formats
+ // make sure we've found both
+ if (checkingPlaybackFormats && checkingRecordFormats)
+ {
+ savedBrowniePoints = Min(savedBrowniePointsPlayback, savedBrowniePointsRecord);
+ }
+ else if (checkingPlaybackFormats)
+ {
+ savedBrowniePoints = savedBrowniePointsPlayback;
+ }
+ else if (checkingRecordFormats)
+ {
+ savedBrowniePoints = savedBrowniePointsRecord;
+ }
+
+ // Checked all formats for this controller, now count our brownie points.
+ switch (savedBrowniePoints)
+ {
+ case 3:
+ User::LeaveIfError(fullMatchControllers.Append(controller));
+ break;
+ case 2:
+ User::LeaveIfError(partMatchControllers.Insert(controller, 0));
+ break;
+ case 1:
+ User::LeaveIfError(partMatchControllers.Append(controller));
+ break;
+ default:
+ break;
+ }
+ }
+
+ // The better the controller matches, the earlier it will be in the final list.
+ for (register TInt x = 0; x < fullMatchControllers.Count(); x++)
+ {
+ if (prioritisedControllers.Find(fullMatchControllers[x]) == KErrNotFound)
+ {
+ User::LeaveIfError(prioritisedControllers.Append(fullMatchControllers[x]));
+ }
+ }
+
+ for (register TInt y = 0; y < partMatchControllers.Count(); y++)
+ {
+ if (prioritisedControllers.Find(partMatchControllers[y]) == KErrNotFound)
+ {
+ User::LeaveIfError(prioritisedControllers.Append(partMatchControllers[y]));
+ }
+ }
+
+ CleanupStack::PopAndDestroy(2, &fullMatchControllers); // fullMatchControllers, partMatchControllers
+ }
+
+/**
+ * @internalComponent
+ */
+EXPORT_C CMMFMdaObjectStateChangeObserverCallback* CMMFMdaObjectStateChangeObserverCallback::NewL(MMdaObjectStateChangeObserver& aCallback)
+ {
+ return new(ELeave) CMMFMdaObjectStateChangeObserverCallback(aCallback);
+ }
+
+/**
+ * @internalComponent
+ */
+CMMFMdaObjectStateChangeObserverCallback::~CMMFMdaObjectStateChangeObserverCallback()
+ {
+ Cancel();
+ }
+
+/**
+ * @internalComponent
+ */
+EXPORT_C void CMMFMdaObjectStateChangeObserverCallback::CallBack(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode)
+ {
+ iObject = aObject;
+ iPreviousState = aPreviousState;
+ iCurrentState = aCurrentState;
+ iErrorCode = aErrorCode;
+ if (!IsActive())
+ {
+ TRequestStatus* s = &iStatus;
+ SetActive();
+ User::RequestComplete(s, KErrNone);
+ }
+ }
+
+CMMFMdaObjectStateChangeObserverCallback::CMMFMdaObjectStateChangeObserverCallback(MMdaObjectStateChangeObserver& aCallback) :
+ CActive(CActive::EPriorityHigh),
+ iCallback(aCallback)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CMMFMdaObjectStateChangeObserverCallback::RunL()
+ {
+ iCallback.MoscoStateChangeEvent(iObject, iPreviousState, iCurrentState, iErrorCode);
+ }
+
+void CMMFMdaObjectStateChangeObserverCallback::DoCancel()
+ {
+ //nothing to cancel
+ }
+
+
+//****************************************
+// CMMFFindAndOpenController
+//****************************************
+
+/**
+ * Factory function to create a CMMFFindAndOpenController class
+ *
+ * @internalComponent
+ */
+EXPORT_C CMMFFindAndOpenController* CMMFFindAndOpenController::NewL(MMMFFindAndOpenControllerObserver& aObserver)
+ {
+ CMMFFindAndOpenController* self = new(ELeave) CMMFFindAndOpenController(aObserver);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CMMFFindAndOpenController::~CMMFFindAndOpenController()
+ {
+ Cancel();
+
+ // delete temporary variables
+ Close();
+
+ // this should cancel the AO
+ delete iAddDataSourceSinkAsync;
+
+ delete iPrimaryConfig;
+ delete iSecondaryConfig;
+ }
+
+/**
+ * Function to free up memory after a successful open has completed
+ * Useful to allow a alloc testing to work.
+ * Must not be called if ReOpen() is to be called
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::Close()
+ {
+
+ Cancel();
+
+ if(iAddDataSourceSinkAsync)
+ {
+ iAddDataSourceSinkAsync->Cancel();
+ }
+
+ if (iPrimaryConfig)
+ iPrimaryConfig->Close();
+ if (iSecondaryConfig)
+ iSecondaryConfig->Close();
+
+ iPrioritisedControllers.Close();
+ iControllers.ResetAndDestroy();
+ iControllers.Close();
+
+ iFileName.SetLength(0);
+ iFileNameSecondary.SetLength(0);
+
+ delete iUrl;
+ iUrl = NULL;
+
+ delete iMimeType;
+ iMimeType = NULL;
+
+ delete iUniqueId;
+ iUniqueId = NULL;
+
+ if (iOwnFileHandle)
+ {
+ iFileHandle.Close();
+ iOwnFileHandle = EFalse;
+ }
+ }
+/**
+ * Function to free up memory of which is not required in ReOpen()
+ * after a successful open has completed
+ * Useful to allow a alloc testing to work.
+ *
+ * @internalComponent
+ */
+
+EXPORT_C void CMMFFindAndOpenController::CloseConfig()
+ {
+ Cancel();
+ if(iAddDataSourceSinkAsync)
+ {
+ iAddDataSourceSinkAsync->Cancel();
+ }
+
+ if (iSecondaryConfig)
+ {
+ iSecondaryConfig->Close();
+ }
+
+ iPrioritisedControllers.Close();
+ iControllers.ResetAndDestroy();
+ iControllers.Close();
+
+ iFileName.SetLength(0);
+ iFileNameSecondary.SetLength(0);
+
+ delete iUrl;
+ iUrl = NULL;
+
+ delete iMimeType;
+ iMimeType = NULL;
+
+ delete iUniqueId;
+ iUniqueId = NULL;
+
+ if (iOwnFileHandle)
+ {
+ iFileHandle.Close();
+ iOwnFileHandle = EFalse;
+ }
+ }
+
+CMMFFindAndOpenController::CMMFFindAndOpenController(MMMFFindAndOpenControllerObserver& aObserver) :
+ CActive(EPriorityStandard),
+ iObserver(aObserver),
+ iDescriptor(NULL, 0)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CMMFFindAndOpenController::ConstructL()
+ {
+ iAddDataSourceSinkAsync = CMMFAddDataSourceSinkAsync::NewL(*this);
+ iPrimaryConfig = new (ELeave) CConfig();
+ iSecondaryConfig = new (ELeave) CConfig;
+ iCurrentConfig = iPrimaryConfig;
+
+ RProcess thisProcess;
+ iHasDrmCapability = thisProcess.HasCapability(ECapabilityDRM, KSuppressPlatSecDiagnostic);
+ thisProcess.Close();
+ }
+
+void CMMFFindAndOpenController::RunL()
+ {
+ Process();
+ }
+
+void CMMFFindAndOpenController::DoCancel()
+ {
+ iAddDataSourceSinkAsync->Cancel();
+ }
+
+/**
+ * Defines the media ID & priority to be used when opening a controller
+ * Normally called once only after class has been constructed
+ *
+ * @param aMediaId
+ * the media ID to use when searching for a controller
+ * e.g. KUidMediaTypeAudio
+ * @param aPrioritySettings
+ * the priority settings to use when opening a controller
+ * @param aMediaIdMatchType
+ * Defines the type of media id match to be performed on the plugins
+ * returned from the ECOM registry.
+ * @leave can leave with KErrNoMemory
+
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::Configure(
+ TUid aMediaId,
+ TMMFPrioritySettings aPrioritySettings,
+ CMMFPluginSelectionParameters::TMediaIdMatchType aMediaIdMatchType)
+ {
+ iPrioritySettings = aPrioritySettings;
+
+ iMediaIdMatchType = aMediaIdMatchType;
+
+ iMediaId = aMediaId;
+ }
+
+void CMMFFindAndOpenController::ConfigureController(
+ CConfig& config,
+ RMMFController& aController,
+ CMMFControllerEventMonitor& aEventMonitor,
+ TControllerMode aControllerMode)
+ {
+ config.iController = &aController;
+ config.iEventMonitor = &aEventMonitor;
+ config.iControllerMode = aControllerMode;
+ }
+
+/**
+ * Configures the primary controller
+ *
+ * @param aController
+ * a reference to the client controller object to use
+ * @param aEventMonitor
+ * a reference to an event monitor object for receiving
+ * events from the controller
+ * @param aControllerMode
+ * indicates whether this controller is to be used for recording
+ * or playback
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::ConfigureController(
+ RMMFController& aController,
+ CMMFControllerEventMonitor& aEventMonitor,
+ TControllerMode aControllerMode)
+ {
+ ConfigureController(
+ *iPrimaryConfig,
+ aController,
+ aEventMonitor,
+ aControllerMode);
+ }
+
+/**
+ * Configures the secondary controller
+ *
+ * This is only needed for the audio recorder utility which opens
+ * one controller for playback and another for recording
+ *
+ * @param aController
+ * a reference to the client controller object to use
+ * @param aEventMonitor
+ * a reference to an event monitor object for receiving
+ * events from the controller
+ * @param aControllerMode
+ * indicates whether this controller is to be used for recording
+ * or playback or converting
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::ConfigureSecondaryController(
+ RMMFController& aController,
+ CMMFControllerEventMonitor& aEventMonitor,
+ TControllerMode aControllerMode)
+ {
+ ConfigureController(
+ *iSecondaryConfig,
+ aController,
+ aEventMonitor,
+ aControllerMode);
+ }
+
+/**
+ * Makes any controllers that are opened subsequently share a single heap.
+ *
+ * The default behaviour is that each controller is created with its own heap.
+ * Each heap uses a chunk, so using this function avoids situations where the number
+ * of chunks per process is limited.
+ * The default behaviour is generally to be preferred, and should give lower overall
+ * memory usage. However, if many controllers are to be created for a particular thread,
+ * then this function should be used to prevent running out of heaps or chunks.
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::UseSharedHeap()
+ {
+ iUseSharedHeap = ETrue;
+ }
+
+void CMMFFindAndOpenController::Init()
+ {
+ // This should be called prior to opening, so reset the error
+ iError = KErrNone;
+ iSourceSinkConfigured = EFalse;
+ iControllerCount = 0;
+ }
+
+void CMMFFindAndOpenController::ConfigureSourceSink(
+ CConfig& config,
+ TSourceSink aSource,
+ TSourceSink aSink)
+ {
+ TInt err;
+ TRAP(err, config.iSource = CreateSourceSinkL(aSource));
+ if (err != KErrNone)
+ {
+ iError = err;
+ return;
+ }
+
+ TRAP(err, config.iSink = CreateSourceSinkL(aSink));
+ if (err != KErrNone)
+ {
+ iError = err;
+ return;
+ }
+ }
+
+
+void CMMFFindAndOpenController::ConfigureSourceSink(
+ CConfig& config,
+ const TMMSource& aSource,
+ TSourceSink aSink)
+ {
+ TInt err;
+ TRAP(err, config.iSource = CreateSourceSinkL(aSource));
+ if (err != KErrNone)
+ {
+ iError = err;
+ return;
+ }
+
+ TRAP(err, config.iSink = CreateSourceSinkL(aSink));
+ if (err != KErrNone)
+ {
+ iError = err;
+ return;
+ }
+ }
+
+
+
+/**
+ * Configure the primary controller's source and sink
+ * The descriptors passed to this function are copied so they do not need to be persistent.
+ * To simplify the API, any errors that occur are reported back asynchronously following
+ * a subsequent call to OpenByXXX()
+ *
+ * @param aSourceUid
+ * the UID of the data source
+ * @param aSourceData
+ * a reference to a descriptor used to configure the source
+ * @param aSinkUid
+ * the UID of the data sink
+ * @param aSinkData
+ * a reference to a descriptor used to configure the sink
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
+ TSourceSink aSource,
+ TSourceSink aSink)
+ {
+
+ CConfig* config = NULL;
+
+ Init();
+ config = iPrimaryConfig;
+
+
+ // must have already called ConfigureController()
+ __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
+
+ ConfigureSourceSink(
+ *config,
+ aSource,
+ aSink);
+ iCurrentConfig = config;
+
+ iSourceSinkConfigured = ETrue;
+ }
+
+
+/**
+ * Configure the primary controller's source and sink
+ * The descriptors passed to this function are copied so they do not need to be persistent.
+ * To simplify the API, any errors that occur are reported back asynchronously following
+ * a subsequent call to OpenByXXX()
+ *
+ * @param aSourceUid
+ * the UID of the data source
+ * @param aSourceData
+ * a reference to a descriptor used to configure the source
+ * @param aSinkUid
+ * the UID of the data sink
+ * @param aSinkData
+ * a reference to a descriptor used to configure the sink
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::ConfigureSecondarySourceSink(
+ TSourceSink aSource,
+ TSourceSink aSink)
+ {
+ if (iError != KErrNone)
+ {
+ // if there was an error configuring the primary source/sink, do not try the secondary one
+ // Don't return the error, since the stored error will be returned by the OpenBy... method
+ return;
+ }
+
+ CConfig* config = NULL;
+
+ config = iSecondaryConfig;
+
+ // must have already configured the primary controller
+ __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+ config = iSecondaryConfig;
+
+ // must have already called ConfigureController()
+ __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
+
+ ConfigureSourceSink(
+ *config,
+ aSource,
+ aSink);
+ iCurrentConfig = config;
+
+ iSourceSinkConfigured = ETrue;
+ }
+
+
+
+EXPORT_C void CMMFFindAndOpenController::ConfigureSourceSink(
+ const TMMSource& aSource,
+ TSourceSink aSink)
+ {
+ Init();
+ CConfig* config = iPrimaryConfig;
+
+ // must have already called ConfigureController()
+ __ASSERT_ALWAYS(config->iController != NULL, CUPanic(EMMFMediaClientUtilityBadState));
+
+ ConfigureSourceSink(
+ *config,
+ aSource,
+ aSink);
+ iCurrentConfig = config;
+
+ iSourceSinkConfigured = ETrue;
+ }
+
+
+
+/**
+ * Opens a controller using the supplied controller UID
+ * and adds the source & sink
+ * Completion is indicated asynchonously by a call to MfaocComplete()
+ *
+ * @param aControllerUid
+ * the UID of the primary controller
+ * @param aControllerUid
+ * the UID of the secondary controller
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::OpenByControllerUid(
+ TUid aControllerUid,
+ TUid aSecondaryControllerUid)
+ {
+ // must have already called ConfigureSourceSink()
+ __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+
+ // Have there been any errors so far ?
+ if (iError != KErrNone)
+ {
+ SchedSendError();
+ return;
+ }
+
+ if (iCurrentConfig == iPrimaryConfig)
+ {
+ // only do this for the playback controller
+ TRAP(iError, iCurrentConfig->iSource->EvaluateIntentL())
+
+ if (iError != KErrNone &&
+ !(iCurrentConfig->iControllerMode == EPlayback && iError == KErrPermissionDenied && !iHasDrmCapability))
+ {
+ // KErrPermissionDenied error and no DRM capability are not problems in Playback mode
+ // proper action will be performed when controller is loaded
+ SchedSendError();
+ return;
+ }
+ }
+
+ iPrimaryConfig->iControllerUid = aControllerUid;
+ if (iCurrentConfig == iSecondaryConfig)
+ {
+ if (aSecondaryControllerUid == KNullUid)
+ iSecondaryConfig->iControllerUid = aControllerUid;
+ else
+ iSecondaryConfig->iControllerUid = aSecondaryControllerUid;
+ }
+
+ iMode = EOpenByControllerUid;
+ iControllerImplInfo = NULL;
+ iState = EOpenController;
+ KickState();
+ }
+
+/**
+ * Opens a controller using the supplied file name
+ * and adds the source & sink
+ * A copy is made of the filename or file handle so that it need not be persistent
+ * Completion is indicated asynchonously by a call to MfaocComplete()
+ *
+ * @param aSource
+ * a reference to a TFileSource object to be used when searching
+ * for a controller
+ * @param aFileNameSecondary
+ * a reference to the seconday filename to be used when searching
+ * for a controller. This need only be supplied when converting
+ * between two files.
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::OpenByFileSource(const TMMSource& aSource, const TDesC& aFileNameSecondary)
+ {
+ // must have already called ConfigureSourceSink()
+ __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+
+ TInt err;
+ // Have there been any errors so far ?
+ if (iError != KErrNone)
+ {
+ SchedSendError();
+ return;
+ }
+
+ if (iOwnFileHandle)
+ {
+ // in case of error
+ iFileHandle.Close();
+ iOwnFileHandle = EFalse;
+ }
+
+ iEnableUi = aSource.IsUIEnabled();
+ if (aSource.SourceType()==KUidMMFileSource)
+ {
+ const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+ iFileName = fileSource.Name();
+ iUseFileHandle = EFalse;
+ }
+
+ if (aSource.SourceType()==KUidMMFileHandleSource)
+ {
+ const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+ ASSERT(iFileHandle.SubSessionHandle()==0); // closed just above
+ err = iFileHandle.Duplicate(fileHandleSource.Handle());
+ if (err != KErrNone)
+ {
+ SchedSendError(err);
+ return;
+ }
+ iFileHandle.Name(iFileName); //ignore error return since we'll just do without the filename if not available
+ iUseFileHandle = ETrue;
+ iOwnFileHandle = ETrue; // because we dup'd it
+ }
+
+ TRAP(err, iUniqueId = aSource.UniqueId().AllocL());
+ iIntent = aSource.Intent();
+ if (err != KErrNone)
+ {
+ SchedSendError(err);
+ return;
+ }
+
+
+ // take a copy of the secondary file name
+ iFileNameSecondary = aFileNameSecondary;
+
+ iMode = EOpenByFileName;
+ iState = EBuildControllerList;
+ KickState();
+ }
+
+/**
+ * Opens a controller using the supplied format UID
+ * and adds the source & sink
+ * Completion is indicated asynchonously by a call to MfaocComplete()
+ *
+ * @param aFormatUid
+ * the UID of a format that must be supported by the controller
+ * @param aFormatUidSecondary
+ * the UID of a secondary format that must be supported by the controller
+ * This need only be supplied when converting between two differnet formats.
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::OpenByFormatUid(TUid aFormatUid, TUid aFormatUidSecondary)
+ {
+ // must have already called ConfigureSourceSink()
+ __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+
+ // Have there been any errors so far ?
+ if (iError != KErrNone)
+ {
+ SchedSendError();
+ return;
+ }
+
+ iFormatUid = aFormatUid;
+ iFormatUidSecondary = aFormatUidSecondary;
+
+ iMode = EOpenByFormatUid;
+ iState = EBuildControllerList;
+ KickState();
+ }
+
+/**
+ * Opens a controller using the supplied descriptor
+ * and adds the source & sink
+ * Completion is indicated asynchonously by a call to MfaocComplete()
+ *
+ * @param aDescriptor
+ * a reference to the descriptor to be used when searching
+ * for a controller
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::OpenByDescriptor(const TDesC8& aDescriptor)
+ {
+ // must have already called ConfigureSourceSink()
+ __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+
+ // Have there been any errors so far ?
+ if (iError != KErrNone)
+ {
+ SchedSendError();
+ return;
+ }
+
+ // take a copy of the descriptor
+ TUint8* desBufferPtr = const_cast<TUint8*> (aDescriptor.Ptr());
+ iDescriptor.Set( desBufferPtr,aDescriptor.Length(),aDescriptor.Length());
+
+ iMode = EOpenByDescriptor;
+ iState = EBuildControllerList;
+ KickState();
+ }
+
+/**
+ * Opens a controller using the supplied URL
+ * and adds the source & sink
+ * Completion is indicated asynchonously by a call to MfaocComplete()
+ *
+ * @param aUrl
+ * a reference to the URL to be used when searching for a controller
+ * @param aIapId
+ * the IAP ID to be used when searching for a controller
+ * @param aMimeType
+ * the MIME type of the data to be used when searching for a controller
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::OpenByUrl(const TDesC& aUrl, TInt aIapId, const TDesC8& aMimeType)
+ {
+ // must have already called ConfigureSourceSink()
+ __ASSERT_ALWAYS(iSourceSinkConfigured, CUPanic(EMMFMediaClientUtilityBadState));
+
+ // Have there been any errors so far ?
+ if (iError != KErrNone)
+ {
+ SchedSendError();
+ return;
+ }
+
+ // take a copy of the Url
+ delete iUrl;
+ iUrl = NULL;
+ iUrl = aUrl.Alloc();
+ if (iUrl == NULL)
+ {
+ SchedSendError(KErrNoMemory);
+ return;
+ }
+
+ // take a copy of the IapId
+ iIapId = aIapId;
+
+ // take a copy of the mime type
+ delete iMimeType;
+ iMimeType = NULL;
+ iMimeType = aMimeType.Alloc();
+ if (iMimeType == NULL)
+ {
+ SchedSendError(KErrNoMemory);
+ return;
+ }
+
+ iMode = EOpenByUrl;
+ iState = EBuildControllerList;
+ KickState();
+ }
+
+/**
+ * Static function to return a TMMFFileConfig object
+ * suitable for passing to ConfigureSourceSink()
+ *
+ * @param aFileName
+ * the filename to use
+ *
+ * @internalComponent
+ */
+EXPORT_C TMMFFileConfig CMMFFindAndOpenController::GetConfigFile(const TDesC& aFileName)
+ {
+ TMMFFileConfig sourceSinkData;
+ sourceSinkData().iPath = aFileName;
+ return sourceSinkData;
+ }
+
+/**
+ * Static function to return a TMMFDescriptorConfig object
+ * suitable for passing to ConfigureSourceSink()
+ *
+ * @param aFileName
+ * the filename to use
+ *
+ * @internalComponent
+ */
+EXPORT_C TMMFDescriptorConfig CMMFFindAndOpenController::GetConfigDescriptor(const TDesC8& aDescriptor)
+ {
+ TMMFDescriptorConfig sourceSinkData;
+ sourceSinkData().iDes = (TAny*)&aDescriptor;
+ sourceSinkData().iDesThreadId = RThread().Id();
+ return sourceSinkData;
+ }
+
+/**
+ * Static function to create a CBufFlat object
+ * suitable for passing to ConfigureSourceSink()
+ *
+ * @param aUrlCfgBuffer
+ * the reference to a caller-supplied pointer used to create
+ * a CBufFlat object. The caller is responsible for deletion.
+ * @param aUrl
+ * a reference to the URL to be used
+ * @param aIapId
+ * the IAP ID to be used
+ * @return can return KErrNone or KErrNoMemory
+ *
+ * @internalComponent
+ */
+
+EXPORT_C void CMMFFindAndOpenController::GetConfigUrlL(CBufFlat*& aUrlCfgBuffer, const TDesC& aUrl, TInt aIapId)
+ {
+ delete aUrlCfgBuffer;
+ aUrlCfgBuffer = NULL;
+
+ CMMFUrlParams* urlCfg = CMMFUrlParams::NewL(aUrl,aIapId);
+ CleanupStack::PushL(urlCfg);
+ aUrlCfgBuffer = urlCfg->ExternalizeToCBufFlatLC();
+ CleanupStack::Pop(aUrlCfgBuffer);
+ CleanupStack::PopAndDestroy(urlCfg);
+ }
+/**
+ * ReOpens the previously opened primary controller
+ *
+ * @internalComponent
+ */
+EXPORT_C void CMMFFindAndOpenController::ReOpen()
+ {
+ // should already have a valid controller uid so just open it
+ iControllerImplInfo = NULL;
+ iState = EOpenController;
+ KickState();
+ }
+
+void CMMFFindAndOpenController::OpenPrimaryController(void)
+ {
+ iCurrentConfig = iPrimaryConfig;
+ switch(iMode)
+ {
+ case EOpenByFileName:
+ case EOpenByFormatUid:
+ case EOpenByDescriptor:
+ case EOpenByUrl:
+ iState = EBuildControllerList;
+ break;
+ case EOpenByControllerUid:
+ iControllerImplInfo = NULL;
+ iState = EOpenController;
+ break;
+ }
+ KickState();
+ }
+
+void CMMFFindAndOpenController::KickState()
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ SetActive();
+ }
+
+void CMMFFindAndOpenController::CloseController()
+ {
+ if (iCurrentConfig->iEventMonitor)
+ iCurrentConfig->iEventMonitor->Cancel();
+ iCurrentConfig->iController->Close();
+ }
+
+void CMMFFindAndOpenController::Process()
+ {
+ switch(iState)
+ {
+ case EBuildControllerList:
+ switch(iMode)
+ {
+ case EOpenByFileName:
+ TRAP(iError, BuildControllerListFileNameL());
+ break;
+ case EOpenByDescriptor:
+ TRAP(iError, BuildControllerListDescriptorL());
+ break;
+ case EOpenByUrl:
+ TRAP(iError, BuildControllerListUrlL());
+ break;
+ case EOpenByFormatUid:
+ TRAP(iError, BuildControllerListFormatL());
+ break;
+ default:
+ CUPanic(EMMFMediaClientUtilityBadState);
+ }
+
+ if (iError != KErrNone)
+ {
+ iState = EIdle;
+ SendError();
+ break;
+ }
+
+ // try the first controller
+ iControllerIndex = -1;
+ TryNextController();
+ break;
+
+ case EOpenController:
+ {
+ // Make sure any existing controller is closed.
+ CloseController();
+
+ TBool isSecureDrmProcess = EFalse;// need to keep it false as UseSecureDRMProcess may return error
+ // Loading controller in new threading model is enabled only in playback mode
+ TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
+ TBool localPlaybackMode = iCurrentConfig->iControllerMode == EPlayback &&
+ (sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource);
+ if(localPlaybackMode)
+ {
+ TRAPD(err,UseSecureDRMProcessL(isSecureDrmProcess));
+ if(err == KErrPermissionDenied)
+ {
+ isSecureDrmProcess = ETrue;
+ }
+ else if(err != KErrNone)
+ {
+ iError = err;
+ SendError(err);
+ return;
+ }
+ }
+ // Open the controller
+ if (iControllerImplInfo)
+ {
+ if(isSecureDrmProcess && localPlaybackMode)
+ {
+ iError = iCurrentConfig->iController->OpenInSecureDRMProcess(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
+ iUsingSecureDrmProcess = ETrue;
+ }
+ else
+ {
+ iError = iCurrentConfig->iController->Open(*iControllerImplInfo, iPrioritySettings, iUseSharedHeap);
+ iUsingSecureDrmProcess = EFalse;;
+ }
+ }
+ else
+ {
+ if(isSecureDrmProcess && localPlaybackMode)
+ {
+ iError = iCurrentConfig->iController->OpenInSecureDRMProcess(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
+ iUsingSecureDrmProcess = ETrue;
+
+ }
+ else
+ {
+ iError = iCurrentConfig->iController->Open(iCurrentConfig->iControllerUid, iPrioritySettings, iUseSharedHeap);
+ iUsingSecureDrmProcess = EFalse;
+ }
+ }
+ //in case of error, including KErrNomemory try next controller
+ if (iError)
+ {
+ TryNextController();
+ }
+ else
+ {
+ #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
+ #ifndef SYMBIAN_BUILD_GCE
+ if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
+ {
+ iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
+ if(iError)
+ {
+ if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
+ {
+ iError = KErrNone;
+ }
+ else
+ {
+ iState = EIdle;
+ SendError();
+ break;
+ }
+ }
+ }
+ #endif // SYMBIAN_BUILD_GCE
+ #endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
+ iCurrentConfig->iEventMonitor->Start();
+
+ if (iCurrentConfig == iSecondaryConfig)
+ {
+ iState = EAddSource;
+ KickState();
+ }
+ else
+ {
+ iState = EAddSink;
+ KickState();
+ }
+ }
+ }
+ break;
+
+ case EAddSource:
+ {
+ iState = EWaitingForSource;
+ const CMMSourceSink* source = iCurrentConfig->iSource;
+ // CMMSourceSink has the ability to transform the data it stored into a data stream
+ // which can be passed to CMMFAddDataSourceSinkAsync for further processing.
+ // CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
+ // source/sink. The info about the file can be a file path or a file handle.
+ // When it holds a file handle and turns info into data stream, the file handle is
+ // stored as a pointer in the stream. However, at this point, it cannot guarantee that
+ // the streamed info is always extracted within the same process. If the pointer is
+ // dereferenced in other process, a panic will raise in the system. Therefore, a file
+ // handle, rather than pointer, is used when necessary.
+ if (iUsingSecureDrmProcess && source->CarryingFileHandle())
+ {
+ iAddDataSourceSinkAsync->AddFileHandleDataSource(*iCurrentConfig->iController,
+ static_cast<const CMMFileSourceSink*>(source)->FileHandle(),
+ source->SourceSinkData());
+ }
+ else
+ {
+ iAddDataSourceSinkAsync->AddDataSource(*iCurrentConfig->iController,
+ source->SourceSinkUid(),
+ source->SourceSinkData());
+ }
+ }
+ break;
+
+ case EAddSink:
+ {
+ iState = EWaitingForSink;
+ const CMMSourceSink* sink = iCurrentConfig->iSink;
+ // CMMSourceSink has the ability to transform the data it stored into a data stream
+ // which can be passed to CMMFAddDataSourceSinkAsync for further processing.
+ // CMMFileSourceSink, which is a specialized CMMSourceSink, stores info about a file
+ // source/sink. The info about the file can be a file path or a file handle.
+ // When it holds a file handle and turns info into data stream, the file handle is
+ // stored as a pointer in the stream. However, at this point, it cannot guarantee that
+ // the streamed info is always extracted within the same process. If the pointer is
+ // dereferenced in other process, a panic will raise in the system. Therefore, a file
+ // handle, rather than pointer, is used when necessary.
+ const TDesC8& sinkData = sink->SourceSinkData();
+ if (iUsingSecureDrmProcess && sink->CarryingFileHandle())
+ {
+ iAddDataSourceSinkAsync->AddFileHandleDataSink(*iCurrentConfig->iController,
+ static_cast<const CMMFileSourceSink*>(sink)->FileHandle(),
+ sinkData);
+ }
+ else
+ {
+ iAddDataSourceSinkAsync->AddDataSink(*iCurrentConfig->iController,
+ sink->SourceSinkUid(),
+ sinkData);
+ }
+ }
+ break;
+
+ case EWaitingForSource:
+ break;
+
+ case EWaitingForSink:
+ break;
+
+ case ESendError:
+ SendError();
+ iState = EIdle;
+ break;
+
+ case EIdle:
+ default:
+ break;
+ }
+ }
+
+void CMMFFindAndOpenController::TryNextController()
+ {
+ // If an error occurred close the controller.
+ if (iError != KErrNone)
+ {
+ CloseController();
+ }
+
+ iStopTryLoadController = EFalse;
+
+ if (iMode == EOpenByControllerUid || ++iControllerIndex >= iControllerCount)
+ {
+ //Raise a flag to stop trying to load the controllers
+ iStopTryLoadController = ETrue;
+
+ // KErrNotSupported is the default error, but will only be used if no other error
+ // has been discovered (the first error found is used by default)
+ // However, KErrBadHandle seems to mean that we tried to use the DRM server without
+ // RFs::ShareProtected() having been called, so force usage of KErrNotSupported so
+ // client does not see changed
+ TBool forceErrorUse = EFalse;
+ if (iError==KErrBadHandle)
+ {
+ forceErrorUse = ETrue;
+ }
+ SendError(KErrNotSupported, forceErrorUse);
+
+ return;
+ }
+
+ if (iMode == EOpenByFileName || iMode == EOpenByFormatUid)
+ {
+ iControllerImplInfo = iPrioritisedControllers[iControllerIndex];
+ }
+ else //if (iMode == EOpenByDescriptor || iMode == EOpenByUrl)
+ {
+ iControllerImplInfo = iControllers[iControllerIndex];
+ }
+
+ iCurrentConfig->iControllerUid = iControllerImplInfo->Uid();
+ iState = EOpenController;
+ KickState();
+ }
+
+void CMMFFindAndOpenController::MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle)
+ {
+ iError = aError;
+
+ // take the first available exit if we're out of memory
+ // or we've been cancelled
+ if (iError == KErrNoMemory || iError == KErrCancel)
+ {
+ SendError();
+ return;
+ }
+
+ // failed to add source or sink - try the next controller
+ if (aError != KErrNone)
+ {
+ TryNextController();
+ return;
+ }
+
+ if (iState == EWaitingForSource)
+ {
+ #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
+ #ifdef SYMBIAN_BUILD_GCE
+ // If surfaces are required try to use them. If this fails then fall back to using
+ // direct screen access.
+ if(iCurrentConfig->iControllerMode == EPlayback && iMediaId == KUidMediaTypeVideo)
+ {
+ // UseSurfaces call has to be done after adding data sink and adding data source.
+ iSurfaceSupported = iVideoPlaySurfaceSupportCustomCommands->UseSurfaces();
+
+ if (iSurfaceSupported == KErrNotSupported)
+ {
+ if (iUseVPU2)
+ {
+ if (ControllerIndex() < ControllerCount() - 1)
+ {
+ // Until end of the list of controllers,
+ // try the next one for surface support
+ TryNextController(); // this will also kick-state
+ return;
+ }
+ else
+ {
+ iError = iSurfaceSupported;
+ }
+ }
+ else
+ {
+ // No surface enabled controller found
+ // not required to do only surface,
+ // use the last one that matched.
+ iError = iVideoSetInitScreenCustomCommands->SetInitScreenNumber(iScreenNumber);
+ if (iError == KErrNotSupported && iScreenNumber == KDefaultScreenNo)
+ {
+ iError = KErrNone;
+ }
+ }
+ }
+ else
+ {
+ iError = iSurfaceSupported;
+ }
+ }
+ #endif // SYMBIAN_BUILD_GCE
+ #endif // SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
+
+ iSourceHandle = aHandle;
+ if (iCurrentConfig == iSecondaryConfig)
+ {
+ iState = EAddSink;
+ }
+ else // completed ok !
+ {
+ iState = EIdle;
+ SendError(KErrNone, ETrue);
+ return;
+ }
+ }
+ else if (iState == EWaitingForSink)
+ {
+ iSinkHandle = aHandle;
+ if (iCurrentConfig == iSecondaryConfig) // completed ok !
+ {
+ iState = EIdle;
+ iError = KErrNone;
+ SendError();
+ return;
+ }
+ else
+ {
+ iState = EAddSource;
+ }
+ }
+
+ KickState();
+ }
+
+void CMMFFindAndOpenController::SendError(TInt aError, TBool aOverrideError)
+ {
+ if (iError == KErrNone || aOverrideError)
+ {
+ iError = aError;
+ }
+
+ iObserver.MfaocComplete(iError, iCurrentConfig->iController, iCurrentConfig->iControllerUid, &iSourceHandle, &iSinkHandle);
+
+ // if we've just attempted to open the Secondary controller,
+ // try to open the Primary controller
+ if (iCurrentConfig == iSecondaryConfig)
+ {
+ if (iError == KErrNone)
+ OpenPrimaryController();
+ }
+
+ // if we failed to open, may as well free up some memory
+ // if open succeeded we need to preserve state in case of a re-open
+ if (iError != KErrNone)
+ {
+ if(iControllerIndex >= iControllerCount-1)
+ {
+ Close();
+ }
+ else //if there are other controllers selected in the controller list, try them
+ {
+ Cancel();
+ if(iAddDataSourceSinkAsync)
+ {
+ iAddDataSourceSinkAsync->Cancel();
+ }
+
+ TryNextController();
+ }
+ }
+ }
+
+void CMMFFindAndOpenController::SchedSendError(TInt aError)
+ {
+ if (aError != KErrNone)
+ iError = aError;
+ iState = ESendError;
+ KickState();
+ }
+
+void CMMFFindAndOpenController::BuildControllerListFileNameL()
+ {
+ // Retrieve a list of possible controllers from ECOM
+ // If we don't have a match, leave with unsupported
+
+ iControllers.ResetAndDestroy();
+ iPrioritisedControllers.Reset();
+
+ TControllerMode mode = iCurrentConfig->iControllerMode;
+
+ // if we're playing, try to get the MIME type from the Content Access
+ // Framework (CAF) & use that to select a controller - if that fails,
+ // try to select a controller based on the header data/file extension
+
+ CMMFUtilityFileInfo* fileInfo = NULL;
+
+ TInt error;
+
+ //If the current CMMSourceSink is a CMMFileSourceSink
+ // Using the previous version we'd get KErrCANoPermission when calling EvaluateIntent in the
+ // CMMFUtilityFileInfo ConstructL as the intent == EUnknown, so now pass the intent as a parameter
+ // to TMMFileHandleSource and....
+ TBool isSecureDrmProcess = EFalse;
+ //need to do this only in local playback mode
+ //UseSecureDRMProcess() function in called only in case of local play / record
+ // so we'll just chk for playback mode
+ if(mode == EPlayback)
+ {
+ TRAP(error, UseSecureDRMProcessL(isSecureDrmProcess));
+ if(error == KErrPermissionDenied)
+ {
+ isSecureDrmProcess = ETrue;
+ }
+ else
+ {
+ User::LeaveIfError(error);
+ }
+ }
+ TRAP(error, fileInfo = CreateFileInfoL(isSecureDrmProcess));
+
+ if (fileInfo != NULL)
+ {
+ CleanupDeletePushL(fileInfo);
+ }
+
+ if (error != KErrNone)
+ {
+ // if playback mode, leave for any error
+ // if record mode, allow KErrNotFound
+ if (mode == EPlayback || (mode != EPlayback && error != KErrNotFound))
+ {
+ User::Leave(error);
+ }
+ }
+
+ CMMFControllerPluginSelectionParameters* cSelect = NULL;
+ if (isSecureDrmProcess)
+ {
+ cSelect = CMMFControllerSecureDrmPluginSelectionParameters::NewLC();
+ }
+ else
+ {
+ cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+ }
+ RArray<TUid> mediaIds;
+ CleanupClosePushL(mediaIds);
+ User::LeaveIfError(mediaIds.Append(iMediaId));
+
+ cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+
+ if (mode == EPlayback)
+ {
+ ASSERT(fileInfo!=NULL);
+ TBuf8<KMaxMimeLength> mimeType;
+ TBool mimeTypeKnown = fileInfo->GetFileMimeTypeL(mimeType);
+ if (mimeTypeKnown)
+ {
+ CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+ fSelect->SetMatchToMimeTypeL(mimeType);
+ cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+ cSelect->ListImplementationsL(iControllers);
+ CleanupStack::PopAndDestroy(fSelect);
+ }
+
+
+ // copy to the iPrioritisedControllers array - this is a NOOP if the
+ // MIME type is not known since iControllers will be empty
+ ASSERT(mimeTypeKnown || iControllers.Count() == 0);
+ for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
+ User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
+
+ iControllerCount = iPrioritisedControllers.Count();
+ if (iControllerCount > 0)
+ {
+ // Clean up
+ // cSelect, mediaIds,
+ CleanupStack::PopAndDestroy(2, cSelect);
+ if (fileInfo != NULL)
+ {
+ CleanupStack::PopAndDestroy(fileInfo);
+ }
+ return;
+ }
+ }
+
+ // Retrieve header data first. If file doesn't exist, its ok.
+ HBufC8* headerData = HBufC8::NewLC(KMaxHeaderSize);
+ TPtr8 headerDataPtr = headerData->Des();
+ if (fileInfo)
+ {
+ fileInfo->GetFileHeaderDataL(headerDataPtr, KMaxHeaderSize);
+ }
+
+ // Get the filename's suffix
+ HBufC8* fileSuffix = CMMFClientUtility::GetFileExtensionL(iFileName);
+
+ CleanupStack::PushL(fileSuffix);
+ TPtr8 fileSuffixPtr = fileSuffix->Des();
+
+ // Get the secondary filename's header data (for convert)
+ HBufC8* headerDataSecondary = HBufC8::NewLC(KMaxHeaderSize);
+ TPtr8 headerDataPtrSecondary = headerDataSecondary->Des();
+ if (iFileNameSecondary.Length() > 0 && fileInfo)
+ {
+ fileInfo->GetFileHeaderDataL(headerDataPtrSecondary, KMaxHeaderSize);
+ }
+
+ // Get the secondary filename's suffix
+ HBufC8* fileSuffixSecondary = CMMFClientUtility::GetFileExtensionL(iFileNameSecondary);
+ CleanupStack::PushL(fileSuffixSecondary);
+ TPtr8 fileSuffixPtrSecondary = fileSuffixSecondary->Des();
+
+
+ CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+
+ if (mode == EPlayback || mode == EConvert)
+ cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+ if (mode == ERecord || mode == EConvert)
+ cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+
+ cSelect->ListImplementationsL(iControllers);
+
+ if (iControllers.Count()==0)
+ User::Leave(KErrNotSupported);
+
+ if (mode == ERecord)
+ {
+ CMMFClientUtility::PrioritiseControllersL(
+ iControllers,
+ headerDataPtrSecondary,
+ fileSuffixPtrSecondary,
+ headerDataPtr,
+ fileSuffixPtr,
+ iPrioritisedControllers);
+ }
+ else
+ {
+ CMMFClientUtility::PrioritiseControllersL(
+ iControllers,
+ headerDataPtr,
+ fileSuffixPtr,
+ headerDataPtrSecondary,
+ fileSuffixPtrSecondary,
+ iPrioritisedControllers);
+ }
+
+ iControllerCount = iPrioritisedControllers.Count();
+ if (iControllerCount == 0)
+ User::Leave(KErrNotSupported);
+
+ // Clean up
+ // cSelect, mediaIds,
+ // headerData, fileSuffix, headerDataSecondary, fileSuffixSecondary,
+ // fSelect
+ CleanupStack::PopAndDestroy(7, cSelect);
+ if (fileInfo != NULL)
+ {
+ CleanupStack::PopAndDestroy(fileInfo);
+ }
+ }
+
+void CMMFFindAndOpenController::BuildControllerListDescriptorL()
+ {
+ // Retrieve a list of possible controllers from ECOM
+ // If we don't have a match, leave with unsupported
+
+ iControllers.ResetAndDestroy();
+
+ CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+ CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+
+
+ RArray<TUid> mediaIds;
+ CleanupClosePushL(mediaIds);
+ User::LeaveIfError(mediaIds.Append(iMediaId));
+
+ cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+
+ TPtrC8 header = iDescriptor.Left(KMaxHeaderSize);
+ fSelect->SetMatchToHeaderDataL(header);
+
+
+ TControllerMode mode = iCurrentConfig->iControllerMode;
+ if (mode == EPlayback || mode == EConvert)
+ cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+ if (mode == ERecord || mode == EConvert)
+ cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+
+ cSelect->ListImplementationsL(iControllers);
+
+ iControllerCount = iControllers.Count();
+ if (iControllerCount == 0)
+ User::Leave(KErrNotSupported);
+
+ // Clean up
+ // cSelect, fSelect, mediaIds
+ CleanupStack::PopAndDestroy(3, cSelect);
+ }
+
+void CMMFFindAndOpenController::BuildControllerListUrlL()
+ {
+ // Retrieve a list of possible controllers from ECOM
+ // If we don't have a match, leave with unsupported
+
+ iControllers.ResetAndDestroy();
+
+ CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+ CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+
+ RArray<TUid> mediaIds;
+ CleanupClosePushL(mediaIds);
+ User::LeaveIfError(mediaIds.Append(iMediaId));
+
+ cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+
+
+ if (*iMimeType != KNullDesC8)
+ {
+ fSelect->SetMatchToMimeTypeL(*iMimeType);//We match to mime type
+ }
+ else
+ {
+ fSelect->SetMatchToUriSupportL(*iUrl);
+ }
+
+ TControllerMode mode = iCurrentConfig->iControllerMode;
+ if (mode == EPlayback || mode == EConvert)
+ cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+ if (mode == ERecord || mode == EConvert)
+ cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+
+ cSelect->ListImplementationsL(iControllers);
+
+ iControllerCount = iControllers.Count();
+ if (iControllerCount == 0)
+ User::Leave(KErrNotSupported);
+
+ // Clean up
+ // cSelect, fSelect, mediaIds
+ CleanupStack::PopAndDestroy(3, cSelect);
+ }
+
+void CMMFFindAndOpenController::BuildControllerListFormatL()
+ {
+ // Retrieve a list of possible controllers from ECOM
+ // If we don't have a match, leave with unsupported
+
+ iControllers.ResetAndDestroy();
+ iPrioritisedControllers.Reset();
+
+ CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
+
+ // Select the media IDs to allow
+ RArray<TUid> mediaIds;
+ CleanupClosePushL(mediaIds);
+ User::LeaveIfError(mediaIds.Append(iMediaId));
+
+ cSelect->SetMediaIdsL(mediaIds, iMediaIdMatchType);
+
+ CMMFFormatSelectionParameters* fSelect = CMMFFormatSelectionParameters::NewLC();
+
+ TControllerMode mode = iCurrentConfig->iControllerMode;
+ if (mode == EPlayback || mode == EConvert)
+ cSelect->SetRequiredPlayFormatSupportL(*fSelect);
+ if (mode == ERecord || mode == EConvert)
+ cSelect->SetRequiredRecordFormatSupportL(*fSelect);
+
+ //Obtain a list of the controllers
+ cSelect->ListImplementationsL(iControllers);
+
+ CleanupStack::PopAndDestroy(3, cSelect); // cSelect, mediaIds, fSelect
+
+ iControllerCount = iControllers.Count();
+ if (iControllerCount == 0)
+ User::Leave(KErrNotSupported);
+
+ TUid formatUidPrimary;
+ TUid formatUidSecondary;
+ if (mode == ERecord)
+ {
+ formatUidSecondary = iFormatUid;
+ formatUidPrimary = iFormatUidSecondary;
+ }
+ else
+ {
+ formatUidPrimary = iFormatUid;
+ formatUidSecondary = iFormatUidSecondary;
+ }
+
+ for (TInt controllerIndex=0; controllerIndex < iControllers.Count(); controllerIndex++)
+ {
+ const RMMFFormatImplInfoArray& recFormatInfo = iControllers[controllerIndex]->RecordFormats();
+ const RMMFFormatImplInfoArray& playFormatInfo = iControllers[controllerIndex]->PlayFormats();
+
+ TBool playFormatMatched = EFalse;
+ TBool recordFormatMatched = EFalse;
+
+ if (formatUidPrimary == KNullUid)
+ {
+ playFormatMatched = ETrue;
+ }
+ else
+ {
+ for(TInt playFormatIndex =0; playFormatIndex < playFormatInfo.Count(); playFormatIndex++)
+ {
+ if(playFormatInfo[playFormatIndex]->Uid() == formatUidPrimary)
+ {
+ playFormatMatched = ETrue;
+ break;
+ }
+ }
+ }
+
+ if (formatUidSecondary == KNullUid)
+ {
+ recordFormatMatched = ETrue;
+ }
+ else
+ {
+ for (TInt recFormatIndex =0; recFormatIndex < recFormatInfo.Count(); recFormatIndex++)
+ {
+ if (recFormatInfo[recFormatIndex]->Uid() == formatUidSecondary)
+ {
+ recordFormatMatched = ETrue;
+ break;
+ }
+ }
+ }
+
+ if (playFormatMatched && recordFormatMatched)
+ User::LeaveIfError(iPrioritisedControllers.Append(iControllers[controllerIndex]));
+ }
+
+ iControllerCount = iPrioritisedControllers.Count();
+ if (iControllerCount == 0)
+ User::Leave(KErrNotSupported);
+ }
+
+CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TSourceSink& aParams)
+ {
+ if (aParams.iUseFileHandle)
+ {
+ return CMMFileSourceSink::NewL(aParams.iUid, aParams.iFileHandle);
+ }
+ return CMMSourceSink::NewL(aParams.iUid, aParams.iConfigData);
+ }
+
+
+CMMSourceSink* CMMFFindAndOpenController::CreateSourceSinkL(const TMMSource& aSource)
+ {
+ if (!(aSource.SourceType()==KUidMMFileSource ||
+ aSource.SourceType()==KUidMMFileHandleSource))
+ User::Leave(KErrNotSupported);
+
+ return CMMFileSourceSink::NewL(KUidMmfFileSource, aSource);
+ }
+
+CMMFUtilityFileInfo* CMMFFindAndOpenController::CreateFileInfoL(TBool aSecureDRMMode)
+ {
+ CMMFUtilityFileInfo* fileInfo = NULL;
+ if (iUseFileHandle)
+ {
+ if (iUniqueId != NULL)
+ {
+ TMMFileHandleSource fileHandleSource(iFileHandle, (*iUniqueId), iIntent,iEnableUi);
+ fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
+ }
+ else
+ {
+ TMMFileHandleSource fileHandleSource(iFileHandle);
+ fileInfo = CMMFUtilityFileInfo::NewL(fileHandleSource, aSecureDRMMode);
+ }
+ }
+ else
+ {
+ if (iUniqueId != NULL)
+ {
+ TMMFileSource fileSource(iFileName, (*iUniqueId), iIntent,iEnableUi);
+ fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
+ }
+ else
+ {
+ TMMFileSource fileSource(iFileName);
+ fileInfo = CMMFUtilityFileInfo::NewL(fileSource, aSecureDRMMode);
+ }
+ }
+ return fileInfo;
+ }
+
+EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const TDesC8& aConfigData)
+ : iConfigData(aConfigData)
+ {
+ iUid = aUid;
+
+ iUseFileHandle = EFalse;
+ }
+
+EXPORT_C CMMFFindAndOpenController::TSourceSink::TSourceSink(TUid aUid, const RFile& aFile)
+ : iConfigData(KNullDesC8)
+ {
+ iUid = aUid;
+
+ iFileHandle = aFile;
+ iUseFileHandle = ETrue;
+ }
+
+EXPORT_C void CMMFFindAndOpenController::SetInitScreenNumber(TInt aScreenNumber, RMMFVideoSetInitScreenCustomCommands* aVideoSetInitScreenCustomCommands)
+ {
+ iScreenNumber = aScreenNumber;
+ iVideoSetInitScreenCustomCommands = aVideoSetInitScreenCustomCommands;
+ }
+
+CMMFFindAndOpenController::CConfig::CConfig()
+ {
+ }
+
+void CMMFFindAndOpenController::CConfig::Close()
+ {
+ delete iSource;
+ iSource = NULL;
+ delete iSink;
+ iSink = NULL;
+ }
+CMMFFindAndOpenController::CConfig::~CConfig()
+ {
+ Close();
+ }
+
+void CMMFFindAndOpenController::UseSecureDRMProcessL(TBool& aIsSecureDrmProcess)
+ {
+ if(iHasDrmCapability)//if client has DRM capability, we never use Secure DRM Process
+ {
+ aIsSecureDrmProcess = EFalse;
+ return;
+ }
+ TBool isDataProtected = EFalse;
+ ContentAccess::CContent* content = NULL;
+ TControllerMode mode = iCurrentConfig->iControllerMode;
+
+ //setting aUseSecureDrmProcess to false(default value)
+ aIsSecureDrmProcess = EFalse;
+
+ //need to proceed only in case of local playback mode
+ TUid sourceUid = iCurrentConfig->iSource->SourceSinkUid();
+ TBool localPlaybackMode = ( mode == EPlayback &&
+ (sourceUid == KUidMmfFileSource || sourceUid == KUidMmfDescriptorSource) );
+ if(!localPlaybackMode)
+ {
+ return;
+ }
+
+ if (iUseFileHandle && iOwnFileHandle)
+ {
+ content = ContentAccess::CContent::NewLC(iFileHandle);
+ }
+ else if(iFileName.Length()) //need to check if file name exist
+ {
+ content = ContentAccess::CContent::NewLC(iFileName);
+ }
+ else
+ {//in case of descriptor source content object will not be created
+ return;
+ }
+ TInt value = 0;
+ TInt error = KErrNone;
+ if(iUniqueId != NULL)
+ {
+ error = content->GetAttribute(EIsProtected, value, *iUniqueId );
+ }
+ else
+ {
+ error = content->GetAttribute(EIsProtected, value);
+ }
+ if( (error == KErrNone && value) || error == KErrPermissionDenied )
+ {//2nd condition can be true if GetAttribute checks for DRM cap and return error if not found
+ isDataProtected = ETrue;
+ }
+ else if( error != KErrNone && error != KErrPermissionDenied)
+ {//leaving as GetAttribute of CAF caused an error.
+ User::Leave(error);
+ }
+
+ CleanupStack::PopAndDestroy(content);
+ if(isDataProtected && !iHasDrmCapability && mode == EPlayback)
+ {//only when the Data is protected and client does not have the DRM capability, we need secure DRM process
+ aIsSecureDrmProcess = ETrue;
+ }
+ }
+
+EXPORT_C CMMSourceSink* CMMSourceSink::NewLC(TUid aUid, const TDesC8& aDescriptor)
+ {
+ CMMSourceSink* self = new (ELeave) CMMSourceSink(aUid);
+ CleanupStack::PushL(self);
+ self->ConstructL(aDescriptor);
+ return self;
+ }
+
+EXPORT_C CMMSourceSink* CMMSourceSink::NewL(TUid aUid, const TDesC8& aDescriptor)
+ {
+ CMMSourceSink* sourcesink = CMMSourceSink::NewLC(aUid, aDescriptor);
+ CleanupStack::Pop(sourcesink);
+ return sourcesink;
+ }
+
+CMMSourceSink::CMMSourceSink(TUid aUid)
+ : iUid(aUid)
+ {
+ }
+
+CMMSourceSink::~CMMSourceSink()
+ {
+ delete iBuf;
+ }
+
+void CMMSourceSink::ConstructL(const TDesC8& aDescriptor)
+ {
+ iBuf = aDescriptor.AllocL();
+ }
+
+TUid CMMSourceSink::SourceSinkUid() const
+ {
+ return iUid;
+ }
+
+const TDesC8& CMMSourceSink::SourceSinkData() const
+ {
+ return *iBuf;
+ }
+
+TBool CMMSourceSink::CarryingFileHandle() const
+ {
+ return EFalse;
+ }
+
+EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const RFile& aFile)
+ {
+ CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);
+ CleanupStack::PushL(self);
+ self->ConstructL(aFile);
+ return self;
+ }
+
+EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const RFile& aFile)
+ {
+ CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aFile);
+ CleanupStack::Pop(sourcesink);
+ return sourcesink;
+ }
+
+CMMFileSourceSink::CMMFileSourceSink(TUid aUid)
+ : CMMSourceSink(aUid)
+ {
+ }
+
+void CMMFileSourceSink::ConstructL(const RFile& aFile)
+ {
+ User::LeaveIfError(iHandle.Duplicate(aFile));
+ iUsingFileHandle = ETrue;
+ iFileName = HBufC::NewMaxL(KMaxFileName);
+ TPtr fileNamePtr = iFileName->Des();
+ iHandle.Name(fileNamePtr);
+ DoCreateFileHandleSourceConfigDataL();
+ }
+
+void CMMFileSourceSink::DoCreateFileHandleSourceConfigDataL()
+ {
+ CBufFlat* buf = CBufFlat::NewL(KExpandSize);
+ CleanupStack::PushL(buf);
+ RBufWriteStream stream;
+ stream.Open(*buf);
+ CleanupClosePushL(stream);
+
+ TPckgBuf<RFile*> fileptr(&iHandle);
+ stream.WriteInt32L(KMMFileHandleSourceUid.iUid);
+ stream.WriteL(fileptr);
+
+ TInt length = 0;
+ if (iUniqueId != NULL)
+ length = iUniqueId->Length();
+ stream.WriteInt32L(length);
+ if (length>0)
+ stream.WriteL(*iUniqueId);
+
+ stream.WriteInt32L(iEnableUI);
+
+ stream.CommitL();
+ CleanupStack::PopAndDestroy(&stream);
+ iSourceSinkData = buf->Ptr(0).AllocL();
+
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+const TDesC8& CMMFileSourceSink::SourceSinkData() const
+ {
+ ASSERT(iSourceSinkData);
+ return *iSourceSinkData;
+ }
+
+CMMFileSourceSink::~CMMFileSourceSink()
+ {
+ iHandle.Close(); // delete whatever
+ delete iFileName;
+ delete iSourceSinkData;
+ delete iUniqueId;
+ }
+
+EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewLC(TUid aUid, const TMMSource& aSource)
+ {
+ CMMFileSourceSink* self = new (ELeave) CMMFileSourceSink(aUid);
+ CleanupStack::PushL(self);
+ self->ConstructL(aSource);
+ return self;
+ }
+
+EXPORT_C CMMFileSourceSink* CMMFileSourceSink::NewL(TUid aUid, const TMMSource& aSource)
+ {
+ CMMFileSourceSink* sourcesink = CMMFileSourceSink::NewLC(aUid, aSource);
+ CleanupStack::Pop(sourcesink);
+ return sourcesink;
+ }
+
+void CMMFileSourceSink::ConstructL(const TMMSource& aSource)
+ {
+ iUniqueId = aSource.UniqueId().AllocL();
+ iIntent = aSource.Intent();
+ iEnableUI = aSource.IsUIEnabled();
+
+ if (aSource.SourceType() == KUidMMFileSource)
+ {
+ const TMMFileSource& fileSource = static_cast<const TMMFileSource&>(aSource);
+ iFileName = fileSource.Name().AllocL();
+
+ DoCreateFileSourceConfigDataL();
+ }
+ else if (aSource.SourceType() == KUidMMFileHandleSource)
+ {
+ const TMMFileHandleSource& fileHandleSource = static_cast<const TMMFileHandleSource&>(aSource);
+ iHandle.Close(); // in case already open
+ User::LeaveIfError(iHandle.Duplicate(fileHandleSource.Handle()));
+ iUsingFileHandle = ETrue;
+ iFileName = HBufC::NewMaxL(KMaxFileName);
+ TPtr fileNamePtr = iFileName->Des();
+ iHandle.Name(fileNamePtr);
+
+ DoCreateFileHandleSourceConfigDataL();
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ }
+ }
+
+void CMMSourceSink::EvaluateIntentL()
+ {
+ }
+
+void CMMFileSourceSink::EvaluateIntentL()
+ {
+ if (iUsingFileHandle)
+ {
+ ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
+ Content->OpenContentLC(iIntent, *iUniqueId);
+ CleanupStack::PopAndDestroy(2, Content);
+ }
+ else
+ {
+ ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
+ Content->OpenContentLC(iIntent, *iUniqueId);
+ CleanupStack::PopAndDestroy(2, Content);
+ }
+ }
+
+
+
+EXPORT_C void CMMFileSourceSink::EvaluateIntentL(ContentAccess::TIntent aIntent)
+ {
+ if (iUsingFileHandle)
+ {
+ ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(iHandle);
+ Content->OpenContentLC(aIntent, *iUniqueId);
+ CleanupStack::PopAndDestroy(2, Content);
+ }
+ else
+ {
+ ContentAccess::CContent* Content = ContentAccess::CContent::NewLC(*iFileName);
+ Content->OpenContentLC(aIntent, *iUniqueId);
+ CleanupStack::PopAndDestroy(2, Content);
+ }
+ }
+
+void CMMFileSourceSink::DoCreateFileSourceConfigDataL()
+ {
+ CBufFlat* buf = CBufFlat::NewL(KExpandSize);
+ CleanupStack::PushL(buf);
+ RBufWriteStream stream;
+ stream.Open(*buf);
+ CleanupClosePushL(stream);
+
+ stream.WriteInt32L(KMMFileSourceUid.iUid);
+ stream.WriteInt32L(iFileName->Length());
+ stream.WriteL(*iFileName);
+ TInt length = 0;
+ if (iUniqueId != NULL)
+ length = iUniqueId->Length();
+ stream.WriteInt32L(length);
+ if (length>0)
+ stream.WriteL(*iUniqueId);
+
+ stream.WriteInt32L(iEnableUI);
+
+ stream.CommitL();
+ CleanupStack::PopAndDestroy(&stream);
+ iSourceSinkData = buf->Ptr(0).AllocL();
+
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+TBool CMMFileSourceSink::CarryingFileHandle() const
+ {
+ return iUsingFileHandle;
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/mmfclientutility.h Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,510 @@
+// Copyright (c) 2002-2009 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:
+// Client utility functions
+//
+//
+
+#ifndef __MMF_CLIENT_UTILITY_H__
+#define __MMF_CLIENT_UTILITY_H__
+
+#include <mda/common/audio.h>
+#include <mda/common/gsmaudio.h>
+#include <mda/client/utility.h>
+#include <mmf/common/mmffourcc.h>
+#include <mmfformatimplementationuids.hrh>
+#include "mmf/common/mmfcontrollerpluginresolver.h"
+#include <mmf/server/mmffile.h>
+#include <mmf/server/mmfdes.h>
+#include "mmf/common/mmfcontroller.h"
+
+#include <f32file.h>
+#include <caf/content.h>
+#include <caf/data.h>
+#include <mmf/common/mmfstandardcustomcommands.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <mmf/common/mmfstandardcustomcommandsenums.h>
+#include <mmf/common/mmfstandardcustomcommandsimpl.h>
+#endif
+#ifdef SYMBIAN_BUILD_GCE
+#include <mmf/common/mmfvideosurfacecustomcommands.h>
+#endif
+
+class CMMSourceSink; // declared here.
+
+NONSHARABLE_CLASS( CMMSourceSink ): public CBase
+ {
+public:
+ IMPORT_C static CMMSourceSink* NewL(TUid aUid, const TDesC8& aDescriptor);
+ IMPORT_C static CMMSourceSink* NewLC(TUid aUid, const TDesC8& aDescriptor);
+
+ virtual ~CMMSourceSink();
+ virtual TUid SourceSinkUid() const;
+ virtual const TDesC8& SourceSinkData() const;
+
+ virtual TBool CarryingFileHandle() const;
+
+ virtual void EvaluateIntentL();
+protected:
+ CMMSourceSink(TUid aUid);
+
+
+private:
+ void ConstructL(const TDesC8& aDescriptor);
+
+ const TUid iUid;
+ HBufC8* iBuf;
+ };
+
+
+
+
+class CMMFileSourceSink; // declared here.
+
+NONSHARABLE_CLASS( CMMFileSourceSink ): public CMMSourceSink
+ {
+public:
+ IMPORT_C static CMMFileSourceSink* NewL(TUid aUid, const RFile& aFile);
+ IMPORT_C static CMMFileSourceSink* NewLC(TUid aUid, const RFile& aFile);
+
+ IMPORT_C static CMMFileSourceSink* NewL(TUid aUid, const TMMSource& aMMSource);
+ IMPORT_C static CMMFileSourceSink* NewLC(TUid aUid, const TMMSource& aMMSource);
+
+ const TDesC& UniqueId() const {return *iUniqueId;}
+
+ virtual ~CMMFileSourceSink();
+
+ const TDesC& FileName() const {return *iFileName;}
+ const TDesC8& SourceSinkData() const;
+
+ IMPORT_C void EvaluateIntentL(ContentAccess::TIntent aIntent);
+ virtual void EvaluateIntentL();
+
+ TBool CarryingFileHandle() const;
+
+ TBool UsingFileHandle() const {return iUsingFileHandle;};
+ const RFile& FileHandle() const {return iHandle;};
+protected:
+ CMMFileSourceSink(TUid aUid);
+
+private:
+ void ConstructL(const TMMSource& aSource);
+ void DoCreateFileSourceConfigDataL();
+ void ConstructL(const RFile& aFile);
+ void DoCreateFileHandleSourceConfigDataL();
+
+ TBool iUsingFileHandle;
+ RFile iHandle;
+ HBufC* iFileName;
+ HBufC8* iSourceSinkData;
+ HBufC* iUniqueId;
+ ContentAccess::TIntent iIntent;
+
+ TBool iEnableUI;
+ };
+
+
+
+class CMMFMdaObjectStateChangeObserverCallback; // declared here.
+/**
+Active object utility class to allow the callback to be called asynchronously.
+This should help prevent re-entrant code in clients of the mediaframework.
+*/
+NONSHARABLE_CLASS( CMMFMdaObjectStateChangeObserverCallback ): public CActive
+ {
+public:
+ IMPORT_C static CMMFMdaObjectStateChangeObserverCallback* NewL(MMdaObjectStateChangeObserver& aCallback);
+ virtual ~CMMFMdaObjectStateChangeObserverCallback();
+ IMPORT_C void CallBack(CBase* aObject, TInt aPreviousState, TInt aCurrentState, TInt aErrorCode);
+private:
+ CMMFMdaObjectStateChangeObserverCallback(MMdaObjectStateChangeObserver& aCallback);
+ void RunL();
+ void DoCancel();
+private:
+ MMdaObjectStateChangeObserver& iCallback;
+ CBase* iObject;
+ TInt iPreviousState;
+ TInt iCurrentState;
+ TInt iErrorCode;
+ };
+
+class CMMFClientUtility; // declared here.
+
+NONSHARABLE_CLASS( CMMFClientUtility )
+ {
+public:
+ IMPORT_C static TUid ConvertMdaFormatUidToECOMWrite(TUid aMdaFormatUid);
+ IMPORT_C static TUid ConvertMdaFormatUidToECOMRead(TUid aMdaFormatUid);
+ IMPORT_C static TFourCC ConvertMdaCodecToFourCC(TMdaPackage& aCodec);
+ IMPORT_C static TInt GetFileHeaderData(const TDesC& aFileName, TDes8& aHeaderData, TInt aMaxLength);
+ IMPORT_C static HBufC8* GetFileExtensionL(const TDesC& aFileName);
+ static void PrioritiseControllersL(
+ const RMMFControllerImplInfoArray& aControllers,
+ const TDesC8& aHeaderDataPlayback,
+ const TDesC8& aFileExtensionPlayback,
+ const TDesC8& aHeaderDataRecord,
+ const TDesC8& aFileExtensionRecord,
+ RMMFControllerImplInfoArray& aPrioritisedControllers);
+ static TInt GetBestMatchL(const CMMFFormatImplementationInformation* format, const TDesC8& aHeaderData, const TDesC8& aFileExtension);
+
+private:
+ CMMFClientUtility();
+ };
+
+class CMMFUtilityFileInfo; // declared here.
+class RMMFDRMPluginServerProxy;
+
+NONSHARABLE_CLASS( CMMFUtilityFileInfo ): public CBase
+ {
+public:
+
+ static CMMFUtilityFileInfo* NewL(TMMSource& aSource, TBool aSecureDRMMode = EFalse);
+ static CMMFUtilityFileInfo* NewLC(TMMSource& aSource, TBool aSecureDRMMode = EFalse);
+
+ ~CMMFUtilityFileInfo();
+
+ TBool GetFileMimeTypeL(TDes8& aMimeType);
+ void GetFileHeaderDataL(TDes8& aHeaderData, TInt aMaxLength);
+ TInt EvaluateIntent(ContentAccess::TIntent aIntent);
+
+private:
+ CMMFUtilityFileInfo();
+
+ void ConstructL(const TMMSource& aSource, TBool aSecureDRMMode);
+
+private:
+ ContentAccess::CData* iData;
+ RMMFDRMPluginServerProxy* iDrmPluginServer;
+ };
+
+inline CMMFUtilityFileInfo::CMMFUtilityFileInfo()
+ {
+ };
+
+/**
+ * Mixin class that the user of the class CMMFFindAndOpenController must derive from.
+ * @internalComponent
+ */
+class MMMFFindAndOpenControllerObserver
+ {
+public:
+ /**
+ * Callback function to indicate the success or failure
+ * of an attempt to find and open a suitable controller and
+ * to add a source and sink.
+ * @see CMMFFindAndOpenController
+ *
+ * @param aError
+ * Indicates whether a controller has been opened sucessfully
+ * This is passed by reference, mainly for the audio recorder utility
+ * which opens two controllers: if the secondary controller (which is
+ * always opened first) fails to open, then the audio recorder utility
+ * may choose to set aError = KErrNone in the MfaocComplete() callback
+ * to indicate to CFindAndOpenControler() that it should continue
+ * to open the primary controller, even though opening the secondary failed.
+ * @param aController
+ * A pointer to the controller that has been opened or has failed to open
+ * This is mainly for the audio recorder utility to indicate
+ * which controller (primary or secondary) has been opened.
+ * @param aControllerUid
+ * the UID of the controller that has been opened
+ * @param aSourceHandle
+ * a pointer to the source handle
+ * @internalComponent
+ * a pointer to the sink handle
+ */
+ virtual void MfaocComplete(
+ TInt& aError,
+ RMMFController* aController,
+ TUid aControllerUid = KNullUid,
+ TMMFMessageDestination* aSourceHandle = NULL,
+ TMMFMessageDestination* aSinkHandle = NULL) = 0;
+ };
+
+
+class CMMFFindAndOpenController; // declared here.
+/**
+ * Utility class used by the MMF client API classes.
+ * Finds and opens a suitable controller and adds a source and a sink
+ * asynchronously. Completion is indicated asynchronously
+ * using the MMMFFindAndOpenControllerObserver mixin class.
+ *
+ * @internalComponent
+ */
+NONSHARABLE_CLASS( CMMFFindAndOpenController ): public CActive, public MMMFAddDataSourceSinkAsyncObserver
+ {
+public:
+ enum TControllerMode
+ {
+ EPlayback,
+ ERecord,
+ EConvert
+ };
+
+ enum TControllerNumber
+ {
+ EPrimaryController,
+ ESecondaryController
+ };
+
+ class TSourceSink
+ {
+ public:
+ IMPORT_C TSourceSink(TUid aUid, const TDesC8& aData = KNullDesC8);
+ IMPORT_C TSourceSink(TUid aUid, const RFile& aFile);
+
+ TUid iUid;
+ const TDesC8& iConfigData;
+ TBool iUseFileHandle;
+ RFile iFileHandle;
+ };
+
+
+
+
+public:
+ IMPORT_C static CMMFFindAndOpenController* NewL(MMMFFindAndOpenControllerObserver& aObserver);
+ virtual ~CMMFFindAndOpenController();
+
+ // from CActive
+ virtual void DoCancel();
+ virtual void RunL();
+
+ // from MMMFAddDataSourceSinkAsyncObserver
+ virtual void MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle);
+
+ IMPORT_C void Configure(
+ TUid aMediaId,
+ TMMFPrioritySettings aPrioritySettings,
+ CMMFPluginSelectionParameters::TMediaIdMatchType aMediaIdMatchType = CMMFPluginSelectionParameters::EAllowOnlySuppliedMediaIds);
+
+ IMPORT_C void ConfigureController(RMMFController& aController, CMMFControllerEventMonitor& aEventMonitor, TControllerMode aControllerMode = EPlayback);
+ IMPORT_C void ConfigureSecondaryController(RMMFController& aController, CMMFControllerEventMonitor& aEventMonitor, TControllerMode aControllerMode = EPlayback);
+
+ IMPORT_C void UseSharedHeap();
+
+ IMPORT_C void ConfigureSourceSink(
+ TSourceSink aSource,
+ TSourceSink aSink);
+ IMPORT_C void ConfigureSecondarySourceSink(
+ TSourceSink aSource,
+ TSourceSink aSink);
+
+ IMPORT_C void ConfigureSourceSink(
+ const TMMSource& aSource,
+ TSourceSink aSink);
+
+ IMPORT_C void OpenByFileSource(const TMMSource& aFileSource, const TDesC& aFileNameSecondary = KNullDesC);
+
+ IMPORT_C void OpenByFormatUid(TUid aFormatUid, TUid aFormatUidSecondary = KNullUid);
+ IMPORT_C void OpenByDescriptor(const TDesC8& aDescriptor);
+ IMPORT_C void OpenByUrl(const TDesC& aUrl, TInt aIapId, const TDesC8& aMimeType);
+ IMPORT_C void OpenByControllerUid(TUid aControllerUid, TUid aSecondaryControllerUid = KNullUid);
+ IMPORT_C void ReOpen();
+ IMPORT_C void Close();
+
+ IMPORT_C static TMMFFileConfig GetConfigFile(const TDesC& aFileName);
+ IMPORT_C static TMMFDescriptorConfig GetConfigDescriptor(const TDesC8& aDescriptor);
+ IMPORT_C void CloseConfig();
+ IMPORT_C static void GetConfigUrlL(CBufFlat*& aUrlCfgBuffer, const TDesC& aUrl, TInt aIapId);
+
+ /** made public to check for further selected controllers in the queue */
+ inline TInt ControllerIndex() const;
+ inline TInt ControllerCount() const;
+
+ /** made public to stop checking for further selected controllers in the queue */
+ inline TBool StopTryLoadController() const;
+ IMPORT_C void SetInitScreenNumber(TInt aScreenNumber, RMMFVideoSetInitScreenCustomCommands* aVideoSetInitScreenCustomCommands);
+#ifdef SYMBIAN_BUILD_GCE
+ inline void SetSurfaceMode(TBool aUseSurface, RMMFVideoPlaySurfaceSupportCustomCommands* aVideoPlaySurfaceSupportCustomCommands);
+ inline TInt SurfaceSupported();
+#endif
+
+private:
+ class CConfig: public CBase
+ {
+ public:
+ CConfig();
+ ~CConfig();
+ void Close();
+ public:
+ RMMFController* iController; // not owned
+ CMMFControllerEventMonitor* iEventMonitor; // not owned
+
+ /** indicates whether this controller is being used for
+ playback, recording or converting */
+ TControllerMode iControllerMode;
+
+ CMMSourceSink* iSource;
+ CMMSourceSink* iSink;
+ TUid iControllerUid;
+ };
+
+ CMMFFindAndOpenController(MMMFFindAndOpenControllerObserver& aObserver);
+ void ConstructL();
+
+ void Init();
+
+ void ConfigureSourceSink(
+ CConfig& config,
+ TSourceSink aSource,
+ TSourceSink aSink);
+
+ void ConfigureSourceSink(
+ CConfig& config,
+ const TMMSource& aSource,
+ TSourceSink aSink);
+
+
+ void ConfigureController(
+ CConfig& config,
+ RMMFController& aController,
+ CMMFControllerEventMonitor& aEventMonitor,
+ TControllerMode aControllerMode);
+
+ void CloseController();
+
+ void OpenPrimaryController(void);
+
+ void KickState();
+ void Process();
+ void SendError(TInt aError = KErrNone, TBool aForcedError = EFalse);
+ void SchedSendError(TInt aError = KErrNone);
+ void BuildControllerListFileNameL();
+ void BuildControllerListDescriptorL();
+ void BuildControllerListUrlL();
+ void BuildControllerListFormatL();
+ void TryNextController();
+
+ CMMSourceSink* CreateSourceSinkL(const TSourceSink& aParams);
+ CMMSourceSink* CreateSourceSinkL(const TMMSource& aSource);
+
+ CMMFUtilityFileInfo* CreateFileInfoL(TBool aSecureDRMMode = EFalse);
+ void UseSecureDRMProcessL(TBool& aIsSecureDrmProcess);
+private:
+ /** primary controller details */
+ CConfig* iPrimaryConfig;
+ /** secondary controller details */
+ CConfig* iSecondaryConfig;
+ /** points to either iPrimaryConfig or iSecondaryConfig */
+ CConfig* iCurrentConfig; // not owned
+
+ enum TMode
+ {
+ EOpenByControllerUid,
+ EOpenByFileName,
+ EOpenByDescriptor,
+ EOpenByUrl,
+ EOpenByFormatUid
+ };
+ TMode iMode;
+
+ /** indicates what state the state machine is in */
+ enum TState
+ {
+ EIdle,
+ EBuildControllerList,
+ EOpenController,
+ EAddSource,
+ EAddSink,
+ EWaitingForSource,
+ EWaitingForSink,
+ ESendError
+ };
+ TState iState;
+
+ MMMFFindAndOpenControllerObserver& iObserver;
+ CMMFAddDataSourceSinkAsync* iAddDataSourceSinkAsync;
+
+ TInt iControllerIndex;
+ TInt iControllerCount;
+
+ TFileName iFileNameSecondary; // for converting
+
+ TFileName iFileName;
+ TBool iUseFileHandle;
+ TBool iOwnFileHandle;
+ HBufC* iUniqueId;
+ RFile iFileHandle;
+ ContentAccess::TIntent iIntent;
+
+ HBufC* iUrl;
+ HBufC8* iMimeType;
+ TPtr8 iDescriptor;
+ TInt iIapId;
+ TUid iFormatUid;
+ TUid iFormatUidSecondary; // for converting
+
+ TUid iMediaId;
+ TMMFPrioritySettings iPrioritySettings;
+ CMMFPluginSelectionParameters::TMediaIdMatchType iMediaIdMatchType;
+
+ RMMFControllerImplInfoArray iControllers;
+ RMMFControllerImplInfoArray iPrioritisedControllers;
+
+ // if this is non-null, then it points to an element in
+ // either iControllers or iPrioritisedControllers
+ CMMFControllerImplementationInformation* iControllerImplInfo; // not owned
+
+ TControllerMode iControllerMode;
+ TBool iSourceSinkConfigured;
+ TInt iError;
+
+ TMMFMessageDestination iSourceHandle;
+ TMMFMessageDestination iSinkHandle;
+ TBool iEnableUi;
+
+ TBool iUseSharedHeap; // should new controllers use shared heaps?
+ TBool iStopTryLoadController; //stop to try loading the selected conrollers from the list
+ RMMFVideoSetInitScreenCustomCommands* iVideoSetInitScreenCustomCommands;
+ TInt iScreenNumber;
+ TBool iHasDrmCapability;
+ TBool iUsingSecureDrmProcess;
+
+#ifdef SYMBIAN_BUILD_GCE
+ RMMFVideoPlaySurfaceSupportCustomCommands* iVideoPlaySurfaceSupportCustomCommands;
+ TBool iUseVPU2;
+ TInt iSurfaceSupported;
+#endif
+ };
+
+inline TInt CMMFFindAndOpenController::ControllerIndex() const
+ {
+ return iControllerIndex;
+ }
+
+inline TInt CMMFFindAndOpenController::ControllerCount() const
+ {
+ return iControllerCount;
+ }
+
+inline TBool CMMFFindAndOpenController::StopTryLoadController() const
+ {
+ return iStopTryLoadController;
+ }
+
+#ifdef SYMBIAN_BUILD_GCE
+inline void CMMFFindAndOpenController::SetSurfaceMode(TBool aUseVPU2, RMMFVideoPlaySurfaceSupportCustomCommands* aVideoPlaySurfaceSupportCustomCommands)
+ {
+ iUseVPU2 = aUseVPU2;
+ iSurfaceSupported = KErrNone;
+ iVideoPlaySurfaceSupportCustomCommands = aVideoPlaySurfaceSupportCustomCommands;
+ }
+
+inline TInt CMMFFindAndOpenController::SurfaceSupported()
+ {
+ return iSurfaceSupported;
+ }
+#endif // SYMBIAN_BUILD_GCE
+
+#endif // __MMF_CLIENT_UTILITY_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eabi/MediaClientAudio.def Fri Nov 12 11:56:07 2010 +0000
@@ -0,0 +1,166 @@
+EXPORTS
+ _ZN13CMdaAudioTypeD0Ev @ 1 NONAME ABSENT
+ _ZN13CMdaAudioTypeD1Ev @ 2 NONAME ABSENT
+ _ZN13CMdaAudioTypeD2Ev @ 3 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility11GetBalanceLEv @ 4 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility11SetBalanceLEi @ 5 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility15CustomInterfaceE4TUid @ 6 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility21PrepareToPlayDualToneEiiRK25TTimeIntervalMicroSeconds @ 7 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility25PrepareToPlayFileSequenceER5RFile @ 8 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility4NewLER21MMdaAudioToneObserverP10CMdaServer @ 9 NONAME ; # first Stem
+ _ZN20CMdaAudioToneUtility4NewLER21MMdaAudioToneObserverP10CMdaServerii @ 10 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility10GetBalanceERi @ 11 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility10GetBitRateERj @ 12 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility10SetBalanceEi @ 13 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility11GetPositionER25TTimeIntervalMicroSeconds @ 14 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility11SetPositionERK25TTimeIntervalMicroSeconds @ 15 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility11SetPriorityEii @ 16 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility13NewDesPlayerLERK6TDesC8R23MMdaAudioPlayerCallbackiiP10CMdaServer @ 17 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility13SetPlayWindowERK25TTimeIntervalMicroSecondsS2_ @ 18 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility14NewFilePlayerLERK7TDesC16R23MMdaAudioPlayerCallbackiiP10CMdaServer @ 19 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility14WillResumePlayEv @ 20 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility15ClearPlayWindowEv @ 21 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility17CustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_ @ 22 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility17CustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8 @ 23 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility17GetMetaDataEntryLEi @ 24 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility18CustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R14TRequestStatus @ 25 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility18CustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8R14TRequestStatus @ 26 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility19GetDRMCustomCommandEv @ 27 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility21NewDesPlayerReadOnlyLERK6TDesC8R23MMdaAudioPlayerCallbackiiP10CMdaServer @ 28 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility24GetAudioLoadingProgressLERi @ 29 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility26GetNumberOfMetaDataEntriesERi @ 30 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility33RegisterAudioResourceNotificationER37MMMFAudioResourceNotificationCallback4TUidRK6TDesC8 @ 31 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility35RegisterForAudioLoadingNotificationER21MAudioLoadingObserver @ 32 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility36ControllerImplementationInformationLEv @ 33 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility39CancelRegisterAudioResourceNotificationE4TUid @ 34 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility4NewLER23MMdaAudioPlayerCallbackii @ 35 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility5CloseEv @ 36 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility5PauseEv @ 37 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility8OpenDesLERK6TDesC8 @ 38 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility8OpenUrlLERK7TDesC16iRK6TDesC8 @ 39 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility9GetVolumeERi @ 40 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility9OpenFileLERK5RFile @ 41 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility9OpenFileLERK7TDesC16 @ 42 NONAME ABSENT ; # Stem
+ _ZN22CMdaAudioPlayerUtility9OpenFileLERK9TMMSource @ 43 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility13SourceFormatLEv @ 44 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility14SourceBitRateLEv @ 45 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility15SourceDataTypeLEv @ 46 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility17CustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_ @ 47 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility17CustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8 @ 48 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility17SourceSampleRateLEv @ 49 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility18CustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R14TRequestStatus @ 50 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility18CustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8R14TRequestStatus @ 51 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility18DestinationFormatLEv @ 52 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility19DestinationBitRateLEv @ 53 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility20DestinationDataTypeLEv @ 54 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility21SetDestinationFormatLE4TUid @ 55 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility22DestinationSampleRateLEv @ 56 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility22SetDestinationBitRateLEj @ 57 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility23SetDestinationDataTypeLE7TFourCC @ 58 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility23SourceNumberOfChannelsLEv @ 59 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility25SetDestinationSampleRateLEj @ 60 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility28DestinationNumberOfChannelsLEv @ 61 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility31GetSupportedConversionBitRatesLER6RArrayIjE @ 62 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility31SetDestinationNumberOfChannelsLEj @ 63 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility33GetSupportedDestinationDataTypesLER6RArrayI7TFourCCE @ 64 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility34GetSupportedConversionSampleRatesLER6RArrayIjE @ 65 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility36ControllerImplementationInformationLEv @ 66 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility39GetSupportedConversionNumberOfChannelsLER6RArrayIjE @ 67 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility4NewLER29MMdaObjectStateChangeObserverP10CMdaServerii @ 68 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility5OpenLEP16TMdaClipLocationS1_4TUidS2_7TFourCC @ 69 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility8ConvertLEv @ 70 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility11SetPriorityEii @ 71 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility14SourceBitRateLEv @ 72 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility14WillResumePlayEv @ 73 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility16GetRecordBalanceERi @ 74 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility16SetRecordBalanceEi @ 75 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility17AddMetaDataEntryLER17CMMFMetaDataEntry @ 76 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility17GetMetaDataEntryLEi @ 77 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility18DestinationFormatLEv @ 78 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility18GetPlaybackBalanceERi @ 79 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility18SetPlaybackBalanceEi @ 80 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility19DestinationBitRateLEv @ 81 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility19GetDRMCustomCommandEv @ 82 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility19RemoveMetaDataEntryEi @ 83 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility20DestinationDataTypeLEv @ 84 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility21GetSupportedBitRatesLER6RArrayIjE @ 85 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility21ReplaceMetaDataEntryLEiR17CMMFMetaDataEntry @ 86 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility21SetDestinationFormatLE4TUid @ 87 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility22DestinationSampleRateLEv @ 88 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility22SetDestinationBitRateLEj @ 89 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility23SetDestinationDataTypeLE7TFourCC @ 90 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility24GetAudioLoadingProgressLERi @ 91 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility24GetSupportedSampleRatesLER6RArrayIjE @ 92 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility25SetDestinationSampleRateLEj @ 93 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility26GetNumberOfMetaDataEntriesERi @ 94 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility28DestinationNumberOfChannelsLEv @ 95 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility29GetSupportedNumberOfChannelsLER6RArrayIjE @ 96 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility31PlayControllerCustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_ @ 97 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility31PlayControllerCustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8 @ 98 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility31SetDestinationNumberOfChannelsLEj @ 99 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility32PlayControllerCustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R14TRequestStatus @ 100 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility32PlayControllerCustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8R14TRequestStatus @ 101 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility33GetSupportedDestinationDataTypesLER6RArrayI7TFourCCE @ 102 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility33RecordControllerCustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_ @ 103 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility33RecordControllerCustomCommandSyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8 @ 104 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility33RegisterAudioResourceNotificationER37MMMFAudioResourceNotificationCallback4TUidRK6TDesC8 @ 105 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility34RecordControllerCustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R14TRequestStatus @ 106 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility34RecordControllerCustomCommandAsyncERK8TPckgBufI22TMMFMessageDestinationEiRK6TDesC8S7_R5TDes8R14TRequestStatus @ 107 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility35RegisterForAudioLoadingNotificationER21MAudioLoadingObserver @ 108 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility39CancelRegisterAudioResourceNotificationE4TUid @ 109 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility45AudioPlayControllerImplementationInformationLEv @ 110 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility49AudioRecorderControllerImplementationInformationLEv @ 111 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility4NewLER29MMdaObjectStateChangeObserverP10CMdaServerii @ 112 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility7GetGainERi @ 113 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility8OpenDesLER5TDes8 @ 114 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility8OpenDesLER5TDes84TUidS2_S2_7TFourCC @ 115 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility8OpenUrlLERK7TDesC16i4TUidS3_S3_7TFourCC @ 116 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility8OpenUrlLERK7TDesC16iRK6TDesC8 @ 117 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility9GetVolumeERi @ 118 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility9OpenFileLERK5RFile @ 119 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility9OpenFileLERK5RFile4TUidS3_S3_7TFourCC @ 120 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility9OpenFileLERK7TDesC164TUidS3_S3_7TFourCC @ 121 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility9OpenFileLERK9TMMSource @ 122 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility9OpenFileLERK9TMMSource4TUidS3_S3_7TFourCC @ 123 NONAME ABSENT
+ _ZTI13CMdaAudioType @ 124 NONAME ABSENT ; #<TI>#
+ _ZTI18CMMFDualToneConfig @ 125 NONAME ABSENT ; #<TI>#
+ _ZTI20CMMFDesSeqToneConfig @ 126 NONAME ABSENT ; #<TI>#
+ _ZTI20CMMFSimpleToneConfig @ 127 NONAME ABSENT ; #<TI>#
+ _ZTI20CMdaAudioClipUtility @ 128 NONAME ABSENT ; #<TI>#
+ _ZTI20CMdaAudioToneUtility @ 129 NONAME ABSENT ; #<TI>#
+ _ZTI21CMMFFileSeqToneConfig @ 130 NONAME ABSENT ; #<TI>#
+ _ZTI22CMMFFixedSeqToneConfig @ 131 NONAME ABSENT ; #<TI>#
+ _ZTI22CMdaAudioPlayerUtility @ 132 NONAME ABSENT ; #<TI>#
+ _ZTI23CMdaAudioConvertUtility @ 133 NONAME ABSENT ; #<TI>#
+ _ZTI24CMMFDTMFStringToneConfig @ 134 NONAME ABSENT ; #<TI>#
+ _ZTI24CMdaAudioRecorderUtility @ 135 NONAME ABSENT ; #<TI>#
+ _ZTI26CMMFMdaAudioPlayerCallBack @ 136 NONAME ABSENT ; #<TI>#
+ _ZTI27CRepeatTrailingSilenceTimer @ 137 NONAME ABSENT ; #<TI>#
+ _ZTI32CMMFMdaAudioToneObserverCallback @ 138 NONAME ABSENT ; #<TI>#
+ _ZTV13CMdaAudioType @ 139 NONAME ABSENT ; #<VT>#
+ _ZTV18CMMFDualToneConfig @ 140 NONAME ABSENT ; #<VT>#
+ _ZTV20CMMFDesSeqToneConfig @ 141 NONAME ABSENT ; #<VT>#
+ _ZTV20CMMFSimpleToneConfig @ 142 NONAME ABSENT ; #<VT>#
+ _ZTV20CMdaAudioClipUtility @ 143 NONAME ABSENT ; #<VT>#
+ _ZTV20CMdaAudioToneUtility @ 144 NONAME ABSENT ; #<VT>#
+ _ZTV21CMMFFileSeqToneConfig @ 145 NONAME ABSENT ; #<VT>#
+ _ZTV22CMMFFixedSeqToneConfig @ 146 NONAME ABSENT ; #<VT>#
+ _ZTV22CMdaAudioPlayerUtility @ 147 NONAME ABSENT ; #<VT>#
+ _ZTV23CMdaAudioConvertUtility @ 148 NONAME ABSENT ; #<VT>#
+ _ZTV24CMMFDTMFStringToneConfig @ 149 NONAME ABSENT ; #<VT>#
+ _ZTV24CMdaAudioRecorderUtility @ 150 NONAME ABSENT ; #<VT>#
+ _ZTV26CMMFMdaAudioPlayerCallBack @ 151 NONAME ABSENT ; #<VT>#
+ _ZTV27CRepeatTrailingSilenceTimer @ 152 NONAME ABSENT ; #<VT>#
+ _ZTV32CMMFMdaAudioToneObserverCallback @ 153 NONAME ABSENT ; #<VT>#
+ _ZNK22CMdaAudioPlayerUtility17SetThreadPriorityERK15TThreadPriority @ 154 NONAME ABSENT
+ _ZNK23CMdaAudioConvertUtility17SetThreadPriorityERK15TThreadPriority @ 155 NONAME ABSENT
+ _ZNK24CMdaAudioRecorderUtility23SetThreadPriorityRecordERK15TThreadPriority @ 156 NONAME ABSENT
+ _ZNK24CMdaAudioRecorderUtility25SetThreadPriorityPlaybackERK15TThreadPriority @ 157 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility13UseSharedHeapEv @ 158 NONAME ABSENT
+ _ZN22CMdaAudioPlayerUtility8DurationER25TTimeIntervalMicroSeconds @ 159 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility8DurationER25TTimeIntervalMicroSeconds @ 160 NONAME ABSENT
+ _ZN23CMdaAudioConvertUtility13UseSharedHeapEv @ 161 NONAME ABSENT
+ _ZN24CMdaAudioRecorderUtility13UseSharedHeapEv @ 162 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility5PauseEv @ 163 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility6ResumeEv @ 164 NONAME ABSENT
+ _ZN20CMdaAudioToneUtility25RegisterPlayStartCallbackER30MMdaAudioTonePlayStartObserver @ 165 NONAME ABSENT
--- a/group/bld.inf Thu Nov 11 17:57:32 2010 +0000
+++ b/group/bld.inf Fri Nov 12 11:56:07 2010 +0000
@@ -23,6 +23,9 @@
PRJ_MMPFILES
+// Pure stemkit code
+../breakdeps/MediaClientAudio.mmp
+
// based on sf/os/devicesrv
../startup/ssmcmdlists.mmp
../startup/ssmstartuppolicy.mmp