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