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