|
1 /* |
|
2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This class is used for MIDI. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <jdebug.h> |
|
21 #include <e32base.h> |
|
22 #include <AudioPreference.h> |
|
23 |
|
24 #include "cmmadrmaudioplayer.h" |
|
25 #include "mmmadisplay.h" |
|
26 |
|
27 const TInt KErrorMessageSize = 32; |
|
28 const TInt64 KDurationUnknown = -1; |
|
29 const TInt KMediaStartTime = 0; |
|
30 const TInt KMediaTimeDurationTreshold = 100000; |
|
31 |
|
32 _LIT(KErrDefaultError, "Symbian OS Error: %d"); |
|
33 |
|
34 CMMADRMAudioPlayer* CMMADRMAudioPlayer::NewLC(const TDesC& aContentType, |
|
35 TFileName aFileName) |
|
36 { |
|
37 CMMADRMAudioPlayer* self = new(ELeave) CMMADRMAudioPlayer(aFileName); |
|
38 CleanupStack::PushL(self); |
|
39 self->ConstructL(aContentType); |
|
40 return self; |
|
41 } |
|
42 |
|
43 CMMADRMAudioPlayer::~CMMADRMAudioPlayer() |
|
44 { |
|
45 CloseClientUtility(); |
|
46 delete iUtility; |
|
47 |
|
48 DEBUG("MMA::CMMADRMAudioPlayer::~CMMADRMAudioPlayer "); |
|
49 } |
|
50 |
|
51 void CMMADRMAudioPlayer::ConstructL(const TDesC& aContentType) |
|
52 { |
|
53 DEBUG("CMMADRMAudioPlayer::ConstructL"); |
|
54 // Only file based sources are supported with DRM |
|
55 if (iFileName == KNullDesC) |
|
56 { |
|
57 User::Leave(KErrNotSupported); |
|
58 } |
|
59 iContentType = aContentType.AllocL(); |
|
60 iUtility = CDrmPlayerUtility::NewL(*this, KAudioPriorityRealOnePlayer, |
|
61 (TMdaPriorityPreference) KAudioPrefRealOneLocalPlayback); |
|
62 |
|
63 CMMAPlayer::ConstructL(); |
|
64 } |
|
65 |
|
66 CMMADRMAudioPlayer::CMMADRMAudioPlayer(TFileName aFileName): |
|
67 CMMAPlayer(), |
|
68 iFileName(aFileName) |
|
69 { |
|
70 } |
|
71 |
|
72 CDrmPlayerUtility* CMMADRMAudioPlayer::DRMUtility() const |
|
73 { |
|
74 return iUtility; |
|
75 } |
|
76 |
|
77 |
|
78 void CMMADRMAudioPlayer::RealizeL() |
|
79 { |
|
80 DEBUG("CMMADRMAudioPlayer::RealizeL"); |
|
81 CMMAPlayer::RealizeL(); |
|
82 } |
|
83 |
|
84 void CMMADRMAudioPlayer::PrefetchL() |
|
85 { |
|
86 DEBUG("CMMADRMAudioPlayer::PrefetchL"); |
|
87 // Prefetch will be completed in init callback |
|
88 iUtility->OpenFileL(iFileName); |
|
89 } |
|
90 |
|
91 void CMMADRMAudioPlayer::DeallocateL() |
|
92 { |
|
93 DEBUG("MMA: CMMAMidiPlayer: DeallocateL +"); |
|
94 if (iState == EPrefetched) |
|
95 { |
|
96 CloseClientUtility(); |
|
97 ChangeState(ERealized); |
|
98 } |
|
99 DEBUG("MMA: CMMAMidiPlayer: DeallocateL -"); |
|
100 } |
|
101 |
|
102 void CMMADRMAudioPlayer::StartL(TBool aPostEvent) |
|
103 { |
|
104 // start can't be called to not ready player |
|
105 ASSERT(iState == EPrefetched); |
|
106 |
|
107 TInt64 time = TInt64(KMediaStartTime); |
|
108 |
|
109 // Media time is not fetched using GetMediaTime |
|
110 // Because it adjusts the result if it is close |
|
111 // to duration. |
|
112 |
|
113 TTimeIntervalMicroSeconds position(KMediaStartTime); |
|
114 User::LeaveIfError(iUtility->GetPosition(position)); |
|
115 |
|
116 time = position.Int64(); |
|
117 |
|
118 TInt64 duration; |
|
119 GetDuration(&duration); |
|
120 if ((duration > 0) && (time > duration - KMediaTimeDurationTreshold)) |
|
121 { |
|
122 time = KMediaStartTime; |
|
123 iUtility->SetPosition(time); |
|
124 } |
|
125 |
|
126 iUtility->Play(); |
|
127 |
|
128 PostActionCompleted(KErrNone); // java start return |
|
129 if (aPostEvent) |
|
130 { |
|
131 // inform java side |
|
132 PostLongEvent(CMMAPlayerEvent::EStarted, time); |
|
133 } |
|
134 ChangeState(EStarted); |
|
135 } |
|
136 |
|
137 void CMMADRMAudioPlayer::StopL(TBool aPostEvent) |
|
138 { |
|
139 if (iState == EStarted) |
|
140 { |
|
141 User::LeaveIfError(iUtility->Pause()); |
|
142 |
|
143 if (aPostEvent) |
|
144 { |
|
145 TInt64 time; |
|
146 GetMediaTime(&time); |
|
147 PostLongEvent(CMMAPlayerEvent::EStopped, time); |
|
148 } |
|
149 // go back to prefetched state |
|
150 ChangeState(EPrefetched); |
|
151 } |
|
152 } |
|
153 |
|
154 void CMMADRMAudioPlayer::GetDuration(TInt64* aDuration) |
|
155 { |
|
156 if (iState < EPrefetched) |
|
157 { |
|
158 *aDuration = KDurationUnknown; |
|
159 } |
|
160 else |
|
161 { |
|
162 *aDuration = iUtility->Duration().Int64(); |
|
163 } |
|
164 } |
|
165 |
|
166 void CMMADRMAudioPlayer::SetMediaTimeL(TInt64* aTime) |
|
167 { |
|
168 DEBUG_INT("MMA::CMMADRMAudioPlayer::SetMediaTimeL + aTime: %d", *aTime); |
|
169 // Duration is needed so we do not try to set media time |
|
170 // too far away. If duration is not known, setting media time |
|
171 // is not allowed. |
|
172 |
|
173 TInt64 duration = TInt64(KMediaStartTime); |
|
174 GetDuration(&duration); |
|
175 if (duration < KErrNone) |
|
176 { |
|
177 // If duration is not known, we will leave with suitable code. |
|
178 User::Leave(KErrNotSupported); |
|
179 } |
|
180 |
|
181 // Check if desired media time is past media duration and |
|
182 // set it to duration in that case. Negative values are not |
|
183 // checked here because it's done already in Java side. |
|
184 |
|
185 // If media time is attempted to set to duration, then |
|
186 // it is set close to duration. This way |
|
187 // when utility is then started, end of media event |
|
188 // will come soon after. This is not indicated to Java |
|
189 // side but instead returned that the media time was |
|
190 // set to duration. |
|
191 |
|
192 TTimeIntervalMicroSeconds position; |
|
193 if (*aTime >= duration) |
|
194 { |
|
195 *aTime = duration; |
|
196 position = duration - KMediaTimeDurationTreshold; |
|
197 } |
|
198 else |
|
199 { |
|
200 position = *aTime; |
|
201 } |
|
202 |
|
203 iUtility->SetPosition(position); |
|
204 |
|
205 // Inform about the position change to the StateListeners |
|
206 ChangeState(iState); |
|
207 |
|
208 // Get the actual media time |
|
209 GetMediaTime(aTime); |
|
210 } |
|
211 |
|
212 void CMMADRMAudioPlayer::GetMediaTime(TInt64* aMediaTime) |
|
213 { |
|
214 DEBUG_INT("MMA::CMMADRMAudioPlayer::GetMediaTime + aMediaTime: %d", *aMediaTime); |
|
215 TTimeIntervalMicroSeconds position; |
|
216 TInt64 duration = TInt64(KMediaStartTime); |
|
217 |
|
218 // Error code discarded on purpose |
|
219 GetDuration(&duration); |
|
220 |
|
221 TInt error(iUtility->GetPosition(position)); |
|
222 if (error == KErrNone) |
|
223 { |
|
224 // set return value |
|
225 *aMediaTime = position.Int64(); |
|
226 //if duration is unknown and position 0, player is realized and |
|
227 //we can not know media time |
|
228 if ((duration == KDurationUnknown) && (position == 0)) |
|
229 { |
|
230 *aMediaTime = KTimeUnknown; |
|
231 } |
|
232 } |
|
233 else |
|
234 { |
|
235 // media time cannot be get |
|
236 *aMediaTime = KTimeUnknown; |
|
237 } |
|
238 |
|
239 // Second part of the set media time workaround. |
|
240 // If position is close to duration, then media |
|
241 // time of duration is returned instead. |
|
242 |
|
243 // If the duration is zero or not known |
|
244 // then this adjustment is not done. |
|
245 if ((duration > KErrNone) && |
|
246 (*aMediaTime >= duration - KMediaTimeDurationTreshold)) |
|
247 { |
|
248 *aMediaTime = duration; |
|
249 } |
|
250 DEBUG_INT("MMA::CMMADRMAudioPlayer::GetMediaTime - aMediaTime: %d", *aMediaTime); |
|
251 } |
|
252 |
|
253 void CMMADRMAudioPlayer::CloseL() |
|
254 { |
|
255 CMMAPlayer::CloseL(); |
|
256 CloseClientUtility(); |
|
257 } |
|
258 |
|
259 const TDesC& CMMADRMAudioPlayer::Type() |
|
260 { |
|
261 return KMMADRMPlayer; |
|
262 } |
|
263 |
|
264 void CMMADRMAudioPlayer::PlayCompleteL(TInt aError) |
|
265 { |
|
266 DEBUG_INT("MMA: CMMADRMAudioPlayer: PlayCompleteL: Error=%d", aError); |
|
267 TInt64 time; |
|
268 GetDuration(&time); |
|
269 |
|
270 // Send 'Stopped' only when stop() is called. |
|
271 PostLongEvent(CMMAPlayerEvent::EEndOfMedia, time); |
|
272 |
|
273 ChangeState(EPrefetched); // ready to play again |
|
274 |
|
275 if (aError == KErrNone) |
|
276 { |
|
277 iRepeatCount++; |
|
278 |
|
279 if (iRepeatForever || iRepeatCount < iRepeatNumberOfTimes) |
|
280 { |
|
281 StartL(ETrue); |
|
282 } |
|
283 else |
|
284 { |
|
285 iRepeatCount = 0; |
|
286 TTimeIntervalMicroSeconds position(time); |
|
287 iUtility->SetPosition(position); |
|
288 } |
|
289 } |
|
290 else |
|
291 { |
|
292 // error has occured, setting correct number of |
|
293 // repeats for next start |
|
294 SetLoopCount(iRepeatNumberOfTimes); |
|
295 } |
|
296 DEBUG("MMA: CMMADRMAudioPlayer: PlayCompleteL -"); |
|
297 } |
|
298 |
|
299 void CMMADRMAudioPlayer::MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/) |
|
300 { |
|
301 DEBUG_INT("MMA::CMMADRMAudioPlayer::MdapcInitComplete: aError = %d", aError); |
|
302 if (!aError) |
|
303 { |
|
304 ChangeState(EPrefetched); |
|
305 } |
|
306 PostActionCompleted(aError); |
|
307 } |
|
308 |
|
309 void CMMADRMAudioPlayer::MdapcPlayComplete(TInt aError) |
|
310 { |
|
311 if (aError) |
|
312 { |
|
313 ErrorPlaybackComplete(aError); |
|
314 } |
|
315 else |
|
316 { |
|
317 TRAPD(error, PlayCompleteL(KErrNone)); |
|
318 if (error) |
|
319 { |
|
320 ErrorPlaybackComplete(error); |
|
321 } |
|
322 } |
|
323 } |
|
324 |
|
325 void CMMADRMAudioPlayer::CloseClientUtility() |
|
326 { |
|
327 DEBUG("MMA: CMMADRMAudioPlayer: CloseClientUtility +"); |
|
328 if (iUtility) |
|
329 { |
|
330 iUtility->Close(); |
|
331 } |
|
332 DEBUG("MMA: CMMADRMAudioPlayer: CloseClientUtility -"); |
|
333 } |
|
334 |
|
335 void CMMADRMAudioPlayer::ErrorPlaybackComplete(TInt aError) |
|
336 { |
|
337 DEBUG_INT("MMA::CMMADRMAudioPlayer::ErrorPlaybackComplete: aError = %d", aError); |
|
338 TBuf<KErrorMessageSize> errorMessage; |
|
339 errorMessage.Format(KErrDefaultError, aError); |
|
340 PostStringEvent(CMMAPlayerEvent::EError, errorMessage); |
|
341 |
|
342 CloseClientUtility(); |
|
343 ChangeState(ERealized); |
|
344 } |
|
345 // END OF FILE |