os/mm/mmlibs/mmfw/src/Client/Audio/mmfclientaudioplayer.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	// XXX: 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 	}