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