breakdeps/mmfclientaudioplayer.cpp
changeset 127 a2070821d450
child 128 8338c5c25b5b
equal deleted inserted replaced
120:052d4b8fc4fd 127:a2070821d450
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <bautils.h>
       
    17 #include <utf.h>
       
    18 #include <mmf/common/mmfpaniccodes.h>
       
    19 #include "mmfclientaudioplayer.h"
       
    20 #include "mmfclientutility.h"
       
    21 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    22 #include <mmf/common/mmfdurationinfocustomcommandsimpl.h>
       
    23 #include <mmf/common/mmfdurationinfocustomcommandsenums.h>
       
    24 #endif
       
    25 
       
    26 using namespace ContentAccess;
       
    27 
       
    28 // declared in the recorder module
       
    29 void Panic(TInt aPanicCode);
       
    30 
       
    31 void TMMFMessage::Complete(TInt aReason)
       
    32 	{
       
    33 	iMessage.Complete(aReason);
       
    34 	iAmCompleted = ETrue;
       
    35 	}
       
    36 
       
    37 /**
       
    38 Constructs and initialises a new instance of the audio player utility.
       
    39 
       
    40 The function leaves if the audio player utility object cannot be created.
       
    41 
       
    42 No callback notification is made upon completion of NewL().
       
    43 
       
    44 @param  aCallback
       
    45         The audio player observer interface.
       
    46 @param  aPriority
       
    47         The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and 
       
    48         EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
       
    49 @param  aPref
       
    50         The Priority Preference - an additional audio policy parameter. The suggested default is 
       
    51         EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional 
       
    52         values may be supported by given phones and/or platforms, but should not be depended upon by 
       
    53         portable code.
       
    54 
       
    55 @return A pointer to the new audio player utility object.
       
    56 
       
    57 Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
       
    58 several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference, 
       
    59 the adaptation may consider other parameters such as the SecureId and Capabilities of the client process. 
       
    60 Whatever, the decision  as to what to do in such situations is up to the audio adaptation, and may
       
    61 vary between different phones. Portable applications are advised not to assume any specific behaviour. 
       
    62 */
       
    63 EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewL(MMdaAudioPlayerCallback& aCallback,
       
    64 															  TInt aPriority,
       
    65 															  TInt aPref)
       
    66 	{
       
    67 	CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
       
    68 	CleanupStack::PushL(self);
       
    69 	self->iProperties = CMMFMdaAudioPlayerUtility::NewL(aCallback, aPriority, aPref);
       
    70 	CleanupStack::Pop(self);
       
    71 	return self;
       
    72 	}
       
    73 
       
    74 /**
       
    75 Constructs and initialises a new instance of the audio player utility for playing sampled audio data 
       
    76 from a file. The audio data must be in a supported format (e.g. WAV and AU).
       
    77 
       
    78 The function leaves if the audio player utility object cannot be created.
       
    79 
       
    80 When initialisation of the audio player utility is complete, successfully or otherwise, the callback 
       
    81 function MMdaAudioPlayerCallback::MapcInitComplete() is called.
       
    82 
       
    83 @param  aFileName 
       
    84         The full path name of the file containing the audio data.
       
    85 @param  aCallback 
       
    86         The audio player observer interface.
       
    87 @param  aPriority
       
    88         The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and 
       
    89         EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
       
    90 @param  aPref
       
    91         The Priority Preference - an additional audio policy parameter. The suggested default is 
       
    92         EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional 
       
    93         values may be supported by given phones and/or platforms, but should not be depended upon by 
       
    94         portable code.
       
    95 @param  aServer
       
    96         Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
       
    97 
       
    98 @return A pointer to the new audio player utility object.
       
    99 
       
   100 Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
       
   101 several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference, 
       
   102 the adaptation may consider other parameters such as the SecureId and Capabilities of the client process. 
       
   103 Whatever, the decision  as to what to do in such situations is up to the audio adaptation, and may
       
   104 vary between different phones. Portable applications are advised not to assume any specific behaviour. 
       
   105 */
       
   106 EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewFilePlayerL(const TDesC& aFileName,
       
   107 																		MMdaAudioPlayerCallback& aCallback,
       
   108 																		TInt aPriority,
       
   109 																		TInt aPref,
       
   110 																		CMdaServer* /*aServer*/)
       
   111 	{
       
   112 	CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
       
   113 	CleanupStack::PushL(self);
       
   114 	self->iProperties = CMMFMdaAudioPlayerUtility::NewFilePlayerL(aFileName, aCallback, aPriority, aPref);
       
   115 	CleanupStack::Pop(self);
       
   116 	return self;
       
   117 	}
       
   118 
       
   119 /**
       
   120 Constructs and initialises a new instance of the audio player utility for playing sampled audio data 
       
   121 from a descriptor.
       
   122 
       
   123 The audio data must be in a supported format (e.g. WAV and AU).
       
   124 
       
   125 The function leaves if the audio player utility object cannot be created. When initialisation of the 
       
   126 audio player utility is complete, successfully or otherwise, the callback function 
       
   127 MMdaAudioPlayerCallback::MapcInitComplete() is called.
       
   128 
       
   129 @param  aData 
       
   130         A descriptor containing the audio data. This descriptor must remain in existence for the 
       
   131         lifetime of this audio player utility object.
       
   132 @param  aCallback 
       
   133         The audio player observer interface.
       
   134 @param  aPriority
       
   135         The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and 
       
   136         EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
       
   137 @param  aPref
       
   138         The Priority Preference - an additional audio policy parameter. The suggested default is 
       
   139         EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional 
       
   140         values may be supported by given phones and/or platforms, but should not be depended upon by 
       
   141         portable code.
       
   142 @param  aServer
       
   143         Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
       
   144 
       
   145 @return A pointer to the new audio player utility object.
       
   146 
       
   147 Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
       
   148 several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference, 
       
   149 the adaptation may consider other parameters such as the SecureId and Capabilities of the client process. 
       
   150 Whatever, the decision  as to what to do in such situations is up to the audio adaptation, and may
       
   151 vary between different phones. Portable applications are advised not to assume any specific behaviour. 
       
   152 */
       
   153 EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewDesPlayerL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
       
   154 	{
       
   155 	CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
       
   156 	CleanupStack::PushL(self);
       
   157 	self->iProperties = CMMFMdaAudioPlayerUtility::NewDesPlayerL(aData, aCallback, aPriority, aPref);
       
   158 	CleanupStack::Pop(self);
       
   159 	return self;
       
   160 	}
       
   161 
       
   162 /**
       
   163 Constructs and initialises a new instance of the audio player utility for playing sampled audio data 
       
   164 from a read only descriptor.
       
   165 
       
   166 The audio data must be in a supported format (e.g. WAV and AU).
       
   167 
       
   168 The function leaves if the audio player utility object cannot be created. When initialisation of 
       
   169 the audio player utility is complete, successfully or otherwise, the callback function 
       
   170 MMdaAudioPlayerCallback::MapcInitComplete() is called.
       
   171 
       
   172 @param  aData 
       
   173         A read only descriptor containing the audio data. This descriptor must remain in existence 
       
   174         for the lifetime of this audio player utility object.
       
   175 @param  aCallback 
       
   176         The audio player observer interface.
       
   177 @param  aPriority
       
   178         The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and 
       
   179         EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
       
   180 @param  aPref
       
   181         The Priority Preference - an additional audio policy parameter. The suggested default is 
       
   182         EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional 
       
   183         values may be supported by given phones and/or platforms, but should not be depended upon by 
       
   184         portable code.
       
   185 @param  aServer
       
   186         Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
       
   187 
       
   188 @return A pointer to a new audio player utility.
       
   189 
       
   190 Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
       
   191 several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference, 
       
   192 the adaptation may consider other parameters such as the SecureId and Capabilities of the client process. 
       
   193 Whatever, the decision  as to what to do in such situations is up to the audio adaptation, and may
       
   194 vary between different phones. Portable applications are advised not to assume any specific behaviour. 
       
   195 */
       
   196 EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
       
   197 	{
       
   198 	CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
       
   199 	CleanupStack::PushL(self);
       
   200 	self->iProperties = CMMFMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(aData, aCallback, aPriority, aPref);
       
   201 	CleanupStack::Pop(self);
       
   202 	return self;
       
   203 	}
       
   204 
       
   205 CMdaAudioPlayerUtility::CMdaAudioPlayerUtility()
       
   206 	{
       
   207 	}
       
   208 
       
   209 /**
       
   210 Destructor.
       
   211 
       
   212 Frees all resources owned by the object prior to its destruction.
       
   213 */
       
   214 CMdaAudioPlayerUtility::~CMdaAudioPlayerUtility()
       
   215 	{
       
   216 	delete iProperties;
       
   217 	}
       
   218 
       
   219 /**
       
   220 Ensures that any subsequent calls to OpenXYZ() will create controllers that
       
   221 share a heap.
       
   222 
       
   223 The default behaviour is that for each player utility a controller with its own heap
       
   224 is created. Each heap uses a chunk, so using this function avoids situations where 
       
   225 the number of chunks per process is limited.
       
   226 The default behaviour is generally to be preferred, and should give lower overall
       
   227 memory usage. However, if many controllers are to be created for a particular thread,
       
   228 then this function should be used to prevent running out of heaps or chunks.
       
   229 
       
   230 @since	9.1
       
   231 */
       
   232 EXPORT_C void CMdaAudioPlayerUtility::UseSharedHeap()
       
   233 	{
       
   234 	ASSERT(iProperties);
       
   235 	iProperties->UseSharedHeap();
       
   236 	}
       
   237 
       
   238 // 5.0 functions
       
   239 
       
   240 /**
       
   241 Begins playback of audio sample data at the current playback position using the current volume,
       
   242 gain and priority settings.
       
   243 
       
   244 When playing of the audio sample is complete, successfully or
       
   245 otherwise, the callback function
       
   246 MMdaAudioPlayerCallback::MapcPlayComplete() is
       
   247 called.
       
   248 
       
   249 If this function is called whilst already playing then 
       
   250 MMdaAudioPlayerCallback::MapcPlayComplete will return with the
       
   251 error code KErrNotReady.
       
   252 
       
   253 @since	5.0
       
   254 */
       
   255 void CMdaAudioPlayerUtility::Play()
       
   256 	{
       
   257 	ASSERT(iProperties);
       
   258 	iProperties->Play();
       
   259 	}
       
   260 
       
   261 /**
       
   262 Stops playback of the audio sample as soon as possible.
       
   263 
       
   264 If the audio sample is playing, playback is stopped as soon as
       
   265 possible. If playback is already complete, nothing further happens as
       
   266 a result of calling this function. The callback function
       
   267 MMdaAudioPlayerCallback::MapcPlayComplete() is not
       
   268 called.
       
   269 
       
   270 @since	5.0
       
   271 */
       
   272 void CMdaAudioPlayerUtility::Stop()
       
   273 	{
       
   274 	ASSERT(iProperties);
       
   275 	iProperties->Stop();
       
   276 	}
       
   277 
       
   278 
       
   279 /**
       
   280 Changes the current playback volume to a specified value.
       
   281 
       
   282 The volume can be changed before or during playback and is effective
       
   283 immediately. The volume can be set to any value between zero (mute) and 
       
   284 the maximum permissible volume (determined using MaxVolume()).
       
   285 
       
   286 @param  aVolume
       
   287         The volume setting. This can be any value from zero to
       
   288         the value returned by a call to
       
   289         CMdaAudioPlayerUtility::MaxVolume().
       
   290         Setting a zero value mutes the sound. Setting the maximum
       
   291         value results in the loudest possible sound. Values less 
       
   292         than zero would be set to zero and the values greater than 
       
   293         the maximum permitted volume would be set to the maximum volume.
       
   294 @return An error code indicating if the function call was successful. KErrNone on success, 
       
   295 		otherwise another of the system-wide error codes.
       
   296 @panic  EMMFMediaClientBadArgument is raised when the audio player utility is not initialised.
       
   297 
       
   298 @since	5.0
       
   299 */
       
   300 TInt CMdaAudioPlayerUtility::SetVolume(TInt aVolume)
       
   301 	{
       
   302 	ASSERT(iProperties);
       
   303 	return iProperties->SetVolume(aVolume);
       
   304 	}
       
   305 
       
   306 /**
       
   307 Sets the number of times the audio sample is to be repeated during the
       
   308 playback operation.
       
   309 
       
   310 A period of silence can follow each playing of the sample. The audio
       
   311 sample can be repeated indefinitely.
       
   312 
       
   313 @param   aRepeatNumberOfTimes
       
   314          The number of times the audio sample, together with
       
   315          the trailing silence, is to be repeated. If this is
       
   316          set to KMdaRepeatForever, then the audio
       
   317          sample, together with the trailing silence, is
       
   318          repeated indefinitely or until Stop() is
       
   319          called. If this is set to zero, then the audio sample
       
   320          is not repeated.
       
   321 @param   aTrailingSilence
       
   322          The time interval of the trailing silence in microseconds.
       
   323 
       
   324 @since	5.0
       
   325 */
       
   326 void CMdaAudioPlayerUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
       
   327 	{
       
   328 	ASSERT(iProperties);
       
   329 	iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
       
   330 	}
       
   331 
       
   332 /**
       
   333 Defines the period over which the volume level is to rise smoothly
       
   334 from nothing to the normal volume level.
       
   335 
       
   336 @param  aRampDuration
       
   337         The period over which the volume is to rise. A zero
       
   338         value causes the audio sample to be played at the
       
   339         normal level for the full duration of the playback. A
       
   340         value which is longer than the duration of the audio
       
   341         sample means that the sample never reaches its normal
       
   342         volume level.
       
   343 
       
   344 @since	5.0
       
   345 */
       
   346 void CMdaAudioPlayerUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
       
   347 	{
       
   348 	ASSERT(iProperties);
       
   349 	iProperties->SetVolumeRamp(aRampDuration);
       
   350 	}
       
   351 
       
   352 /**
       
   353 Returns the duration of the audio sample in microseconds.
       
   354 
       
   355 @return The duration of the sample in microseconds.
       
   356 
       
   357 @since	5.0
       
   358 */
       
   359 const TTimeIntervalMicroSeconds& CMdaAudioPlayerUtility::Duration()
       
   360 	{
       
   361 	ASSERT(iProperties);
       
   362 	return iProperties->Duration();
       
   363 	}
       
   364 
       
   365 /**
       
   366 Returns the duration of the audio sample in microseconds, and the duration state.
       
   367 
       
   368 @param aDuration
       
   369 	   The duration of the sample in microseconds.
       
   370 @return The duration state
       
   371 
       
   372 @since	9.1
       
   373 */	
       
   374 EXPORT_C TMMFDurationInfo CMdaAudioPlayerUtility::Duration(TTimeIntervalMicroSeconds& aDuration)
       
   375 {
       
   376 	ASSERT(iProperties);
       
   377 	return iProperties->Duration(aDuration);
       
   378 }
       
   379 
       
   380 /**
       
   381 Returns an integer representing the maximum volume.
       
   382 
       
   383 This is the maximum value which can be passed to
       
   384 CMdaAudioPlayerUtility::SetVolume(). This value is platform 
       
   385 independent, but is always greater than or equal to one.
       
   386 
       
   387 @return The maximum volume setting.
       
   388 @panic  EMMFMediaClientPanicServerCommunicationProblem is raised when the audio player utility is not initialised. 
       
   389 
       
   390 @since	5.0
       
   391 */
       
   392 TInt CMdaAudioPlayerUtility::MaxVolume()
       
   393 	{
       
   394 	ASSERT(iProperties);
       
   395 	return iProperties->MaxVolume();
       
   396 	}
       
   397 
       
   398 // 7.0s functions
       
   399 
       
   400 /**
       
   401 Opens an audio clip from a file.
       
   402 
       
   403 The audio data must be in a supported format (for example, WAV or AU).
       
   404 
       
   405 This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
       
   406 
       
   407 @param  aFileName
       
   408         The file to open.
       
   409 @leave  KErrNotReady
       
   410         If a previous open statement is awaiting notification of completion.
       
   411 		opening the file
       
   412 @since	7.0s
       
   413 */
       
   414 EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const TDesC& aFileName)
       
   415 	{
       
   416 	ASSERT(iProperties);
       
   417 	iProperties->OpenFileL(aFileName);
       
   418 	}
       
   419 	
       
   420 /**
       
   421 Opens an audio clip from a file.
       
   422 
       
   423 The audio data must be in a supported format (for example, WAV or AU).
       
   424 
       
   425 This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
       
   426 
       
   427 Note: it is generally advisable that the RFile is shared through the call RFs::ShareProtected().
       
   428 This allows the adaptation to pass it to another process, if that is required. This is particularly
       
   429 true of playing DRM encrypted files.
       
   430 
       
   431 @param  aFile
       
   432         The open shared session file handle to use
       
   433 @leave 	KErrBadHandle
       
   434 		If the file handle is not shared through the call RFs::ShareProtected(), and the adaptation needs it to be.
       
   435 @leave  KErrNotReady
       
   436         If a previous open statement is awaiting notification of completion.
       
   437 		opening the file
       
   438 */
       
   439 EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const RFile& aFile)
       
   440 	{
       
   441 	ASSERT(iProperties);
       
   442 	RFile& file = const_cast<RFile&>(aFile);
       
   443 	TMMFileHandleSource tfs(file, KDefaultContentObject, EPlay);
       
   444 	iProperties->OpenFileL(tfs);
       
   445 	}
       
   446 
       
   447 /**
       
   448 Opens an audio clip from a file.
       
   449 
       
   450 The audio data must be in a supported format (for example, WAV or AU).
       
   451 
       
   452 This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
       
   453 
       
   454 @param  aSource
       
   455         The file to open or an open file handle to use
       
   456 @leave  KErrNotReady
       
   457         If a previous open statement is awaiting notification of completion.
       
   458 		opening the file
       
   459 */
       
   460 EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const TMMSource& aSource)
       
   461 	{
       
   462 	ASSERT(iProperties);
       
   463 	iProperties->OpenFileL(aSource);
       
   464 	}
       
   465 	
       
   466 /**
       
   467 Opens an audio clip from a descriptor.
       
   468 
       
   469 The audio data must be in a supported format (for example, WAV or AU).
       
   470 
       
   471 @param  aDescriptor
       
   472         A descriptor containing the audio clip.
       
   473 @leave  KErrInUse
       
   474         If a previous open statement is awaiting notification of completion.
       
   475 
       
   476 @since	7.0s
       
   477 */
       
   478 EXPORT_C void CMdaAudioPlayerUtility::OpenDesL(const TDesC8& aDescriptor)
       
   479 	{
       
   480 	ASSERT(iProperties);
       
   481 	iProperties->OpenDesL(aDescriptor);
       
   482 	}
       
   483 
       
   484 /**
       
   485 Opens an audio clip from a URL.
       
   486 
       
   487 The audio data must be in a supported format (for example, WAV or AU).
       
   488 
       
   489 @param	aUrl
       
   490 		The URL to open.
       
   491 @param 	aIapId
       
   492 		Internet access point(IAP) ID to use. KUseDefaultIap selects the default IAP.
       
   493 @param  aMimeType
       
   494 		MIME type of the URL source.
       
   495 
       
   496 @leave  KErrInUse 
       
   497         If a previous open statement is awaiting notification of completion.
       
   498 
       
   499 @since  7.0s
       
   500 */
       
   501 EXPORT_C void CMdaAudioPlayerUtility::OpenUrlL(const TDesC& aUrl, const TInt aIapId /*=KUseDefaultIap*/, const TDesC8& aMimeType /*=KNullDesC8*/)
       
   502 	{
       
   503 	ASSERT(iProperties);
       
   504 	iProperties->OpenUrlL(aUrl, aIapId, aMimeType);
       
   505 	}
       
   506 
       
   507 /**
       
   508 Pauses the playback of the audio clip.
       
   509 
       
   510 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   511         another of the system-wide error codes.
       
   512 
       
   513 @since	7.0s
       
   514 */
       
   515 EXPORT_C TInt CMdaAudioPlayerUtility::Pause()
       
   516 	{
       
   517 	ASSERT(iProperties);
       
   518 	return iProperties->Pause();
       
   519 	}
       
   520 
       
   521 /**
       
   522 Closes the current audio clip (allowing another clip to be opened).
       
   523 
       
   524 @since	7.0s
       
   525 */
       
   526 EXPORT_C void CMdaAudioPlayerUtility::Close()
       
   527 	{
       
   528 	ASSERT(iProperties);
       
   529 	iProperties->Close();
       
   530 	}
       
   531 
       
   532 /**
       
   533 Returns the current playback position in microseconds from the start of the clip.
       
   534 
       
   535 @param   aPosition
       
   536          The current time position in microseconds from the start of the clip to the current
       
   537          play position.
       
   538 
       
   539 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   540         another of the system-wide error codes.
       
   541 
       
   542 @since	7.0s
       
   543 */
       
   544 EXPORT_C TInt CMdaAudioPlayerUtility::GetPosition(TTimeIntervalMicroSeconds& aPosition)
       
   545 	{
       
   546 	ASSERT(iProperties);
       
   547 	return iProperties->GetPosition(aPosition);
       
   548 	}
       
   549 
       
   550 /**
       
   551 Sets the current playback position in microseconds from the start of the clip.
       
   552 
       
   553 @param  aPosition
       
   554         The position to move to in microseconds from the start of the clip.
       
   555 
       
   556 @since	7.0s
       
   557 */
       
   558 EXPORT_C void CMdaAudioPlayerUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
       
   559 	{
       
   560 	ASSERT(iProperties);
       
   561 	iProperties->SetPosition(aPosition);
       
   562 	}
       
   563 
       
   564 /**
       
   565 Sets the priority for playback. This is used to arbitrate between multiple
       
   566 objects trying to access a single sound device.
       
   567 
       
   568 @param  aPriority
       
   569         The Priority Value.
       
   570 @param  aPref
       
   571         The Priority Preference.
       
   572 
       
   573 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   574         another of the system-wide error codes.
       
   575 
       
   576 @since  7.0s
       
   577 
       
   578 @see CMdaAudioPlayerUtility::NewL()
       
   579 
       
   580 */
       
   581 EXPORT_C TInt CMdaAudioPlayerUtility::SetPriority(TInt aPriority, TInt aPref)
       
   582 	{
       
   583 	ASSERT(iProperties);
       
   584 	return iProperties->SetPriority(aPriority, aPref);
       
   585 	}
       
   586 
       
   587 /**
       
   588 Returns the current playback volume.
       
   589 
       
   590 @param  aVolume
       
   591         A value between 0 and the maximum volume settings returned by MaxVolume().
       
   592 
       
   593 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   594         another of the system-wide error codes.
       
   595 
       
   596 @since	7.0s
       
   597 */
       
   598 EXPORT_C TInt CMdaAudioPlayerUtility::GetVolume(TInt& aVolume)
       
   599 	{
       
   600 	ASSERT(iProperties);
       
   601 	return iProperties->GetVolume(aVolume);
       
   602 	}
       
   603 
       
   604 /**
       
   605 Returns the number of meta data entries in the current audio clip.
       
   606 
       
   607 @param  aNumEntries
       
   608         The number of meta data entries in the header of the current clip.
       
   609 
       
   610 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   611         another of the system-wide error codes.
       
   612 
       
   613 @since	7.0s
       
   614 */
       
   615 EXPORT_C TInt CMdaAudioPlayerUtility::GetNumberOfMetaDataEntries(TInt& aNumEntries)
       
   616 	{
       
   617 	ASSERT(iProperties);
       
   618 	return iProperties->GetNumberOfMetaDataEntries(aNumEntries);
       
   619 	}
       
   620 
       
   621 /**
       
   622 Returns the requested meta data entry.
       
   623 
       
   624 @param  aMetaDataIndex
       
   625         The index number of the meta data to retrieve.
       
   626 
       
   627 @return The requested meta data entry.
       
   628 @leave  KErrNotFound
       
   629         The meta data entry does not exist.
       
   630 @leave  KErrNotImplemented
       
   631         The controller does not support meta data information for this format.
       
   632 
       
   633 @since	7.0s
       
   634 */
       
   635 EXPORT_C CMMFMetaDataEntry* CMdaAudioPlayerUtility::GetMetaDataEntryL(TInt aMetaDataIndex)
       
   636 	{
       
   637 	ASSERT(iProperties);
       
   638 	return iProperties->GetMetaDataEntryL(aMetaDataIndex);
       
   639 	}
       
   640 
       
   641 /**
       
   642 Defines a window on the audio sample data.
       
   643 
       
   644 The window is defined in terms of a start and end position.
       
   645 When the current playback position reaches the window end position, or Stop() is called, the
       
   646 current playback position is set to the window start position and playback stops.
       
   647 
       
   648 The current playback position is not affected by a call to SetPlayWindow() unless it is outside
       
   649 the new playback window, in which case it is set to the window start or end position depending
       
   650 on which one is closer.
       
   651 
       
   652 The window persists until ClearPlayWindow() is called.
       
   653 Loading new audio sample data without adjusting or clearing the window will result in
       
   654 playback errors if the window is outside the new data.
       
   655 
       
   656 @param  aStart
       
   657         The position defining the start of the window, measured in microseconds. If this value is less
       
   658         than zero, it is set to zero. If this value is greater than aEnd, then it is swapped with aEnd.
       
   659 @param  aEnd
       
   660         The position defining the end of the window, measured in microseconds. If this value is greater
       
   661         than the value returned by Duration(), it is set to the value of Duration(). If this value is
       
   662         less than aStart, then it is swapped with aStart.
       
   663 
       
   664 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   665         another of the system-wide error codes.
       
   666 
       
   667 @since	7.0s
       
   668 */
       
   669 EXPORT_C TInt CMdaAudioPlayerUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aStart,
       
   670 													const TTimeIntervalMicroSeconds& aEnd)
       
   671 	{
       
   672 	ASSERT(iProperties);
       
   673 	return iProperties->SetPlayWindow(aStart, aEnd);
       
   674 	}
       
   675 
       
   676 /**
       
   677 Clears the current playback window.
       
   678 
       
   679 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   680         another of the system-wide error codes.
       
   681 
       
   682 @since	7.0s
       
   683 */
       
   684 EXPORT_C TInt CMdaAudioPlayerUtility::ClearPlayWindow()
       
   685 	{
       
   686 	ASSERT(iProperties);
       
   687 	return iProperties->ClearPlayWindow();
       
   688 	}
       
   689 
       
   690 /**
       
   691 Sets the current playback balance.
       
   692 
       
   693 @param  aBalance
       
   694         A value between KMMFBalanceMaxLeft
       
   695         and KMMFBalanceMaxRight. The default value is
       
   696         KMMFBalanceCenter.
       
   697 
       
   698 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   699         another of the system-wide error codes.
       
   700 
       
   701 @since  7.0s
       
   702 */
       
   703 EXPORT_C TInt CMdaAudioPlayerUtility::SetBalance(TInt aBalance /*= KMMFBalanceCenter*/)
       
   704 	{
       
   705 	ASSERT(iProperties);
       
   706 	return iProperties->SetBalance(aBalance);
       
   707 	}
       
   708 
       
   709 /**
       
   710  *	Returns The current playback balance. This function may not return the same value 	
       
   711  *			as passed to SetBalance depending on the internal implementation in 
       
   712  *			the underlying components.
       
   713  *
       
   714  *	@param  aBalance
       
   715  *        	A value between KMMFBalanceMaxLeft
       
   716  *       	and KMMFBalanceMaxRight.
       
   717  *
       
   718  *	@return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   719  *        	another of the system-wide error codes.
       
   720  *
       
   721  *	@since	7.0s
       
   722  */
       
   723 EXPORT_C TInt CMdaAudioPlayerUtility::GetBalance(TInt& aBalance)
       
   724 	{
       
   725 	ASSERT(iProperties);
       
   726 	return iProperties->GetBalance(aBalance);
       
   727 	}
       
   728 
       
   729 /**
       
   730 Returns the controller implementation information associated with the current controller.
       
   731 
       
   732 @return The controller implementation structure
       
   733 
       
   734 @since 7.0s
       
   735 */
       
   736 EXPORT_C const CMMFControllerImplementationInformation& CMdaAudioPlayerUtility::ControllerImplementationInformationL()
       
   737 	{
       
   738 	ASSERT(iProperties);
       
   739 	return iProperties->ControllerImplementationInformationL();
       
   740 	}
       
   741 
       
   742 /**
       
   743 Registers callback object to receive notifications of audio loading/rebuffering.
       
   744 
       
   745 @param  aCallback
       
   746         The object to receive audio loading notifications.
       
   747 
       
   748 @since  7.0s
       
   749 */
       
   750 EXPORT_C void CMdaAudioPlayerUtility::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aCallback)
       
   751 	{
       
   752 	ASSERT(iProperties);
       
   753 	iProperties->RegisterForAudioLoadingNotification(aCallback);
       
   754 	}
       
   755 
       
   756 /**
       
   757 Returns the current progress of audio loading.
       
   758 
       
   759 @param  aPercentageProgress
       
   760         The percentage of the audio clip loaded.
       
   761 
       
   762 @since  7.0s
       
   763 */
       
   764 EXPORT_C void CMdaAudioPlayerUtility::GetAudioLoadingProgressL(TInt& aPercentageProgress)
       
   765 	{
       
   766 	ASSERT(iProperties);
       
   767 	iProperties->GetAudioLoadingProgressL(aPercentageProgress);
       
   768 	}
       
   769 
       
   770 /**
       
   771 Sends a synchronous custom command to the controller.
       
   772 
       
   773 @param  aDestination
       
   774         The destination of the message, consisting of the UID of
       
   775         the interface of this message.
       
   776 @param  aFunction
       
   777         The function number to indicate which function is to be called
       
   778         on the interface defined in the aDestination parameter.
       
   779 @param  aDataTo1
       
   780         A reference to the first chunk of data to be copied to the controller
       
   781         framework. The exact contents of the data are dependent on the
       
   782         interface being called.  Can be KNullDesC8.
       
   783 @param  aDataTo2
       
   784         A reference to the second chunk of data to be copied to the controller
       
   785         framework. The exact contents of the data are dependent on the
       
   786         interface being called.  Can be KNullDesC8.
       
   787 @param  aDataFrom
       
   788         A reference to an area of memory to which the controller framework will
       
   789         write any data to be passed back to the client.  Can't be KNullDesC8.
       
   790 
       
   791 @return The result of the request.  Exact range of values is dependent on the interface.
       
   792 
       
   793 @since  7.0s
       
   794 */
       
   795 EXPORT_C TInt CMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
       
   796 	{
       
   797 	ASSERT(iProperties);
       
   798 	return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
       
   799 	}
       
   800 
       
   801 /**
       
   802 Sends a synchronous custom command to the controller.
       
   803 
       
   804 @param  aDestination
       
   805         The destination of the message, consisting of the UID of
       
   806         the interface of this message.
       
   807 @param  aFunction
       
   808         The function number to indicate which function is to be called
       
   809         on the interface defined in the aDestination parameter.
       
   810 @param  aDataTo1
       
   811         A reference to the first chunk of data to be copied to the controller
       
   812         framework. The exact contents of the data are dependent on the
       
   813         interface being called.  Can be KNullDesC8.
       
   814 @param  aDataTo2
       
   815         A reference to the second chunk of data to be copied to the controller
       
   816         framework. The exact contents of the data are dependent on the
       
   817         interface being called.  Can be KNullDesC8.
       
   818 
       
   819 @return The result of the request.  Exact range of values is dependent on the interface.
       
   820 
       
   821 @since  7.0s
       
   822 */
       
   823 EXPORT_C TInt CMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
       
   824 	{
       
   825 	ASSERT(iProperties);
       
   826 	return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
       
   827 	}
       
   828 
       
   829 /**
       
   830 Sends an asynchronous custom command to the controller.
       
   831 
       
   832 Note: 
       
   833 This method will return immediately.  The RunL of the active object owning the
       
   834 aStatus parameter will be called when the command is completed by the
       
   835 controller framework.
       
   836 
       
   837 @param  aDestination
       
   838         The destination of the message, consisting of the uid of
       
   839         the interface of this message.
       
   840 @param  aFunction
       
   841         The function number to indicate which function is to be called
       
   842         on the interface defined in the aDestination parameter.
       
   843 @param  aDataTo1
       
   844         A reference to the first chunk of data to be copied to the controller
       
   845         framework. The exact contents of the data are dependent on the
       
   846         interface being called.  Can be KNullDesC8.
       
   847 @param  aDataTo2
       
   848         A reference to the second chunk of data to be copied to the controller
       
   849         framework. The exact contents of the data are dependent on the
       
   850         interface being called.  Can be KNullDesC8.
       
   851 @param  aDataFrom
       
   852         A reference to an area of memory to which the controller framework will
       
   853         write any data to be passed back to the client.  Can't be KNullDesC8."
       
   854 @param  aStatus
       
   855         The TRequestStatus of an active object.  This will contain the
       
   856         result of the request on completion.  The exact range of
       
   857         result values is dependent on the interface.
       
   858 
       
   859 @since  7.0s
       
   860 */
       
   861 EXPORT_C void CMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
       
   862 	{
       
   863 	ASSERT(iProperties);
       
   864 	iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
       
   865 	}
       
   866 
       
   867 /**
       
   868 Sends an asynchronous custom command to the controller.
       
   869 
       
   870 Note: 
       
   871 This method will return immediately.  The RunL of the active object owning the
       
   872 aStatus parameter will be called when the command is completed by the
       
   873 controller framework.
       
   874 
       
   875 @param  aDestination
       
   876         The destination of the message, consisting of the uid of
       
   877         the interface of this message.
       
   878 @param  aFunction
       
   879         The function number to indicate which function is to be called
       
   880         on the interface defined in the aDestination parameter.
       
   881 @param  aDataTo1
       
   882         A reference to the first chunk of data to be copied to the controller
       
   883         framework. The exact contents of the data are dependent on the
       
   884         interface being called.  Can be KNullDesC8.
       
   885 @param  aDataTo2
       
   886         A reference to the second chunk of data to be copied to the controller
       
   887         framework. The exact contents of the data are dependent on the
       
   888         interface being called.  Can be KNullDesC8.
       
   889 @param  aStatus
       
   890         The TRequestStatus of an active object.  This will contain the
       
   891         result of the request on completion.  The exact range of
       
   892         result values is dependent on the interface.
       
   893 
       
   894 @since  7.0s
       
   895 */
       
   896 EXPORT_C void CMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
       
   897 	{
       
   898 	ASSERT(iProperties);
       
   899 	iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
       
   900 	}
       
   901 
       
   902 /**
       
   903 Returns the bit rate of the audio clip.
       
   904 
       
   905 @param  aBitRate
       
   906 		The bit rate of the audio clip
       
   907 
       
   908 @return An error code indicating if the function call was successful. KErrNone on success, 
       
   909 		otherwise another of the system-wide error codes.
       
   910 
       
   911 @since  7.0s
       
   912 */
       
   913 EXPORT_C TInt CMdaAudioPlayerUtility::GetBitRate(TUint& aBitRate)
       
   914 	{
       
   915 	ASSERT(iProperties);
       
   916 	return iProperties->GetBitRate(aBitRate);	
       
   917 	}
       
   918 
       
   919 /**
       
   920 Gets a controller's DRM custom command implementation.
       
   921 
       
   922 @return A pointer to a controller's DRM custom command implementation, or NULL if the
       
   923 controller does not support it.
       
   924 */
       
   925 EXPORT_C MMMFDRMCustomCommand* CMdaAudioPlayerUtility::GetDRMCustomCommand()
       
   926 	{
       
   927 	ASSERT(iProperties);
       
   928 	return iProperties->GetDRMCustomCommand();
       
   929 	}
       
   930 
       
   931 /**
       
   932 Registers the Event for Notification when resource is avaliable.
       
   933 
       
   934 @param	aCallback
       
   935       	The audio outputstream observer interface..
       
   936       	
       
   937 @param 	aNotificationEventUid
       
   938  	The Event for which the client is registered.
       
   939  	
       
   940 @param 	aNotificationRegistrationData
       
   941 	Notification registration specific data.
       
   942 	
       
   943 @return An error code indicating if the registration was successful. KErrNone on success, 
       
   944 	otherwise another of the system-wide error codes.
       
   945 */
       
   946 EXPORT_C TInt CMdaAudioPlayerUtility::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,TUid aNotificationEventUid,const TDesC8& aNotificationRegistrationData)
       
   947 	{
       
   948 	ASSERT(iProperties);
       
   949 	return iProperties->RegisterAudioResourceNotification(aCallback,aNotificationEventUid,aNotificationRegistrationData);
       
   950 	}
       
   951 
       
   952 /**
       
   953 Cancels the registered notification event.
       
   954 
       
   955 @param  aNotificationEventUid
       
   956 	The Event to notify the client.
       
   957 	
       
   958 @return An error code indicating if the registration was successful. KErrNone on success, 
       
   959 	otherwise another of the system-wide error codes.
       
   960 */
       
   961 EXPORT_C TInt CMdaAudioPlayerUtility::CancelRegisterAudioResourceNotification(TUid aNotificationEventUid)
       
   962 	{
       
   963 	ASSERT(iProperties);
       
   964 	return iProperties->CancelRegisterAudioResourceNotification(aNotificationEventUid);
       
   965 	}
       
   966 
       
   967 /**
       
   968 Waits for the client to resume the play even after the default timer expires.
       
   969 
       
   970 @return An error code indicating if the registration was successful. KErrNone on success, 
       
   971 		otherwise another of the system-wide error codes.
       
   972 */
       
   973 EXPORT_C TInt CMdaAudioPlayerUtility::WillResumePlay()
       
   974 	{
       
   975 	ASSERT(iProperties);
       
   976 	return iProperties->WillResumePlay();
       
   977 	}
       
   978 
       
   979 
       
   980 /**
       
   981 Set the priority of the controller's sub thread.
       
   982 
       
   983 This can be used to increase the responsiveness of the audio plugin to minimise
       
   984 any lag in processing. This function should be used with care as it may have knock-on
       
   985 effects elsewhere in the system.
       
   986 
       
   987 @param	aPriority
       
   988 		The TThreadPriority that the thread should run under.  The default is EPriorityNormal.
       
   989 @return	TInt
       
   990 		A standard error code: KErrNone if successful, KErrNotReady if the thread does not have a
       
   991 		valid handle.
       
   992 */
       
   993 EXPORT_C TInt CMdaAudioPlayerUtility::SetThreadPriority(const TThreadPriority& aPriority) const
       
   994 	{
       
   995 	ASSERT(iProperties);
       
   996 	return iProperties->SetThreadPriority(aPriority);
       
   997 	}
       
   998 
       
   999 
       
  1000 
       
  1001 
       
  1002 CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewL(MMdaAudioPlayerCallback& aCallback,
       
  1003 															  TInt aPriority,
       
  1004 															  TInt aPref)
       
  1005 	{
       
  1006 	CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
       
  1007 	CleanupStack::PushL(self);
       
  1008 	self->ConstructL();
       
  1009 	CleanupStack::Pop(self);
       
  1010 	return self;
       
  1011 	}
       
  1012 
       
  1013 CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewFilePlayerL(const TDesC& aFileName,
       
  1014 																		MMdaAudioPlayerCallback& aCallback,
       
  1015 																		TInt aPriority,
       
  1016 																		TInt aPref,
       
  1017 																		CMdaServer* /*aServer*/)
       
  1018 	{
       
  1019 	CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
       
  1020 	CleanupStack::PushL(self);
       
  1021 	self->ConstructL();
       
  1022 	TMMFileSource filesource(aFileName, KDefaultContentObject, EPlay);
       
  1023 	self->OpenFileL(filesource);
       
  1024 	CleanupStack::Pop(self);
       
  1025 	return self;
       
  1026 	}
       
  1027 
       
  1028 CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewDesPlayerL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
       
  1029 	{
       
  1030 	CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
       
  1031 	CleanupStack::PushL(self);
       
  1032 	self->ConstructL();
       
  1033 	self->OpenDesL(aData);
       
  1034 	CleanupStack::Pop(self);
       
  1035 	return self;
       
  1036 	}
       
  1037 
       
  1038 CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
       
  1039 	{
       
  1040 	CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
       
  1041 	CleanupStack::PushL(self);
       
  1042 	self->ConstructL();
       
  1043 	self->OpenDesL(aData);
       
  1044 	CleanupStack::Pop(self);
       
  1045 	return self;
       
  1046 	}
       
  1047 
       
  1048 void CMMFMdaAudioPlayerUtility::UseSharedHeap()
       
  1049 	{
       
  1050 	iFindAndOpenController->UseSharedHeap();
       
  1051 	}
       
  1052 
       
  1053 // CMMFMdaAudioPlayerUtility
       
  1054 CMMFMdaAudioPlayerUtility::~CMMFMdaAudioPlayerUtility()
       
  1055 	{
       
  1056 	
       
  1057 	delete iControllerImplementationInformation;
       
  1058 	delete iAsyncCallBack;
       
  1059 	delete iRepeatTrailingSilenceTimer;
       
  1060 	delete iFindAndOpenController;
       
  1061 	delete iControllerEventMonitor;
       
  1062 	iMediaIds.Close();
       
  1063 	iController.Close();
       
  1064 	}
       
  1065 
       
  1066 CMMFMdaAudioPlayerUtility::CMMFMdaAudioPlayerUtility(MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref) :
       
  1067 	iCallback(aCallback),
       
  1068 	iAudioPlayDeviceCommands(iController),
       
  1069 	iAudioPlayControllerCommands(iController),
       
  1070 	iNotificationRegistrationCommands(iController),
       
  1071 	iDRMCustomCommands(iController),
       
  1072 	iAudioPlayControllerSetRepeatsCommands(iController)
       
  1073 	{
       
  1074 	iState = EStopped;
       
  1075 	iPrioritySettings.iPriority = aPriority;
       
  1076 	iPrioritySettings.iPref = aPref;
       
  1077 	iPlayStart = TTimeIntervalMicroSeconds(0);
       
  1078 	iPlayEnd = TTimeIntervalMicroSeconds(0);
       
  1079 	iPlayWindowSet = ENone;
       
  1080 	iEventHolder = KNullUid;
       
  1081 	}
       
  1082 
       
  1083 void CMMFMdaAudioPlayerUtility::ConstructL()
       
  1084 	{
       
  1085 	iControllerEventMonitor = CMMFControllerEventMonitor::NewL(*this, iController);
       
  1086 	iRepeatTrailingSilenceTimer = CRepeatTrailingSilenceTimer::NewL(*this);
       
  1087 	iAsyncCallBack = CMMFMdaAudioPlayerCallBack::NewL(iCallback);
       
  1088 	User::LeaveIfError(iMediaIds.Append(KUidMediaTypeAudio));
       
  1089 	iFindAndOpenController = CMMFFindAndOpenController::NewL(*this);
       
  1090 	iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings);
       
  1091 	iFindAndOpenController->ConfigureController(iController, *iControllerEventMonitor, CMMFFindAndOpenController::EPlayback);
       
  1092 	}
       
  1093 
       
  1094 void CMMFMdaAudioPlayerUtility::MfaocComplete(		
       
  1095 		TInt& aError, 
       
  1096 		RMMFController* /*aController*/,
       
  1097 		TUid aControllerUid, 
       
  1098 		TMMFMessageDestination* /*aSourceHandle*/, 
       
  1099 		TMMFMessageDestination* /*aSinkHandle*/)
       
  1100 	{
       
  1101 	if (aError == KErrNone)
       
  1102 		{
       
  1103 		iControllerUid = aControllerUid;
       
  1104 
       
  1105 		// Get the clip duration
       
  1106 		iDuration = TTimeIntervalMicroSeconds(0);
       
  1107 		aError = iController.GetDuration(iDuration);
       
  1108 				
       
  1109 		// If an error occurred during GetDuration, may try for next controller, if present.
       
  1110 		if (aError != KErrNone)
       
  1111 			{
       
  1112 			iControllerEventMonitor->Cancel();
       
  1113 			
       
  1114 			if (iFindAndOpenController)	
       
  1115 				{
       
  1116 				if(iFindAndOpenController-> ControllerIndex() < (iFindAndOpenController->ControllerCount())-1)
       
  1117 					{
       
  1118 					return;   //actually tries to load next controllers, if there are other controllers selected in the controller list
       
  1119 					}
       
  1120 				}
       
  1121 			
       
  1122 			iController.Close(); // otherwise close the controller
       
  1123 			}
       
  1124 	
       
  1125 		if (iFindAndOpenController)	
       
  1126 			{
       
  1127 			iFindAndOpenController->Close();
       
  1128 			}
       
  1129 		}
       
  1130 	
       
  1131 	iAsyncCallBack->InitComplete(aError, iDuration);
       
  1132 	}
       
  1133 
       
  1134 /**
       
  1135 	Open an audio clip from a file
       
  1136 	@param "const TFileSource& aFileSource" "the file to open"
       
  1137 	@leave "" "Leaves on an error opening the file
       
  1138 	@since version 5.0
       
  1139 */
       
  1140 void CMMFMdaAudioPlayerUtility::OpenFileL(const TDesC& aFileName)
       
  1141 	{
       
  1142 	TMMFileSource filesource(aFileName, KDefaultContentObject, EPlay);
       
  1143 	OpenFileL(filesource);
       
  1144 	}
       
  1145 	
       
  1146 /**
       
  1147 	Open an audio clip from a file
       
  1148 	@param "const RFile& aFile" "the shared session file handle to open"
       
  1149 	@leave "" "KErrBadHandle if the file handle is not shared through the call RFs::ShareProtected(), and the underlying CAF layer needs it to be.
       
  1150 	@leave "" "Leaves on an error opening the file
       
  1151 	@since version 5.0
       
  1152 */
       
  1153 void CMMFMdaAudioPlayerUtility::OpenFileL(const RFile& aFile)
       
  1154 	{
       
  1155 	RFile& file = const_cast<RFile&>(aFile);
       
  1156 	TMMFileHandleSource filesource(file, KDefaultContentObject, EPlay);
       
  1157 	OpenFileL(filesource);
       
  1158 	}
       
  1159 
       
  1160 void CMMFMdaAudioPlayerUtility::OpenFileL(const TMMSource& aSource)
       
  1161 	{
       
  1162 	// If iAsyncCallBack is already active, we're still in the process of notifying the client
       
  1163 	// that a previous request to Open...(...) has completed.
       
  1164 	if (iAsyncCallBack->IsActive())
       
  1165 		User::Leave(KErrNotReady);
       
  1166 	
       
  1167 	if (aSource.SourceType()==KUidMMFileHandleSource)
       
  1168 		{
       
  1169 		RFile& fileHandle = static_cast<const TMMFileHandleSource&>(aSource).Handle();
       
  1170 		iFindAndOpenController->ConfigureSourceSink(
       
  1171 			TMMFileHandleSource(fileHandle, aSource.UniqueId(), aSource.Intent(), aSource.IsUIEnabled()),
       
  1172 			CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
       
  1173 
       
  1174 		}
       
  1175 	if (aSource.SourceType()==KUidMMFileSource)
       
  1176 		{
       
  1177 		const TDesC& fileName = static_cast<const TMMFileSource&>(aSource).Name();
       
  1178 		iFindAndOpenController->ConfigureSourceSink(
       
  1179 			TMMFileSource(fileName, aSource.UniqueId(), aSource.Intent(), aSource.IsUIEnabled()),
       
  1180 			CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
       
  1181 		}
       
  1182 
       
  1183 	iFindAndOpenController->OpenByFileSource(aSource);
       
  1184 	}
       
  1185 
       
  1186 /**
       
  1187 	Open an audio clip from a descriptor
       
  1188 	@param "const TDesC8& aDescriptor" "the descriptor containing the clip"
       
  1189 	@leave "" "Leaves on an error opening the descriptor"
       
  1190 	@since version 5.0
       
  1191 */
       
  1192 void CMMFMdaAudioPlayerUtility::OpenDesL(const TDesC8& aDescriptor)
       
  1193 	{
       
  1194 	// If iAsyncCallBack is already active, we're still in the process of notifying the client
       
  1195 	// that a previous request to Open...(...) has completed.
       
  1196 	if (iAsyncCallBack->IsActive())
       
  1197 		User::Leave(KErrInUse);
       
  1198 
       
  1199 	iFindAndOpenController->ConfigureSourceSink(
       
  1200 		CMMFFindAndOpenController::TSourceSink(KUidMmfDescriptorSource,
       
  1201 													CMMFFindAndOpenController::GetConfigDescriptor(aDescriptor)),
       
  1202 		CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
       
  1203 	iFindAndOpenController->OpenByDescriptor(aDescriptor);
       
  1204 	}
       
  1205 
       
  1206 /**
       
  1207 	Open an audio clip from a Url
       
  1208 	@param "const TDesC& aUrl" "the url reference to the clip"
       
  1209 	@leave "" "Leaves on an error opening the url"
       
  1210 	@since version 7.0s
       
  1211 */
       
  1212 void CMMFMdaAudioPlayerUtility::OpenUrlL(const TDesC& aUrl, const TInt aIapId, const TDesC8& aMimeType)
       
  1213 	{
       
  1214 	// If iAsyncCallBack is already active, we're still in the process of notifying the client
       
  1215 	// that a previous request to Open...(...) has completed.
       
  1216 	if (iAsyncCallBack->IsActive())
       
  1217 		User::Leave(KErrInUse);
       
  1218 
       
  1219 	CBufFlat* urlCfgBuffer = NULL;
       
  1220 	CMMFFindAndOpenController::GetConfigUrlL(urlCfgBuffer, aUrl, aIapId);
       
  1221 	
       
  1222 	iFindAndOpenController->ConfigureSourceSink(
       
  1223 		CMMFFindAndOpenController::TSourceSink(KUidMmfUrlSource, urlCfgBuffer->Ptr(0)), 
       
  1224 		CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
       
  1225 	iFindAndOpenController->OpenByUrl(aUrl, aIapId, aMimeType);
       
  1226 	delete urlCfgBuffer;
       
  1227 	}
       
  1228 
       
  1229 /**
       
  1230 Begins playback of the initialised audio sample at the current volume
       
  1231 and priority levels.
       
  1232 
       
  1233 When playing of the audio sample is complete, successfully or
       
  1234 otherwise, the callback function
       
  1235 MMdaAudioPlayerCallback::MapcPlayComplete() is
       
  1236 called.
       
  1237 
       
  1238 If this function is called whilst already playing then 
       
  1239 MMdaAudioPlayerCallback::MapcPlayComplete will return with the
       
  1240 error code KErrNotReady.
       
  1241 
       
  1242 @since	5.0
       
  1243 */
       
  1244 void CMMFMdaAudioPlayerUtility::Play()
       
  1245 	{
       
  1246 	// if we're already playing, call the client's callback with KErrNotReady.
       
  1247 	// This is what the controller would do if we allowed the Play()
       
  1248 	// to propagate down. Need to do it here too (for consistency)
       
  1249 	// in case we're in a trailing silence period.
       
  1250     if (iState == EPlaying)
       
  1251 		{
       
  1252 		iAsyncCallBack->PlayComplete(KErrNotReady);
       
  1253 		return;
       
  1254 		}
       
  1255 
       
  1256 	// cancel the repeat timer in case the client has called Play()
       
  1257 	// without waiting for the previous play to complete
       
  1258 	iRepeatTrailingSilenceTimer->Cancel();	
       
  1259 	// Reset played count
       
  1260 	if(iState != EPaused)
       
  1261 		{
       
  1262 		iNumberOfTimesPlayed = 0;	
       
  1263 		if(iNumberOfTimesToRepeat>0 || iNumberOfTimesToRepeat == KMdaRepeatForever)
       
  1264 			{
       
  1265 			TInt err = iAudioPlayControllerSetRepeatsCommands.SetRepeats(iNumberOfTimesToRepeat, iTrailingSilence);
       
  1266 			if(err==KErrNone)
       
  1267 				{
       
  1268 				iNumberOfTimesToRepeat = 0;
       
  1269 				iTrailingSilence = 0;
       
  1270 				}
       
  1271 			//Controller not supporting setrepeats custom command is not a real error
       
  1272 			//we revert back to playerutility's loop play implementation in that case
       
  1273 			}
       
  1274 		}
       
  1275 
       
  1276 	DoPlay();
       
  1277 	}
       
  1278 
       
  1279 void CMMFMdaAudioPlayerUtility::DoPlay()
       
  1280 	{
       
  1281 #if defined(__AUDIO_PROFILING)
       
  1282 	RDebug::ProfileStart(4);
       
  1283 #endif  // defined(__AUDIO_PROFILING)
       
  1284     TInt err = KErrNone;
       
  1285     if (iState != EPaused || iRepeatCancelled)
       
  1286         {
       
  1287 		err = iController.Prime();
       
  1288 		iRepeatCancelled = EFalse;
       
  1289 
       
  1290 #if defined(__AUDIO_PROFILING)
       
  1291 	RDebug::ProfileEnd(4);
       
  1292 #endif  // defined(__AUDIO_PROFILING)
       
  1293 
       
  1294 		// make sure we don't set the position outside the play window -
       
  1295 		// but allow it to remain unchanged if it's within the window
       
  1296 		if (iPlayWindowSet == ESet &&
       
  1297 			(iPosition < iPlayStart || iPosition >= iPlayEnd))
       
  1298 			iPosition = iPlayStart;
       
  1299 
       
  1300 		if (err==KErrNone)
       
  1301 			err = iController.SetPosition(iPosition);
       
  1302         }
       
  1303 
       
  1304 	if (err==KErrNone)
       
  1305 		{
       
  1306 		if (iPlayWindowSet == ESet)
       
  1307 			err = iAudioPlayControllerCommands.SetPlaybackWindow(iPlayStart, iPlayEnd);
       
  1308 		else if (iPlayWindowSet == EClear)
       
  1309 			{
       
  1310 			err = iAudioPlayControllerCommands.DeletePlaybackWindow();
       
  1311 			iPlayWindowSet = ENone;	// assume window will stay cleared
       
  1312 			}
       
  1313 		}
       
  1314 
       
  1315 	if (err==KErrNone)
       
  1316 		{
       
  1317 #if defined(__AUDIO_PROFILING)
       
  1318 		RDebug::ProfileStart(5);
       
  1319 #endif  // defined(__AUDIO_PROFILING)
       
  1320 		
       
  1321 		err = iController.Play();
       
  1322 	
       
  1323 #if defined(__AUDIO_PROFILING)
       
  1324 		RDebug::ProfileEnd(5);
       
  1325 #endif  // defined(__AUDIO_PROFILING)
       
  1326 		}
       
  1327 
       
  1328 	if (err!=KErrNone)
       
  1329 		iAsyncCallBack->PlayComplete(err);
       
  1330 	else
       
  1331 		iState = EPlaying;
       
  1332 	
       
  1333 	if(iEventHolder != KNullUid)
       
  1334 		{
       
  1335 		err = iNotificationRegistrationCommands.RegisterAsClient(iEventHolder,iNotificationDataHolder);			
       
  1336 		iEventHolder = KNullUid;
       
  1337 		iNotificationDataHolder = KNullDesC8;
       
  1338 		if(err == KErrNotSupported)
       
  1339 			{
       
  1340 			return;
       
  1341 			}
       
  1342 		if(err != KErrNone)
       
  1343 			{
       
  1344 			iController.Stop();
       
  1345 			iAsyncCallBack->PlayComplete(err);
       
  1346 			}
       
  1347 		}
       
  1348 	}
       
  1349 
       
  1350 /**
       
  1351 Stops playback of the audio sample as soon as possible.
       
  1352 
       
  1353 If the audio sample is playing, playback is stopped as soon as
       
  1354 possible. If playback is already complete, nothing further happens as
       
  1355 a result of calling this function. The callback function
       
  1356 MMdaAudioPlayerCallback::MapcPlayComplete() is not
       
  1357 called.
       
  1358 
       
  1359 @since	5.0
       
  1360 */
       
  1361 void CMMFMdaAudioPlayerUtility::Stop()
       
  1362 	{
       
  1363 	
       
  1364 	if (iState==EStopped)
       
  1365 		{
       
  1366 		// resetting the position to the start.
       
  1367 		//if any position change in stoped state
       
  1368 		iPosition = iPlayStart;	
       
  1369 		return;
       
  1370 		}
       
  1371 	
       
  1372 	if (iState==EPlaying || iState==EPaused)
       
  1373 		{
       
  1374 		// cancel the repeat timer in case the client has called Stop()
       
  1375 		// during the trailing silence period
       
  1376 		iRepeatTrailingSilenceTimer->Cancel();	
       
  1377 
       
  1378 		iController.Stop();
       
  1379 		iPosition = iPlayStart;	
       
  1380 		iState = EStopped;	
       
  1381 		}
       
  1382 
       
  1383 	}
       
  1384 
       
  1385 /**
       
  1386  *
       
  1387  * Pauses playback of the audio clip
       
  1388  * @return One of the system-wide error codes
       
  1389  * @since	7.0s
       
  1390  */
       
  1391 TInt CMMFMdaAudioPlayerUtility::Pause()
       
  1392 	{
       
  1393 	TInt err = KErrNone;
       
  1394 	if(iRepeatTrailingSilenceTimer->IsActive())
       
  1395 		{
       
  1396 		iRepeatTrailingSilenceTimer->Cancel();
       
  1397 		iRepeatCancelled = ETrue;
       
  1398 		iState = EPaused;	
       
  1399 		return KErrNone;
       
  1400 		}
       
  1401 	if (iState==EPlaying)
       
  1402 		{
       
  1403 		err = iController.Pause();
       
  1404 		if (!err || err==KErrNotReady)
       
  1405 			err = iController.GetPosition(iPosition);
       
  1406 		iState = EPaused;
       
  1407 		}
       
  1408 	return err;
       
  1409 	}
       
  1410 
       
  1411 /**
       
  1412  *
       
  1413  * Closes the current audio clip (allowing another clip to be opened)
       
  1414  *
       
  1415  * @since	7.0s
       
  1416  */
       
  1417 void CMMFMdaAudioPlayerUtility::Close()
       
  1418 	{
       
  1419 	// Reset the audio player state.
       
  1420 	Stop();
       
  1421 	iControllerEventMonitor->Cancel();
       
  1422 	iController.Close();
       
  1423 	if (iFindAndOpenController)	
       
  1424 		iFindAndOpenController->Close();
       
  1425 	if(iControllerImplementationInformation)
       
  1426 		{
       
  1427 		delete iControllerImplementationInformation;
       
  1428 		iControllerImplementationInformation = NULL;
       
  1429 		}
       
  1430 	iControllerUid = KNullUid;
       
  1431 	}
       
  1432 
       
  1433 
       
  1434 /**
       
  1435 Changes the current playback volume to a specified value.
       
  1436 
       
  1437 The volume can be changed before or during playback and is effective
       
  1438 immediately.
       
  1439 
       
  1440 @param  aVolume
       
  1441         The volume setting. This can be any value from zero to
       
  1442         the value returned by a call to
       
  1443         CMdaAudioPlayerUtility::MaxVolume().
       
  1444         Setting a zero value mutes the sound. Setting the
       
  1445         maximum value results in the loudest possible sound.
       
  1446 @return An error code indicating if the function call was successful. KErrNone on success, 
       
  1447 		otherwise another of the system-wide error codes.
       
  1448 @panic  EMMFMediaClientBadArgument is raised when the audio player utility is not initialised.
       
  1449 
       
  1450 @since  5.0
       
  1451 */
       
  1452 TInt CMMFMdaAudioPlayerUtility::SetVolume(TInt aVolume)
       
  1453 	{
       
  1454 	TInt err = iAudioPlayDeviceCommands.SetVolume(aVolume);
       
  1455 	if (err == KErrArgument)
       
  1456 		{
       
  1457 		TInt maxVolume = MaxVolume();
       
  1458 		if (aVolume < 0)
       
  1459 			{
       
  1460 			aVolume = 0;
       
  1461 			}
       
  1462 		else if (aVolume > maxVolume)
       
  1463 			{
       
  1464 			aVolume = maxVolume;
       
  1465 			}
       
  1466 		err = iAudioPlayDeviceCommands.SetVolume(aVolume);			
       
  1467 		}
       
  1468 
       
  1469 	return err;
       
  1470 	}
       
  1471 
       
  1472 /**
       
  1473 Sets the number of times the audio sample is to be repeated during the
       
  1474 playback operation.
       
  1475 
       
  1476 A period of silence can follow each playing of the sample. The audio
       
  1477 sample can be repeated indefinitely.
       
  1478 
       
  1479 @param  aRepeatNumberOfTimes
       
  1480         The number of times the audio sample, together with
       
  1481         the trailing silence, is to be repeated. If this is
       
  1482         set to KMdaRepeatForever, then the audio
       
  1483         sample, together with the trailing silence, is
       
  1484         repeated indefinitely or until Stop() is
       
  1485         called. If this is set to zero, then the audio sample
       
  1486         is not repeated. The behaviour is undefined for
       
  1487 		negative values (other than KMdaRepeatForever).
       
  1488 @param  aTrailingSilence
       
  1489         The time interval of the training silence.
       
  1490 		Negative values will produce a panic USER 87.
       
  1491 @since	5.0
       
  1492 */
       
  1493 void CMMFMdaAudioPlayerUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
       
  1494 	{
       
  1495 	TInt err = iAudioPlayControllerSetRepeatsCommands.SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
       
  1496 	
       
  1497 	if(err!=KErrNone)
       
  1498 		{
       
  1499 		iNumberOfTimesToRepeat = aRepeatNumberOfTimes;
       
  1500 		iTrailingSilence = aTrailingSilence;
       
  1501 		}
       
  1502 	}
       
  1503 
       
  1504 /**
       
  1505 Defines the period over which the volume level is to rise smoothly
       
  1506 from nothing to the normal volume level.
       
  1507 
       
  1508 @param  aRampDuration
       
  1509         The period over which the volume is to rise. A zero
       
  1510         value causes the audio sample to be played at the
       
  1511         normal level for the full duration of the playback. A
       
  1512         value which is longer than the duration of the audio
       
  1513         sample means that the sample never reaches its normal
       
  1514         volume level.
       
  1515 
       
  1516 @since  5.0
       
  1517 */
       
  1518 void CMMFMdaAudioPlayerUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
       
  1519 	{
       
  1520 	iAudioPlayDeviceCommands.SetVolumeRamp(aRampDuration);
       
  1521 	}
       
  1522 
       
  1523 TInt CMMFMdaAudioPlayerUtility::SetPriority(TInt aPriority, TInt aPref)
       
  1524 	{
       
  1525 	iPrioritySettings.iPref = aPref;
       
  1526 	iPrioritySettings.iPriority = aPriority;
       
  1527 	iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings);
       
  1528 
       
  1529 	return iController.SetPrioritySettings(iPrioritySettings);
       
  1530 	}
       
  1531 
       
  1532 /**
       
  1533 Returns the duration of the audio sample.
       
  1534 
       
  1535 @return The duration in microseconds.
       
  1536 
       
  1537 @since  5.0
       
  1538 */
       
  1539 const TTimeIntervalMicroSeconds& CMMFMdaAudioPlayerUtility::Duration()
       
  1540 	{
       
  1541 	TInt err = iController.GetDuration(iDuration);
       
  1542 	if (err)
       
  1543 		{
       
  1544 		iDuration = 0;
       
  1545 		}
       
  1546 	return iDuration;
       
  1547 	}
       
  1548 	
       
  1549 /**
       
  1550 Returns the duration of the audio sample in microseconds, and the duration state.
       
  1551 
       
  1552 @param aDuration
       
  1553 	   The duration of the sample in microseconds.
       
  1554 @return The duration state
       
  1555 
       
  1556 @since	9.1
       
  1557 */	
       
  1558 TMMFDurationInfo CMMFMdaAudioPlayerUtility::Duration(TTimeIntervalMicroSeconds& aDuration)
       
  1559 {	
       
  1560 	TPckgBuf<TMMFDurationInfo> pckg;
       
  1561 	TMMFDurationInfo result = EMMFDurationInfoValid;
       
  1562 	
       
  1563 	TMMFMessageDestinationPckg iDestinationPckg(TMMFMessageDestination(KUidInterfaceMMFDurationInfoControl, KMMFObjectHandleController));
       
  1564 	
       
  1565 	TInt err = iController.CustomCommandSync(iDestinationPckg,
       
  1566 										 	 EMMFGetDurationInfo,
       
  1567 										 	 KNullDesC8,
       
  1568 										 	 KNullDesC8,
       
  1569 										     pckg );
       
  1570 																 
       
  1571 	switch ( err )
       
  1572 		{
       
  1573 		case KErrNone:
       
  1574 			result = pckg();
       
  1575 			break;
       
  1576 		
       
  1577 		case KErrNotSupported:
       
  1578 			// Custom command not implemented return EMMFDurationInfoValid as the default value
       
  1579 			break;
       
  1580 		
       
  1581 		default:
       
  1582 			// Unknown error
       
  1583 			result = EMMFDurationInfoUnknown;
       
  1584 			break;
       
  1585 		}
       
  1586 
       
  1587 	// Get the duration information to return in aDuration
       
  1588 	// This is the intended behaviour regardless of what value err has
       
  1589 	aDuration = Duration();
       
  1590 	return result;
       
  1591 }	
       
  1592 	
       
  1593 /**
       
  1594 Returns an integer representing the maximum volume.
       
  1595 
       
  1596 This is the maximum value which can be passed to
       
  1597 CMdaAudioPlayerUtility::SetVolume().
       
  1598 
       
  1599 @return The maximum volume. This value is platform dependent but is always greater than or equal 
       
  1600         to one.
       
  1601 @panic  EMMFMediaClientPanicServerCommunicationProblem is raised when the audio player utility is not initialised.
       
  1602 
       
  1603 @since  5.0
       
  1604 */
       
  1605 TInt CMMFMdaAudioPlayerUtility::MaxVolume()
       
  1606 	{
       
  1607 	TInt maxVolume = 0;
       
  1608 #ifdef _DEBUG
       
  1609 	TInt error = 
       
  1610 #endif
       
  1611 		iAudioPlayDeviceCommands.GetMaxVolume(maxVolume);
       
  1612 	__ASSERT_DEBUG(error==KErrNone, Panic(EMMFMediaClientPanicServerCommunicationProblem));
       
  1613 	return maxVolume;
       
  1614 	}
       
  1615 
       
  1616 void CMMFMdaAudioPlayerUtility::HandleEvent(const TMMFEvent& aEvent)
       
  1617 	{
       
  1618 	// handle loading started/complete messages first, as the later code does not explicitly check the event type
       
  1619 	if (aEvent.iEventType == KMMFEventCategoryAudioLoadingStarted)
       
  1620 		{
       
  1621 		if (iLoadingObserver)
       
  1622 			{
       
  1623 			iLoadingObserver->MaloLoadingStarted();
       
  1624 			}
       
  1625 		}
       
  1626 	else if (aEvent.iEventType == KMMFEventCategoryAudioLoadingComplete)
       
  1627 		{
       
  1628 		if (iLoadingObserver)
       
  1629 			{
       
  1630 			iLoadingObserver->MaloLoadingComplete();
       
  1631 			}
       
  1632 		}
       
  1633 	else if (aEvent.iEventType == KMMFEventCategoryAudioResourceAvailable)
       
  1634 		{
       
  1635 		if (iAudioResourceNotificationCallBack != NULL)
       
  1636 			{
       
  1637 			TBuf8<TMMFAudioConfig::KNotificationDataBufferSize> notificationData;
       
  1638 			if (KErrNone != iNotificationRegistrationCommands.GetResourceNotificationData(aEvent.iEventType, notificationData))
       
  1639 				{
       
  1640 				notificationData.SetLength(0);
       
  1641 				}
       
  1642 			iAudioResourceNotificationCallBack->MarncResourceAvailable(aEvent.iEventType, notificationData);
       
  1643 			}
       
  1644 		}
       
  1645 	else if (aEvent.iEventType == KMMFEventCategoryPlaybackComplete)
       
  1646 		{
       
  1647 		TInt oldState = iState;
       
  1648 		//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.
       
  1649 		if(aEvent.iErrorCode == KErrInUse ||aEvent.iErrorCode == KErrDied ||aEvent.iErrorCode == KErrAccessDenied )
       
  1650 		    {
       
  1651 		    TInt err= iController.GetPosition(iPosition);
       
  1652 		    if(err != KErrNone)
       
  1653 		        {
       
  1654 		        iPosition = iPlayStart;
       
  1655 		        }
       
  1656 		    }
       
  1657 		else
       
  1658 		    {
       
  1659 		    iPosition = iPlayStart;
       
  1660 		    }
       
  1661 		if (aEvent.iErrorCode == KErrNone)
       
  1662 			{
       
  1663 			//If we weren't playing, ignore the event.
       
  1664 			if (oldState == EPlaying)
       
  1665 				{
       
  1666 				//we finished playing the clip so repeat if required
       
  1667 				iNumberOfTimesPlayed++;
       
  1668 				if ((iNumberOfTimesPlayed > iNumberOfTimesToRepeat) && (iNumberOfTimesToRepeat != KMdaRepeatForever))
       
  1669 					{
       
  1670 					//we've repeated enough times now
       
  1671 					iNumberOfTimesPlayed = 0;
       
  1672 					iState = EStopped;
       
  1673 					iCallback.MapcPlayComplete(KErrNone);
       
  1674 					}
       
  1675 				else
       
  1676 					{
       
  1677 					// We need to play silence, then repeat the clip
       
  1678 					iTrailingSilenceLeftToPlay = iTrailingSilence;
       
  1679 					PlaySilence();
       
  1680 					}
       
  1681 				}
       
  1682 			}
       
  1683 		else
       
  1684 			{ //aEvent.iErrorCode != KErrNone
       
  1685 			//if we weren't playing, don't advise Client.
       
  1686 			iState = EStopped;
       
  1687 			if (oldState == EPlaying)
       
  1688 				{
       
  1689 				iCallback.MapcPlayComplete(aEvent.iErrorCode);
       
  1690 				}
       
  1691 			}
       
  1692 		}
       
  1693 	else if(aEvent.iEventType == KMMFErrorCategoryControllerGeneralError)
       
  1694 		{
       
  1695 		TInt oldState = iState;
       
  1696 		iPosition = iPlayStart;
       
  1697 		iState = EStopped;
       
  1698 		if (oldState == EPlaying)
       
  1699 			{
       
  1700 			iCallback.MapcPlayComplete(aEvent.iErrorCode);
       
  1701 			}
       
  1702 		}
       
  1703 	// else we have an unexpected event that cannot be dealt with by the client.
       
  1704 	// We will simply ignore this.
       
  1705 	}
       
  1706 
       
  1707 void CMMFMdaAudioPlayerUtility::PlaySilence()
       
  1708 	{
       
  1709 	// iRepeatTrailingSilenceTimer->After() takes a TTimeIntervalMicroSeconds32
       
  1710 	// so for longer periods of silence call it repeatedly with KMaxTInt lengths
       
  1711 	TTimeIntervalMicroSeconds32 silence;
       
  1712 	if (iTrailingSilenceLeftToPlay.Int64() > KMaxTInt)
       
  1713 		{
       
  1714 		silence = KMaxTInt;
       
  1715 		iTrailingSilenceLeftToPlay = iTrailingSilenceLeftToPlay.Int64() - KMaxTInt;
       
  1716 		}
       
  1717 	else
       
  1718 		{
       
  1719 		silence = I64INT(iTrailingSilenceLeftToPlay.Int64());
       
  1720 		iTrailingSilenceLeftToPlay = 0;
       
  1721 		}
       
  1722 	iRepeatTrailingSilenceTimer->After(silence);
       
  1723 	}
       
  1724 
       
  1725 void CMMFMdaAudioPlayerUtility::RepeatTrailingSilenceTimerComplete()
       
  1726 	{
       
  1727 	if (iTrailingSilenceLeftToPlay.Int64() > 0)
       
  1728 		{
       
  1729 		PlaySilence();
       
  1730 		}
       
  1731 	else
       
  1732 		{
       
  1733 		// reset the position for subsequent plays
       
  1734 		iPosition = iPlayStart;
       
  1735 		DoPlay();
       
  1736 		}
       
  1737 	}
       
  1738 
       
  1739 /**
       
  1740  *
       
  1741  * Returns the current playback position in microseconds
       
  1742  *
       
  1743  * @param "TTimeIntervalMicroSeconds& aPosition"
       
  1744  *          The current time position in microseconds from the start of the file
       
  1745  * @return "TInt" One of the global error codes
       
  1746  *
       
  1747  * @since	7.0s
       
  1748  */
       
  1749 TInt CMMFMdaAudioPlayerUtility::GetPosition(TTimeIntervalMicroSeconds& aPosition)
       
  1750 	{
       
  1751 	TInt error = KErrNone;
       
  1752 	if (iState==EPlaying)
       
  1753 		error = iController.GetPosition(iPosition);
       
  1754 	aPosition = iPosition;
       
  1755 	return error;
       
  1756 	}
       
  1757 
       
  1758 /**
       
  1759  *
       
  1760  * Set the current playback position in microseconds from the start of the file
       
  1761  *
       
  1762  * @param "TTimeIntervalMicroSeconds& aPosition"
       
  1763  *         The position to move to in microseconds from the start of the file.
       
  1764  *         If aPosition is negative, the position is set to the start of the file.
       
  1765  *         If aPosition is greater than the file duration, the position is set to the
       
  1766  *         end of the file.
       
  1767  *
       
  1768  * @since	7.0s
       
  1769  */
       
  1770 void CMMFMdaAudioPlayerUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
       
  1771 	{
       
  1772 	// Clip the position if aPosition is greater than the duration
       
  1773 	// or if aPosition is negative.
       
  1774 	const TTimeIntervalMicroSeconds maxPosition(Duration());
       
  1775 	const TTimeIntervalMicroSeconds minPosition(0);
       
  1776 
       
  1777 	if (aPosition > maxPosition)
       
  1778 		iPosition = maxPosition;
       
  1779 	else if (aPosition < minPosition)
       
  1780 		iPosition = minPosition;
       
  1781 	else
       
  1782 		iPosition = aPosition;
       
  1783 
       
  1784     if (iState==EPlaying || iState==EPaused)
       
  1785 		{
       
  1786 		iController.SetPosition(iPosition);
       
  1787 		}
       
  1788 //	else if (iState == EPaused)
       
  1789 //		{
       
  1790 //		Stop();	// We call stop so that DevSound's internal buffers are reset
       
  1791 //		}
       
  1792 	}
       
  1793 
       
  1794 /**
       
  1795 Returns the current playback volume
       
  1796 
       
  1797 @param aVolume
       
  1798        A volume value between 0 and the value returned by MaxVolume().
       
  1799 
       
  1800 @return One of the global error codes.
       
  1801 
       
  1802 @since  7.0s
       
  1803 */
       
  1804 TInt CMMFMdaAudioPlayerUtility::GetVolume(TInt& aVolume)
       
  1805 	{
       
  1806 	TInt error = iAudioPlayDeviceCommands.GetVolume(aVolume);
       
  1807 	return error;
       
  1808 	}
       
  1809 
       
  1810 /**
       
  1811  *
       
  1812  * Returns the number of meta data entries in the current clip
       
  1813  *
       
  1814  * @param "TInt& aNumEntries"
       
  1815  *          The number of meta data entries in the header of the current clip
       
  1816  * @return "TInt" One of the global error codes
       
  1817  *
       
  1818  * @since	7.0s
       
  1819  */
       
  1820 TInt CMMFMdaAudioPlayerUtility::GetNumberOfMetaDataEntries(TInt& aNumEntries) 
       
  1821 	{
       
  1822 	TInt error = iController.GetNumberOfMetaDataEntries(aNumEntries);
       
  1823 	return error;
       
  1824 	}
       
  1825 
       
  1826 /**
       
  1827  *
       
  1828  * Returns the requested meta data entry
       
  1829  *
       
  1830  * @param "TInt aMetaDataIndex"
       
  1831  *          The index number of the meta data to retrieve
       
  1832  * @return "CMMFMetaDataEntry*" The meta data entry to return
       
  1833  * @leave	Leaves with KErrNotFound if the meta data entry does not exist or
       
  1834  *			KErrNotImplemented if the controller does not support meta data 
       
  1835  *			information for this format. Other errors indicate more general system
       
  1836  *			failure.
       
  1837  *
       
  1838  * @since	7.0s
       
  1839  */
       
  1840 CMMFMetaDataEntry* CMMFMdaAudioPlayerUtility::GetMetaDataEntryL(TInt aMetaDataIndex)
       
  1841 	{
       
  1842 	return iController.GetMetaDataEntryL(aMetaDataIndex);
       
  1843 	}
       
  1844 
       
  1845 /**
       
  1846  *
       
  1847  * Set the current playback window
       
  1848  *
       
  1849  * @param	"const TTimeIntervalMicroSeconds& aStart"
       
  1850  *			Start time of playback window relative to start of file
       
  1851  * @param	"const TTimeIntervalMicroSeconds& aEnd"
       
  1852  *			End time of playback window relative to start of file
       
  1853  *
       
  1854  * @return "TInt" One of the global error codes
       
  1855  *
       
  1856  * @since	7.0s
       
  1857  */
       
  1858 TInt CMMFMdaAudioPlayerUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aPlayStart,
       
  1859 											  const TTimeIntervalMicroSeconds& aPlayEnd)
       
  1860 	{
       
  1861 	TInt error = KErrNone;
       
  1862 
       
  1863 	if (aPlayStart >= TTimeIntervalMicroSeconds(0) &&
       
  1864 		aPlayStart < iDuration &&
       
  1865 			aPlayStart < aPlayEnd &&
       
  1866 			aPlayEnd <= iDuration )
       
  1867 		{
       
  1868 		iPlayStart = aPlayStart;
       
  1869 		iPlayEnd = aPlayEnd;
       
  1870 		iPlayWindowSet = ESet;
       
  1871 
       
  1872 		if (iState==EPlaying)
       
  1873 			error = iAudioPlayControllerCommands.SetPlaybackWindow(aPlayStart, aPlayEnd);
       
  1874 		}
       
  1875 	else
       
  1876 		error = KErrArgument;
       
  1877 
       
  1878 	return error;
       
  1879 	}
       
  1880 	
       
  1881 /**
       
  1882  *
       
  1883  * Clear the current playback window
       
  1884  *
       
  1885  * @return "TInt" One of the global error codes
       
  1886  *
       
  1887  * @since	7.0s
       
  1888  */
       
  1889 TInt CMMFMdaAudioPlayerUtility::ClearPlayWindow()
       
  1890 	{
       
  1891 	// clear play window start - very important because this is assigned 
       
  1892 	// to iPosition when we stop & is used to set the position on the next Play()
       
  1893 	iPosition = iPlayStart = iPlayEnd = TTimeIntervalMicroSeconds(0);
       
  1894 
       
  1895 	iPlayWindowSet = EClear;
       
  1896 	TInt err = KErrNone;
       
  1897 	if (iState==EPlaying)
       
  1898 		err = iAudioPlayControllerCommands.DeletePlaybackWindow();
       
  1899 	return err;
       
  1900 	}
       
  1901 
       
  1902 /**
       
  1903 Sets the current playback balance
       
  1904 
       
  1905 @param  aBalance
       
  1906         A value between KMMFBalanceMaxLeft and KMMFBalanceMaxRight. The default value is
       
  1907         KMMFBalanceCenter.
       
  1908 
       
  1909 @return One of the global error codes.
       
  1910 
       
  1911 @since  7.0s
       
  1912 */
       
  1913 TInt CMMFMdaAudioPlayerUtility::SetBalance(TInt aBalance)
       
  1914 	{
       
  1915 	TInt err = iAudioPlayDeviceCommands.SetBalance(aBalance);
       
  1916 	return err;
       
  1917 	}
       
  1918 
       
  1919 /**
       
  1920 Returns the bit rate of the audio clip.
       
  1921 
       
  1922 @param  aBitRate
       
  1923         Bit rate of the audio clip.
       
  1924 
       
  1925 @return One of the global error codes.
       
  1926 
       
  1927 @since  7.0s
       
  1928 */
       
  1929 TInt CMMFMdaAudioPlayerUtility::GetBitRate(TUint& aBitRate)
       
  1930 	{
       
  1931 	RMMFAudioControllerCustomCommands controller(iController);
       
  1932 	TInt err = controller.GetSourceBitRate(aBitRate);
       
  1933 	return err;	
       
  1934 	}
       
  1935 
       
  1936 const CMMFControllerImplementationInformation& CMMFMdaAudioPlayerUtility::ControllerImplementationInformationL()
       
  1937 	{
       
  1938 	if (!iControllerImplementationInformation)
       
  1939 		{
       
  1940 		if (iControllerUid==KNullUid)
       
  1941 			User::Leave(KErrNotReady);
       
  1942 		iControllerImplementationInformation = CMMFControllerImplementationInformation::NewL(iControllerUid);
       
  1943 		}
       
  1944 	return *iControllerImplementationInformation;
       
  1945 	}
       
  1946 	
       
  1947 void CMMFMdaAudioPlayerUtility::GetAudioLoadingProgressL(TInt& aPercentageProgress)
       
  1948 	{
       
  1949 	User::LeaveIfError(iAudioPlayControllerCommands.GetLoadingProgress(aPercentageProgress));
       
  1950 	}
       
  1951 	
       
  1952 TInt CMMFMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
       
  1953 	{
       
  1954 	return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
       
  1955 	}
       
  1956 	
       
  1957 TInt CMMFMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
       
  1958 	{
       
  1959 	return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
       
  1960 	}
       
  1961 	
       
  1962 void CMMFMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
       
  1963 	{
       
  1964 	iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
       
  1965 	}
       
  1966 	
       
  1967 void CMMFMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
       
  1968 	{
       
  1969 	iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
       
  1970 	}
       
  1971 
       
  1972 /**
       
  1973 Returns the current playback balance
       
  1974 
       
  1975 @param  aBalance
       
  1976         A value between KMMFBalanceMaxLeft and KMMFBalanceMaxRight
       
  1977 
       
  1978 @return One of the global error codes.
       
  1979 
       
  1980 @since  7.0s
       
  1981 */
       
  1982 TInt CMMFMdaAudioPlayerUtility::GetBalance(TInt& aBalance)
       
  1983 	{
       
  1984 	TInt err = iAudioPlayDeviceCommands.GetBalance(aBalance);
       
  1985 	return err;
       
  1986 	}
       
  1987 	
       
  1988 MMMFDRMCustomCommand* CMMFMdaAudioPlayerUtility::GetDRMCustomCommand()
       
  1989 	{
       
  1990 	// TODO: check controller supports MMMFDRMCustomCommandImplementor
       
  1991 	if (iDRMCustomCommands.IsSupported())
       
  1992 		{
       
  1993 		return static_cast<MMMFDRMCustomCommand*>(&iDRMCustomCommands);
       
  1994 		}
       
  1995 	else
       
  1996 		{
       
  1997 		return NULL;
       
  1998 		}
       
  1999 	}
       
  2000 	
       
  2001 void CMMFMdaAudioPlayerUtility::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aLoadingObserver)
       
  2002 	{
       
  2003 	iLoadingObserver = &aLoadingObserver;
       
  2004 	}
       
  2005 
       
  2006 TInt CMMFMdaAudioPlayerUtility::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,
       
  2007 																	TUid aNotificationEventUid,
       
  2008 																	const TDesC8& aNotificationRegistrationData)
       
  2009 	{
       
  2010 	iAudioResourceNotificationCallBack = &aCallback;
       
  2011 	TInt err = iNotificationRegistrationCommands.RegisterAsClient(aNotificationEventUid, aNotificationRegistrationData);
       
  2012 	if(err == KErrNotReady)
       
  2013 		{
       
  2014 		iEventHolder = 	aNotificationEventUid;
       
  2015 		iNotificationDataHolder = aNotificationRegistrationData;
       
  2016 		return KErrNone;
       
  2017 		}
       
  2018 	iNotificationDataHolder = KNullDesC8;
       
  2019 	iEventHolder = KNullUid;
       
  2020 	return err;
       
  2021 	}
       
  2022 
       
  2023 TInt CMMFMdaAudioPlayerUtility::CancelRegisterAudioResourceNotification(TUid aNotificationEventId)
       
  2024 	{
       
  2025 	TInt err = iNotificationRegistrationCommands.CancelRegisterAsClient(aNotificationEventId);
       
  2026 	if(err == KErrNotReady)
       
  2027 		{
       
  2028 		if(aNotificationEventId != KMMFEventCategoryAudioResourceAvailable)	
       
  2029 			{
       
  2030 			return KErrNotSupported;
       
  2031 			}
       
  2032 		if(iEventHolder == KNullUid)	
       
  2033 			{
       
  2034 			return KErrCancel;
       
  2035 			}
       
  2036 		iEventHolder = KNullUid;
       
  2037 		iNotificationDataHolder = KNullDesC8;
       
  2038 		return KErrNone;
       
  2039 		}
       
  2040 	return err;
       
  2041 	}
       
  2042 	
       
  2043 TInt CMMFMdaAudioPlayerUtility::WillResumePlay()
       
  2044 	{
       
  2045 	return iNotificationRegistrationCommands.WillResumePlay();
       
  2046 	}
       
  2047 	
       
  2048 TInt CMMFMdaAudioPlayerUtility::SetThreadPriority(const TThreadPriority& aThreadPriority) const
       
  2049 	{
       
  2050 	return iController.SetThreadPriority(aThreadPriority);
       
  2051 	}
       
  2052 	
       
  2053 CRepeatTrailingSilenceTimer* CRepeatTrailingSilenceTimer::NewL(MRepeatTrailingSilenceTimerObs& aObs)
       
  2054 	{
       
  2055 	CRepeatTrailingSilenceTimer* s = new(ELeave) CRepeatTrailingSilenceTimer(aObs);
       
  2056 	CleanupStack::PushL(s);
       
  2057 	s->ConstructL();
       
  2058 	CleanupStack::Pop();
       
  2059 	return s;
       
  2060 	}
       
  2061 
       
  2062 void CRepeatTrailingSilenceTimer::RunL()
       
  2063 	{
       
  2064 	iObs.RepeatTrailingSilenceTimerComplete();
       
  2065 	}
       
  2066 
       
  2067 CRepeatTrailingSilenceTimer::CRepeatTrailingSilenceTimer(MRepeatTrailingSilenceTimerObs& aObs) :
       
  2068 	CTimer(EPriorityHigh),
       
  2069 	iObs(aObs)
       
  2070 	{
       
  2071 	CActiveScheduler::Add(this);
       
  2072 	}
       
  2073 
       
  2074 
       
  2075 
       
  2076 CMMFMdaAudioPlayerCallBack* CMMFMdaAudioPlayerCallBack::NewL(MMdaAudioPlayerCallback& aCallback)
       
  2077 	{
       
  2078 	return new(ELeave) CMMFMdaAudioPlayerCallBack(aCallback);
       
  2079 	}
       
  2080 
       
  2081 CMMFMdaAudioPlayerCallBack::CMMFMdaAudioPlayerCallBack(MMdaAudioPlayerCallback& aCallback) :
       
  2082 	CActive(CActive::EPriorityHigh), iCallback(aCallback)
       
  2083 	{
       
  2084 	CActiveScheduler::Add(this);
       
  2085 	}
       
  2086 
       
  2087 CMMFMdaAudioPlayerCallBack::~CMMFMdaAudioPlayerCallBack()
       
  2088 	{
       
  2089 	Cancel();
       
  2090 	}
       
  2091 
       
  2092 void CMMFMdaAudioPlayerCallBack::InitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration)
       
  2093 	{
       
  2094 	iError = aError;
       
  2095 	iDuration = aDuration;
       
  2096 	iState = ECallbackInitComplete;
       
  2097 	if (!IsActive())
       
  2098 		{
       
  2099 		TRequestStatus* s = &iStatus;
       
  2100 		SetActive();
       
  2101 		User::RequestComplete(s, KErrNone);
       
  2102 		}
       
  2103 	}
       
  2104 
       
  2105 void CMMFMdaAudioPlayerCallBack::PlayComplete(TInt aError)
       
  2106 	{
       
  2107 	iError = aError;
       
  2108 	iState = ECallbackPlayComplete;
       
  2109 	if (!IsActive())
       
  2110 		{
       
  2111 		TRequestStatus* s = &iStatus;
       
  2112 		SetActive();
       
  2113 		User::RequestComplete(s, KErrNone);
       
  2114 		}
       
  2115 	}
       
  2116 
       
  2117 void CMMFMdaAudioPlayerCallBack::RunL()
       
  2118 	{
       
  2119 	switch (iState)
       
  2120 		{
       
  2121 		case ECallbackInitComplete: 
       
  2122 			iCallback.MapcInitComplete(iError, iDuration);
       
  2123 			break;
       
  2124 		case ECallbackPlayComplete:
       
  2125 			iCallback.MapcPlayComplete(iError);
       
  2126 			break;
       
  2127 		}
       
  2128 	}
       
  2129 
       
  2130 void CMMFMdaAudioPlayerCallBack::DoCancel()
       
  2131 	{
       
  2132 	// Nothing to cancel
       
  2133 	}