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 <logger.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 LOG( EJavaMMAPI, EInfo, "MMA::CMMADRMAudioPlayer::~CMMADRMAudioPlayer "); |
|
49 } |
|
50 |
|
51 void CMMADRMAudioPlayer::ConstructL(const TDesC& aContentType) |
|
52 { |
|
53 LOG( EJavaMMAPI, EInfo, "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 LOG( EJavaMMAPI, EInfo, "CMMADRMAudioPlayer::RealizeL"); |
|
81 CMMAPlayer::RealizeL(); |
|
82 } |
|
83 |
|
84 void CMMADRMAudioPlayer::PrefetchL() |
|
85 { |
|
86 LOG( EJavaMMAPI, EInfo, "CMMADRMAudioPlayer::PrefetchL"); |
|
87 // Prefetch will be completed in init callback |
|
88 iUtility->OpenFileL(iFileName); |
|
89 } |
|
90 |
|
91 void CMMADRMAudioPlayer::DeallocateL() |
|
92 { |
|
93 LOG( EJavaMMAPI, EInfo, "MMA: CMMAMidiPlayer: DeallocateL +"); |
|
94 if (iState == EPrefetched) |
|
95 { |
|
96 CloseClientUtility(); |
|
97 ChangeState(ERealized); |
|
98 } |
|
99 LOG( EJavaMMAPI, EInfo, "MMA: CMMAMidiPlayer: DeallocateL -"); |
|
100 } |
|
101 |
|
102 void CMMADRMAudioPlayer::StartL() |
|
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 PostActionCompletedStart(); |
|
128 // inform java side |
|
129 PostActionCompleted(KErrNone); // java start return |
|
130 PostLongEvent(CMMAPlayerEvent::EStarted, time); |
|
131 ChangeState(EStarted); |
|
132 } |
|
133 |
|
134 void CMMADRMAudioPlayer::StopL(TBool aPostEvent) |
|
135 { |
|
136 if (iState == EStarted) |
|
137 { |
|
138 User::LeaveIfError(iUtility->Pause()); |
|
139 |
|
140 if (aPostEvent) |
|
141 { |
|
142 TInt64 time; |
|
143 GetMediaTime(&time); |
|
144 PostLongEvent(CMMAPlayerEvent::EStopped, time); |
|
145 } |
|
146 // go back to prefetched state |
|
147 ChangeState(EPrefetched); |
|
148 } |
|
149 } |
|
150 |
|
151 void CMMADRMAudioPlayer::GetDuration(TInt64* aDuration) |
|
152 { |
|
153 if (iState < EPrefetched) |
|
154 { |
|
155 *aDuration = KDurationUnknown; |
|
156 } |
|
157 else |
|
158 { |
|
159 *aDuration = iUtility->Duration().Int64(); |
|
160 } |
|
161 } |
|
162 |
|
163 void CMMADRMAudioPlayer::SetMediaTimeL(TInt64* aTime) |
|
164 { |
|
165 LOG1( EJavaMMAPI, EInfo, "MMA::CMMADRMAudioPlayer::SetMediaTimeL + aTime: %d", *aTime); |
|
166 // Duration is needed so we do not try to set media time |
|
167 // too far away. If duration is not known, setting media time |
|
168 // is not allowed. |
|
169 |
|
170 TInt64 duration = TInt64(KMediaStartTime); |
|
171 GetDuration(&duration); |
|
172 if (duration < KErrNone) |
|
173 { |
|
174 // If duration is not known, we will leave with suitable code. |
|
175 User::Leave(KErrNotSupported); |
|
176 } |
|
177 |
|
178 // Check if desired media time is past media duration and |
|
179 // set it to duration in that case. Negative values are not |
|
180 // checked here because it's done already in Java side. |
|
181 |
|
182 // If media time is attempted to set to duration, then |
|
183 // it is set close to duration. This way |
|
184 // when utility is then started, end of media event |
|
185 // will come soon after. This is not indicated to Java |
|
186 // side but instead returned that the media time was |
|
187 // set to duration. |
|
188 |
|
189 TTimeIntervalMicroSeconds position; |
|
190 if (*aTime >= duration) |
|
191 { |
|
192 *aTime = duration; |
|
193 position = duration - KMediaTimeDurationTreshold; |
|
194 } |
|
195 else |
|
196 { |
|
197 position = *aTime; |
|
198 } |
|
199 |
|
200 iUtility->SetPosition(position); |
|
201 |
|
202 // Inform about the position change to the StateListeners |
|
203 ChangeState(iState); |
|
204 |
|
205 // Get the actual media time |
|
206 GetMediaTime(aTime); |
|
207 } |
|
208 |
|
209 void CMMADRMAudioPlayer::GetMediaTime(TInt64* aMediaTime) |
|
210 { |
|
211 LOG1( EJavaMMAPI, EInfo, "MMA::CMMADRMAudioPlayer::GetMediaTime + aMediaTime: %d", *aMediaTime); |
|
212 TTimeIntervalMicroSeconds position; |
|
213 TInt64 duration = TInt64(KMediaStartTime); |
|
214 |
|
215 // Error code discarded on purpose |
|
216 GetDuration(&duration); |
|
217 |
|
218 TInt error(iUtility->GetPosition(position)); |
|
219 if (error == KErrNone) |
|
220 { |
|
221 // set return value |
|
222 *aMediaTime = position.Int64(); |
|
223 //if duration is unknown and position 0, player is realized and |
|
224 //we can not know media time |
|
225 if ((duration == KDurationUnknown) && (position == 0)) |
|
226 { |
|
227 *aMediaTime = KTimeUnknown; |
|
228 } |
|
229 } |
|
230 else |
|
231 { |
|
232 // media time cannot be get |
|
233 *aMediaTime = KTimeUnknown; |
|
234 } |
|
235 |
|
236 // Second part of the set media time workaround. |
|
237 // If position is close to duration, then media |
|
238 // time of duration is returned instead. |
|
239 |
|
240 // If the duration is zero or not known |
|
241 // then this adjustment is not done. |
|
242 if ((duration > KErrNone) && |
|
243 (*aMediaTime >= duration - KMediaTimeDurationTreshold)) |
|
244 { |
|
245 *aMediaTime = duration; |
|
246 } |
|
247 LOG1( EJavaMMAPI, EInfo, "MMA::CMMADRMAudioPlayer::GetMediaTime - aMediaTime: %d", *aMediaTime); |
|
248 } |
|
249 |
|
250 void CMMADRMAudioPlayer::CloseL() |
|
251 { |
|
252 CMMAPlayer::CloseL(); |
|
253 CloseClientUtility(); |
|
254 } |
|
255 |
|
256 const TDesC& CMMADRMAudioPlayer::Type() |
|
257 { |
|
258 return KMMADRMPlayer; |
|
259 } |
|
260 |
|
261 void CMMADRMAudioPlayer::PlayCompleteL(TInt aError) |
|
262 { |
|
263 ELOG1( EJavaMMAPI, "MMA: CMMADRMAudioPlayer: PlayCompleteL: Error=%d", aError); |
|
264 TInt64 time; |
|
265 GetDuration(&time); |
|
266 |
|
267 // Send 'Stopped' only when stop() is called. |
|
268 PostLongEvent(CMMAPlayerEvent::EEndOfMedia, time); |
|
269 |
|
270 ChangeState(EPrefetched); // ready to play again |
|
271 |
|
272 if (aError == KErrNone) |
|
273 { |
|
274 iRepeatCount++; |
|
275 |
|
276 if (iRepeatForever || iRepeatCount < iRepeatNumberOfTimes) |
|
277 { |
|
278 StartL(); |
|
279 } |
|
280 else |
|
281 { |
|
282 iRepeatCount = 0; |
|
283 TTimeIntervalMicroSeconds position(time); |
|
284 iUtility->SetPosition(position); |
|
285 } |
|
286 } |
|
287 else |
|
288 { |
|
289 // error has occured, setting correct number of |
|
290 // repeats for next start |
|
291 SetLoopCount(iRepeatNumberOfTimes); |
|
292 } |
|
293 LOG( EJavaMMAPI, EInfo, "MMA: CMMADRMAudioPlayer: PlayCompleteL -"); |
|
294 } |
|
295 |
|
296 void CMMADRMAudioPlayer::MdapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/) |
|
297 { |
|
298 ELOG1( EJavaMMAPI, "MMA::CMMADRMAudioPlayer::MdapcInitComplete: aError = %d", aError); |
|
299 if (!aError) |
|
300 { |
|
301 ChangeState(EPrefetched); |
|
302 } |
|
303 PostActionCompleted(aError); |
|
304 } |
|
305 |
|
306 void CMMADRMAudioPlayer::MdapcPlayComplete(TInt aError) |
|
307 { |
|
308 if (aError) |
|
309 { |
|
310 ErrorPlaybackComplete(aError); |
|
311 } |
|
312 else |
|
313 { |
|
314 TRAPD(error, PlayCompleteL(KErrNone)); |
|
315 if (error) |
|
316 { |
|
317 ErrorPlaybackComplete(error); |
|
318 } |
|
319 } |
|
320 } |
|
321 |
|
322 void CMMADRMAudioPlayer::CloseClientUtility() |
|
323 { |
|
324 LOG( EJavaMMAPI, EInfo, "MMA: CMMADRMAudioPlayer: CloseClientUtility +"); |
|
325 if (iUtility) |
|
326 { |
|
327 iUtility->Close(); |
|
328 } |
|
329 LOG( EJavaMMAPI, EInfo, "MMA: CMMADRMAudioPlayer: CloseClientUtility -"); |
|
330 } |
|
331 |
|
332 void CMMADRMAudioPlayer::ErrorPlaybackComplete(TInt aError) |
|
333 { |
|
334 ELOG1( EJavaMMAPI, "MMA::CMMADRMAudioPlayer::ErrorPlaybackComplete: aError = %d", aError); |
|
335 TBuf<KErrorMessageSize> errorMessage; |
|
336 errorMessage.Format(KErrDefaultError, aError); |
|
337 PostStringEvent(CMMAPlayerEvent::EError, errorMessage); |
|
338 |
|
339 CloseClientUtility(); |
|
340 ChangeState(ERealized); |
|
341 } |
|
342 // END OF FILE |
|