|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "xarecordsessionimpl.h" |
|
43 #include "xarecordsessioncommon.h" |
|
44 |
|
45 _LIT8(K8WAVMIMETYPE, "audio/x-wav"); |
|
46 |
|
47 /* |
|
48 * These codec names are not part of AL. Hence we need to define names here. |
|
49 * */ |
|
50 _LIT(KAUDIOCODECPCM, "pcm"); |
|
51 _LIT(KAUDIOCODECAMR, "amr"); |
|
52 _LIT(KAUDIOCODECAAC, "aac"); |
|
53 |
|
54 _LIT(KCONTAINERWAV, "wav"); |
|
55 _LIT(KCONTAINERWAVDESC, "wav container"); |
|
56 _LIT(KCONTAINERAMR, "amr-nb"); |
|
57 _LIT(KCONTAINERAMRDESC, "amr-nb File format"); |
|
58 _LIT(KCONTAINERMP4, "mp4"); |
|
59 _LIT(KCONTAINERMP4DESC, "mp4 container"); |
|
60 |
|
61 const TUint KRecordPosUpdatePeriod = 1000; |
|
62 const TUint KMilliToHz = 1000; |
|
63 const TUint KMaxNameLength = 256; |
|
64 |
|
65 |
|
66 /* Local functions for callback registation */ |
|
67 void cbXAObjectItf( |
|
68 XAObjectItf caller, |
|
69 const void *pContext, |
|
70 XAuint32 event, |
|
71 XAresult result, |
|
72 XAuint32 param, |
|
73 void *pInterface); |
|
74 |
|
75 void cbXARecordItf( |
|
76 XARecordItf caller, |
|
77 void *pContext, |
|
78 XAuint32 event); |
|
79 |
|
80 void cbXAAvailableAudioInputsChanged( |
|
81 XAAudioIODeviceCapabilitiesItf caller, |
|
82 void *pContext, |
|
83 XAuint32 deviceID, |
|
84 XAint32 numInputs, |
|
85 XAboolean isNew); |
|
86 |
|
87 XARecordSessionImpl::XARecordSessionImpl(XARecordObserver &parent) |
|
88 :m_Parent(parent), |
|
89 m_EOEngine(NULL), |
|
90 m_MORecorder(NULL), |
|
91 m_RecordItf(NULL), |
|
92 m_AudioEncItf(NULL), |
|
93 m_WAVMime(NULL), |
|
94 m_URIName(NULL), |
|
95 m_InputDeviceId(0), |
|
96 m_ContainerType(0), |
|
97 m_BitRate(0), |
|
98 m_RateControl(0), |
|
99 m_ChannelsOut(0), |
|
100 m_SampleRate(0), |
|
101 m_AudioIODevCapsItf(NULL), |
|
102 m_AudioInputDeviceNames(NULL), |
|
103 m_DefaultAudioInputDeviceNames(NULL), |
|
104 m_AudioEncCapsItf(NULL) |
|
105 { |
|
106 TRACE_FUNCTION_ENTRY_EXIT; |
|
107 } |
|
108 |
|
109 XARecordSessionImpl::~XARecordSessionImpl() |
|
110 { |
|
111 TRACE_FUNCTION_ENTRY; |
|
112 |
|
113 if (m_MORecorder) |
|
114 (*m_MORecorder)->Destroy(m_MORecorder); |
|
115 |
|
116 if (m_EOEngine) |
|
117 (*m_EOEngine)->Destroy(m_EOEngine); |
|
118 |
|
119 delete m_WAVMime; |
|
120 delete m_URIName; |
|
121 |
|
122 m_InputDeviceIDs.Close(); |
|
123 if (m_AudioInputDeviceNames) |
|
124 m_AudioInputDeviceNames->Reset(); |
|
125 delete m_AudioInputDeviceNames; |
|
126 m_DefaultInputDeviceIDs.Close(); |
|
127 if (m_DefaultAudioInputDeviceNames) |
|
128 m_DefaultAudioInputDeviceNames->Reset(); |
|
129 delete m_DefaultAudioInputDeviceNames; |
|
130 m_EncoderIds.Close(); |
|
131 m_EncoderNames.Close(); |
|
132 m_ContainerNames.Close(); |
|
133 m_ContainerDescs.Close(); |
|
134 |
|
135 TRACE_FUNCTION_EXIT; |
|
136 } |
|
137 |
|
138 TInt32 XARecordSessionImpl::postConstruct() |
|
139 { |
|
140 TRACE_FUNCTION_ENTRY; |
|
141 |
|
142 XAEngineOption engineOption[] = { (XAuint32) XA_ENGINEOPTION_THREADSAFE, (XAuint32) XA_BOOLEAN_TRUE}; |
|
143 |
|
144 /* Create and realize Engine object */ |
|
145 TRACE_LOG(_L("XARecordSessionImpl: Creating Engine...")); |
|
146 XAresult xa_result = xaCreateEngine (&m_EOEngine, 1, engineOption, 0, NULL, NULL); |
|
147 TInt returnValue = mapError(xa_result, ETrue); |
|
148 RET_ERR_IF_ERR(returnValue); |
|
149 TRACE_LOG(_L("XARecordSessionImpl: Realizing engine...")); |
|
150 xa_result = (*m_EOEngine)->Realize(m_EOEngine, XA_BOOLEAN_FALSE); |
|
151 returnValue = mapError(xa_result, ETrue); |
|
152 RET_ERR_IF_ERR(returnValue); |
|
153 TRACE_LOG(_L("XARecordSessionImpl: OMX AL Engine realized successfully")); |
|
154 |
|
155 XAEngineItf engineItf; |
|
156 xa_result = (*m_EOEngine)->GetInterface(m_EOEngine, XA_IID_ENGINE, (void**) &engineItf); |
|
157 returnValue = mapError(xa_result, ETrue); |
|
158 RET_ERR_IF_ERR(returnValue); |
|
159 |
|
160 xa_result = (*m_EOEngine)->GetInterface(m_EOEngine, |
|
161 XA_IID_AUDIOIODEVICECAPABILITIES, |
|
162 (void**) &m_AudioIODevCapsItf); |
|
163 returnValue = mapError(xa_result, ETrue); |
|
164 RET_ERR_IF_ERR(returnValue); |
|
165 xa_result = (*m_AudioIODevCapsItf)->RegisterAvailableAudioInputsChangedCallback( |
|
166 m_AudioIODevCapsItf, |
|
167 cbXAAvailableAudioInputsChanged, |
|
168 (void*)this); |
|
169 |
|
170 xa_result = (*m_EOEngine)->GetInterface( |
|
171 m_EOEngine, |
|
172 XA_IID_AUDIOENCODERCAPABILITIES, |
|
173 (void**) &m_AudioEncCapsItf); |
|
174 returnValue = mapError(xa_result, ETrue); |
|
175 RET_ERR_IF_ERR(returnValue); |
|
176 |
|
177 TRAP(returnValue, m_WAVMime = HBufC8::NewL(K8WAVMIMETYPE().Length() + 1)); |
|
178 RET_ERR_IF_ERR(returnValue); |
|
179 TPtr8 ptr = m_WAVMime->Des(); |
|
180 ptr = K8WAVMIMETYPE(); // copy uri name into local variable |
|
181 ptr.PtrZ(); // append zero terminator to end of URI |
|
182 |
|
183 m_AudioInputDeviceNames = new CDesC16ArrayFlat(2); |
|
184 if (m_AudioInputDeviceNames == NULL) |
|
185 returnValue = KErrNoMemory; |
|
186 RET_ERR_IF_ERR(returnValue); |
|
187 |
|
188 m_DefaultAudioInputDeviceNames = new CDesC16ArrayFlat(2); |
|
189 if (m_DefaultAudioInputDeviceNames == NULL) |
|
190 returnValue = KErrNoMemory; |
|
191 RET_ERR_IF_ERR(returnValue); |
|
192 |
|
193 returnValue = initContainersList(); |
|
194 RET_ERR_IF_ERR(returnValue); |
|
195 returnValue = initAudioEncodersList(); |
|
196 RET_ERR_IF_ERR(returnValue); |
|
197 returnValue = initAudioInputDevicesList(); |
|
198 RET_ERR_IF_ERR(returnValue); |
|
199 |
|
200 TRACE_FUNCTION_EXIT; |
|
201 return returnValue; |
|
202 } |
|
203 |
|
204 TInt32 XARecordSessionImpl::setURI(const TDesC &aURI) |
|
205 { |
|
206 TRACE_FUNCTION_ENTRY; |
|
207 |
|
208 /* This function will only get called when aURI is different than m_URIName |
|
209 * and only when recorder is in stopped state. |
|
210 * If the recorder object was created for a different URI (than aURI), we |
|
211 * need to tear it down here. |
|
212 */ |
|
213 if (!m_URIName && m_MORecorder) { |
|
214 (*m_MORecorder)->Destroy(m_MORecorder); |
|
215 m_MORecorder = NULL; |
|
216 m_RecordItf = NULL; |
|
217 } |
|
218 |
|
219 delete m_URIName; |
|
220 m_URIName = NULL; |
|
221 TRAPD(returnValue, m_URIName = HBufC8::NewL(aURI.Length()+1)); |
|
222 RET_ERR_IF_ERR(returnValue); |
|
223 |
|
224 TPtr8 uriPtr = m_URIName->Des(); |
|
225 /* copy uri name into local variable */ |
|
226 uriPtr.Copy(aURI); |
|
227 |
|
228 TRACE_FUNCTION_EXIT; |
|
229 return returnValue; |
|
230 } |
|
231 |
|
232 TInt32 XARecordSessionImpl::record() |
|
233 { |
|
234 TRACE_FUNCTION_ENTRY; |
|
235 |
|
236 TInt32 returnValue(KErrGeneral); |
|
237 if (!m_MORecorder || !m_RecordItf) { |
|
238 TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created")); |
|
239 returnValue = createMediaRecorderObject(); |
|
240 RET_ERR_IF_ERR(returnValue); |
|
241 } |
|
242 |
|
243 returnValue = setEncoderSettingsToMediaRecorder(); |
|
244 RET_ERR_IF_ERR(returnValue); |
|
245 |
|
246 XAuint32 state; |
|
247 XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state); |
|
248 returnValue = mapError(xa_result, ETrue); |
|
249 RET_ERR_IF_ERR(returnValue); |
|
250 |
|
251 if ((state == XA_RECORDSTATE_STOPPED) |
|
252 || (state == XA_RECORDSTATE_PAUSED)) { |
|
253 TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Recording...")); |
|
254 xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_RECORDING); |
|
255 returnValue = mapError(xa_result, ETrue); |
|
256 RET_ERR_IF_ERR(returnValue); |
|
257 TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Recording")); |
|
258 } |
|
259 |
|
260 TRACE_FUNCTION_EXIT; |
|
261 return returnValue; |
|
262 } |
|
263 |
|
264 TInt32 XARecordSessionImpl::pause() |
|
265 { |
|
266 TRACE_FUNCTION_ENTRY; |
|
267 |
|
268 TInt32 returnValue(KErrGeneral); |
|
269 if (!m_MORecorder || !m_RecordItf) { |
|
270 TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created")); |
|
271 return returnValue; |
|
272 } |
|
273 |
|
274 XAuint32 state; |
|
275 XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state); |
|
276 returnValue = mapError(xa_result, ETrue); |
|
277 RET_ERR_IF_ERR(returnValue); |
|
278 |
|
279 if ((state == XA_RECORDSTATE_STOPPED) |
|
280 || (state == XA_RECORDSTATE_RECORDING)) { |
|
281 TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Paused...")); |
|
282 xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_PAUSED); |
|
283 returnValue = mapError(xa_result, ETrue); |
|
284 RET_ERR_IF_ERR(returnValue); |
|
285 TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Paused")); |
|
286 } |
|
287 |
|
288 TRACE_FUNCTION_EXIT; |
|
289 return returnValue; |
|
290 } |
|
291 |
|
292 TInt32 XARecordSessionImpl::stop() |
|
293 { |
|
294 TRACE_FUNCTION_ENTRY; |
|
295 |
|
296 TInt32 returnValue(KErrGeneral); |
|
297 if (!m_MORecorder || !m_RecordItf) { |
|
298 TRACE_LOG(_L("XARecordSessionImpl::Record: MORecorder/RecordItf is not created")); |
|
299 return returnValue; |
|
300 } |
|
301 |
|
302 XAuint32 state; |
|
303 XAresult xa_result = (*m_RecordItf)->GetRecordState(m_RecordItf, &state); |
|
304 returnValue = mapError(xa_result, ETrue); |
|
305 RET_ERR_IF_ERR(returnValue); |
|
306 |
|
307 if ((state == XA_RECORDSTATE_PAUSED) |
|
308 || (state == XA_RECORDSTATE_RECORDING)) { |
|
309 TRACE_LOG(_L("XARecordSessionImpl::Record: Setting State to Stopped...")); |
|
310 xa_result = (*m_RecordItf)->SetRecordState(m_RecordItf, XA_RECORDSTATE_STOPPED); |
|
311 returnValue = mapError(xa_result, ETrue); |
|
312 RET_ERR_IF_ERR(returnValue); |
|
313 TRACE_LOG(_L("XARecordSessionImpl::Record: SetState to Stopped")); |
|
314 } |
|
315 |
|
316 TRACE_FUNCTION_EXIT; |
|
317 return returnValue; |
|
318 } |
|
319 |
|
320 TInt32 XARecordSessionImpl::duration(TInt64 &aDur) |
|
321 { |
|
322 TRACE_FUNCTION_ENTRY; |
|
323 |
|
324 TInt32 returnValue(KErrGeneral); |
|
325 |
|
326 if (!m_MORecorder || !m_RecordItf) { |
|
327 TRACE_LOG(_L("XARecordSessionImpl::Duration: MORecoder/RecordItf is not created")); |
|
328 return returnValue; |
|
329 } |
|
330 |
|
331 XAmillisecond milliSec; |
|
332 XAresult xa_result = (*m_RecordItf)->GetPosition(m_RecordItf, &milliSec); |
|
333 returnValue = mapError(xa_result, ETrue); |
|
334 if (returnValue == KErrNone) |
|
335 aDur = (TInt64)milliSec; |
|
336 |
|
337 TRACE_FUNCTION_EXIT; |
|
338 return returnValue; |
|
339 } |
|
340 |
|
341 void XARecordSessionImpl::cbMediaRecorder( |
|
342 XAObjectItf /*caller*/, |
|
343 const void */*pContext*/, |
|
344 XAuint32 event, |
|
345 XAresult result, |
|
346 XAuint32 /*param*/, |
|
347 void */*pInterface*/) |
|
348 { |
|
349 TRACE_FUNCTION_ENTRY; |
|
350 |
|
351 switch (event) { |
|
352 case XA_OBJECT_EVENT_RESOURCES_LOST: |
|
353 m_Parent.cbRecordingStopped(); |
|
354 break; |
|
355 case XA_OBJECT_EVENT_RUNTIME_ERROR: { |
|
356 switch (result) { |
|
357 case XA_RESULT_RESOURCE_LOST: |
|
358 m_Parent.cbRecordingStopped(); |
|
359 break; |
|
360 default: |
|
361 break; |
|
362 }; /* of switch (result) */ |
|
363 } |
|
364 default: |
|
365 break; |
|
366 } /* of switch (event) */ |
|
367 |
|
368 TRACE_FUNCTION_EXIT; |
|
369 } |
|
370 |
|
371 void XARecordSessionImpl::cbRecordItf( |
|
372 XARecordItf /*caller*/, |
|
373 void */*pContext*/, |
|
374 XAuint32 event) |
|
375 { |
|
376 TRACE_FUNCTION_ENTRY; |
|
377 |
|
378 switch(event) { |
|
379 case XA_RECORDEVENT_HEADATLIMIT: |
|
380 TRACE_LOG(_L("XA_RECORDEVENT_HEADATLIMIT")); |
|
381 break; |
|
382 case XA_RECORDEVENT_HEADATMARKER: |
|
383 TRACE_LOG(_L("XA_RECORDEVENT_HEADATMARKER")); |
|
384 break; |
|
385 case XA_RECORDEVENT_HEADATNEWPOS: { |
|
386 TInt32 returnValue; |
|
387 XAresult xa_result; |
|
388 XAmillisecond milliSec; |
|
389 xa_result = (*m_RecordItf)->GetPosition(m_RecordItf, &milliSec); |
|
390 returnValue = mapError(xa_result, ETrue); |
|
391 if (returnValue == KErrNone) |
|
392 m_Parent.cbDurationChanged((TInt64)milliSec); |
|
393 } |
|
394 break; |
|
395 case XA_RECORDEVENT_HEADMOVING: |
|
396 TRACE_LOG(_L("XA_RECORDEVENT_HEADMOVING")); |
|
397 m_Parent.cbRecordingStarted(); |
|
398 break; |
|
399 case XA_RECORDEVENT_HEADSTALLED: |
|
400 TRACE_LOG(_L("XA_RECORDEVENT_HEADSTALLED")); |
|
401 break; |
|
402 case XA_RECORDEVENT_BUFFER_FULL: |
|
403 TRACE_LOG(_L("XA_RECORDEVENT_BUFFER_FULL")); |
|
404 break; |
|
405 default: |
|
406 TRACE_LOG(_L("UNKNOWN RECORDEVENT EVENT")); |
|
407 break; |
|
408 } /* of switch(event) */ |
|
409 |
|
410 TRACE_FUNCTION_EXIT; |
|
411 } |
|
412 |
|
413 /* For QAudioEndpointSelector begin */ |
|
414 void XARecordSessionImpl::getAudioInputDeviceNames(RArray<TPtrC> &aArray) |
|
415 { |
|
416 TRACE_FUNCTION_ENTRY; |
|
417 |
|
418 for(TInt index = 0; index < m_AudioInputDeviceNames->MdcaCount(); index++) |
|
419 aArray.Append(m_AudioInputDeviceNames->MdcaPoint(index)); |
|
420 TRACE_FUNCTION_EXIT; |
|
421 } |
|
422 |
|
423 TInt32 XARecordSessionImpl::defaultAudioInputDevice(TPtrC &endPoint) |
|
424 { |
|
425 TRACE_FUNCTION_ENTRY; |
|
426 |
|
427 TInt32 err(KErrGeneral); |
|
428 if (m_DefaultAudioInputDeviceNames->MdcaCount() >= 0) |
|
429 endPoint.Set(m_DefaultAudioInputDeviceNames->MdcaPoint(0)); |
|
430 |
|
431 TRACE_FUNCTION_EXIT; |
|
432 return err; |
|
433 } |
|
434 |
|
435 TInt32 XARecordSessionImpl::activeAudioInputDevice(TPtrC &endPoint) |
|
436 { |
|
437 TRACE_FUNCTION_ENTRY; |
|
438 |
|
439 TInt32 returnValue(KErrGeneral); |
|
440 TBool found(EFalse); |
|
441 TInt index = 0; |
|
442 for(; index < m_InputDeviceIDs.Count(); index++) { |
|
443 if (m_InputDeviceIDs[index] == m_InputDeviceId) { |
|
444 found = ETrue; |
|
445 break; |
|
446 } |
|
447 } |
|
448 |
|
449 /* Comparing found with ETrue produces linker error */ |
|
450 if (found == true) { |
|
451 endPoint.Set(m_AudioInputDeviceNames->MdcaPoint(index)); |
|
452 returnValue = KErrNone; |
|
453 } |
|
454 |
|
455 TRACE_FUNCTION_EXIT; |
|
456 return returnValue; |
|
457 } |
|
458 |
|
459 TBool XARecordSessionImpl::setAudioInputDevice(const TDesC &aDevice) |
|
460 { |
|
461 TRACE_FUNCTION_ENTRY; |
|
462 |
|
463 /* validate if we can set input device id */ |
|
464 TBool found(EFalse); |
|
465 m_InputDeviceId = 0; |
|
466 TInt index = 0; |
|
467 for(; index < m_AudioInputDeviceNames->MdcaCount(); index++) { |
|
468 if (m_AudioInputDeviceNames->MdcaPoint(index).Compare(aDevice) == 0) { |
|
469 found = ETrue; |
|
470 break; |
|
471 } |
|
472 } |
|
473 if (found == true) { |
|
474 m_InputDeviceId = m_InputDeviceIDs[index]; |
|
475 } |
|
476 |
|
477 TRACE_FUNCTION_EXIT; |
|
478 return found; |
|
479 } |
|
480 |
|
481 void XARecordSessionImpl::cbAvailableAudioInputsChanged( |
|
482 XAAudioIODeviceCapabilitiesItf /*caller*/, |
|
483 void */*pContext*/, |
|
484 XAuint32 deviceID, |
|
485 XAint32 /*numInputs*/, |
|
486 XAboolean isNew) |
|
487 { |
|
488 TRACE_FUNCTION_ENTRY; |
|
489 |
|
490 /* If a new device is added into the system, append it to available input list */ |
|
491 if (isNew == XA_BOOLEAN_TRUE) { |
|
492 XAAudioInputDescriptor audioInputDescriptor; |
|
493 m_InputDeviceIDs.Append(deviceID); |
|
494 |
|
495 XAresult xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities( |
|
496 m_AudioIODevCapsItf, |
|
497 deviceID, |
|
498 &audioInputDescriptor); |
|
499 |
|
500 if ((mapError(xa_result, ETrue)) == KErrNone) { |
|
501 TUint8* inDevNamePtr = audioInputDescriptor.deviceName; |
|
502 TUint8* tempPtr = audioInputDescriptor.deviceName; |
|
503 TInt32 inDevNameLength = 0; |
|
504 while (*tempPtr++) inDevNameLength++; |
|
505 TPtrC8 ptr(inDevNamePtr, inDevNameLength); |
|
506 /* Convert 8 bit to 16 bit */ |
|
507 TBuf16<KMaxNameLength> name; |
|
508 name.Copy(ptr); |
|
509 /* Using TRAP with returnValue results in compiler error */ |
|
510 TRAP_IGNORE(m_AudioInputDeviceNames->AppendL(name)); |
|
511 } |
|
512 } |
|
513 else { |
|
514 /* an available device has been removed from the the system, remove it from |
|
515 * available input list and also default list */ |
|
516 TBool found(EFalse); |
|
517 TInt index = 0; |
|
518 for (; index < m_InputDeviceIDs.Count(); index++) { |
|
519 if (deviceID == m_InputDeviceIDs[index]) { |
|
520 found = ETrue; |
|
521 break; |
|
522 } |
|
523 } |
|
524 if (found == true) { |
|
525 m_InputDeviceIDs.Remove(index); |
|
526 m_AudioInputDeviceNames->Delete(index); |
|
527 } |
|
528 if (deviceID == m_InputDeviceId) |
|
529 m_InputDeviceId = 0; |
|
530 |
|
531 found = EFalse; |
|
532 for (index = 0; index < m_DefaultInputDeviceIDs.Count(); index++) { |
|
533 if (deviceID == m_DefaultInputDeviceIDs[index]) { |
|
534 found = ETrue; |
|
535 break; |
|
536 } |
|
537 } |
|
538 if (found == true) { |
|
539 m_DefaultInputDeviceIDs.Remove(index); |
|
540 m_DefaultAudioInputDeviceNames->Delete(index); |
|
541 } |
|
542 } |
|
543 m_Parent.cbAvailableAudioInputsChanged(); |
|
544 |
|
545 TRACE_FUNCTION_EXIT; |
|
546 } |
|
547 /* For QAudioEndpointSelector end */ |
|
548 |
|
549 /* For QAudioEncoderControl begin */ |
|
550 const RArray<TPtrC>& XARecordSessionImpl::getAudioEncoderNames() |
|
551 { |
|
552 TRACE_FUNCTION_ENTRY_EXIT; |
|
553 return m_EncoderNames; |
|
554 } |
|
555 |
|
556 TInt32 XARecordSessionImpl::getSampleRates( |
|
557 const TDesC& aEncoder, |
|
558 RArray<TInt32> &aSampleRates, |
|
559 TBool &aIsContinuous) |
|
560 { |
|
561 TRACE_FUNCTION_ENTRY; |
|
562 |
|
563 |
|
564 aSampleRates.Reset(); |
|
565 aIsContinuous = EFalse; |
|
566 |
|
567 XAuint32 encoderId = 0; |
|
568 TBool found(EFalse); |
|
569 for (TInt index = 0; index < m_EncoderIds.Count(); index++) { |
|
570 if (m_EncoderNames[index].Compare(aEncoder) == 0) { |
|
571 found = ETrue; |
|
572 encoderId = m_EncoderIds[index]; |
|
573 break; |
|
574 } |
|
575 } |
|
576 |
|
577 TInt32 returnValue(KErrGeneral); |
|
578 if (found == false) |
|
579 return returnValue; |
|
580 |
|
581 XAuint32 numCaps = 0; |
|
582 XAAudioCodecDescriptor codecDesc; |
|
583 XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoderCapabilities( |
|
584 m_AudioEncCapsItf, |
|
585 encoderId, |
|
586 &numCaps, |
|
587 &codecDesc); |
|
588 returnValue = mapError(xa_result, ETrue); |
|
589 RET_ERR_IF_ERR(returnValue); |
|
590 |
|
591 /* TODO What do we do if we have more than one caps?? */ |
|
592 aIsContinuous = codecDesc.isFreqRangeContinuous; |
|
593 if (aIsContinuous) { |
|
594 aSampleRates.Append(codecDesc.minSampleRate / KMilliToHz); |
|
595 aSampleRates.Append(codecDesc.maxSampleRate / KMilliToHz); |
|
596 } |
|
597 else { |
|
598 XAuint32 numSRSupported = codecDesc.numSampleRatesSupported; |
|
599 XAmilliHertz *pSampleRatesSupported(NULL); |
|
600 pSampleRatesSupported = codecDesc.pSampleRatesSupported; |
|
601 for (TInt index = 0; index < numSRSupported; index++) |
|
602 aSampleRates.Append((*(pSampleRatesSupported + index)) / KMilliToHz); |
|
603 } |
|
604 |
|
605 TRACE_FUNCTION_EXIT; |
|
606 return returnValue; |
|
607 } |
|
608 |
|
609 TInt32 XARecordSessionImpl::getBitrates( |
|
610 const TDesC& aEncoder, |
|
611 RArray<TUint32> &aBitrates) |
|
612 { |
|
613 TRACE_FUNCTION_ENTRY; |
|
614 |
|
615 aBitrates.Reset(); |
|
616 |
|
617 XAuint32 encoderId = 0; |
|
618 TBool found(EFalse); |
|
619 for (TInt index = 0; index < m_EncoderIds.Count(); index++) { |
|
620 if (m_EncoderNames[index].Compare(aEncoder) == 0) { |
|
621 found = ETrue; |
|
622 encoderId = m_EncoderIds[index]; |
|
623 break; |
|
624 } |
|
625 } |
|
626 |
|
627 TInt32 returnValue(KErrNotSupported); |
|
628 if (found == false) |
|
629 return returnValue; |
|
630 |
|
631 returnValue = getBitratesByAudioCodecID(encoderId, aBitrates); |
|
632 |
|
633 TRACE_FUNCTION_EXIT; |
|
634 return returnValue; |
|
635 } |
|
636 |
|
637 /* For QAudioEncoderControl end */ |
|
638 |
|
639 /* For QMediaContainerControl begin */ |
|
640 const RArray<TPtrC>& XARecordSessionImpl::getContainerNames() |
|
641 { |
|
642 TRACE_FUNCTION_ENTRY_EXIT; |
|
643 return m_ContainerNames; |
|
644 } |
|
645 |
|
646 const RArray<TPtrC>& XARecordSessionImpl::getContainerDescs() |
|
647 { |
|
648 TRACE_FUNCTION_ENTRY_EXIT; |
|
649 return m_ContainerDescs; |
|
650 } |
|
651 |
|
652 /* For QMediaContainerControl end */ |
|
653 |
|
654 void XARecordSessionImpl::resetEncoderAttributes() |
|
655 { |
|
656 m_ContainerType = 0; |
|
657 m_AudioEncoderId = 0; |
|
658 m_ProfileSetting = 0; |
|
659 m_BitRate = 0; |
|
660 m_ChannelsOut = 0; |
|
661 m_SampleRate = 0; |
|
662 m_RateControl = 0; |
|
663 } |
|
664 |
|
665 void XARecordSessionImpl::setContainerType(const TDesC &aURI) |
|
666 { |
|
667 TRACE_FUNCTION_ENTRY; |
|
668 |
|
669 if (aURI.Compare(KCONTAINERWAV()) == 0) |
|
670 m_ContainerType = XA_CONTAINERTYPE_WAV; |
|
671 else if (aURI.Compare(KCONTAINERAMR()) == 0) |
|
672 m_ContainerType = XA_CONTAINERTYPE_AMR; |
|
673 else if (aURI.Compare(KCONTAINERMP4()) == 0) |
|
674 m_ContainerType = XA_CONTAINERTYPE_MP4; |
|
675 |
|
676 TRACE_FUNCTION_EXIT; |
|
677 } |
|
678 |
|
679 TBool XARecordSessionImpl::setCodec(const TDesC &aCodec) |
|
680 { |
|
681 TRACE_FUNCTION_ENTRY; |
|
682 |
|
683 TBool returnValue(EFalse); |
|
684 if (aCodec.Compare(KAUDIOCODECPCM()) == 0) { |
|
685 m_AudioEncoderId = XA_AUDIOCODEC_PCM; |
|
686 m_ProfileSetting = XA_AUDIOPROFILE_PCM; |
|
687 returnValue = ETrue; |
|
688 } |
|
689 else if (aCodec.Compare(KAUDIOCODECAAC()) == 0) { |
|
690 m_AudioEncoderId = XA_AUDIOCODEC_AAC; |
|
691 m_ProfileSetting = XA_AUDIOPROFILE_AAC_AAC; |
|
692 returnValue = ETrue; |
|
693 } |
|
694 else if (aCodec.Compare(KAUDIOCODECAMR()) == 0) { |
|
695 m_AudioEncoderId = XA_AUDIOCODEC_AMR; |
|
696 m_ProfileSetting = XA_AUDIOPROFILE_AMR; |
|
697 returnValue = ETrue; |
|
698 } |
|
699 |
|
700 TRACE_FUNCTION_EXIT; |
|
701 return returnValue; |
|
702 } |
|
703 |
|
704 void XARecordSessionImpl::setBitRate(TUint32 aBitRate) { |
|
705 TRACE_FUNCTION_ENTRY; |
|
706 m_BitRate = aBitRate; |
|
707 TRACE_FUNCTION_EXIT; |
|
708 } |
|
709 |
|
710 void XARecordSessionImpl::setChannels(TUint32 aChannels) { |
|
711 TRACE_FUNCTION_ENTRY; |
|
712 m_ChannelsOut = aChannels; |
|
713 TRACE_FUNCTION_EXIT; |
|
714 } |
|
715 |
|
716 void XARecordSessionImpl::setOptimalChannelCount() { |
|
717 TRACE_FUNCTION_ENTRY; |
|
718 m_ChannelsOut = 0xffffffff; |
|
719 TRACE_FUNCTION_EXIT; |
|
720 } |
|
721 |
|
722 void XARecordSessionImpl::setSampleRate(TUint32 aSampleRate) { |
|
723 TRACE_FUNCTION_ENTRY; |
|
724 /* convert Hz to MilliHz */ |
|
725 m_SampleRate = aSampleRate * KMilliToHz; |
|
726 TRACE_FUNCTION_EXIT; |
|
727 } |
|
728 |
|
729 void XARecordSessionImpl::setOptimalSampleRate() { |
|
730 TRACE_FUNCTION_ENTRY; |
|
731 m_SampleRate = 0xffffffff; |
|
732 TRACE_FUNCTION_EXIT; |
|
733 } |
|
734 |
|
735 TInt32 XARecordSessionImpl::setCBRMode() |
|
736 { |
|
737 TRACE_FUNCTION_ENTRY; |
|
738 |
|
739 m_RateControl = XA_RATECONTROLMODE_CONSTANTBITRATE; |
|
740 |
|
741 TRACE_FUNCTION_EXIT; |
|
742 return KErrNone; |
|
743 } |
|
744 |
|
745 TInt32 XARecordSessionImpl::setVBRMode() |
|
746 { |
|
747 TRACE_FUNCTION_ENTRY; |
|
748 |
|
749 m_RateControl = XA_RATECONTROLMODE_VARIABLEBITRATE; |
|
750 |
|
751 TRACE_FUNCTION_EXIT; |
|
752 return KErrNone; |
|
753 } |
|
754 |
|
755 void XARecordSessionImpl::setVeryLowQuality() |
|
756 { |
|
757 /* Set to very low quality encoder preset */ |
|
758 RArray<TUint32> bitrates; |
|
759 TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates); |
|
760 if ((res == KErrNone) && (bitrates.Count() > 0) ) { |
|
761 /* Sort the array and pick the lowest bit rate */ |
|
762 bitrates.SortUnsigned(); |
|
763 m_BitRate = bitrates[0]; |
|
764 } |
|
765 } |
|
766 |
|
767 void XARecordSessionImpl::setLowQuality() |
|
768 { |
|
769 /* Set to low quality encoder preset */ |
|
770 RArray<TUint32> bitrates; |
|
771 TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates); |
|
772 if ((res == KErrNone) && (bitrates.Count() > 0)) { |
|
773 /* Sort the array and pick the low quality bit rate */ |
|
774 bitrates.SortUnsigned(); |
|
775 m_BitRate = bitrates[bitrates.Count()*1/4]; |
|
776 } |
|
777 } |
|
778 |
|
779 void XARecordSessionImpl::setNormalQuality() |
|
780 { |
|
781 /* Set to normal quality encoder preset */ |
|
782 RArray<TUint32> bitrates; |
|
783 TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates); |
|
784 if ((res == KErrNone) && (bitrates.Count() > 0)) { |
|
785 /* Sort the array and pick the middle range bit rate */ |
|
786 bitrates.SortUnsigned(); |
|
787 m_BitRate = bitrates[bitrates.Count()/2]; |
|
788 } |
|
789 } |
|
790 |
|
791 void XARecordSessionImpl::setHighQuality() |
|
792 { |
|
793 /* Set to high quality encoder preset */ |
|
794 RArray<TUint32> bitrates; |
|
795 TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates); |
|
796 if ((res == KErrNone) && (bitrates.Count() > 0)) { |
|
797 /* Sort the array and pick the high quality bit rate */ |
|
798 bitrates.SortUnsigned(); |
|
799 m_BitRate = bitrates[bitrates.Count()*3/4]; |
|
800 } |
|
801 } |
|
802 |
|
803 void XARecordSessionImpl::setVeryHighQuality() |
|
804 { |
|
805 /* Set to very high quality encoder preset */ |
|
806 RArray<TUint32> bitrates; |
|
807 TInt res = getBitratesByAudioCodecID(m_AudioEncoderId, bitrates); |
|
808 if ((res == KErrNone) && (bitrates.Count() > 0)) { |
|
809 /* Sort the array and pick the highest bit rate */ |
|
810 bitrates.SortUnsigned(); |
|
811 m_BitRate = bitrates[bitrates.Count()-1]; |
|
812 } |
|
813 } |
|
814 |
|
815 /* Internal function */ |
|
816 TInt32 XARecordSessionImpl::createMediaRecorderObject() |
|
817 { |
|
818 TRACE_FUNCTION_ENTRY; |
|
819 |
|
820 if (!m_EOEngine) |
|
821 return KErrGeneral; |
|
822 |
|
823 TInt32 returnValue(KErrNone); |
|
824 |
|
825 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject")); |
|
826 if (!m_MORecorder && !m_RecordItf) { |
|
827 |
|
828 /* Setup the data source */ |
|
829 m_LocatorMic.locatorType = XA_DATALOCATOR_IODEVICE; |
|
830 m_LocatorMic.deviceType = XA_IODEVICE_AUDIOINPUT; |
|
831 m_LocatorMic.deviceID = m_InputDeviceId; |
|
832 m_LocatorMic.device = NULL; |
|
833 m_DataSource.pLocator = (void*) &m_LocatorMic; |
|
834 m_DataSource.pFormat = NULL; |
|
835 |
|
836 /* Setup the data sink structure */ |
|
837 m_Uri.locatorType = XA_DATALOCATOR_URI; |
|
838 /* append zero terminator to end of URI */ |
|
839 TPtr8 uriPtr = m_URIName->Des(); |
|
840 m_Uri.URI = (XAchar*) uriPtr.PtrZ(); |
|
841 m_Mime.formatType = XA_DATAFORMAT_MIME; |
|
842 m_Mime.containerType = XA_CONTAINERTYPE_WAV; |
|
843 TPtr8 mimeTypePtr(m_WAVMime->Des()); |
|
844 m_Mime.mimeType = (XAchar*)mimeTypePtr.Ptr(); |
|
845 m_DataSink.pLocator = (void*) &m_Uri; |
|
846 m_DataSink.pFormat = (void*) &m_Mime; |
|
847 |
|
848 /* Init arrays required[] and iidArray[] */ |
|
849 XAboolean required[MAX_NUMBER_INTERFACES]; |
|
850 XAInterfaceID iidArray[MAX_NUMBER_INTERFACES]; |
|
851 for (TInt32 i = 0; i < MAX_NUMBER_INTERFACES; i++) { |
|
852 required[i] = XA_BOOLEAN_FALSE; |
|
853 iidArray[i] = XA_IID_NULL; |
|
854 } |
|
855 XAuint32 noOfInterfaces = 0; |
|
856 required[noOfInterfaces] = XA_BOOLEAN_FALSE; |
|
857 iidArray[noOfInterfaces] = XA_IID_RECORD; |
|
858 noOfInterfaces++; |
|
859 required[noOfInterfaces] = XA_BOOLEAN_FALSE; |
|
860 iidArray[noOfInterfaces] = XA_IID_AUDIOENCODER; |
|
861 noOfInterfaces++; |
|
862 |
|
863 XAEngineItf engineItf; |
|
864 XAresult xa_result = (*m_EOEngine)->GetInterface(m_EOEngine, XA_IID_ENGINE, (void**) &engineItf); |
|
865 returnValue = mapError(xa_result, ETrue); |
|
866 RET_ERR_IF_ERR(returnValue); |
|
867 |
|
868 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Create Media Recorder...")); |
|
869 |
|
870 /* Create recorder with NULL for a the image/video source, since this is for audio-only recording */ |
|
871 xa_result = (*engineItf)->CreateMediaRecorder( |
|
872 engineItf, |
|
873 &m_MORecorder, |
|
874 &m_DataSource, |
|
875 NULL, |
|
876 &m_DataSink, |
|
877 noOfInterfaces, |
|
878 iidArray, |
|
879 required); |
|
880 returnValue = mapError(xa_result, ETrue); |
|
881 RET_ERR_IF_ERR(returnValue); |
|
882 |
|
883 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Realize Media Recorder...")); |
|
884 xa_result = (*m_MORecorder)->Realize(m_MORecorder, XA_BOOLEAN_FALSE); |
|
885 returnValue = mapError(xa_result, ETrue); |
|
886 RET_ERR_IF_ERR(returnValue); |
|
887 |
|
888 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Register Callback on recorder...")); |
|
889 xa_result = (*m_MORecorder)->RegisterCallback(m_MORecorder, cbXAObjectItf, (void*)this); |
|
890 returnValue = mapError(xa_result, ETrue); |
|
891 RET_ERR_IF_ERR(returnValue); |
|
892 |
|
893 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Getting Record Interface...")); |
|
894 xa_result = (*m_MORecorder)->GetInterface(m_MORecorder, XA_IID_RECORD, &m_RecordItf); |
|
895 returnValue = mapError(xa_result, ETrue); |
|
896 RET_ERR_IF_ERR(returnValue); |
|
897 |
|
898 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Registering Callback on record Interface...")); |
|
899 xa_result = (*m_RecordItf)->RegisterCallback(m_RecordItf, cbXARecordItf, (void*)this); |
|
900 returnValue = mapError(xa_result, ETrue); |
|
901 RET_ERR_IF_ERR(returnValue); |
|
902 |
|
903 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: SetPositionUpdatePeriod on record Interface...")); |
|
904 xa_result = (*m_RecordItf)->SetPositionUpdatePeriod(m_RecordItf, (XAmillisecond)KRecordPosUpdatePeriod); |
|
905 returnValue = mapError(xa_result, ETrue); |
|
906 RET_ERR_IF_ERR(returnValue); |
|
907 |
|
908 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: SetCallbackEventsMask on record Interface...")); |
|
909 xa_result = (*m_RecordItf)->SetCallbackEventsMask(m_RecordItf, XA_RECORDEVENT_HEADATNEWPOS | |
|
910 XA_RECORDEVENT_HEADMOVING | |
|
911 XA_RECORDEVENT_HEADSTALLED); |
|
912 returnValue = mapError(xa_result, ETrue); |
|
913 RET_ERR_IF_ERR(returnValue); |
|
914 |
|
915 TRACE_LOG(_L("XARecordSessionImpl::CreateMediaRecorderObject: Getting Audio Encoder Interface...")); |
|
916 xa_result = (*m_MORecorder)->GetInterface(m_MORecorder, XA_IID_AUDIOENCODER, &m_AudioEncItf); |
|
917 returnValue = mapError(xa_result, ETrue); |
|
918 RET_ERR_IF_ERR(returnValue); |
|
919 } |
|
920 |
|
921 TRACE_FUNCTION_EXIT; |
|
922 return returnValue; |
|
923 } |
|
924 |
|
925 TInt32 XARecordSessionImpl::mapError(XAresult xa_err, TBool debPrn) |
|
926 { |
|
927 TInt32 returnValue(KErrGeneral); |
|
928 switch(xa_err) { |
|
929 case XA_RESULT_SUCCESS: |
|
930 returnValue = KErrNone; |
|
931 break; |
|
932 case XA_RESULT_PRECONDITIONS_VIOLATED: |
|
933 if (debPrn) |
|
934 TRACE_LOG(_L("XA_RESULT_PRECONDITIONS_VIOLATED")); |
|
935 break; |
|
936 case XA_RESULT_PARAMETER_INVALID: |
|
937 if (debPrn) |
|
938 TRACE_LOG(_L("XA_RESULT_PARAMETER_INVALID")); |
|
939 break; |
|
940 case XA_RESULT_MEMORY_FAILURE: |
|
941 if (debPrn) |
|
942 TRACE_LOG(_L("XA_RESULT_MEMORY_FAILURE")); |
|
943 break; |
|
944 case XA_RESULT_RESOURCE_ERROR: |
|
945 if (debPrn) |
|
946 TRACE_LOG(_L("XA_RESULT_RESOURCE_ERROR")); |
|
947 break; |
|
948 case XA_RESULT_RESOURCE_LOST: |
|
949 if (debPrn) |
|
950 TRACE_LOG(_L("XA_RESULT_RESOURCE_LOST")); |
|
951 break; |
|
952 case XA_RESULT_IO_ERROR: |
|
953 if (debPrn) |
|
954 TRACE_LOG(_L("XA_RESULT_IO_ERROR")); |
|
955 break; |
|
956 case XA_RESULT_BUFFER_INSUFFICIENT: |
|
957 if (debPrn) |
|
958 TRACE_LOG(_L("XA_RESULT_BUFFER_INSUFFICIENT")); |
|
959 break; |
|
960 case XA_RESULT_CONTENT_CORRUPTED: |
|
961 if (debPrn) |
|
962 TRACE_LOG(_L("XA_RESULT_CONTENT_CORRUPTED")); |
|
963 break; |
|
964 case XA_RESULT_CONTENT_UNSUPPORTED: |
|
965 if (debPrn) |
|
966 TRACE_LOG(_L("XA_RESULT_CONTENT_UNSUPPORTED")); |
|
967 break; |
|
968 case XA_RESULT_CONTENT_NOT_FOUND: |
|
969 if (debPrn) |
|
970 TRACE_LOG(_L("XA_RESULT_CONTENT_NOT_FOUND")); |
|
971 break; |
|
972 case XA_RESULT_PERMISSION_DENIED: |
|
973 if (debPrn) |
|
974 TRACE_LOG(_L("XA_RESULT_PERMISSION_DENIED")); |
|
975 break; |
|
976 case XA_RESULT_FEATURE_UNSUPPORTED: |
|
977 if (debPrn) |
|
978 TRACE_LOG(_L("XA_RESULT_FEATURE_UNSUPPORTED")); |
|
979 break; |
|
980 case XA_RESULT_INTERNAL_ERROR: |
|
981 if (debPrn) |
|
982 TRACE_LOG(_L("XA_RESULT_INTERNAL_ERROR")); |
|
983 break; |
|
984 case XA_RESULT_UNKNOWN_ERROR: |
|
985 if (debPrn) |
|
986 TRACE_LOG(_L("XA_RESULT_UNKNOWN_ERROR")); |
|
987 break; |
|
988 case XA_RESULT_OPERATION_ABORTED: |
|
989 if (debPrn) |
|
990 TRACE_LOG(_L("XA_RESULT_OPERATION_ABORTED")); |
|
991 break; |
|
992 case XA_RESULT_CONTROL_LOST: |
|
993 if (debPrn) |
|
994 TRACE_LOG(_L("XA_RESULT_CONTROL_LOST")); |
|
995 break; |
|
996 default: |
|
997 if (debPrn) |
|
998 TRACE_LOG(_L("Unknown Error!!!")); |
|
999 break; |
|
1000 } |
|
1001 return returnValue; |
|
1002 } |
|
1003 |
|
1004 TInt32 XARecordSessionImpl::initContainersList() |
|
1005 { |
|
1006 TRACE_FUNCTION_ENTRY; |
|
1007 |
|
1008 m_ContainerNames.Reset(); |
|
1009 m_ContainerDescs.Reset(); |
|
1010 |
|
1011 m_ContainerNames.Append(KCONTAINERWAV()); |
|
1012 m_ContainerNames.Append(KCONTAINERAMR()); |
|
1013 m_ContainerNames.Append(KCONTAINERMP4()); |
|
1014 |
|
1015 m_ContainerDescs.Append(KCONTAINERWAVDESC()); |
|
1016 m_ContainerDescs.Append(KCONTAINERAMRDESC()); |
|
1017 m_ContainerDescs.Append(KCONTAINERMP4DESC()); |
|
1018 |
|
1019 TRACE_FUNCTION_EXIT; |
|
1020 return KErrNone; |
|
1021 } |
|
1022 |
|
1023 TInt32 XARecordSessionImpl::initAudioEncodersList() |
|
1024 { |
|
1025 TRACE_FUNCTION_ENTRY; |
|
1026 |
|
1027 m_EncoderIds.Reset(); |
|
1028 m_EncoderNames.Reset(); |
|
1029 |
|
1030 XAuint32 encoderIds[MAX_NUMBER_ENCODERS]; |
|
1031 |
|
1032 for(TInt index = 0; index < MAX_NUMBER_ENCODERS; index++) |
|
1033 encoderIds[index] = 0; |
|
1034 |
|
1035 XAuint32 numEncoders = MAX_NUMBER_ENCODERS; |
|
1036 XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoders( |
|
1037 m_AudioEncCapsItf, |
|
1038 &numEncoders, |
|
1039 encoderIds); |
|
1040 TInt32 returnValue = mapError(xa_result, ETrue); |
|
1041 RET_ERR_IF_ERR(returnValue); |
|
1042 |
|
1043 for (TInt index = 0; index < numEncoders; index++) { |
|
1044 m_EncoderIds.Append(encoderIds[index]); |
|
1045 switch (encoderIds[index]) { |
|
1046 case XA_AUDIOCODEC_PCM: |
|
1047 m_EncoderNames.Append(KAUDIOCODECPCM()); |
|
1048 break; |
|
1049 case XA_AUDIOCODEC_AMR: |
|
1050 m_EncoderNames.Append(KAUDIOCODECAMR()); |
|
1051 break; |
|
1052 case XA_AUDIOCODEC_AAC: |
|
1053 m_EncoderNames.Append(KAUDIOCODECAAC()); |
|
1054 break; |
|
1055 default: |
|
1056 break; |
|
1057 }; |
|
1058 } |
|
1059 |
|
1060 TRACE_FUNCTION_EXIT; |
|
1061 return returnValue; |
|
1062 } |
|
1063 |
|
1064 TInt32 XARecordSessionImpl::initAudioInputDevicesList() |
|
1065 { |
|
1066 TRACE_FUNCTION_ENTRY; |
|
1067 |
|
1068 m_InputDeviceIDs.Reset(); |
|
1069 |
|
1070 XAuint32 deviceIds[MAX_NUMBER_INPUT_DEVICES]; |
|
1071 for(TInt index = 0; index < MAX_NUMBER_INPUT_DEVICES; index++) |
|
1072 deviceIds[index] = 0; |
|
1073 |
|
1074 XAint32 numInputs = MAX_NUMBER_INPUT_DEVICES; |
|
1075 XAresult xa_result = (*m_AudioIODevCapsItf)->GetAvailableAudioInputs( |
|
1076 m_AudioIODevCapsItf, |
|
1077 &numInputs, |
|
1078 deviceIds); |
|
1079 TInt32 returnValue = mapError(xa_result, ETrue); |
|
1080 RET_ERR_IF_ERR(returnValue); |
|
1081 |
|
1082 XAAudioInputDescriptor audioInputDescriptor; |
|
1083 for (TInt index = 0; index < numInputs; index++) { |
|
1084 m_InputDeviceIDs.Append(deviceIds[index]); |
|
1085 xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities( |
|
1086 m_AudioIODevCapsItf, |
|
1087 deviceIds[index], |
|
1088 &audioInputDescriptor); |
|
1089 returnValue = mapError(xa_result, ETrue); |
|
1090 if (returnValue != KErrNone) |
|
1091 continue; |
|
1092 |
|
1093 TUint8 * inDevNamePtr = audioInputDescriptor.deviceName; |
|
1094 TUint8 * tempPtr = audioInputDescriptor.deviceName; |
|
1095 TInt32 inDevNameLength = 0; |
|
1096 while (*tempPtr++) inDevNameLength++; |
|
1097 TPtrC8 ptr(inDevNamePtr, inDevNameLength); |
|
1098 /* Convert 8 bit to 16 bit */ |
|
1099 TBuf16<KMaxNameLength> name; |
|
1100 name.Copy(ptr); |
|
1101 /* Using TRAP with returnValue results in compiler error */ |
|
1102 TRAPD(err2, m_AudioInputDeviceNames->AppendL(name)); |
|
1103 returnValue = err2; |
|
1104 RET_ERR_IF_ERR(returnValue); |
|
1105 } |
|
1106 |
|
1107 numInputs = MAX_NUMBER_INPUT_DEVICES; |
|
1108 for(TInt index = 0; index < MAX_NUMBER_INPUT_DEVICES; index++) |
|
1109 deviceIds[index] = 0; |
|
1110 xa_result = (*m_AudioIODevCapsItf)->GetDefaultAudioDevices( |
|
1111 m_AudioIODevCapsItf, |
|
1112 XA_DEFAULTDEVICEID_AUDIOINPUT, |
|
1113 &numInputs, |
|
1114 deviceIds); |
|
1115 returnValue = mapError(xa_result, ETrue); |
|
1116 RET_ERR_IF_ERR(returnValue); |
|
1117 |
|
1118 for (TInt index = 0; index < numInputs; index++) { |
|
1119 m_DefaultInputDeviceIDs.Append(deviceIds[index]); |
|
1120 xa_result = (*m_AudioIODevCapsItf)->QueryAudioInputCapabilities( |
|
1121 m_AudioIODevCapsItf, |
|
1122 deviceIds[index], |
|
1123 &audioInputDescriptor); |
|
1124 returnValue = mapError(xa_result, ETrue); |
|
1125 if (returnValue != KErrNone) |
|
1126 continue; |
|
1127 TUint8* inDevNamePtr = audioInputDescriptor.deviceName; |
|
1128 TUint8* tempPtr = audioInputDescriptor.deviceName; |
|
1129 TInt32 inDevNameLength = 0; |
|
1130 while (*tempPtr++) inDevNameLength++; |
|
1131 TPtrC8 ptr(inDevNamePtr, inDevNameLength); |
|
1132 /* Convert 8 bit to 16 bit */ |
|
1133 TBuf16<KMaxNameLength> name; |
|
1134 name.Copy(ptr); |
|
1135 /* Using TRAP with returnValue results in compiler error */ |
|
1136 TRAPD(err2, m_DefaultAudioInputDeviceNames->AppendL(name)); |
|
1137 returnValue = err2; |
|
1138 RET_ERR_IF_ERR(returnValue); |
|
1139 } |
|
1140 |
|
1141 TRACE_FUNCTION_EXIT; |
|
1142 return returnValue; |
|
1143 } |
|
1144 |
|
1145 TInt32 XARecordSessionImpl::setEncoderSettingsToMediaRecorder() |
|
1146 { |
|
1147 TRACE_FUNCTION_EXIT; |
|
1148 |
|
1149 /* Get current settings */ |
|
1150 XAAudioEncoderSettings settings; |
|
1151 XAresult xa_result = (*m_AudioEncItf)->GetEncoderSettings( |
|
1152 m_AudioEncItf, |
|
1153 &settings); |
|
1154 TInt32 returnValue = mapError(xa_result, ETrue); |
|
1155 |
|
1156 settings.encoderId = m_AudioEncoderId; |
|
1157 if (m_ChannelsOut != 0xffffffff) |
|
1158 settings.channelsOut = m_ChannelsOut; |
|
1159 if (m_SampleRate != 0xffffffff) |
|
1160 settings.sampleRate = m_SampleRate; |
|
1161 if (m_BitRate != 0) |
|
1162 settings.bitRate = m_BitRate; |
|
1163 if (m_RateControl != 0) |
|
1164 settings.rateControl = m_RateControl; |
|
1165 settings.profileSetting = m_ProfileSetting; |
|
1166 xa_result = (*m_AudioEncItf)->SetEncoderSettings( |
|
1167 m_AudioEncItf, |
|
1168 &settings); |
|
1169 returnValue = mapError(xa_result, ETrue); |
|
1170 |
|
1171 TRACE_FUNCTION_EXIT; |
|
1172 return returnValue; |
|
1173 } |
|
1174 |
|
1175 TInt32 XARecordSessionImpl::getBitratesByAudioCodecID( |
|
1176 XAuint32 encoderId, |
|
1177 RArray<TUint32> &aBitrates) |
|
1178 { |
|
1179 TRACE_FUNCTION_ENTRY; |
|
1180 |
|
1181 if (!m_AudioEncCapsItf) |
|
1182 return KErrGeneral; |
|
1183 |
|
1184 XAuint32 numCaps = 0; |
|
1185 XAAudioCodecDescriptor codecDesc; |
|
1186 XAresult xa_result = (*m_AudioEncCapsItf)->GetAudioEncoderCapabilities( |
|
1187 m_AudioEncCapsItf, |
|
1188 encoderId, |
|
1189 &numCaps, |
|
1190 &codecDesc); |
|
1191 TInt32 returnValue = mapError(xa_result, ETrue); |
|
1192 RET_ERR_IF_ERR(returnValue); |
|
1193 |
|
1194 /* TODO What do we do if we have more than one caps?? */ |
|
1195 if (codecDesc.isBitrateRangeContinuous == XA_BOOLEAN_TRUE) { |
|
1196 aBitrates.Append(codecDesc.minBitRate); |
|
1197 aBitrates.Append(codecDesc.maxBitRate); |
|
1198 } |
|
1199 else { |
|
1200 XAuint32 numBrSupported = codecDesc.numBitratesSupported; |
|
1201 XAuint32 * pBitratesSupported(NULL); |
|
1202 pBitratesSupported = codecDesc.pBitratesSupported; |
|
1203 TInt32 index = 0; |
|
1204 for (index = 0; index < numBrSupported; index++) |
|
1205 aBitrates.Append(*(pBitratesSupported + index)); |
|
1206 } |
|
1207 |
|
1208 TRACE_FUNCTION_ENTRY; |
|
1209 return returnValue; |
|
1210 } |
|
1211 |
|
1212 /* Local function implementation */ |
|
1213 void cbXAObjectItf( |
|
1214 XAObjectItf caller, |
|
1215 const void *pContext, |
|
1216 XAuint32 event, |
|
1217 XAresult result, |
|
1218 XAuint32 param, |
|
1219 void *pInterface) |
|
1220 { |
|
1221 if (pContext) { |
|
1222 ((XARecordSessionImpl*)pContext)->cbMediaRecorder( |
|
1223 caller, |
|
1224 pContext, |
|
1225 event, |
|
1226 result, |
|
1227 param, |
|
1228 pInterface); |
|
1229 } |
|
1230 } |
|
1231 |
|
1232 void cbXARecordItf( |
|
1233 XARecordItf caller, |
|
1234 void *pContext, |
|
1235 XAuint32 event) |
|
1236 { |
|
1237 if (pContext) { |
|
1238 ((XARecordSessionImpl*)pContext)->cbRecordItf( |
|
1239 caller, |
|
1240 pContext, |
|
1241 event); |
|
1242 } |
|
1243 } |
|
1244 |
|
1245 void cbXAAvailableAudioInputsChanged( |
|
1246 XAAudioIODeviceCapabilitiesItf caller, |
|
1247 void * pContext, |
|
1248 XAuint32 deviceID, |
|
1249 XAint32 numInputs, |
|
1250 XAboolean isNew) |
|
1251 { |
|
1252 if (pContext) { |
|
1253 ((XARecordSessionImpl*)pContext)->cbAvailableAudioInputsChanged( |
|
1254 caller, |
|
1255 pContext, |
|
1256 deviceID, |
|
1257 numInputs, |
|
1258 isNew); |
|
1259 } |
|
1260 } |