|
1 #include <string.h> |
|
2 #include <stdlib.h> |
|
3 #include "openmaxplayerutility.h" |
|
4 |
|
5 #define FILE_EXTN "file:///" |
|
6 #define FILE_EXTN_LEN strlen("file:///") |
|
7 |
|
8 XAboolean bIsPlayDone = XA_BOOLEAN_FALSE; |
|
9 |
|
10 void PlayCallbackFun (XAPlayItf /*caller*/, void* pContext, XAuint32 event) |
|
11 { |
|
12 char callback_string[50]; |
|
13 COpenMaxPlayerUtility* pSelf = (COpenMaxPlayerUtility*)pContext; |
|
14 if(event & XA_PLAYEVENT_HEADMOVING) |
|
15 { |
|
16 strcpy(callback_string, "XA_PLAYEVENT_HEADMOVING"); |
|
17 } |
|
18 else if(event & XA_PLAYEVENT_HEADATEND) |
|
19 { |
|
20 strcpy(callback_string, "XA_PLAYEVENT_HEADATEND"); |
|
21 bIsPlayDone = XA_BOOLEAN_TRUE; |
|
22 pSelf->Stop(); |
|
23 } |
|
24 else if(event & XA_PLAYEVENT_HEADATMARKER) |
|
25 { |
|
26 strcpy(callback_string, "XA_PLAYEVENT_HEADATMARKER"); |
|
27 } |
|
28 else if(event & XA_PLAYEVENT_HEADATNEWPOS) |
|
29 { |
|
30 strcpy(callback_string, "XA_PLAYEVENT_HEADATNEWPOS"); |
|
31 } |
|
32 else if(event & XA_PLAYEVENT_HEADSTALLED) |
|
33 { |
|
34 strcpy(callback_string, "XA_PLAYEVENT_HEADSTALLED"); |
|
35 } |
|
36 //LOGFILE (callback_string); |
|
37 } |
|
38 |
|
39 COpenMaxPlayerUtility::COpenMaxPlayerUtility() |
|
40 { |
|
41 Init(); |
|
42 } |
|
43 |
|
44 COpenMaxPlayerUtility::~COpenMaxPlayerUtility() |
|
45 { |
|
46 /* Destroy the player */ |
|
47 DestroyPlayer (); |
|
48 |
|
49 /* Destroy Output Mix object */ |
|
50 (*m_outputMix)->Destroy(m_outputMix); |
|
51 |
|
52 /* Shutdown OpenMAX AL */ |
|
53 (*m_engine)->Destroy(m_engine); |
|
54 } |
|
55 |
|
56 // Initializes the OpenMAX AL engine and start the playback of some |
|
57 // music from a file and draw the graphical equalizer |
|
58 // |
|
59 void COpenMaxPlayerUtility::Init (void) |
|
60 { |
|
61 XAresult res; |
|
62 int i; |
|
63 XAEngineOption EngineOption[] = { |
|
64 (XAuint32) XA_ENGINEOPTION_THREADSAFE, |
|
65 (XAuint32) XA_BOOLEAN_TRUE |
|
66 }; |
|
67 |
|
68 /* Create OpenMAX AL */ |
|
69 res = xaCreateEngine(&m_engine, 1, EngineOption, 0, NULL, NULL); |
|
70 CheckErr(res, "xaCreateEngine"); |
|
71 |
|
72 /* Realizing the XA Engine in synchronous mode. */ |
|
73 res = (*m_engine)->Realize(m_engine, XA_BOOLEAN_FALSE); |
|
74 CheckErr(res, "Realize(engine)"); |
|
75 |
|
76 /* Get the XA Engine Interface which is implicit */ |
|
77 res = (*m_engine)->GetInterface(m_engine, XA_IID_ENGINE, (void**) &m_EngineItf); |
|
78 CheckErr(res, "GetInterface(engine)"); |
|
79 |
|
80 /* Initialize arrays required[] and iidArray[] */ |
|
81 for (i = 0; i < MAX_NUMBER_INTERFACES; i++) |
|
82 { |
|
83 m_required[i] = XA_BOOLEAN_FALSE; |
|
84 m_iidArray[i] = XA_IID_NULL; |
|
85 } |
|
86 |
|
87 /* Set arrays required[] and iidArray[] for VOLUME and EQUALIZER interfaces */ |
|
88 m_required[0] = XA_BOOLEAN_TRUE; |
|
89 m_iidArray[0] = XA_IID_VOLUME; |
|
90 m_required[1] = XA_BOOLEAN_TRUE; |
|
91 m_iidArray[1] = XA_IID_EQUALIZER; |
|
92 |
|
93 /* Create Output Mix object to be used by player */ |
|
94 res = (*m_EngineItf)->CreateOutputMix(m_EngineItf, &m_outputMix, 2, m_iidArray, m_required); |
|
95 CheckErr(res, "CreateOutputMix"); |
|
96 |
|
97 /* Realizing the Output Mix object in synchronous mode. */ |
|
98 res = (*m_outputMix)->Realize(m_outputMix, XA_BOOLEAN_FALSE); |
|
99 CheckErr(res, "Realize(outputMix)"); |
|
100 |
|
101 /* Get volume and equalizer interfaces */ |
|
102 res = (*m_outputMix)->GetInterface(m_outputMix, XA_IID_VOLUME, (void**) &m_volumeItf); |
|
103 CheckErr(res, "GetInterface(volume)"); |
|
104 res = (*m_outputMix)->GetInterface(m_outputMix, XA_IID_EQUALIZER, (void**) &m_equalizerItf); |
|
105 CheckErr(res, "GetInterface(equalizer)"); |
|
106 |
|
107 // Setup the audio sink structure |
|
108 m_locator_outputmix.locatorType = XA_DATALOCATOR_OUTPUTMIX; |
|
109 m_locator_outputmix.outputMix = m_outputMix; |
|
110 m_audioSink.pLocator = (void*) &m_locator_outputmix; |
|
111 m_audioSink.pFormat = NULL; |
|
112 |
|
113 /* Set arrays required[] and iidArray[] for no interfaces (PlayItf is implicit) */ |
|
114 m_required[0] = XA_BOOLEAN_TRUE; |
|
115 m_iidArray[0] = XA_IID_DYNAMICSOURCE; |
|
116 m_required[1] = XA_BOOLEAN_FALSE; |
|
117 m_iidArray[1] = XA_IID_NULL; |
|
118 |
|
119 // Setup the video sink structure |
|
120 // Set nativeWindowHandle and nativeDisplayHandle to platform specific values |
|
121 XANativeHandle nativeWindowHandle = NULL; |
|
122 XANativeHandle nativeDisplayHandle = NULL; |
|
123 |
|
124 m_locator_displayregion.locatorType = XA_DATALOCATOR_NATIVEDISPLAY; |
|
125 m_locator_displayregion.hDisplay = nativeDisplayHandle; |
|
126 m_locator_displayregion.hWindow = nativeWindowHandle; |
|
127 m_videoSink.pLocator = (void*) &m_locator_displayregion; |
|
128 m_videoSink.pFormat = NULL; |
|
129 |
|
130 /* Before we start set volume to -3dB (-300mB) and enable equalizer */ |
|
131 XAmillibel minVol = m_nVolume = XA_MILLIBEL_MIN; |
|
132 XAmillibel maxVol = 0; |
|
133 res = (*m_volumeItf)->GetMaxVolumeLevel (m_volumeItf, &maxVol); |
|
134 CheckErr(res, "GetMaxVolumeLevel"); |
|
135 |
|
136 // before Play, set volume |
|
137 res = (*m_volumeItf)->SetVolumeLevel(m_volumeItf, minVol); |
|
138 CheckErr(res, "SetVolumeLevel"); |
|
139 } |
|
140 |
|
141 void COpenMaxPlayerUtility::DestroyPlayer () |
|
142 { |
|
143 XAresult res; |
|
144 XAuint32 playState; |
|
145 /* Stop the music */ |
|
146 res = (*m_playItf)->GetPlayState(m_playItf, &playState); |
|
147 CheckErr(res, "GetPlayState"); |
|
148 |
|
149 if ( playState != XA_PLAYSTATE_STOPPED ) |
|
150 { |
|
151 res = (*m_playItf)->SetPlayState(m_playItf, XA_PLAYSTATE_STOPPED); |
|
152 CheckErr(res, "SetPlayState(stopped)"); |
|
153 } |
|
154 |
|
155 // Destroy the player caused app to crash |
|
156 // (*player)->Destroy(player); |
|
157 } |
|
158 |
|
159 /* |
|
160 * Called when the display is repainted. |
|
161 */ |
|
162 void COpenMaxPlayerUtility::DrawEQDisplay (void) |
|
163 { |
|
164 XAuint16 numBands; |
|
165 XAmillibel bandLevel; |
|
166 XAmillibel minLevel; |
|
167 XAmillibel maxLevel; |
|
168 XAmilliHertz minFreq; |
|
169 XAmilliHertz maxFreq; |
|
170 int band; |
|
171 XAresult res; |
|
172 res = (*m_equalizerItf)->GetNumberOfBands(m_equalizerItf, &numBands); |
|
173 CheckErr(res, "GetNumberOfBands(equalizerItf)"); |
|
174 res = (*m_equalizerItf)->GetBandLevelRange(m_equalizerItf, &minLevel, &maxLevel); |
|
175 CheckErr(res, "GetBandLevelRange(equalizerItf)"); |
|
176 for (band = 0; band<numBands; band++) |
|
177 { |
|
178 res = (*m_equalizerItf)->GetBandFreqRange(m_equalizerItf, (XAint16) band, &minFreq, &maxFreq); |
|
179 CheckErr(res, "GetBandFreqRange(equalizerItf)"); |
|
180 res = (*m_equalizerItf)->GetBandLevel(m_equalizerItf, (XAint16)band, &bandLevel); |
|
181 CheckErr(res, "GetBandLevel(equalizerItf)"); |
|
182 // drawEQBand(minFreq, maxFreq, bandLevel); |
|
183 } |
|
184 } |
|
185 |
|
186 void COpenMaxPlayerUtility::VideoFrameSize(TSize& /*aSize*/) const |
|
187 { |
|
188 } |
|
189 |
|
190 TTimeIntervalMicroSeconds COpenMaxPlayerUtility::Position() const |
|
191 { |
|
192 return 0; |
|
193 } |
|
194 |
|
195 TTimeIntervalMicroSeconds COpenMaxPlayerUtility::Duration() const |
|
196 { |
|
197 return 0; |
|
198 } |
|
199 |
|
200 TInt COpenMaxPlayerUtility::Volume() const |
|
201 { |
|
202 return m_nVolume; |
|
203 } |
|
204 |
|
205 TInt COpenMaxPlayerUtility::MaxVolume() const |
|
206 { |
|
207 return m_nVolume; |
|
208 } |
|
209 |
|
210 TInt COpenMaxPlayerUtility::Balance()const |
|
211 { |
|
212 return 0; |
|
213 } |
|
214 |
|
215 TVideoRotation COpenMaxPlayerUtility::Rotation() const |
|
216 { |
|
217 return EVideoRotationNone; |
|
218 } |
|
219 |
|
220 void COpenMaxPlayerUtility::SetVolume(TInt aVolume) |
|
221 { |
|
222 m_nVolume = aVolume; |
|
223 XAresult res = (*m_volumeItf)->SetVolumeLevel(m_volumeItf, (XAmillibel)m_nVolume); |
|
224 CheckErr(res, "SetVolumeL"); |
|
225 } |
|
226 |
|
227 void COpenMaxPlayerUtility::SetBalance(TInt /*aBalance*/) |
|
228 { |
|
229 } |
|
230 |
|
231 void COpenMaxPlayerUtility::SetPosition(const TTimeIntervalMicroSeconds& /*aPosition*/) |
|
232 { |
|
233 |
|
234 } |
|
235 |
|
236 void COpenMaxPlayerUtility::SetRotation(const RWindow& /*aWindow*/, TVideoRotation /*aRotation*/) |
|
237 { |
|
238 |
|
239 } |
|
240 |
|
241 void COpenMaxPlayerUtility::SetScaleFactor(const RWindow& /*aWindow*/, TReal32 /*aWidthPercentage*/, |
|
242 TReal32 /*aHeightPercentage*/) |
|
243 { |
|
244 |
|
245 } |
|
246 |
|
247 void COpenMaxPlayerUtility::SetAutoScale(const RWindow& /*aWindow*/, TAutoScaleType /*aScaleType*/) |
|
248 { |
|
249 |
|
250 } |
|
251 |
|
252 void COpenMaxPlayerUtility::StepFrame(TInt /*aStep*/) |
|
253 { |
|
254 |
|
255 } |
|
256 |
|
257 void COpenMaxPlayerUtility::OpenFile(const TDesC& aFileName, TUid /*aControllerUid*/) |
|
258 { |
|
259 const TUint16 *pFile = aFileName.Ptr(); |
|
260 TInt len = aFileName.Length(); |
|
261 |
|
262 if (pFile) |
|
263 { |
|
264 strcpy((char*)m_sourceName, FILE_EXTN); |
|
265 len = wcstombs((char*)&m_sourceName[FILE_EXTN_LEN], (const wchar_t *)pFile, len); |
|
266 m_sourceName[FILE_EXTN_LEN + len] = '\0'; |
|
267 uri.locatorType = XA_DATALOCATOR_URI; |
|
268 uri.URI = (XAchar*) m_sourceName; |
|
269 m_mime.formatType = XA_DATAFORMAT_MIME; |
|
270 m_mime.mimeType = (XAchar *) "audio/ra"; |
|
271 |
|
272 //Do we need this here? |
|
273 PlaySource (uri); |
|
274 } |
|
275 } |
|
276 |
|
277 void COpenMaxPlayerUtility::OpenUrl(const TDesC& /*aUrl*/) |
|
278 { |
|
279 |
|
280 } |
|
281 |
|
282 void COpenMaxPlayerUtility::Prepare() |
|
283 { |
|
284 |
|
285 } |
|
286 |
|
287 void COpenMaxPlayerUtility::Close() |
|
288 { |
|
289 |
|
290 } |
|
291 |
|
292 void COpenMaxPlayerUtility::Pause() |
|
293 { |
|
294 XAresult res; |
|
295 res = (*m_playItf)->SetPlayState(m_playItf, XA_PLAYSTATE_PAUSED); |
|
296 CheckErr(res, "SetPlayState(paused)"); |
|
297 } |
|
298 |
|
299 void COpenMaxPlayerUtility::Play() |
|
300 { |
|
301 XAresult res; |
|
302 res = (*m_playItf)->SetPlayState(m_playItf, XA_PLAYSTATE_PLAYING); |
|
303 CheckErr(res, "SetPlayState(playing)"); |
|
304 } |
|
305 |
|
306 TInt COpenMaxPlayerUtility::Stop() |
|
307 { |
|
308 DestroyPlayer(); |
|
309 return 0; |
|
310 } |
|
311 |
|
312 void COpenMaxPlayerUtility::AddDisplayWindow(RWsSession& aWs, CWsScreenDevice& /*aScreenDevice*/, RWindow& aWindow) |
|
313 { |
|
314 m_locator_displayregion.hDisplay = &aWs; //pointer to RWsSession |
|
315 m_locator_displayregion.hWindow = &aWindow; //pointer to RWindow |
|
316 } |
|
317 |
|
318 void COpenMaxPlayerUtility::SetWindowClipRect(const RWindow& /*aWindow*/, const TRect& /*aWindowClipRect*/) |
|
319 { |
|
320 |
|
321 } |
|
322 |
|
323 void COpenMaxPlayerUtility::SetVideoExtent(const RWindow& /*aWindow*/, const TRect& /*aVideoExtent*/) |
|
324 { |
|
325 |
|
326 } |
|
327 |
|
328 /* Checks for error. If any errors exit the application! */ |
|
329 bool COpenMaxPlayerUtility::CheckErr (XAresult res, char* /*aMsg*/) |
|
330 { |
|
331 return (res == XA_RESULT_SUCCESS); |
|
332 } |
|
333 |
|
334 |
|
335 /* |
|
336 * Called by UI when user increases or decreases a band level. |
|
337 */ |
|
338 void COpenMaxPlayerUtility::SetBandLevel(XAint16 band, XAboolean increase) |
|
339 { |
|
340 XAuint16 numBands; |
|
341 XAmillibel bandLevel; |
|
342 XAmillibel minLevel; |
|
343 XAmillibel maxLevel; |
|
344 XAresult res; |
|
345 |
|
346 res = (*m_equalizerItf)->GetNumberOfBands(m_equalizerItf, &numBands); |
|
347 CheckErr(res, "GetNumberOfBands"); |
|
348 |
|
349 res = (*m_equalizerItf)->GetBandLevelRange(m_equalizerItf, &minLevel, &maxLevel); |
|
350 CheckErr(res, "GetBandLevelRange"); |
|
351 if (band >= numBands) |
|
352 { |
|
353 /* Error. Insert debug print here. */ |
|
354 exit(0); |
|
355 } |
|
356 |
|
357 res = (*m_equalizerItf)->GetBandLevel(m_equalizerItf, band, &bandLevel); |
|
358 CheckErr(res, "GetBandLevel"); |
|
359 |
|
360 if (increase==XA_BOOLEAN_TRUE) |
|
361 { |
|
362 /* increase the level by 1 dB (100mB) if the max supported level |
|
363 * is not exceeded */ |
|
364 bandLevel = bandLevel + 100; |
|
365 if(bandLevel < maxLevel) |
|
366 { |
|
367 res = (*m_equalizerItf)->SetBandLevel(m_equalizerItf, band, bandLevel); |
|
368 CheckErr(res); |
|
369 DrawEQDisplay(); |
|
370 } |
|
371 } |
|
372 else /* increase==false */ |
|
373 { |
|
374 /* decrease the level by 1 dB (100mB) if the min supported level |
|
375 * is not crossed */ |
|
376 bandLevel = bandLevel - 100; |
|
377 if( bandLevel > minLevel ) |
|
378 { |
|
379 res = (*m_equalizerItf)->SetBandLevel(m_equalizerItf, band, bandLevel); |
|
380 CheckErr(res); |
|
381 DrawEQDisplay(); |
|
382 } |
|
383 } |
|
384 } |
|
385 |
|
386 void COpenMaxPlayerUtility::PlaySource(const XADataLocator_URI &source) |
|
387 { |
|
388 m_dataSource.pLocator = (void*) &source; |
|
389 m_dataSource.pFormat = (void*) &m_mime; |
|
390 |
|
391 // Create the music player // |
|
392 XAresult res; |
|
393 res = (*m_EngineItf)->CreateMediaPlayer ( m_EngineItf, &player, &m_dataSource, NULL, &m_audioSink, |
|
394 &m_videoSink, NULL, NULL, 1, m_iidArray, m_required); |
|
395 CheckErr(res, "CreateMediaPlayer"); |
|
396 |
|
397 // Realizing the player in synchronous mode. |
|
398 res = (*player)->Realize(player, XA_BOOLEAN_FALSE); |
|
399 CheckErr(res, "Realize(player)"); |
|
400 |
|
401 // Get the play interface |
|
402 res = (*player)->GetInterface(player, XA_IID_PLAY, (void**) &m_playItf); |
|
403 CheckErr(res, "GetInterface(player)"); |
|
404 |
|
405 /* XADynamicSourceItf sourceItf; |
|
406 res = (*player)->GetInterface(player, XA_IID_DYNAMICSOURCE, (void**) &sourceItf); |
|
407 CheckErr(res, "GetDynamicSource"); |
|
408 |
|
409 res = (*sourceItf)->SetSource (sourceItf, &m_dataSource); |
|
410 CheckErr(res, "SetSource"); |
|
411 */ |
|
412 // before Play, set volume |
|
413 res = (*m_volumeItf)->SetVolumeLevel(m_volumeItf, m_nVolume); |
|
414 CheckErr(res, "SetVolumeLevel"); |
|
415 |
|
416 XAmillisecond playDuration = 0; |
|
417 res = (*m_playItf)->GetDuration(m_playItf, &playDuration); |
|
418 bool b = CheckErr(res, "GetDuration"); |
|
419 //if ( b && (playDuration != XA_DURATION_UNKNOWN) ) |
|
420 //SetDurationL ((playDuration/1000)); |
|
421 |
|
422 res = (*m_playItf)->SetCallbackEventsMask(m_playItf, XA_PLAYEVENT_HEADATEND | XA_PLAYEVENT_HEADMOVING); |
|
423 CheckErr(res, "SetCallbackEventsMask"); |
|
424 |
|
425 res = (*m_playItf)->RegisterCallback(m_playItf, PlayCallbackFun, this); |
|
426 CheckErr(res, "RegisterCallback"); |
|
427 //Do we need this here? |
|
428 Play(); |
|
429 } |
|
430 |
|
431 void COpenMaxPlayerUtility::PlayPause(bool bChecked) |
|
432 { |
|
433 if (bChecked) |
|
434 { |
|
435 Pause(); |
|
436 } |
|
437 else |
|
438 { |
|
439 Play(); |
|
440 } |
|
441 } |
|
442 |
|
443 void COpenMaxPlayerUtility::MuteChanged(bool bChecked) |
|
444 { |
|
445 XAresult res = (*m_volumeItf)->SetMute(m_volumeItf, (XAboolean)bChecked); |
|
446 CheckErr(res, "MuteChanged"); |
|
447 } |
|
448 |
|
449 TInt COpenMaxPlayerUtility::SetPlayVelocity( TInt aVelocity ) |
|
450 { |
|
451 m_Velocity = aVelocity; |
|
452 return 0; |
|
453 } |