1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmlibs/mmfw/src/Client/Audio/mmfclientaudioplayer.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2127 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <bautils.h>
1.20 +#include <utf.h>
1.21 +#include <mmf/common/mmfpaniccodes.h>
1.22 +#include "mmfclientaudioplayer.h"
1.23 +#include "mmfclientutility.h"
1.24 +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
1.25 +#include <mmf/common/mmfdurationinfocustomcommandsimpl.h>
1.26 +#include <mmf/common/mmfdurationinfocustomcommandsenums.h>
1.27 +#endif
1.28 +
1.29 +using namespace ContentAccess;
1.30 +
1.31 +// declared in the recorder module
1.32 +void Panic(TInt aPanicCode);
1.33 +
1.34 +/**
1.35 +Constructs and initialises a new instance of the audio player utility.
1.36 +
1.37 +The function leaves if the audio player utility object cannot be created.
1.38 +
1.39 +No callback notification is made upon completion of NewL().
1.40 +
1.41 +@param aCallback
1.42 + The audio player observer interface.
1.43 +@param aPriority
1.44 + The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
1.45 + EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
1.46 +@param aPref
1.47 + The Priority Preference - an additional audio policy parameter. The suggested default is
1.48 + EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
1.49 + values may be supported by given phones and/or platforms, but should not be depended upon by
1.50 + portable code.
1.51 +
1.52 +@return A pointer to the new audio player utility object.
1.53 +
1.54 +Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
1.55 +several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
1.56 +the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
1.57 +Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
1.58 +vary between different phones. Portable applications are advised not to assume any specific behaviour.
1.59 +*/
1.60 +EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewL(MMdaAudioPlayerCallback& aCallback,
1.61 + TInt aPriority,
1.62 + TInt aPref)
1.63 + {
1.64 + CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
1.65 + CleanupStack::PushL(self);
1.66 + self->iProperties = CMMFMdaAudioPlayerUtility::NewL(aCallback, aPriority, aPref);
1.67 + CleanupStack::Pop(self);
1.68 + return self;
1.69 + }
1.70 +
1.71 +/**
1.72 +Constructs and initialises a new instance of the audio player utility for playing sampled audio data
1.73 +from a file. The audio data must be in a supported format (e.g. WAV and AU).
1.74 +
1.75 +The function leaves if the audio player utility object cannot be created.
1.76 +
1.77 +When initialisation of the audio player utility is complete, successfully or otherwise, the callback
1.78 +function MMdaAudioPlayerCallback::MapcInitComplete() is called.
1.79 +
1.80 +@param aFileName
1.81 + The full path name of the file containing the audio data.
1.82 +@param aCallback
1.83 + The audio player observer interface.
1.84 +@param aPriority
1.85 + The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
1.86 + EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
1.87 +@param aPref
1.88 + The Priority Preference - an additional audio policy parameter. The suggested default is
1.89 + EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
1.90 + values may be supported by given phones and/or platforms, but should not be depended upon by
1.91 + portable code.
1.92 +@param aServer
1.93 + Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
1.94 +
1.95 +@return A pointer to the new audio player utility object.
1.96 +
1.97 +Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
1.98 +several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
1.99 +the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
1.100 +Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
1.101 +vary between different phones. Portable applications are advised not to assume any specific behaviour.
1.102 +*/
1.103 +EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewFilePlayerL(const TDesC& aFileName,
1.104 + MMdaAudioPlayerCallback& aCallback,
1.105 + TInt aPriority,
1.106 + TInt aPref,
1.107 + CMdaServer* /*aServer*/)
1.108 + {
1.109 + CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
1.110 + CleanupStack::PushL(self);
1.111 + self->iProperties = CMMFMdaAudioPlayerUtility::NewFilePlayerL(aFileName, aCallback, aPriority, aPref);
1.112 + CleanupStack::Pop(self);
1.113 + return self;
1.114 + }
1.115 +
1.116 +/**
1.117 +Constructs and initialises a new instance of the audio player utility for playing sampled audio data
1.118 +from a descriptor.
1.119 +
1.120 +The audio data must be in a supported format (e.g. WAV and AU).
1.121 +
1.122 +The function leaves if the audio player utility object cannot be created. When initialisation of the
1.123 +audio player utility is complete, successfully or otherwise, the callback function
1.124 +MMdaAudioPlayerCallback::MapcInitComplete() is called.
1.125 +
1.126 +@param aData
1.127 + A descriptor containing the audio data. This descriptor must remain in existence for the
1.128 + lifetime of this audio player utility object.
1.129 +@param aCallback
1.130 + The audio player observer interface.
1.131 +@param aPriority
1.132 + The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
1.133 + EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
1.134 +@param aPref
1.135 + The Priority Preference - an additional audio policy parameter. The suggested default is
1.136 + EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
1.137 + values may be supported by given phones and/or platforms, but should not be depended upon by
1.138 + portable code.
1.139 +@param aServer
1.140 + Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
1.141 +
1.142 +@return A pointer to the new audio player utility object.
1.143 +
1.144 +Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
1.145 +several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
1.146 +the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
1.147 +Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
1.148 +vary between different phones. Portable applications are advised not to assume any specific behaviour.
1.149 +*/
1.150 +EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewDesPlayerL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
1.151 + {
1.152 + CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
1.153 + CleanupStack::PushL(self);
1.154 + self->iProperties = CMMFMdaAudioPlayerUtility::NewDesPlayerL(aData, aCallback, aPriority, aPref);
1.155 + CleanupStack::Pop(self);
1.156 + return self;
1.157 + }
1.158 +
1.159 +/**
1.160 +Constructs and initialises a new instance of the audio player utility for playing sampled audio data
1.161 +from a read only descriptor.
1.162 +
1.163 +The audio data must be in a supported format (e.g. WAV and AU).
1.164 +
1.165 +The function leaves if the audio player utility object cannot be created. When initialisation of
1.166 +the audio player utility is complete, successfully or otherwise, the callback function
1.167 +MMdaAudioPlayerCallback::MapcInitComplete() is called.
1.168 +
1.169 +@param aData
1.170 + A read only descriptor containing the audio data. This descriptor must remain in existence
1.171 + for the lifetime of this audio player utility object.
1.172 +@param aCallback
1.173 + The audio player observer interface.
1.174 +@param aPriority
1.175 + The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and
1.176 + EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request.
1.177 +@param aPref
1.178 + The Priority Preference - an additional audio policy parameter. The suggested default is
1.179 + EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional
1.180 + values may be supported by given phones and/or platforms, but should not be depended upon by
1.181 + portable code.
1.182 +@param aServer
1.183 + Not used in 7.0s. This parameter is provided for binary compatibility with previous versions.
1.184 +
1.185 +@return A pointer to a new audio player utility.
1.186 +
1.187 +Note: The Priority Value and Priority Preference are used primarily when deciding what to do when
1.188 +several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference,
1.189 +the adaptation may consider other parameters such as the SecureId and Capabilities of the client process.
1.190 +Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may
1.191 +vary between different phones. Portable applications are advised not to assume any specific behaviour.
1.192 +*/
1.193 +EXPORT_C CMdaAudioPlayerUtility* CMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
1.194 + {
1.195 + CMdaAudioPlayerUtility* self = new(ELeave) CMdaAudioPlayerUtility();
1.196 + CleanupStack::PushL(self);
1.197 + self->iProperties = CMMFMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(aData, aCallback, aPriority, aPref);
1.198 + CleanupStack::Pop(self);
1.199 + return self;
1.200 + }
1.201 +
1.202 +CMdaAudioPlayerUtility::CMdaAudioPlayerUtility()
1.203 + {
1.204 + }
1.205 +
1.206 +/**
1.207 +Destructor.
1.208 +
1.209 +Frees all resources owned by the object prior to its destruction.
1.210 +*/
1.211 +CMdaAudioPlayerUtility::~CMdaAudioPlayerUtility()
1.212 + {
1.213 + delete iProperties;
1.214 + }
1.215 +
1.216 +/**
1.217 +Ensures that any subsequent calls to OpenXYZ() will create controllers that
1.218 +share a heap.
1.219 +
1.220 +The default behaviour is that for each player utility a controller with its own heap
1.221 +is created. Each heap uses a chunk, so using this function avoids situations where
1.222 +the number of chunks per process is limited.
1.223 +The default behaviour is generally to be preferred, and should give lower overall
1.224 +memory usage. However, if many controllers are to be created for a particular thread,
1.225 +then this function should be used to prevent running out of heaps or chunks.
1.226 +
1.227 +@since 9.1
1.228 +*/
1.229 +EXPORT_C void CMdaAudioPlayerUtility::UseSharedHeap()
1.230 + {
1.231 + ASSERT(iProperties);
1.232 + iProperties->UseSharedHeap();
1.233 + }
1.234 +
1.235 +// 5.0 functions
1.236 +
1.237 +/**
1.238 +Begins playback of audio sample data at the current playback position using the current volume,
1.239 +gain and priority settings.
1.240 +
1.241 +When playing of the audio sample is complete, successfully or
1.242 +otherwise, the callback function
1.243 +MMdaAudioPlayerCallback::MapcPlayComplete() is
1.244 +called.
1.245 +
1.246 +If this function is called whilst already playing then
1.247 +MMdaAudioPlayerCallback::MapcPlayComplete will return with the
1.248 +error code KErrNotReady.
1.249 +
1.250 +@since 5.0
1.251 +*/
1.252 +void CMdaAudioPlayerUtility::Play()
1.253 + {
1.254 + ASSERT(iProperties);
1.255 + iProperties->Play();
1.256 + }
1.257 +
1.258 +/**
1.259 +Stops playback of the audio sample as soon as possible.
1.260 +
1.261 +If the audio sample is playing, playback is stopped as soon as
1.262 +possible. If playback is already complete, nothing further happens as
1.263 +a result of calling this function. The callback function
1.264 +MMdaAudioPlayerCallback::MapcPlayComplete() is not
1.265 +called.
1.266 +
1.267 +@since 5.0
1.268 +*/
1.269 +void CMdaAudioPlayerUtility::Stop()
1.270 + {
1.271 + ASSERT(iProperties);
1.272 + iProperties->Stop();
1.273 + }
1.274 +
1.275 +
1.276 +/**
1.277 +Changes the current playback volume to a specified value.
1.278 +
1.279 +The volume can be changed before or during playback and is effective
1.280 +immediately. The volume can be set to any value between zero (mute) and
1.281 +the maximum permissible volume (determined using MaxVolume()).
1.282 +
1.283 +@param aVolume
1.284 + The volume setting. This can be any value from zero to
1.285 + the value returned by a call to
1.286 + CMdaAudioPlayerUtility::MaxVolume().
1.287 + Setting a zero value mutes the sound. Setting the maximum
1.288 + value results in the loudest possible sound. Values less
1.289 + than zero would be set to zero and the values greater than
1.290 + the maximum permitted volume would be set to the maximum volume.
1.291 +@return An error code indicating if the function call was successful. KErrNone on success,
1.292 + otherwise another of the system-wide error codes.
1.293 +@panic EMMFMediaClientBadArgument is raised when the audio player utility is not initialised.
1.294 +
1.295 +@since 5.0
1.296 +*/
1.297 +TInt CMdaAudioPlayerUtility::SetVolume(TInt aVolume)
1.298 + {
1.299 + ASSERT(iProperties);
1.300 + return iProperties->SetVolume(aVolume);
1.301 + }
1.302 +
1.303 +/**
1.304 +Sets the number of times the audio sample is to be repeated during the
1.305 +playback operation.
1.306 +
1.307 +A period of silence can follow each playing of the sample. The audio
1.308 +sample can be repeated indefinitely.
1.309 +
1.310 +@param aRepeatNumberOfTimes
1.311 + The number of times the audio sample, together with
1.312 + the trailing silence, is to be repeated. If this is
1.313 + set to KMdaRepeatForever, then the audio
1.314 + sample, together with the trailing silence, is
1.315 + repeated indefinitely or until Stop() is
1.316 + called. If this is set to zero, then the audio sample
1.317 + is not repeated.
1.318 +@param aTrailingSilence
1.319 + The time interval of the trailing silence in microseconds.
1.320 +
1.321 +@since 5.0
1.322 +*/
1.323 +void CMdaAudioPlayerUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
1.324 + {
1.325 + ASSERT(iProperties);
1.326 + iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
1.327 + }
1.328 +
1.329 +/**
1.330 +Defines the period over which the volume level is to rise smoothly
1.331 +from nothing to the normal volume level.
1.332 +
1.333 +@param aRampDuration
1.334 + The period over which the volume is to rise. A zero
1.335 + value causes the audio sample to be played at the
1.336 + normal level for the full duration of the playback. A
1.337 + value which is longer than the duration of the audio
1.338 + sample means that the sample never reaches its normal
1.339 + volume level.
1.340 +
1.341 +@since 5.0
1.342 +*/
1.343 +void CMdaAudioPlayerUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
1.344 + {
1.345 + ASSERT(iProperties);
1.346 + iProperties->SetVolumeRamp(aRampDuration);
1.347 + }
1.348 +
1.349 +/**
1.350 +Returns the duration of the audio sample in microseconds.
1.351 +
1.352 +@return The duration of the sample in microseconds.
1.353 +
1.354 +@since 5.0
1.355 +*/
1.356 +const TTimeIntervalMicroSeconds& CMdaAudioPlayerUtility::Duration()
1.357 + {
1.358 + ASSERT(iProperties);
1.359 + return iProperties->Duration();
1.360 + }
1.361 +
1.362 +/**
1.363 +Returns the duration of the audio sample in microseconds, and the duration state.
1.364 +
1.365 +@param aDuration
1.366 + The duration of the sample in microseconds.
1.367 +@return The duration state
1.368 +
1.369 +@since 9.1
1.370 +*/
1.371 +EXPORT_C TMMFDurationInfo CMdaAudioPlayerUtility::Duration(TTimeIntervalMicroSeconds& aDuration)
1.372 +{
1.373 + ASSERT(iProperties);
1.374 + return iProperties->Duration(aDuration);
1.375 +}
1.376 +
1.377 +/**
1.378 +Returns an integer representing the maximum volume.
1.379 +
1.380 +This is the maximum value which can be passed to
1.381 +CMdaAudioPlayerUtility::SetVolume(). This value is platform
1.382 +independent, but is always greater than or equal to one.
1.383 +
1.384 +@return The maximum volume setting.
1.385 +@panic EMMFMediaClientPanicServerCommunicationProblem is raised when the audio player utility is not initialised.
1.386 +
1.387 +@since 5.0
1.388 +*/
1.389 +TInt CMdaAudioPlayerUtility::MaxVolume()
1.390 + {
1.391 + ASSERT(iProperties);
1.392 + return iProperties->MaxVolume();
1.393 + }
1.394 +
1.395 +// 7.0s functions
1.396 +
1.397 +/**
1.398 +Opens an audio clip from a file.
1.399 +
1.400 +The audio data must be in a supported format (for example, WAV or AU).
1.401 +
1.402 +This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
1.403 +
1.404 +@param aFileName
1.405 + The file to open.
1.406 +@leave KErrNotReady
1.407 + If a previous open statement is awaiting notification of completion.
1.408 + opening the file
1.409 +@since 7.0s
1.410 +*/
1.411 +EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const TDesC& aFileName)
1.412 + {
1.413 + ASSERT(iProperties);
1.414 + iProperties->OpenFileL(aFileName);
1.415 + }
1.416 +
1.417 +/**
1.418 +Opens an audio clip from a file.
1.419 +
1.420 +The audio data must be in a supported format (for example, WAV or AU).
1.421 +
1.422 +This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
1.423 +
1.424 +Note: it is generally advisable that the RFile is shared through the call RFs::ShareProtected().
1.425 +This allows the adaptation to pass it to another process, if that is required. This is particularly
1.426 +true of playing DRM encrypted files.
1.427 +
1.428 +@param aFile
1.429 + The open shared session file handle to use
1.430 +@leave KErrBadHandle
1.431 + If the file handle is not shared through the call RFs::ShareProtected(), and the adaptation needs it to be.
1.432 +@leave KErrNotReady
1.433 + If a previous open statement is awaiting notification of completion.
1.434 + opening the file
1.435 +*/
1.436 +EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const RFile& aFile)
1.437 + {
1.438 + ASSERT(iProperties);
1.439 + RFile& file = const_cast<RFile&>(aFile);
1.440 + TMMFileHandleSource tfs(file, KDefaultContentObject, EPlay);
1.441 + iProperties->OpenFileL(tfs);
1.442 + }
1.443 +
1.444 +/**
1.445 +Opens an audio clip from a file.
1.446 +
1.447 +The audio data must be in a supported format (for example, WAV or AU).
1.448 +
1.449 +This function leaves with KErrNotReady if there is a previous open statement awaiting notification of completion.
1.450 +
1.451 +@param aSource
1.452 + The file to open or an open file handle to use
1.453 +@leave KErrNotReady
1.454 + If a previous open statement is awaiting notification of completion.
1.455 + opening the file
1.456 +*/
1.457 +EXPORT_C void CMdaAudioPlayerUtility::OpenFileL(const TMMSource& aSource)
1.458 + {
1.459 + ASSERT(iProperties);
1.460 + iProperties->OpenFileL(aSource);
1.461 + }
1.462 +
1.463 +/**
1.464 +Opens an audio clip from a descriptor.
1.465 +
1.466 +The audio data must be in a supported format (for example, WAV or AU).
1.467 +
1.468 +@param aDescriptor
1.469 + A descriptor containing the audio clip.
1.470 +@leave KErrInUse
1.471 + If a previous open statement is awaiting notification of completion.
1.472 +
1.473 +@since 7.0s
1.474 +*/
1.475 +EXPORT_C void CMdaAudioPlayerUtility::OpenDesL(const TDesC8& aDescriptor)
1.476 + {
1.477 + ASSERT(iProperties);
1.478 + iProperties->OpenDesL(aDescriptor);
1.479 + }
1.480 +
1.481 +/**
1.482 +Opens an audio clip from a URL.
1.483 +
1.484 +The audio data must be in a supported format (for example, WAV or AU).
1.485 +
1.486 +@param aUrl
1.487 + The URL to open.
1.488 +@param aIapId
1.489 + Internet access point(IAP) ID to use. KUseDefaultIap selects the default IAP.
1.490 +@param aMimeType
1.491 + MIME type of the URL source.
1.492 +
1.493 +@leave KErrInUse
1.494 + If a previous open statement is awaiting notification of completion.
1.495 +
1.496 +@since 7.0s
1.497 +*/
1.498 +EXPORT_C void CMdaAudioPlayerUtility::OpenUrlL(const TDesC& aUrl, const TInt aIapId /*=KUseDefaultIap*/, const TDesC8& aMimeType /*=KNullDesC8*/)
1.499 + {
1.500 + ASSERT(iProperties);
1.501 + iProperties->OpenUrlL(aUrl, aIapId, aMimeType);
1.502 + }
1.503 +
1.504 +/**
1.505 +Pauses the playback of the audio clip.
1.506 +
1.507 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.508 + another of the system-wide error codes.
1.509 +
1.510 +@since 7.0s
1.511 +*/
1.512 +EXPORT_C TInt CMdaAudioPlayerUtility::Pause()
1.513 + {
1.514 + ASSERT(iProperties);
1.515 + return iProperties->Pause();
1.516 + }
1.517 +
1.518 +/**
1.519 +Closes the current audio clip (allowing another clip to be opened).
1.520 +
1.521 +@since 7.0s
1.522 +*/
1.523 +EXPORT_C void CMdaAudioPlayerUtility::Close()
1.524 + {
1.525 + ASSERT(iProperties);
1.526 + iProperties->Close();
1.527 + }
1.528 +
1.529 +/**
1.530 +Returns the current playback position in microseconds from the start of the clip.
1.531 +
1.532 +@param aPosition
1.533 + The current time position in microseconds from the start of the clip to the current
1.534 + play position.
1.535 +
1.536 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.537 + another of the system-wide error codes.
1.538 +
1.539 +@since 7.0s
1.540 +*/
1.541 +EXPORT_C TInt CMdaAudioPlayerUtility::GetPosition(TTimeIntervalMicroSeconds& aPosition)
1.542 + {
1.543 + ASSERT(iProperties);
1.544 + return iProperties->GetPosition(aPosition);
1.545 + }
1.546 +
1.547 +/**
1.548 +Sets the current playback position in microseconds from the start of the clip.
1.549 +
1.550 +@param aPosition
1.551 + The position to move to in microseconds from the start of the clip.
1.552 +
1.553 +@since 7.0s
1.554 +*/
1.555 +EXPORT_C void CMdaAudioPlayerUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
1.556 + {
1.557 + ASSERT(iProperties);
1.558 + iProperties->SetPosition(aPosition);
1.559 + }
1.560 +
1.561 +/**
1.562 +Sets the priority for playback. This is used to arbitrate between multiple
1.563 +objects trying to access a single sound device.
1.564 +
1.565 +@param aPriority
1.566 + The Priority Value.
1.567 +@param aPref
1.568 + The Priority Preference.
1.569 +
1.570 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.571 + another of the system-wide error codes.
1.572 +
1.573 +@since 7.0s
1.574 +
1.575 +@see CMdaAudioPlayerUtility::NewL()
1.576 +
1.577 +*/
1.578 +EXPORT_C TInt CMdaAudioPlayerUtility::SetPriority(TInt aPriority, TInt aPref)
1.579 + {
1.580 + ASSERT(iProperties);
1.581 + return iProperties->SetPriority(aPriority, aPref);
1.582 + }
1.583 +
1.584 +/**
1.585 +Returns the current playback volume.
1.586 +
1.587 +@param aVolume
1.588 + A value between 0 and the maximum volume settings returned by MaxVolume().
1.589 +
1.590 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.591 + another of the system-wide error codes.
1.592 +
1.593 +@since 7.0s
1.594 +*/
1.595 +EXPORT_C TInt CMdaAudioPlayerUtility::GetVolume(TInt& aVolume)
1.596 + {
1.597 + ASSERT(iProperties);
1.598 + return iProperties->GetVolume(aVolume);
1.599 + }
1.600 +
1.601 +/**
1.602 +Returns the number of meta data entries in the current audio clip.
1.603 +
1.604 +@param aNumEntries
1.605 + The number of meta data entries in the header of the current clip.
1.606 +
1.607 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.608 + another of the system-wide error codes.
1.609 +
1.610 +@since 7.0s
1.611 +*/
1.612 +EXPORT_C TInt CMdaAudioPlayerUtility::GetNumberOfMetaDataEntries(TInt& aNumEntries)
1.613 + {
1.614 + ASSERT(iProperties);
1.615 + return iProperties->GetNumberOfMetaDataEntries(aNumEntries);
1.616 + }
1.617 +
1.618 +/**
1.619 +Returns the requested meta data entry.
1.620 +
1.621 +@param aMetaDataIndex
1.622 + The index number of the meta data to retrieve.
1.623 +
1.624 +@return The requested meta data entry.
1.625 +@leave KErrNotFound
1.626 + The meta data entry does not exist.
1.627 +@leave KErrNotImplemented
1.628 + The controller does not support meta data information for this format.
1.629 +
1.630 +@since 7.0s
1.631 +*/
1.632 +EXPORT_C CMMFMetaDataEntry* CMdaAudioPlayerUtility::GetMetaDataEntryL(TInt aMetaDataIndex)
1.633 + {
1.634 + ASSERT(iProperties);
1.635 + return iProperties->GetMetaDataEntryL(aMetaDataIndex);
1.636 + }
1.637 +
1.638 +/**
1.639 +Defines a window on the audio sample data.
1.640 +
1.641 +The window is defined in terms of a start and end position.
1.642 +When the current playback position reaches the window end position, or Stop() is called, the
1.643 +current playback position is set to the window start position and playback stops.
1.644 +
1.645 +The current playback position is not affected by a call to SetPlayWindow() unless it is outside
1.646 +the new playback window, in which case it is set to the window start or end position depending
1.647 +on which one is closer.
1.648 +
1.649 +The window persists until ClearPlayWindow() is called.
1.650 +Loading new audio sample data without adjusting or clearing the window will result in
1.651 +playback errors if the window is outside the new data.
1.652 +
1.653 +@param aStart
1.654 + The position defining the start of the window, measured in microseconds. If this value is less
1.655 + than zero, it is set to zero. If this value is greater than aEnd, then it is swapped with aEnd.
1.656 +@param aEnd
1.657 + The position defining the end of the window, measured in microseconds. If this value is greater
1.658 + than the value returned by Duration(), it is set to the value of Duration(). If this value is
1.659 + less than aStart, then it is swapped with aStart.
1.660 +
1.661 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.662 + another of the system-wide error codes.
1.663 +
1.664 +@since 7.0s
1.665 +*/
1.666 +EXPORT_C TInt CMdaAudioPlayerUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aStart,
1.667 + const TTimeIntervalMicroSeconds& aEnd)
1.668 + {
1.669 + ASSERT(iProperties);
1.670 + return iProperties->SetPlayWindow(aStart, aEnd);
1.671 + }
1.672 +
1.673 +/**
1.674 +Clears the current playback window.
1.675 +
1.676 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.677 + another of the system-wide error codes.
1.678 +
1.679 +@since 7.0s
1.680 +*/
1.681 +EXPORT_C TInt CMdaAudioPlayerUtility::ClearPlayWindow()
1.682 + {
1.683 + ASSERT(iProperties);
1.684 + return iProperties->ClearPlayWindow();
1.685 + }
1.686 +
1.687 +/**
1.688 +Sets the current playback balance.
1.689 +
1.690 +@param aBalance
1.691 + A value between KMMFBalanceMaxLeft
1.692 + and KMMFBalanceMaxRight. The default value is
1.693 + KMMFBalanceCenter.
1.694 +
1.695 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.696 + another of the system-wide error codes.
1.697 +
1.698 +@since 7.0s
1.699 +*/
1.700 +EXPORT_C TInt CMdaAudioPlayerUtility::SetBalance(TInt aBalance /*= KMMFBalanceCenter*/)
1.701 + {
1.702 + ASSERT(iProperties);
1.703 + return iProperties->SetBalance(aBalance);
1.704 + }
1.705 +
1.706 +/**
1.707 + * Returns The current playback balance. This function may not return the same value
1.708 + * as passed to SetBalance depending on the internal implementation in
1.709 + * the underlying components.
1.710 + *
1.711 + * @param aBalance
1.712 + * A value between KMMFBalanceMaxLeft
1.713 + * and KMMFBalanceMaxRight.
1.714 + *
1.715 + * @return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.716 + * another of the system-wide error codes.
1.717 + *
1.718 + * @since 7.0s
1.719 + */
1.720 +EXPORT_C TInt CMdaAudioPlayerUtility::GetBalance(TInt& aBalance)
1.721 + {
1.722 + ASSERT(iProperties);
1.723 + return iProperties->GetBalance(aBalance);
1.724 + }
1.725 +
1.726 +/**
1.727 +Returns the controller implementation information associated with the current controller.
1.728 +
1.729 +@return The controller implementation structure
1.730 +
1.731 +@since 7.0s
1.732 +*/
1.733 +EXPORT_C const CMMFControllerImplementationInformation& CMdaAudioPlayerUtility::ControllerImplementationInformationL()
1.734 + {
1.735 + ASSERT(iProperties);
1.736 + return iProperties->ControllerImplementationInformationL();
1.737 + }
1.738 +
1.739 +/**
1.740 +Registers callback object to receive notifications of audio loading/rebuffering.
1.741 +
1.742 +@param aCallback
1.743 + The object to receive audio loading notifications.
1.744 +
1.745 +@since 7.0s
1.746 +*/
1.747 +EXPORT_C void CMdaAudioPlayerUtility::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aCallback)
1.748 + {
1.749 + ASSERT(iProperties);
1.750 + iProperties->RegisterForAudioLoadingNotification(aCallback);
1.751 + }
1.752 +
1.753 +/**
1.754 +Returns the current progress of audio loading.
1.755 +
1.756 +@param aPercentageProgress
1.757 + The percentage of the audio clip loaded.
1.758 +
1.759 +@since 7.0s
1.760 +*/
1.761 +EXPORT_C void CMdaAudioPlayerUtility::GetAudioLoadingProgressL(TInt& aPercentageProgress)
1.762 + {
1.763 + ASSERT(iProperties);
1.764 + iProperties->GetAudioLoadingProgressL(aPercentageProgress);
1.765 + }
1.766 +
1.767 +/**
1.768 +Sends a synchronous custom command to the controller.
1.769 +
1.770 +@param aDestination
1.771 + The destination of the message, consisting of the UID of
1.772 + the interface of this message.
1.773 +@param aFunction
1.774 + The function number to indicate which function is to be called
1.775 + on the interface defined in the aDestination parameter.
1.776 +@param aDataTo1
1.777 + A reference to the first chunk of data to be copied to the controller
1.778 + framework. The exact contents of the data are dependent on the
1.779 + interface being called. Can be KNullDesC8.
1.780 +@param aDataTo2
1.781 + A reference to the second chunk of data to be copied to the controller
1.782 + framework. The exact contents of the data are dependent on the
1.783 + interface being called. Can be KNullDesC8.
1.784 +@param aDataFrom
1.785 + A reference to an area of memory to which the controller framework will
1.786 + write any data to be passed back to the client. Can't be KNullDesC8.
1.787 +
1.788 +@return The result of the request. Exact range of values is dependent on the interface.
1.789 +
1.790 +@since 7.0s
1.791 +*/
1.792 +EXPORT_C TInt CMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
1.793 + {
1.794 + ASSERT(iProperties);
1.795 + return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
1.796 + }
1.797 +
1.798 +/**
1.799 +Sends a synchronous custom command to the controller.
1.800 +
1.801 +@param aDestination
1.802 + The destination of the message, consisting of the UID of
1.803 + the interface of this message.
1.804 +@param aFunction
1.805 + The function number to indicate which function is to be called
1.806 + on the interface defined in the aDestination parameter.
1.807 +@param aDataTo1
1.808 + A reference to the first chunk of data to be copied to the controller
1.809 + framework. The exact contents of the data are dependent on the
1.810 + interface being called. Can be KNullDesC8.
1.811 +@param aDataTo2
1.812 + A reference to the second chunk of data to be copied to the controller
1.813 + framework. The exact contents of the data are dependent on the
1.814 + interface being called. Can be KNullDesC8.
1.815 +
1.816 +@return The result of the request. Exact range of values is dependent on the interface.
1.817 +
1.818 +@since 7.0s
1.819 +*/
1.820 +EXPORT_C TInt CMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
1.821 + {
1.822 + ASSERT(iProperties);
1.823 + return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
1.824 + }
1.825 +
1.826 +/**
1.827 +Sends an asynchronous custom command to the controller.
1.828 +
1.829 +Note:
1.830 +This method will return immediately. The RunL of the active object owning the
1.831 +aStatus parameter will be called when the command is completed by the
1.832 +controller framework.
1.833 +
1.834 +@param aDestination
1.835 + The destination of the message, consisting of the uid of
1.836 + the interface of this message.
1.837 +@param aFunction
1.838 + The function number to indicate which function is to be called
1.839 + on the interface defined in the aDestination parameter.
1.840 +@param aDataTo1
1.841 + A reference to the first chunk of data to be copied to the controller
1.842 + framework. The exact contents of the data are dependent on the
1.843 + interface being called. Can be KNullDesC8.
1.844 +@param aDataTo2
1.845 + A reference to the second chunk of data to be copied to the controller
1.846 + framework. The exact contents of the data are dependent on the
1.847 + interface being called. Can be KNullDesC8.
1.848 +@param aDataFrom
1.849 + A reference to an area of memory to which the controller framework will
1.850 + write any data to be passed back to the client. Can't be KNullDesC8."
1.851 +@param aStatus
1.852 + The TRequestStatus of an active object. This will contain the
1.853 + result of the request on completion. The exact range of
1.854 + result values is dependent on the interface.
1.855 +
1.856 +@since 7.0s
1.857 +*/
1.858 +EXPORT_C void CMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
1.859 + {
1.860 + ASSERT(iProperties);
1.861 + iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
1.862 + }
1.863 +
1.864 +/**
1.865 +Sends an asynchronous custom command to the controller.
1.866 +
1.867 +Note:
1.868 +This method will return immediately. The RunL of the active object owning the
1.869 +aStatus parameter will be called when the command is completed by the
1.870 +controller framework.
1.871 +
1.872 +@param aDestination
1.873 + The destination of the message, consisting of the uid of
1.874 + the interface of this message.
1.875 +@param aFunction
1.876 + The function number to indicate which function is to be called
1.877 + on the interface defined in the aDestination parameter.
1.878 +@param aDataTo1
1.879 + A reference to the first chunk of data to be copied to the controller
1.880 + framework. The exact contents of the data are dependent on the
1.881 + interface being called. Can be KNullDesC8.
1.882 +@param aDataTo2
1.883 + A reference to the second chunk of data to be copied to the controller
1.884 + framework. The exact contents of the data are dependent on the
1.885 + interface being called. Can be KNullDesC8.
1.886 +@param aStatus
1.887 + The TRequestStatus of an active object. This will contain the
1.888 + result of the request on completion. The exact range of
1.889 + result values is dependent on the interface.
1.890 +
1.891 +@since 7.0s
1.892 +*/
1.893 +EXPORT_C void CMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
1.894 + {
1.895 + ASSERT(iProperties);
1.896 + iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
1.897 + }
1.898 +
1.899 +/**
1.900 +Returns the bit rate of the audio clip.
1.901 +
1.902 +@param aBitRate
1.903 + The bit rate of the audio clip
1.904 +
1.905 +@return An error code indicating if the function call was successful. KErrNone on success,
1.906 + otherwise another of the system-wide error codes.
1.907 +
1.908 +@since 7.0s
1.909 +*/
1.910 +EXPORT_C TInt CMdaAudioPlayerUtility::GetBitRate(TUint& aBitRate)
1.911 + {
1.912 + ASSERT(iProperties);
1.913 + return iProperties->GetBitRate(aBitRate);
1.914 + }
1.915 +
1.916 +/**
1.917 +Gets a controller's DRM custom command implementation.
1.918 +
1.919 +@return A pointer to a controller's DRM custom command implementation, or NULL if the
1.920 +controller does not support it.
1.921 +*/
1.922 +EXPORT_C MMMFDRMCustomCommand* CMdaAudioPlayerUtility::GetDRMCustomCommand()
1.923 + {
1.924 + ASSERT(iProperties);
1.925 + return iProperties->GetDRMCustomCommand();
1.926 + }
1.927 +
1.928 +/**
1.929 +Registers the Event for Notification when resource is avaliable.
1.930 +
1.931 +@param aCallback
1.932 + The audio outputstream observer interface..
1.933 +
1.934 +@param aNotificationEventUid
1.935 + The Event for which the client is registered.
1.936 +
1.937 +@param aNotificationRegistrationData
1.938 + Notification registration specific data.
1.939 +
1.940 +@return An error code indicating if the registration was successful. KErrNone on success,
1.941 + otherwise another of the system-wide error codes.
1.942 +*/
1.943 +EXPORT_C TInt CMdaAudioPlayerUtility::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,TUid aNotificationEventUid,const TDesC8& aNotificationRegistrationData)
1.944 + {
1.945 + ASSERT(iProperties);
1.946 + return iProperties->RegisterAudioResourceNotification(aCallback,aNotificationEventUid,aNotificationRegistrationData);
1.947 + }
1.948 +
1.949 +/**
1.950 +Cancels the registered notification event.
1.951 +
1.952 +@param aNotificationEventUid
1.953 + The Event to notify the client.
1.954 +
1.955 +@return An error code indicating if the registration was successful. KErrNone on success,
1.956 + otherwise another of the system-wide error codes.
1.957 +*/
1.958 +EXPORT_C TInt CMdaAudioPlayerUtility::CancelRegisterAudioResourceNotification(TUid aNotificationEventUid)
1.959 + {
1.960 + ASSERT(iProperties);
1.961 + return iProperties->CancelRegisterAudioResourceNotification(aNotificationEventUid);
1.962 + }
1.963 +
1.964 +/**
1.965 +Waits for the client to resume the play even after the default timer expires.
1.966 +
1.967 +@return An error code indicating if the registration was successful. KErrNone on success,
1.968 + otherwise another of the system-wide error codes.
1.969 +*/
1.970 +EXPORT_C TInt CMdaAudioPlayerUtility::WillResumePlay()
1.971 + {
1.972 + ASSERT(iProperties);
1.973 + return iProperties->WillResumePlay();
1.974 + }
1.975 +
1.976 +
1.977 +/**
1.978 +Set the priority of the controller's sub thread.
1.979 +
1.980 +This can be used to increase the responsiveness of the audio plugin to minimise
1.981 +any lag in processing. This function should be used with care as it may have knock-on
1.982 +effects elsewhere in the system.
1.983 +
1.984 +@param aPriority
1.985 + The TThreadPriority that the thread should run under. The default is EPriorityNormal.
1.986 +@return TInt
1.987 + A standard error code: KErrNone if successful, KErrNotReady if the thread does not have a
1.988 + valid handle.
1.989 +*/
1.990 +EXPORT_C TInt CMdaAudioPlayerUtility::SetThreadPriority(const TThreadPriority& aPriority) const
1.991 + {
1.992 + ASSERT(iProperties);
1.993 + return iProperties->SetThreadPriority(aPriority);
1.994 + }
1.995 +
1.996 +
1.997 +
1.998 +
1.999 +CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewL(MMdaAudioPlayerCallback& aCallback,
1.1000 + TInt aPriority,
1.1001 + TInt aPref)
1.1002 + {
1.1003 + CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
1.1004 + CleanupStack::PushL(self);
1.1005 + self->ConstructL();
1.1006 + CleanupStack::Pop(self);
1.1007 + return self;
1.1008 + }
1.1009 +
1.1010 +CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewFilePlayerL(const TDesC& aFileName,
1.1011 + MMdaAudioPlayerCallback& aCallback,
1.1012 + TInt aPriority,
1.1013 + TInt aPref,
1.1014 + CMdaServer* /*aServer*/)
1.1015 + {
1.1016 + CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
1.1017 + CleanupStack::PushL(self);
1.1018 + self->ConstructL();
1.1019 + TMMFileSource filesource(aFileName, KDefaultContentObject, EPlay);
1.1020 + self->OpenFileL(filesource);
1.1021 + CleanupStack::Pop(self);
1.1022 + return self;
1.1023 + }
1.1024 +
1.1025 +CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewDesPlayerL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
1.1026 + {
1.1027 + CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
1.1028 + CleanupStack::PushL(self);
1.1029 + self->ConstructL();
1.1030 + self->OpenDesL(aData);
1.1031 + CleanupStack::Pop(self);
1.1032 + return self;
1.1033 + }
1.1034 +
1.1035 +CMMFMdaAudioPlayerUtility* CMMFMdaAudioPlayerUtility::NewDesPlayerReadOnlyL(const TDesC8& aData, MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref, CMdaServer* /*aServer*/)
1.1036 + {
1.1037 + CMMFMdaAudioPlayerUtility* self = new(ELeave) CMMFMdaAudioPlayerUtility(aCallback, aPriority, aPref);
1.1038 + CleanupStack::PushL(self);
1.1039 + self->ConstructL();
1.1040 + self->OpenDesL(aData);
1.1041 + CleanupStack::Pop(self);
1.1042 + return self;
1.1043 + }
1.1044 +
1.1045 +void CMMFMdaAudioPlayerUtility::UseSharedHeap()
1.1046 + {
1.1047 + iFindAndOpenController->UseSharedHeap();
1.1048 + }
1.1049 +
1.1050 +// CMMFMdaAudioPlayerUtility
1.1051 +CMMFMdaAudioPlayerUtility::~CMMFMdaAudioPlayerUtility()
1.1052 + {
1.1053 +
1.1054 + delete iControllerImplementationInformation;
1.1055 + delete iAsyncCallBack;
1.1056 + delete iRepeatTrailingSilenceTimer;
1.1057 + delete iFindAndOpenController;
1.1058 + delete iControllerEventMonitor;
1.1059 + iMediaIds.Close();
1.1060 + iController.Close();
1.1061 + }
1.1062 +
1.1063 +CMMFMdaAudioPlayerUtility::CMMFMdaAudioPlayerUtility(MMdaAudioPlayerCallback& aCallback, TInt aPriority, TInt aPref) :
1.1064 + iCallback(aCallback),
1.1065 + iAudioPlayDeviceCommands(iController),
1.1066 + iAudioPlayControllerCommands(iController),
1.1067 + iNotificationRegistrationCommands(iController),
1.1068 + iDRMCustomCommands(iController),
1.1069 + iAudioPlayControllerSetRepeatsCommands(iController)
1.1070 + {
1.1071 + iState = EStopped;
1.1072 + iPrioritySettings.iPriority = aPriority;
1.1073 + iPrioritySettings.iPref = aPref;
1.1074 + iPlayStart = TTimeIntervalMicroSeconds(0);
1.1075 + iPlayEnd = TTimeIntervalMicroSeconds(0);
1.1076 + iPlayWindowSet = ENone;
1.1077 + iEventHolder = KNullUid;
1.1078 + }
1.1079 +
1.1080 +void CMMFMdaAudioPlayerUtility::ConstructL()
1.1081 + {
1.1082 + iControllerEventMonitor = CMMFControllerEventMonitor::NewL(*this, iController);
1.1083 + iRepeatTrailingSilenceTimer = CRepeatTrailingSilenceTimer::NewL(*this);
1.1084 + iAsyncCallBack = CMMFMdaAudioPlayerCallBack::NewL(iCallback);
1.1085 + User::LeaveIfError(iMediaIds.Append(KUidMediaTypeAudio));
1.1086 + iFindAndOpenController = CMMFFindAndOpenController::NewL(*this);
1.1087 + iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings);
1.1088 + iFindAndOpenController->ConfigureController(iController, *iControllerEventMonitor, CMMFFindAndOpenController::EPlayback);
1.1089 + }
1.1090 +
1.1091 +void CMMFMdaAudioPlayerUtility::MfaocComplete(
1.1092 + TInt& aError,
1.1093 + RMMFController* /*aController*/,
1.1094 + TUid aControllerUid,
1.1095 + TMMFMessageDestination* /*aSourceHandle*/,
1.1096 + TMMFMessageDestination* /*aSinkHandle*/)
1.1097 + {
1.1098 + if (aError == KErrNone)
1.1099 + {
1.1100 + iControllerUid = aControllerUid;
1.1101 +
1.1102 + // Get the clip duration
1.1103 + iDuration = TTimeIntervalMicroSeconds(0);
1.1104 + aError = iController.GetDuration(iDuration);
1.1105 +
1.1106 + // If an error occurred during GetDuration, may try for next controller, if present.
1.1107 + if (aError != KErrNone)
1.1108 + {
1.1109 + iControllerEventMonitor->Cancel();
1.1110 +
1.1111 + if (iFindAndOpenController)
1.1112 + {
1.1113 + if(iFindAndOpenController-> ControllerIndex() < (iFindAndOpenController->ControllerCount())-1)
1.1114 + {
1.1115 + return; //actually tries to load next controllers, if there are other controllers selected in the controller list
1.1116 + }
1.1117 + }
1.1118 +
1.1119 + iController.Close(); // otherwise close the controller
1.1120 + }
1.1121 +
1.1122 + if (iFindAndOpenController)
1.1123 + {
1.1124 + iFindAndOpenController->Close();
1.1125 + }
1.1126 + }
1.1127 +
1.1128 + iAsyncCallBack->InitComplete(aError, iDuration);
1.1129 + }
1.1130 +
1.1131 +/**
1.1132 + Open an audio clip from a file
1.1133 + @param "const TFileSource& aFileSource" "the file to open"
1.1134 + @leave "" "Leaves on an error opening the file
1.1135 + @since version 5.0
1.1136 +*/
1.1137 +void CMMFMdaAudioPlayerUtility::OpenFileL(const TDesC& aFileName)
1.1138 + {
1.1139 + TMMFileSource filesource(aFileName, KDefaultContentObject, EPlay);
1.1140 + OpenFileL(filesource);
1.1141 + }
1.1142 +
1.1143 +/**
1.1144 + Open an audio clip from a file
1.1145 + @param "const RFile& aFile" "the shared session file handle to open"
1.1146 + @leave "" "KErrBadHandle if the file handle is not shared through the call RFs::ShareProtected(), and the underlying CAF layer needs it to be.
1.1147 + @leave "" "Leaves on an error opening the file
1.1148 + @since version 5.0
1.1149 +*/
1.1150 +void CMMFMdaAudioPlayerUtility::OpenFileL(const RFile& aFile)
1.1151 + {
1.1152 + RFile& file = const_cast<RFile&>(aFile);
1.1153 + TMMFileHandleSource filesource(file, KDefaultContentObject, EPlay);
1.1154 + OpenFileL(filesource);
1.1155 + }
1.1156 +
1.1157 +void CMMFMdaAudioPlayerUtility::OpenFileL(const TMMSource& aSource)
1.1158 + {
1.1159 + // If iAsyncCallBack is already active, we're still in the process of notifying the client
1.1160 + // that a previous request to Open...(...) has completed.
1.1161 + if (iAsyncCallBack->IsActive())
1.1162 + User::Leave(KErrNotReady);
1.1163 +
1.1164 + if (aSource.SourceType()==KUidMMFileHandleSource)
1.1165 + {
1.1166 + RFile& fileHandle = static_cast<const TMMFileHandleSource&>(aSource).Handle();
1.1167 + iFindAndOpenController->ConfigureSourceSink(
1.1168 + TMMFileHandleSource(fileHandle, aSource.UniqueId(), aSource.Intent(), aSource.IsUIEnabled()),
1.1169 + CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
1.1170 +
1.1171 + }
1.1172 + if (aSource.SourceType()==KUidMMFileSource)
1.1173 + {
1.1174 + const TDesC& fileName = static_cast<const TMMFileSource&>(aSource).Name();
1.1175 + iFindAndOpenController->ConfigureSourceSink(
1.1176 + TMMFileSource(fileName, aSource.UniqueId(), aSource.Intent(), aSource.IsUIEnabled()),
1.1177 + CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
1.1178 + }
1.1179 +
1.1180 + iFindAndOpenController->OpenByFileSource(aSource);
1.1181 + }
1.1182 +
1.1183 +/**
1.1184 + Open an audio clip from a descriptor
1.1185 + @param "const TDesC8& aDescriptor" "the descriptor containing the clip"
1.1186 + @leave "" "Leaves on an error opening the descriptor"
1.1187 + @since version 5.0
1.1188 +*/
1.1189 +void CMMFMdaAudioPlayerUtility::OpenDesL(const TDesC8& aDescriptor)
1.1190 + {
1.1191 + // If iAsyncCallBack is already active, we're still in the process of notifying the client
1.1192 + // that a previous request to Open...(...) has completed.
1.1193 + if (iAsyncCallBack->IsActive())
1.1194 + User::Leave(KErrInUse);
1.1195 +
1.1196 + iFindAndOpenController->ConfigureSourceSink(
1.1197 + CMMFFindAndOpenController::TSourceSink(KUidMmfDescriptorSource,
1.1198 + CMMFFindAndOpenController::GetConfigDescriptor(aDescriptor)),
1.1199 + CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
1.1200 + iFindAndOpenController->OpenByDescriptor(aDescriptor);
1.1201 + }
1.1202 +
1.1203 +/**
1.1204 + Open an audio clip from a Url
1.1205 + @param "const TDesC& aUrl" "the url reference to the clip"
1.1206 + @leave "" "Leaves on an error opening the url"
1.1207 + @since version 7.0s
1.1208 +*/
1.1209 +void CMMFMdaAudioPlayerUtility::OpenUrlL(const TDesC& aUrl, const TInt aIapId, const TDesC8& aMimeType)
1.1210 + {
1.1211 + // If iAsyncCallBack is already active, we're still in the process of notifying the client
1.1212 + // that a previous request to Open...(...) has completed.
1.1213 + if (iAsyncCallBack->IsActive())
1.1214 + User::Leave(KErrInUse);
1.1215 +
1.1216 + CBufFlat* urlCfgBuffer = NULL;
1.1217 + CMMFFindAndOpenController::GetConfigUrlL(urlCfgBuffer, aUrl, aIapId);
1.1218 +
1.1219 + iFindAndOpenController->ConfigureSourceSink(
1.1220 + CMMFFindAndOpenController::TSourceSink(KUidMmfUrlSource, urlCfgBuffer->Ptr(0)),
1.1221 + CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
1.1222 + iFindAndOpenController->OpenByUrl(aUrl, aIapId, aMimeType);
1.1223 + delete urlCfgBuffer;
1.1224 + }
1.1225 +
1.1226 +/**
1.1227 +Begins playback of the initialised audio sample at the current volume
1.1228 +and priority levels.
1.1229 +
1.1230 +When playing of the audio sample is complete, successfully or
1.1231 +otherwise, the callback function
1.1232 +MMdaAudioPlayerCallback::MapcPlayComplete() is
1.1233 +called.
1.1234 +
1.1235 +If this function is called whilst already playing then
1.1236 +MMdaAudioPlayerCallback::MapcPlayComplete will return with the
1.1237 +error code KErrNotReady.
1.1238 +
1.1239 +@since 5.0
1.1240 +*/
1.1241 +void CMMFMdaAudioPlayerUtility::Play()
1.1242 + {
1.1243 + // if we're already playing, call the client's callback with KErrNotReady.
1.1244 + // This is what the controller would do if we allowed the Play()
1.1245 + // to propagate down. Need to do it here too (for consistency)
1.1246 + // in case we're in a trailing silence period.
1.1247 + if (iState == EPlaying)
1.1248 + {
1.1249 + iAsyncCallBack->PlayComplete(KErrNotReady);
1.1250 + return;
1.1251 + }
1.1252 +
1.1253 + // cancel the repeat timer in case the client has called Play()
1.1254 + // without waiting for the previous play to complete
1.1255 + iRepeatTrailingSilenceTimer->Cancel();
1.1256 + // Reset played count
1.1257 + if(iState != EPaused)
1.1258 + {
1.1259 + iNumberOfTimesPlayed = 0;
1.1260 + if(iNumberOfTimesToRepeat>0 || iNumberOfTimesToRepeat == KMdaRepeatForever)
1.1261 + {
1.1262 + TInt err = iAudioPlayControllerSetRepeatsCommands.SetRepeats(iNumberOfTimesToRepeat, iTrailingSilence);
1.1263 + if(err==KErrNone)
1.1264 + {
1.1265 + iNumberOfTimesToRepeat = 0;
1.1266 + iTrailingSilence = 0;
1.1267 + }
1.1268 + //Controller not supporting setrepeats custom command is not a real error
1.1269 + //we revert back to playerutility's loop play implementation in that case
1.1270 + }
1.1271 + }
1.1272 +
1.1273 + DoPlay();
1.1274 + }
1.1275 +
1.1276 +void CMMFMdaAudioPlayerUtility::DoPlay()
1.1277 + {
1.1278 +#if defined(__AUDIO_PROFILING)
1.1279 + RDebug::ProfileStart(4);
1.1280 +#endif // defined(__AUDIO_PROFILING)
1.1281 + TInt err = KErrNone;
1.1282 + if (iState != EPaused || iRepeatCancelled)
1.1283 + {
1.1284 + err = iController.Prime();
1.1285 + iRepeatCancelled = EFalse;
1.1286 +
1.1287 +#if defined(__AUDIO_PROFILING)
1.1288 + RDebug::ProfileEnd(4);
1.1289 +#endif // defined(__AUDIO_PROFILING)
1.1290 +
1.1291 + // make sure we don't set the position outside the play window -
1.1292 + // but allow it to remain unchanged if it's within the window
1.1293 + if (iPlayWindowSet == ESet &&
1.1294 + (iPosition < iPlayStart || iPosition >= iPlayEnd))
1.1295 + iPosition = iPlayStart;
1.1296 +
1.1297 + if (err==KErrNone)
1.1298 + err = iController.SetPosition(iPosition);
1.1299 + }
1.1300 +
1.1301 + if (err==KErrNone)
1.1302 + {
1.1303 + if (iPlayWindowSet == ESet)
1.1304 + err = iAudioPlayControllerCommands.SetPlaybackWindow(iPlayStart, iPlayEnd);
1.1305 + else if (iPlayWindowSet == EClear)
1.1306 + {
1.1307 + err = iAudioPlayControllerCommands.DeletePlaybackWindow();
1.1308 + iPlayWindowSet = ENone; // assume window will stay cleared
1.1309 + }
1.1310 + }
1.1311 +
1.1312 + if (err==KErrNone)
1.1313 + {
1.1314 +#if defined(__AUDIO_PROFILING)
1.1315 + RDebug::ProfileStart(5);
1.1316 +#endif // defined(__AUDIO_PROFILING)
1.1317 +
1.1318 + err = iController.Play();
1.1319 +
1.1320 +#if defined(__AUDIO_PROFILING)
1.1321 + RDebug::ProfileEnd(5);
1.1322 +#endif // defined(__AUDIO_PROFILING)
1.1323 + }
1.1324 +
1.1325 + if (err!=KErrNone)
1.1326 + iAsyncCallBack->PlayComplete(err);
1.1327 + else
1.1328 + iState = EPlaying;
1.1329 +
1.1330 + if(iEventHolder != KNullUid)
1.1331 + {
1.1332 + err = iNotificationRegistrationCommands.RegisterAsClient(iEventHolder,iNotificationDataHolder);
1.1333 + iEventHolder = KNullUid;
1.1334 + iNotificationDataHolder = KNullDesC8;
1.1335 + if(err == KErrNotSupported)
1.1336 + {
1.1337 + return;
1.1338 + }
1.1339 + if(err != KErrNone)
1.1340 + {
1.1341 + iController.Stop();
1.1342 + iAsyncCallBack->PlayComplete(err);
1.1343 + }
1.1344 + }
1.1345 + }
1.1346 +
1.1347 +/**
1.1348 +Stops playback of the audio sample as soon as possible.
1.1349 +
1.1350 +If the audio sample is playing, playback is stopped as soon as
1.1351 +possible. If playback is already complete, nothing further happens as
1.1352 +a result of calling this function. The callback function
1.1353 +MMdaAudioPlayerCallback::MapcPlayComplete() is not
1.1354 +called.
1.1355 +
1.1356 +@since 5.0
1.1357 +*/
1.1358 +void CMMFMdaAudioPlayerUtility::Stop()
1.1359 + {
1.1360 +
1.1361 + if (iState==EStopped)
1.1362 + {
1.1363 + // resetting the position to the start.
1.1364 + //if any position change in stoped state
1.1365 + iPosition = iPlayStart;
1.1366 + return;
1.1367 + }
1.1368 +
1.1369 + if (iState==EPlaying || iState==EPaused)
1.1370 + {
1.1371 + // cancel the repeat timer in case the client has called Stop()
1.1372 + // during the trailing silence period
1.1373 + iRepeatTrailingSilenceTimer->Cancel();
1.1374 +
1.1375 + iController.Stop();
1.1376 + iPosition = iPlayStart;
1.1377 + iState = EStopped;
1.1378 + }
1.1379 +
1.1380 + }
1.1381 +
1.1382 +/**
1.1383 + *
1.1384 + * Pauses playback of the audio clip
1.1385 + * @return One of the system-wide error codes
1.1386 + * @since 7.0s
1.1387 + */
1.1388 +TInt CMMFMdaAudioPlayerUtility::Pause()
1.1389 + {
1.1390 + TInt err = KErrNone;
1.1391 + if(iRepeatTrailingSilenceTimer->IsActive())
1.1392 + {
1.1393 + iRepeatTrailingSilenceTimer->Cancel();
1.1394 + iRepeatCancelled = ETrue;
1.1395 + iState = EPaused;
1.1396 + return KErrNone;
1.1397 + }
1.1398 + if (iState==EPlaying)
1.1399 + {
1.1400 + err = iController.Pause();
1.1401 + if (!err || err==KErrNotReady)
1.1402 + err = iController.GetPosition(iPosition);
1.1403 + iState = EPaused;
1.1404 + }
1.1405 + return err;
1.1406 + }
1.1407 +
1.1408 +/**
1.1409 + *
1.1410 + * Closes the current audio clip (allowing another clip to be opened)
1.1411 + *
1.1412 + * @since 7.0s
1.1413 + */
1.1414 +void CMMFMdaAudioPlayerUtility::Close()
1.1415 + {
1.1416 + // Reset the audio player state.
1.1417 + Stop();
1.1418 + iControllerEventMonitor->Cancel();
1.1419 + iController.Close();
1.1420 + if (iFindAndOpenController)
1.1421 + iFindAndOpenController->Close();
1.1422 + if(iControllerImplementationInformation)
1.1423 + {
1.1424 + delete iControllerImplementationInformation;
1.1425 + iControllerImplementationInformation = NULL;
1.1426 + }
1.1427 + iControllerUid = KNullUid;
1.1428 + }
1.1429 +
1.1430 +
1.1431 +/**
1.1432 +Changes the current playback volume to a specified value.
1.1433 +
1.1434 +The volume can be changed before or during playback and is effective
1.1435 +immediately.
1.1436 +
1.1437 +@param aVolume
1.1438 + The volume setting. This can be any value from zero to
1.1439 + the value returned by a call to
1.1440 + CMdaAudioPlayerUtility::MaxVolume().
1.1441 + Setting a zero value mutes the sound. Setting the
1.1442 + maximum value results in the loudest possible sound.
1.1443 +@return An error code indicating if the function call was successful. KErrNone on success,
1.1444 + otherwise another of the system-wide error codes.
1.1445 +@panic EMMFMediaClientBadArgument is raised when the audio player utility is not initialised.
1.1446 +
1.1447 +@since 5.0
1.1448 +*/
1.1449 +TInt CMMFMdaAudioPlayerUtility::SetVolume(TInt aVolume)
1.1450 + {
1.1451 + TInt err = iAudioPlayDeviceCommands.SetVolume(aVolume);
1.1452 + if (err == KErrArgument)
1.1453 + {
1.1454 + TInt maxVolume = MaxVolume();
1.1455 + if (aVolume < 0)
1.1456 + {
1.1457 + aVolume = 0;
1.1458 + }
1.1459 + else if (aVolume > maxVolume)
1.1460 + {
1.1461 + aVolume = maxVolume;
1.1462 + }
1.1463 + err = iAudioPlayDeviceCommands.SetVolume(aVolume);
1.1464 + }
1.1465 +
1.1466 + return err;
1.1467 + }
1.1468 +
1.1469 +/**
1.1470 +Sets the number of times the audio sample is to be repeated during the
1.1471 +playback operation.
1.1472 +
1.1473 +A period of silence can follow each playing of the sample. The audio
1.1474 +sample can be repeated indefinitely.
1.1475 +
1.1476 +@param aRepeatNumberOfTimes
1.1477 + The number of times the audio sample, together with
1.1478 + the trailing silence, is to be repeated. If this is
1.1479 + set to KMdaRepeatForever, then the audio
1.1480 + sample, together with the trailing silence, is
1.1481 + repeated indefinitely or until Stop() is
1.1482 + called. If this is set to zero, then the audio sample
1.1483 + is not repeated. The behaviour is undefined for
1.1484 + negative values (other than KMdaRepeatForever).
1.1485 +@param aTrailingSilence
1.1486 + The time interval of the training silence.
1.1487 + Negative values will produce a panic USER 87.
1.1488 +@since 5.0
1.1489 +*/
1.1490 +void CMMFMdaAudioPlayerUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
1.1491 + {
1.1492 + TInt err = iAudioPlayControllerSetRepeatsCommands.SetRepeats(aRepeatNumberOfTimes, aTrailingSilence);
1.1493 +
1.1494 + if(err!=KErrNone)
1.1495 + {
1.1496 + iNumberOfTimesToRepeat = aRepeatNumberOfTimes;
1.1497 + iTrailingSilence = aTrailingSilence;
1.1498 + }
1.1499 + }
1.1500 +
1.1501 +/**
1.1502 +Defines the period over which the volume level is to rise smoothly
1.1503 +from nothing to the normal volume level.
1.1504 +
1.1505 +@param aRampDuration
1.1506 + The period over which the volume is to rise. A zero
1.1507 + value causes the audio sample to be played at the
1.1508 + normal level for the full duration of the playback. A
1.1509 + value which is longer than the duration of the audio
1.1510 + sample means that the sample never reaches its normal
1.1511 + volume level.
1.1512 +
1.1513 +@since 5.0
1.1514 +*/
1.1515 +void CMMFMdaAudioPlayerUtility::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
1.1516 + {
1.1517 + iAudioPlayDeviceCommands.SetVolumeRamp(aRampDuration);
1.1518 + }
1.1519 +
1.1520 +TInt CMMFMdaAudioPlayerUtility::SetPriority(TInt aPriority, TInt aPref)
1.1521 + {
1.1522 + iPrioritySettings.iPref = aPref;
1.1523 + iPrioritySettings.iPriority = aPriority;
1.1524 + iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings);
1.1525 +
1.1526 + return iController.SetPrioritySettings(iPrioritySettings);
1.1527 + }
1.1528 +
1.1529 +/**
1.1530 +Returns the duration of the audio sample.
1.1531 +
1.1532 +@return The duration in microseconds.
1.1533 +
1.1534 +@since 5.0
1.1535 +*/
1.1536 +const TTimeIntervalMicroSeconds& CMMFMdaAudioPlayerUtility::Duration()
1.1537 + {
1.1538 + TInt err = iController.GetDuration(iDuration);
1.1539 + if (err)
1.1540 + {
1.1541 + iDuration = 0;
1.1542 + }
1.1543 + return iDuration;
1.1544 + }
1.1545 +
1.1546 +/**
1.1547 +Returns the duration of the audio sample in microseconds, and the duration state.
1.1548 +
1.1549 +@param aDuration
1.1550 + The duration of the sample in microseconds.
1.1551 +@return The duration state
1.1552 +
1.1553 +@since 9.1
1.1554 +*/
1.1555 +TMMFDurationInfo CMMFMdaAudioPlayerUtility::Duration(TTimeIntervalMicroSeconds& aDuration)
1.1556 +{
1.1557 + TPckgBuf<TMMFDurationInfo> pckg;
1.1558 + TMMFDurationInfo result = EMMFDurationInfoValid;
1.1559 +
1.1560 + TMMFMessageDestinationPckg iDestinationPckg(TMMFMessageDestination(KUidInterfaceMMFDurationInfoControl, KMMFObjectHandleController));
1.1561 +
1.1562 + TInt err = iController.CustomCommandSync(iDestinationPckg,
1.1563 + EMMFGetDurationInfo,
1.1564 + KNullDesC8,
1.1565 + KNullDesC8,
1.1566 + pckg );
1.1567 +
1.1568 + switch ( err )
1.1569 + {
1.1570 + case KErrNone:
1.1571 + result = pckg();
1.1572 + break;
1.1573 +
1.1574 + case KErrNotSupported:
1.1575 + // Custom command not implemented return EMMFDurationInfoValid as the default value
1.1576 + break;
1.1577 +
1.1578 + default:
1.1579 + // Unknown error
1.1580 + result = EMMFDurationInfoUnknown;
1.1581 + break;
1.1582 + }
1.1583 +
1.1584 + // Get the duration information to return in aDuration
1.1585 + // This is the intended behaviour regardless of what value err has
1.1586 + aDuration = Duration();
1.1587 + return result;
1.1588 +}
1.1589 +
1.1590 +/**
1.1591 +Returns an integer representing the maximum volume.
1.1592 +
1.1593 +This is the maximum value which can be passed to
1.1594 +CMdaAudioPlayerUtility::SetVolume().
1.1595 +
1.1596 +@return The maximum volume. This value is platform dependent but is always greater than or equal
1.1597 + to one.
1.1598 +@panic EMMFMediaClientPanicServerCommunicationProblem is raised when the audio player utility is not initialised.
1.1599 +
1.1600 +@since 5.0
1.1601 +*/
1.1602 +TInt CMMFMdaAudioPlayerUtility::MaxVolume()
1.1603 + {
1.1604 + TInt maxVolume = 0;
1.1605 +#ifdef _DEBUG
1.1606 + TInt error =
1.1607 +#endif
1.1608 + iAudioPlayDeviceCommands.GetMaxVolume(maxVolume);
1.1609 + __ASSERT_DEBUG(error==KErrNone, Panic(EMMFMediaClientPanicServerCommunicationProblem));
1.1610 + return maxVolume;
1.1611 + }
1.1612 +
1.1613 +void CMMFMdaAudioPlayerUtility::HandleEvent(const TMMFEvent& aEvent)
1.1614 + {
1.1615 + // handle loading started/complete messages first, as the later code does not explicitly check the event type
1.1616 + if (aEvent.iEventType == KMMFEventCategoryAudioLoadingStarted)
1.1617 + {
1.1618 + if (iLoadingObserver)
1.1619 + {
1.1620 + iLoadingObserver->MaloLoadingStarted();
1.1621 + }
1.1622 + }
1.1623 + else if (aEvent.iEventType == KMMFEventCategoryAudioLoadingComplete)
1.1624 + {
1.1625 + if (iLoadingObserver)
1.1626 + {
1.1627 + iLoadingObserver->MaloLoadingComplete();
1.1628 + }
1.1629 + }
1.1630 + else if (aEvent.iEventType == KMMFEventCategoryAudioResourceAvailable)
1.1631 + {
1.1632 + if (iAudioResourceNotificationCallBack != NULL)
1.1633 + {
1.1634 + TBuf8<TMMFAudioConfig::KNotificationDataBufferSize> notificationData;
1.1635 + if (KErrNone != iNotificationRegistrationCommands.GetResourceNotificationData(aEvent.iEventType, notificationData))
1.1636 + {
1.1637 + notificationData.SetLength(0);
1.1638 + }
1.1639 + iAudioResourceNotificationCallBack->MarncResourceAvailable(aEvent.iEventType, notificationData);
1.1640 + }
1.1641 + }
1.1642 + else if (aEvent.iEventType == KMMFEventCategoryPlaybackComplete)
1.1643 + {
1.1644 + TInt oldState = iState;
1.1645 + //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.
1.1646 + if(aEvent.iErrorCode == KErrInUse ||aEvent.iErrorCode == KErrDied ||aEvent.iErrorCode == KErrAccessDenied )
1.1647 + {
1.1648 + TInt err= iController.GetPosition(iPosition);
1.1649 + if(err != KErrNone)
1.1650 + {
1.1651 + iPosition = iPlayStart;
1.1652 + }
1.1653 + }
1.1654 + else
1.1655 + {
1.1656 + iPosition = iPlayStart;
1.1657 + }
1.1658 + if (aEvent.iErrorCode == KErrNone)
1.1659 + {
1.1660 + //If we weren't playing, ignore the event.
1.1661 + if (oldState == EPlaying)
1.1662 + {
1.1663 + //we finished playing the clip so repeat if required
1.1664 + iNumberOfTimesPlayed++;
1.1665 + if ((iNumberOfTimesPlayed > iNumberOfTimesToRepeat) && (iNumberOfTimesToRepeat != KMdaRepeatForever))
1.1666 + {
1.1667 + //we've repeated enough times now
1.1668 + iNumberOfTimesPlayed = 0;
1.1669 + iState = EStopped;
1.1670 + iCallback.MapcPlayComplete(KErrNone);
1.1671 + }
1.1672 + else
1.1673 + {
1.1674 + // We need to play silence, then repeat the clip
1.1675 + iTrailingSilenceLeftToPlay = iTrailingSilence;
1.1676 + PlaySilence();
1.1677 + }
1.1678 + }
1.1679 + }
1.1680 + else
1.1681 + { //aEvent.iErrorCode != KErrNone
1.1682 + //if we weren't playing, don't advise Client.
1.1683 + iState = EStopped;
1.1684 + if (oldState == EPlaying)
1.1685 + {
1.1686 + iCallback.MapcPlayComplete(aEvent.iErrorCode);
1.1687 + }
1.1688 + }
1.1689 + }
1.1690 + else if(aEvent.iEventType == KMMFErrorCategoryControllerGeneralError)
1.1691 + {
1.1692 + TInt oldState = iState;
1.1693 + iPosition = iPlayStart;
1.1694 + iState = EStopped;
1.1695 + if (oldState == EPlaying)
1.1696 + {
1.1697 + iCallback.MapcPlayComplete(aEvent.iErrorCode);
1.1698 + }
1.1699 + }
1.1700 + // else we have an unexpected event that cannot be dealt with by the client.
1.1701 + // We will simply ignore this.
1.1702 + }
1.1703 +
1.1704 +void CMMFMdaAudioPlayerUtility::PlaySilence()
1.1705 + {
1.1706 + // iRepeatTrailingSilenceTimer->After() takes a TTimeIntervalMicroSeconds32
1.1707 + // so for longer periods of silence call it repeatedly with KMaxTInt lengths
1.1708 + TTimeIntervalMicroSeconds32 silence;
1.1709 + if (iTrailingSilenceLeftToPlay.Int64() > KMaxTInt)
1.1710 + {
1.1711 + silence = KMaxTInt;
1.1712 + iTrailingSilenceLeftToPlay = iTrailingSilenceLeftToPlay.Int64() - KMaxTInt;
1.1713 + }
1.1714 + else
1.1715 + {
1.1716 + silence = I64INT(iTrailingSilenceLeftToPlay.Int64());
1.1717 + iTrailingSilenceLeftToPlay = 0;
1.1718 + }
1.1719 + iRepeatTrailingSilenceTimer->After(silence);
1.1720 + }
1.1721 +
1.1722 +void CMMFMdaAudioPlayerUtility::RepeatTrailingSilenceTimerComplete()
1.1723 + {
1.1724 + if (iTrailingSilenceLeftToPlay.Int64() > 0)
1.1725 + {
1.1726 + PlaySilence();
1.1727 + }
1.1728 + else
1.1729 + {
1.1730 + // reset the position for subsequent plays
1.1731 + iPosition = iPlayStart;
1.1732 + DoPlay();
1.1733 + }
1.1734 + }
1.1735 +
1.1736 +/**
1.1737 + *
1.1738 + * Returns the current playback position in microseconds
1.1739 + *
1.1740 + * @param "TTimeIntervalMicroSeconds& aPosition"
1.1741 + * The current time position in microseconds from the start of the file
1.1742 + * @return "TInt" One of the global error codes
1.1743 + *
1.1744 + * @since 7.0s
1.1745 + */
1.1746 +TInt CMMFMdaAudioPlayerUtility::GetPosition(TTimeIntervalMicroSeconds& aPosition)
1.1747 + {
1.1748 + TInt error = KErrNone;
1.1749 + if (iState==EPlaying)
1.1750 + error = iController.GetPosition(iPosition);
1.1751 + aPosition = iPosition;
1.1752 + return error;
1.1753 + }
1.1754 +
1.1755 +/**
1.1756 + *
1.1757 + * Set the current playback position in microseconds from the start of the file
1.1758 + *
1.1759 + * @param "TTimeIntervalMicroSeconds& aPosition"
1.1760 + * The position to move to in microseconds from the start of the file.
1.1761 + * If aPosition is negative, the position is set to the start of the file.
1.1762 + * If aPosition is greater than the file duration, the position is set to the
1.1763 + * end of the file.
1.1764 + *
1.1765 + * @since 7.0s
1.1766 + */
1.1767 +void CMMFMdaAudioPlayerUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition)
1.1768 + {
1.1769 + // Clip the position if aPosition is greater than the duration
1.1770 + // or if aPosition is negative.
1.1771 + const TTimeIntervalMicroSeconds maxPosition(Duration());
1.1772 + const TTimeIntervalMicroSeconds minPosition(0);
1.1773 +
1.1774 + if (aPosition > maxPosition)
1.1775 + iPosition = maxPosition;
1.1776 + else if (aPosition < minPosition)
1.1777 + iPosition = minPosition;
1.1778 + else
1.1779 + iPosition = aPosition;
1.1780 +
1.1781 + if (iState==EPlaying || iState==EPaused)
1.1782 + {
1.1783 + iController.SetPosition(iPosition);
1.1784 + }
1.1785 +// else if (iState == EPaused)
1.1786 +// {
1.1787 +// Stop(); // We call stop so that DevSound's internal buffers are reset
1.1788 +// }
1.1789 + }
1.1790 +
1.1791 +/**
1.1792 +Returns the current playback volume
1.1793 +
1.1794 +@param aVolume
1.1795 + A volume value between 0 and the value returned by MaxVolume().
1.1796 +
1.1797 +@return One of the global error codes.
1.1798 +
1.1799 +@since 7.0s
1.1800 +*/
1.1801 +TInt CMMFMdaAudioPlayerUtility::GetVolume(TInt& aVolume)
1.1802 + {
1.1803 + TInt error = iAudioPlayDeviceCommands.GetVolume(aVolume);
1.1804 + return error;
1.1805 + }
1.1806 +
1.1807 +/**
1.1808 + *
1.1809 + * Returns the number of meta data entries in the current clip
1.1810 + *
1.1811 + * @param "TInt& aNumEntries"
1.1812 + * The number of meta data entries in the header of the current clip
1.1813 + * @return "TInt" One of the global error codes
1.1814 + *
1.1815 + * @since 7.0s
1.1816 + */
1.1817 +TInt CMMFMdaAudioPlayerUtility::GetNumberOfMetaDataEntries(TInt& aNumEntries)
1.1818 + {
1.1819 + TInt error = iController.GetNumberOfMetaDataEntries(aNumEntries);
1.1820 + return error;
1.1821 + }
1.1822 +
1.1823 +/**
1.1824 + *
1.1825 + * Returns the requested meta data entry
1.1826 + *
1.1827 + * @param "TInt aMetaDataIndex"
1.1828 + * The index number of the meta data to retrieve
1.1829 + * @return "CMMFMetaDataEntry*" The meta data entry to return
1.1830 + * @leave Leaves with KErrNotFound if the meta data entry does not exist or
1.1831 + * KErrNotImplemented if the controller does not support meta data
1.1832 + * information for this format. Other errors indicate more general system
1.1833 + * failure.
1.1834 + *
1.1835 + * @since 7.0s
1.1836 + */
1.1837 +CMMFMetaDataEntry* CMMFMdaAudioPlayerUtility::GetMetaDataEntryL(TInt aMetaDataIndex)
1.1838 + {
1.1839 + return iController.GetMetaDataEntryL(aMetaDataIndex);
1.1840 + }
1.1841 +
1.1842 +/**
1.1843 + *
1.1844 + * Set the current playback window
1.1845 + *
1.1846 + * @param "const TTimeIntervalMicroSeconds& aStart"
1.1847 + * Start time of playback window relative to start of file
1.1848 + * @param "const TTimeIntervalMicroSeconds& aEnd"
1.1849 + * End time of playback window relative to start of file
1.1850 + *
1.1851 + * @return "TInt" One of the global error codes
1.1852 + *
1.1853 + * @since 7.0s
1.1854 + */
1.1855 +TInt CMMFMdaAudioPlayerUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aPlayStart,
1.1856 + const TTimeIntervalMicroSeconds& aPlayEnd)
1.1857 + {
1.1858 + TInt error = KErrNone;
1.1859 +
1.1860 + if (aPlayStart >= TTimeIntervalMicroSeconds(0) &&
1.1861 + aPlayStart < iDuration &&
1.1862 + aPlayStart < aPlayEnd &&
1.1863 + aPlayEnd <= iDuration )
1.1864 + {
1.1865 + iPlayStart = aPlayStart;
1.1866 + iPlayEnd = aPlayEnd;
1.1867 + iPlayWindowSet = ESet;
1.1868 +
1.1869 + if (iState==EPlaying)
1.1870 + error = iAudioPlayControllerCommands.SetPlaybackWindow(aPlayStart, aPlayEnd);
1.1871 + }
1.1872 + else
1.1873 + error = KErrArgument;
1.1874 +
1.1875 + return error;
1.1876 + }
1.1877 +
1.1878 +/**
1.1879 + *
1.1880 + * Clear the current playback window
1.1881 + *
1.1882 + * @return "TInt" One of the global error codes
1.1883 + *
1.1884 + * @since 7.0s
1.1885 + */
1.1886 +TInt CMMFMdaAudioPlayerUtility::ClearPlayWindow()
1.1887 + {
1.1888 + // clear play window start - very important because this is assigned
1.1889 + // to iPosition when we stop & is used to set the position on the next Play()
1.1890 + iPosition = iPlayStart = iPlayEnd = TTimeIntervalMicroSeconds(0);
1.1891 +
1.1892 + iPlayWindowSet = EClear;
1.1893 + TInt err = KErrNone;
1.1894 + if (iState==EPlaying)
1.1895 + err = iAudioPlayControllerCommands.DeletePlaybackWindow();
1.1896 + return err;
1.1897 + }
1.1898 +
1.1899 +/**
1.1900 +Sets the current playback balance
1.1901 +
1.1902 +@param aBalance
1.1903 + A value between KMMFBalanceMaxLeft and KMMFBalanceMaxRight. The default value is
1.1904 + KMMFBalanceCenter.
1.1905 +
1.1906 +@return One of the global error codes.
1.1907 +
1.1908 +@since 7.0s
1.1909 +*/
1.1910 +TInt CMMFMdaAudioPlayerUtility::SetBalance(TInt aBalance)
1.1911 + {
1.1912 + TInt err = iAudioPlayDeviceCommands.SetBalance(aBalance);
1.1913 + return err;
1.1914 + }
1.1915 +
1.1916 +/**
1.1917 +Returns the bit rate of the audio clip.
1.1918 +
1.1919 +@param aBitRate
1.1920 + Bit rate of the audio clip.
1.1921 +
1.1922 +@return One of the global error codes.
1.1923 +
1.1924 +@since 7.0s
1.1925 +*/
1.1926 +TInt CMMFMdaAudioPlayerUtility::GetBitRate(TUint& aBitRate)
1.1927 + {
1.1928 + RMMFAudioControllerCustomCommands controller(iController);
1.1929 + TInt err = controller.GetSourceBitRate(aBitRate);
1.1930 + return err;
1.1931 + }
1.1932 +
1.1933 +const CMMFControllerImplementationInformation& CMMFMdaAudioPlayerUtility::ControllerImplementationInformationL()
1.1934 + {
1.1935 + if (!iControllerImplementationInformation)
1.1936 + {
1.1937 + if (iControllerUid==KNullUid)
1.1938 + User::Leave(KErrNotReady);
1.1939 + iControllerImplementationInformation = CMMFControllerImplementationInformation::NewL(iControllerUid);
1.1940 + }
1.1941 + return *iControllerImplementationInformation;
1.1942 + }
1.1943 +
1.1944 +void CMMFMdaAudioPlayerUtility::GetAudioLoadingProgressL(TInt& aPercentageProgress)
1.1945 + {
1.1946 + User::LeaveIfError(iAudioPlayControllerCommands.GetLoadingProgress(aPercentageProgress));
1.1947 + }
1.1948 +
1.1949 +TInt CMMFMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
1.1950 + {
1.1951 + return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
1.1952 + }
1.1953 +
1.1954 +TInt CMMFMdaAudioPlayerUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
1.1955 + {
1.1956 + return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
1.1957 + }
1.1958 +
1.1959 +void CMMFMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
1.1960 + {
1.1961 + iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
1.1962 + }
1.1963 +
1.1964 +void CMMFMdaAudioPlayerUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
1.1965 + {
1.1966 + iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
1.1967 + }
1.1968 +
1.1969 +/**
1.1970 +Returns the current playback balance
1.1971 +
1.1972 +@param aBalance
1.1973 + A value between KMMFBalanceMaxLeft and KMMFBalanceMaxRight
1.1974 +
1.1975 +@return One of the global error codes.
1.1976 +
1.1977 +@since 7.0s
1.1978 +*/
1.1979 +TInt CMMFMdaAudioPlayerUtility::GetBalance(TInt& aBalance)
1.1980 + {
1.1981 + TInt err = iAudioPlayDeviceCommands.GetBalance(aBalance);
1.1982 + return err;
1.1983 + }
1.1984 +
1.1985 +MMMFDRMCustomCommand* CMMFMdaAudioPlayerUtility::GetDRMCustomCommand()
1.1986 + {
1.1987 + // XXX: check controller supports MMMFDRMCustomCommandImplementor
1.1988 + if (iDRMCustomCommands.IsSupported())
1.1989 + {
1.1990 + return static_cast<MMMFDRMCustomCommand*>(&iDRMCustomCommands);
1.1991 + }
1.1992 + else
1.1993 + {
1.1994 + return NULL;
1.1995 + }
1.1996 + }
1.1997 +
1.1998 +void CMMFMdaAudioPlayerUtility::RegisterForAudioLoadingNotification(MAudioLoadingObserver& aLoadingObserver)
1.1999 + {
1.2000 + iLoadingObserver = &aLoadingObserver;
1.2001 + }
1.2002 +
1.2003 +TInt CMMFMdaAudioPlayerUtility::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,
1.2004 + TUid aNotificationEventUid,
1.2005 + const TDesC8& aNotificationRegistrationData)
1.2006 + {
1.2007 + iAudioResourceNotificationCallBack = &aCallback;
1.2008 + TInt err = iNotificationRegistrationCommands.RegisterAsClient(aNotificationEventUid, aNotificationRegistrationData);
1.2009 + if(err == KErrNotReady)
1.2010 + {
1.2011 + iEventHolder = aNotificationEventUid;
1.2012 + iNotificationDataHolder = aNotificationRegistrationData;
1.2013 + return KErrNone;
1.2014 + }
1.2015 + iNotificationDataHolder = KNullDesC8;
1.2016 + iEventHolder = KNullUid;
1.2017 + return err;
1.2018 + }
1.2019 +
1.2020 +TInt CMMFMdaAudioPlayerUtility::CancelRegisterAudioResourceNotification(TUid aNotificationEventId)
1.2021 + {
1.2022 + TInt err = iNotificationRegistrationCommands.CancelRegisterAsClient(aNotificationEventId);
1.2023 + if(err == KErrNotReady)
1.2024 + {
1.2025 + if(aNotificationEventId != KMMFEventCategoryAudioResourceAvailable)
1.2026 + {
1.2027 + return KErrNotSupported;
1.2028 + }
1.2029 + if(iEventHolder == KNullUid)
1.2030 + {
1.2031 + return KErrCancel;
1.2032 + }
1.2033 + iEventHolder = KNullUid;
1.2034 + iNotificationDataHolder = KNullDesC8;
1.2035 + return KErrNone;
1.2036 + }
1.2037 + return err;
1.2038 + }
1.2039 +
1.2040 +TInt CMMFMdaAudioPlayerUtility::WillResumePlay()
1.2041 + {
1.2042 + return iNotificationRegistrationCommands.WillResumePlay();
1.2043 + }
1.2044 +
1.2045 +TInt CMMFMdaAudioPlayerUtility::SetThreadPriority(const TThreadPriority& aThreadPriority) const
1.2046 + {
1.2047 + return iController.SetThreadPriority(aThreadPriority);
1.2048 + }
1.2049 +
1.2050 +CRepeatTrailingSilenceTimer* CRepeatTrailingSilenceTimer::NewL(MRepeatTrailingSilenceTimerObs& aObs)
1.2051 + {
1.2052 + CRepeatTrailingSilenceTimer* s = new(ELeave) CRepeatTrailingSilenceTimer(aObs);
1.2053 + CleanupStack::PushL(s);
1.2054 + s->ConstructL();
1.2055 + CleanupStack::Pop();
1.2056 + return s;
1.2057 + }
1.2058 +
1.2059 +void CRepeatTrailingSilenceTimer::RunL()
1.2060 + {
1.2061 + iObs.RepeatTrailingSilenceTimerComplete();
1.2062 + }
1.2063 +
1.2064 +CRepeatTrailingSilenceTimer::CRepeatTrailingSilenceTimer(MRepeatTrailingSilenceTimerObs& aObs) :
1.2065 + CTimer(EPriorityHigh),
1.2066 + iObs(aObs)
1.2067 + {
1.2068 + CActiveScheduler::Add(this);
1.2069 + }
1.2070 +
1.2071 +
1.2072 +
1.2073 +CMMFMdaAudioPlayerCallBack* CMMFMdaAudioPlayerCallBack::NewL(MMdaAudioPlayerCallback& aCallback)
1.2074 + {
1.2075 + return new(ELeave) CMMFMdaAudioPlayerCallBack(aCallback);
1.2076 + }
1.2077 +
1.2078 +CMMFMdaAudioPlayerCallBack::CMMFMdaAudioPlayerCallBack(MMdaAudioPlayerCallback& aCallback) :
1.2079 + CActive(CActive::EPriorityHigh), iCallback(aCallback)
1.2080 + {
1.2081 + CActiveScheduler::Add(this);
1.2082 + }
1.2083 +
1.2084 +CMMFMdaAudioPlayerCallBack::~CMMFMdaAudioPlayerCallBack()
1.2085 + {
1.2086 + Cancel();
1.2087 + }
1.2088 +
1.2089 +void CMMFMdaAudioPlayerCallBack::InitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration)
1.2090 + {
1.2091 + iError = aError;
1.2092 + iDuration = aDuration;
1.2093 + iState = ECallbackInitComplete;
1.2094 + if (!IsActive())
1.2095 + {
1.2096 + TRequestStatus* s = &iStatus;
1.2097 + SetActive();
1.2098 + User::RequestComplete(s, KErrNone);
1.2099 + }
1.2100 + }
1.2101 +
1.2102 +void CMMFMdaAudioPlayerCallBack::PlayComplete(TInt aError)
1.2103 + {
1.2104 + iError = aError;
1.2105 + iState = ECallbackPlayComplete;
1.2106 + if (!IsActive())
1.2107 + {
1.2108 + TRequestStatus* s = &iStatus;
1.2109 + SetActive();
1.2110 + User::RequestComplete(s, KErrNone);
1.2111 + }
1.2112 + }
1.2113 +
1.2114 +void CMMFMdaAudioPlayerCallBack::RunL()
1.2115 + {
1.2116 + switch (iState)
1.2117 + {
1.2118 + case ECallbackInitComplete:
1.2119 + iCallback.MapcInitComplete(iError, iDuration);
1.2120 + break;
1.2121 + case ECallbackPlayComplete:
1.2122 + iCallback.MapcPlayComplete(iError);
1.2123 + break;
1.2124 + }
1.2125 + }
1.2126 +
1.2127 +void CMMFMdaAudioPlayerCallBack::DoCancel()
1.2128 + {
1.2129 + // Nothing to cancel
1.2130 + }