|
1 /* |
|
2 * Copyright (c) 2006 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 provides utility functions such as parsing of header |
|
15 * information for VBR type clips. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // INCLUDES |
|
21 #include "AdvancedAudioUtility.h" |
|
22 #include "AdvancedAudioDecoder.h" |
|
23 #include "DebugMacros.h" |
|
24 #include <mmffile.h> |
|
25 #include <mmfcontrollerframeworkbase.h> |
|
26 #include <stdlib.h> // for abs |
|
27 #include <mmfclip.h> |
|
28 |
|
29 // CONSTANTS |
|
30 const TUint64 KMaxScanDuration = 36000000000U; // 10 hours |
|
31 const TUint KSizeOfTagOffset = 6; |
|
32 |
|
33 |
|
34 // ============================ MEMBER FUNCTIONS =============================== |
|
35 |
|
36 // ----------------------------------------------------------------------------- |
|
37 // CAdvancedAudioUtility::CAdvancedAudioUtility |
|
38 // C++ default constructor can NOT contain any code, that |
|
39 // might leave. |
|
40 // ----------------------------------------------------------------------------- |
|
41 // |
|
42 EXPORT_C CAdvancedAudioUtility::CAdvancedAudioUtility() |
|
43 : iPosArr(NULL), |
|
44 iSamplingRate(0), |
|
45 iBitRate(0), |
|
46 iChannels(0), |
|
47 iSamplesPerFrame(0), |
|
48 iScanDuration(0), |
|
49 iScanByteCount(0), |
|
50 iScanInvByteCount(0), |
|
51 iSavedLength(0), |
|
52 iClipSize(0), |
|
53 iHeaderOffset(0), |
|
54 iSyncOffset(0), |
|
55 iNumFrames(0), |
|
56 iSumBitRate(0), |
|
57 iLenMetaData(0) |
|
58 |
|
59 { |
|
60 iObserver = NULL; |
|
61 iFrameTimeMs = 0; |
|
62 iReferenceBitRate = 0; |
|
63 iScannedOnce = EFalse; |
|
64 iDecoder = NULL; |
|
65 } |
|
66 |
|
67 // Destructor |
|
68 EXPORT_C CAdvancedAudioUtility::~CAdvancedAudioUtility() |
|
69 { |
|
70 } |
|
71 |
|
72 |
|
73 // ----------------------------------------------------------------------------- |
|
74 // CAdvancedAudioUtility::ScanFramesL |
|
75 // Scan source buffer, frame by frame to update the frame count, byte count and |
|
76 // duration. Record controller still uses this, but not play controller. |
|
77 // ----------------------------------------------------------------------------- |
|
78 // |
|
79 EXPORT_C TInt CAdvancedAudioUtility::ScanFramesL( |
|
80 CMMFClip* aClip, |
|
81 CMMFDataBuffer* aBuf, |
|
82 TBool aScanThisBufferOnly, |
|
83 TInt /*aSourcePosition*/) |
|
84 { |
|
85 if (iScanDuration && !aScanThisBufferOnly) |
|
86 { |
|
87 // Already scanned once! |
|
88 return aBuf->Data().Size(); |
|
89 } |
|
90 |
|
91 iClipSize = aClip->Size(); |
|
92 |
|
93 if (!aScanThisBufferOnly) |
|
94 { |
|
95 iHeaderOffset = this->SeekSync(aBuf, aBuf->Data().Size()); |
|
96 } |
|
97 |
|
98 TInt readLen; |
|
99 TInt seekLen; |
|
100 const TUint8* seekPtr; |
|
101 |
|
102 TBool Done = EFalse; |
|
103 TInt SeekOffset = this->SeekSync(aBuf, aBuf->Data().Size()); |
|
104 |
|
105 if (SeekOffset == aBuf->Data().Size()) |
|
106 return SeekOffset; |
|
107 |
|
108 while (!Done) |
|
109 { |
|
110 readLen = aBuf->Data().Length(); |
|
111 seekLen = readLen - SeekOffset; |
|
112 seekPtr = aBuf->Data().Ptr() + SeekOffset; |
|
113 |
|
114 TAudioFrameInfo frameInfo; |
|
115 while (seekLen >= this->FrameHeaderSize()) |
|
116 { |
|
117 // Scan frame by frame until free format frame or EOB detected. |
|
118 TInt length = this->FrameInfo(seekPtr, seekLen, frameInfo); |
|
119 if (length > 0 && frameInfo.iBitRate > 0) |
|
120 { |
|
121 // record time position every time the frame length changes |
|
122 RecordTimeStampL(length); |
|
123 // update counters |
|
124 iScanByteCount += length; |
|
125 iScanDuration += (1000000*frameInfo.iFrameSamples) / |
|
126 frameInfo.iSamplingRateOut; |
|
127 iSamplingRate = frameInfo.iSamplingRate; |
|
128 // Ignoring NO_DATA and SID Frames in bitrate calculation |
|
129 if (frameInfo.iBitRate != 400 && frameInfo.iBitRate != 2400) |
|
130 { |
|
131 iSumBitRate += frameInfo.iBitRate; |
|
132 iNumFrames++; |
|
133 iBitRate = iSumBitRate/iNumFrames; |
|
134 } |
|
135 iSamplesPerFrame = frameInfo.iFrameSamples; |
|
136 iChannels = frameInfo.iChannels; |
|
137 seekPtr += length; |
|
138 seekLen -= length; |
|
139 } |
|
140 else if (frameInfo.iBitRate < 0) |
|
141 { |
|
142 seekLen = readLen = 0; |
|
143 } |
|
144 else |
|
145 { |
|
146 iScanInvByteCount++; |
|
147 seekPtr++; |
|
148 seekLen--; |
|
149 iSavedLength = 0; |
|
150 } |
|
151 } |
|
152 |
|
153 // request more data, if eof or max scan duration has not been exceeded |
|
154 if ((readLen < this->FrameHeaderSize()) || (iScanDuration > KMaxScanDuration) || aScanThisBufferOnly) |
|
155 { |
|
156 Done = ETrue; |
|
157 } |
|
158 else |
|
159 { |
|
160 // request more data |
|
161 SeekOffset = 0; |
|
162 aClip->ReadBufferL(aBuf, iHeaderOffset+iScanByteCount+iScanInvByteCount); |
|
163 } |
|
164 } |
|
165 |
|
166 return aBuf->Data().Size(); |
|
167 } |
|
168 |
|
169 // ----------------------------------------------------------------------------- |
|
170 // CAdvancedAudioUtility::ScanHeaderL |
|
171 // ----------------------------------------------------------------------------- |
|
172 // |
|
173 EXPORT_C void CAdvancedAudioUtility::ScanHeaderL( |
|
174 CMMFDataBuffer* aDataBuf) |
|
175 { |
|
176 // currently we are not handling how to search past the metadata |
|
177 ScanFramesL(aDataBuf, EFalse, 0); |
|
178 |
|
179 // reset iScanDuration because we didn't scan through the whole file, |
|
180 // and iScanDuration would not be the Total Duration of the source |
|
181 iScanDuration = 0; |
|
182 } |
|
183 |
|
184 // ----------------------------------------------------------------------------- |
|
185 // CAdvancedAudioUtility::ScanFramesL |
|
186 // Scan source buffer, frame by frame to update the frame count, byte count and |
|
187 // duration. |
|
188 // ----------------------------------------------------------------------------- |
|
189 // |
|
190 EXPORT_C TInt CAdvancedAudioUtility::ScanFramesL( |
|
191 CMMFDataBuffer* aBuf, |
|
192 TBool aScanThisBufferOnly, |
|
193 TInt /*aSourcePosition*/) |
|
194 { |
|
195 if (!aScanThisBufferOnly) |
|
196 { |
|
197 // Already scanned once! |
|
198 if (iScannedOnce) |
|
199 return aBuf->Data().Size(); |
|
200 |
|
201 iHeaderOffset = this->SeekSync(aBuf, aBuf->Data().Size()); |
|
202 } |
|
203 |
|
204 TInt readLen; |
|
205 TInt seekLen; |
|
206 const TUint8* seekPtr; |
|
207 |
|
208 TBool Done = EFalse; |
|
209 TInt SeekOffset = this->SeekSync(aBuf, aBuf->Data().Size()); |
|
210 |
|
211 while (!Done) |
|
212 { |
|
213 readLen = aBuf->Data().Length(); |
|
214 seekLen = readLen - SeekOffset; |
|
215 seekPtr = aBuf->Data().Ptr() + SeekOffset; |
|
216 TAudioFrameInfo frameInfo; |
|
217 while (seekLen >= this->FrameHeaderSize()) |
|
218 { |
|
219 // Scan frame by frame until free format frame or EOB detected. |
|
220 TInt length = this->FrameInfo(seekPtr, seekLen, frameInfo); |
|
221 if (length > 0 && frameInfo.iBitRate > 0) |
|
222 { |
|
223 // record time position every time the frame length changes |
|
224 RecordTimeStampL(length); |
|
225 // update counters |
|
226 iScanByteCount += length; |
|
227 iScanDuration += (1000000*frameInfo.iFrameSamples)/frameInfo.iSamplingRateOut; |
|
228 iSamplingRate = frameInfo.iSamplingRate; |
|
229 |
|
230 if (iScanDuration) |
|
231 iScannedOnce = ETrue; |
|
232 |
|
233 // Ignoring NO_DATA and SID Frames in bitrate calculation |
|
234 // this logic here is kinda dangerous, because ScanFramesL can be called |
|
235 // multiple time when SetPositionL is supported in Streaming/PDL, hence |
|
236 // the avg bitrate can be mess up the the repeat of the same frame |
|
237 if (frameInfo.iBitRate != 400 && frameInfo.iBitRate != 2400) |
|
238 { |
|
239 iSumBitRate += frameInfo.iBitRate; |
|
240 iNumFrames++; |
|
241 iBitRate = iSumBitRate/iNumFrames; |
|
242 } |
|
243 |
|
244 iSamplesPerFrame = frameInfo.iFrameSamples; |
|
245 iChannels = frameInfo.iChannels; |
|
246 seekPtr += length; |
|
247 seekLen -= length; |
|
248 } |
|
249 else if (frameInfo.iBitRate < 0) |
|
250 { |
|
251 seekLen = readLen = 0; |
|
252 } |
|
253 else |
|
254 { |
|
255 iScanInvByteCount++; |
|
256 seekPtr++; |
|
257 seekLen--; |
|
258 iSavedLength = 0; |
|
259 } |
|
260 } |
|
261 |
|
262 // request more data how? , if eof or max scan duration has not been exceeded |
|
263 if (aScanThisBufferOnly) |
|
264 { |
|
265 Done = ETrue; |
|
266 } |
|
267 } |
|
268 |
|
269 return aBuf->Data().Size(); |
|
270 } |
|
271 |
|
272 // ----------------------------------------------------------------------------- |
|
273 // CAdvancedAudioUtility::FindFramePos |
|
274 // Finds the byte position of the frame at given time position. |
|
275 // ----------------------------------------------------------------------------- |
|
276 // |
|
277 EXPORT_C TInt CAdvancedAudioUtility::FindFramePos( |
|
278 const TInt64& aTimePos, |
|
279 CMMFClip* /*aClip*/) |
|
280 { |
|
281 TInt ret = KErrNotFound; |
|
282 |
|
283 // calculate frame duration |
|
284 TInt64 frmTime((iSamplesPerFrame*1000000) / iSamplingRate); |
|
285 |
|
286 // find the closest larger time stamp corresponding to time position |
|
287 TInt pos = 0; |
|
288 TTimePos timeStamp((aTimePos), 0, 0); |
|
289 TKeyArrayFix timeKey(_FOFF(TTimePos,iTimePos),ECmpTInt64); |
|
290 iPosArr->FindIsq(timeStamp, timeKey, pos); |
|
291 |
|
292 // calculate byte position based on the closest smaller time stamp |
|
293 if (iPosArr->Count() > 0) |
|
294 { |
|
295 // get the closest smaller |
|
296 if (pos > 0) |
|
297 { |
|
298 pos--; |
|
299 } |
|
300 TTimePos& ts = iPosArr->At(pos); |
|
301 // offset from the closest smaller time stamp |
|
302 TInt64 dTime = aTimePos - ts.iTimePos; |
|
303 // time stamp position plus byte offset within this segment |
|
304 ret = ts.iBytePos + ((dTime / frmTime) * ts.iFrameLen); |
|
305 } |
|
306 |
|
307 // limit check |
|
308 if (ret < 0) |
|
309 { |
|
310 ret = 0; |
|
311 } |
|
312 |
|
313 if ((ret > iClipSize) && (iClipSize != 0)) |
|
314 { |
|
315 ret = iClipSize; |
|
316 } |
|
317 |
|
318 DP3(_L("CAdvancedAudioUtility::FindFramePos high[%d], low[%d], ret[%d]"), I64HIGH(aTimePos), I64LOW(aTimePos), ret); |
|
319 |
|
320 return ret; |
|
321 } |
|
322 // CAdvancedAudioUtility::FrameInfo |
|
323 // ----------------------------------------------------------------------------- |
|
324 // |
|
325 EXPORT_C TInt CAdvancedAudioUtility::FrameInfo( |
|
326 const TUint8* /*aBuf*/, |
|
327 TInt /*aBufLen*/, |
|
328 TAudioFrameInfo& /*aInfo*/) |
|
329 { |
|
330 return 0; |
|
331 } |
|
332 |
|
333 // ----------------------------------------------------------------------------- |
|
334 // CAdvancedAudioUtility::SampleRate |
|
335 // ----------------------------------------------------------------------------- |
|
336 // |
|
337 EXPORT_C TInt CAdvancedAudioUtility::SampleRate() |
|
338 { |
|
339 return iSamplingRate; |
|
340 } |
|
341 |
|
342 // ----------------------------------------------------------------------------- |
|
343 // CAdvancedAudioUtility::Channels |
|
344 // ----------------------------------------------------------------------------- |
|
345 // |
|
346 EXPORT_C TInt CAdvancedAudioUtility::Channels() |
|
347 { |
|
348 return iChannels; |
|
349 } |
|
350 |
|
351 // ----------------------------------------------------------------------------- |
|
352 // CAdvancedAudioUtility::ChannelsOut |
|
353 // ----------------------------------------------------------------------------- |
|
354 // |
|
355 EXPORT_C TInt CAdvancedAudioUtility::ChannelsOut() |
|
356 { |
|
357 return iChannelsOut; |
|
358 } |
|
359 |
|
360 // ----------------------------------------------------------------------------- |
|
361 // CAdvancedAudioUtility::ScanDuration |
|
362 // ----------------------------------------------------------------------------- |
|
363 // get rid of this |
|
364 EXPORT_C TInt64 CAdvancedAudioUtility::ScanDuration() |
|
365 { |
|
366 return iScanDuration; |
|
367 } |
|
368 |
|
369 // ----------------------------------------------------------------------------- |
|
370 // CAdvancedAudioUtility::Duration |
|
371 // ----------------------------------------------------------------------------- |
|
372 // default impl |
|
373 EXPORT_C TInt64 CAdvancedAudioUtility::Duration() |
|
374 { |
|
375 DP0(_L("CAdvancedAudioUtility::Duration()")); |
|
376 |
|
377 TInt64 bitRate = BitRate(); // update bitrate |
|
378 TInt64 size = iClipSize; |
|
379 size -= (iSyncOffset+iHeaderOffset); |
|
380 if (size >= 0) |
|
381 { |
|
382 if (bitRate > 0) |
|
383 { |
|
384 iDurationUs = size*8000000/bitRate; |
|
385 } |
|
386 } |
|
387 DP3(_L("CAdvancedAudioUtility::Duration() iDuration(ms)[%d] bitRate[%d] size[%d]"), iDurationUs/1000, bitRate, iClipSize-iSyncOffset-iHeaderOffset); |
|
388 return iDurationUs; |
|
389 } |
|
390 |
|
391 // ----------------------------------------------------------------------------- |
|
392 // CAdvancedAudioUtility::BitRate |
|
393 // ----------------------------------------------------------------------------- |
|
394 // default impl - BitRate() would be called by user and updates reference |
|
395 EXPORT_C TInt CAdvancedAudioUtility::BitRate() |
|
396 { |
|
397 if (iDecoder && !iBitRateFrozen) |
|
398 { |
|
399 TInt bitrate = iDecoder->BitRate(); |
|
400 if (bitrate > 0) |
|
401 { |
|
402 iBitRate = bitrate; |
|
403 } |
|
404 } |
|
405 return iBitRate; |
|
406 } |
|
407 |
|
408 |
|
409 // ----------------------------------------------------------------------------- |
|
410 // CAdvancedAudioUtility::HeaderOffset |
|
411 // ----------------------------------------------------------------------------- |
|
412 // |
|
413 EXPORT_C TInt CAdvancedAudioUtility::HeaderOffset() |
|
414 { |
|
415 return iHeaderOffset; |
|
416 } |
|
417 |
|
418 // ----------------------------------------------------------------------------- |
|
419 // CAdvancedAudioUtility::SyncOffset |
|
420 // ----------------------------------------------------------------------------- |
|
421 // |
|
422 EXPORT_C TInt CAdvancedAudioUtility::SyncOffset() |
|
423 { |
|
424 return iSyncOffset; |
|
425 } |
|
426 |
|
427 // ----------------------------------------------------------------------------- |
|
428 // CAdvancedAudioUtility::SetCodecConfigData |
|
429 // ----------------------------------------------------------------------------- |
|
430 // |
|
431 EXPORT_C void CAdvancedAudioUtility::SetCodecConfigData( |
|
432 RArray<TInt>& /*aCodecConfig*/) |
|
433 { |
|
434 } |
|
435 |
|
436 // ----------------------------------------------------------------------------- |
|
437 // CAdvancedAudioUtility::SetObserver |
|
438 // ----------------------------------------------------------------------------- |
|
439 // |
|
440 EXPORT_C void CAdvancedAudioUtility::SetObserver(MAdvancedAudioUtilityObserver& aObserver) |
|
441 { |
|
442 iObserver = &aObserver; |
|
443 } |
|
444 |
|
445 // ----------------------------------------------------------------------------- |
|
446 // CAdvancedAudioUtility::SetDecoder |
|
447 // ----------------------------------------------------------------------------- |
|
448 // |
|
449 EXPORT_C void CAdvancedAudioUtility::SetDecoder(CAdvancedAudioDecoder& aDecoder) |
|
450 { |
|
451 iDecoder = &aDecoder; |
|
452 } |
|
453 |
|
454 // ----------------------------------------------------------------------------- |
|
455 // CAdvancedAudioUtility::DeReferenceDecoder |
|
456 // ----------------------------------------------------------------------------- |
|
457 // |
|
458 EXPORT_C void CAdvancedAudioUtility::DeReferenceDecoder() |
|
459 { |
|
460 iDecoder = NULL; |
|
461 } |
|
462 |
|
463 // ----------------------------------------------------------------------------- |
|
464 // CAdvancedAudioUtility::FrameHeaderSize |
|
465 // ----------------------------------------------------------------------------- |
|
466 // |
|
467 EXPORT_C TInt CAdvancedAudioUtility::FrameHeaderSize() |
|
468 { |
|
469 return 0; |
|
470 } |
|
471 |
|
472 // ----------------------------------------------------------------------------- |
|
473 // CAdvancedAudioUtility::GetDriveNumber |
|
474 // ----------------------------------------------------------------------------- |
|
475 // is this needed? |
|
476 EXPORT_C TDriveNumber CAdvancedAudioUtility::GetDriveNumber( |
|
477 const TDesC& aDriveName) |
|
478 { |
|
479 TDriveNumber driveNumber = EDriveC; |
|
480 |
|
481 if (!aDriveName.Length()) |
|
482 { |
|
483 return driveNumber; |
|
484 } |
|
485 else |
|
486 { |
|
487 switch (aDriveName[0]) |
|
488 { |
|
489 case 'a': |
|
490 case 'A': |
|
491 driveNumber = EDriveA; |
|
492 break; |
|
493 case 'b': |
|
494 case 'B': |
|
495 driveNumber = EDriveB; |
|
496 break; |
|
497 case 'c': |
|
498 case 'C': |
|
499 driveNumber = EDriveC; |
|
500 break; |
|
501 case 'd': |
|
502 case 'D': |
|
503 driveNumber = EDriveD; |
|
504 break; |
|
505 case 'e': |
|
506 case 'E': |
|
507 driveNumber = EDriveE; |
|
508 break; |
|
509 case 'f': |
|
510 case 'F': |
|
511 driveNumber = EDriveF; |
|
512 break; |
|
513 case 'g': |
|
514 case 'G': |
|
515 driveNumber = EDriveG; |
|
516 break; |
|
517 case 'h': |
|
518 case 'H': |
|
519 driveNumber = EDriveH; |
|
520 break; |
|
521 case 'i': |
|
522 case 'I': |
|
523 driveNumber = EDriveI; |
|
524 break; |
|
525 case 'j': |
|
526 case 'J': |
|
527 driveNumber = EDriveJ; |
|
528 break; |
|
529 case 'k': |
|
530 case 'K': |
|
531 driveNumber = EDriveK; |
|
532 break; |
|
533 case 'l': |
|
534 case 'L': |
|
535 driveNumber = EDriveL; |
|
536 break; |
|
537 case 'm': |
|
538 case 'M': |
|
539 driveNumber = EDriveM; |
|
540 break; |
|
541 case 'n': |
|
542 case 'N': |
|
543 driveNumber = EDriveN; |
|
544 break; |
|
545 case 'o': |
|
546 case 'O': |
|
547 driveNumber = EDriveO; |
|
548 break; |
|
549 case 'p': |
|
550 case 'P': |
|
551 driveNumber = EDriveP; |
|
552 break; |
|
553 case 'q': |
|
554 case 'Q': |
|
555 driveNumber = EDriveQ; |
|
556 break; |
|
557 case 'r': |
|
558 case 'R': |
|
559 driveNumber = EDriveR; |
|
560 break; |
|
561 case 's': |
|
562 case 'S': |
|
563 driveNumber = EDriveS; |
|
564 break; |
|
565 case 't': |
|
566 case 'T': |
|
567 driveNumber = EDriveT; |
|
568 break; |
|
569 case 'u': |
|
570 case 'U': |
|
571 driveNumber = EDriveU; |
|
572 break; |
|
573 case 'v': |
|
574 case 'V': |
|
575 driveNumber = EDriveV; |
|
576 break; |
|
577 case 'x': |
|
578 case 'X': |
|
579 driveNumber = EDriveX; |
|
580 break; |
|
581 case 'y': |
|
582 case 'Y': |
|
583 driveNumber = EDriveY; |
|
584 break; |
|
585 case 'z': |
|
586 case 'Z': |
|
587 driveNumber = EDriveZ; |
|
588 break; |
|
589 default: |
|
590 break; |
|
591 } |
|
592 } |
|
593 return driveNumber; |
|
594 } |
|
595 |
|
596 // ----------------------------------------------------------------------------- |
|
597 // CAdvancedAudioUtility::SetClipSizeL |
|
598 // Set/Update the iClipSize varilable |
|
599 // ----------------------------------------------------------------------------- |
|
600 // |
|
601 EXPORT_C void CAdvancedAudioUtility::SetClipSizeL(TUint aSize) |
|
602 { |
|
603 DP1(_L("CAdvancedAudioUtility::SetClipSizeL size[%d]"), aSize); |
|
604 if (aSize > (iSyncOffset+iHeaderOffset)) |
|
605 { |
|
606 iClipSize = aSize; |
|
607 } |
|
608 else |
|
609 { |
|
610 User::Leave(KErrArgument); |
|
611 } |
|
612 } |
|
613 |
|
614 // ----------------------------------------------------------------------------- |
|
615 // CAdvancedAudioUtility::EnableBitRateChangedEventL |
|
616 // Enable bitrate change callback |
|
617 // ----------------------------------------------------------------------------- |
|
618 // |
|
619 EXPORT_C void CAdvancedAudioUtility::EnableBitRateChangedEventL(TInt aIntervalInMilliSeconds) |
|
620 { |
|
621 if (!iObserver) |
|
622 User::Leave(KErrNotReady); |
|
623 else if (aIntervalInMilliSeconds < -1) |
|
624 User::Leave(KErrArgument); |
|
625 |
|
626 if (iDecoder) |
|
627 { |
|
628 TInt err = KErrNone; |
|
629 |
|
630 if (aIntervalInMilliSeconds == -1) |
|
631 err = iDecoder->EnableDecodeIntervalEvent(EFalse); |
|
632 else |
|
633 err = iDecoder->EnableDecodeIntervalEvent(ETrue, aIntervalInMilliSeconds); |
|
634 |
|
635 // KErrNone means the decoder would callback on desire interval as it decodes |
|
636 // KErrNotSupported implys Utility would need to keep track of the interval |
|
637 // otherwise, leave on any other situation |
|
638 if (err == KErrNone) |
|
639 return; |
|
640 else if (err != KErrNotSupported) |
|
641 User::LeaveIfError(err); |
|
642 } |
|
643 } |
|
644 |
|
645 // ----------------------------------------------------------------------------- |
|
646 // CAdvancedAudioUtility::SetSourceReference |
|
647 // ----------------------------------------------------------------------------- |
|
648 // |
|
649 EXPORT_C TInt CAdvancedAudioUtility::SetSourceReference(TUint aTimeMs, TUint aPos) |
|
650 { |
|
651 TInt stat; |
|
652 if (iDecoder) |
|
653 { |
|
654 stat = iDecoder->SetSourceReference(aTimeMs, aPos); |
|
655 } |
|
656 else |
|
657 { |
|
658 stat = KErrNotSupported; |
|
659 } |
|
660 return stat; |
|
661 } |
|
662 |
|
663 // ----------------------------------------------------------------------------- |
|
664 // CAdvancedAudioUtility::FindFramePosFromTime |
|
665 // ----------------------------------------------------------------------------- |
|
666 // |
|
667 EXPORT_C TInt CAdvancedAudioUtility::FindFramePosFromTime(TUint& aTimeMs, TUint& aPos) |
|
668 { |
|
669 TInt stat; |
|
670 if (iDecoder) |
|
671 { |
|
672 stat = iDecoder->FindFramePosFromTime(aTimeMs, aPos); |
|
673 } |
|
674 else |
|
675 { |
|
676 stat = KErrNotSupported; |
|
677 } |
|
678 return stat; |
|
679 } |
|
680 |
|
681 EXPORT_C TInt CAdvancedAudioUtility::FindFrameTimeFromPos(TUint& aTime, TUint& aPos) |
|
682 { |
|
683 TInt stat; |
|
684 if (iDecoder) |
|
685 { |
|
686 stat = iDecoder->FindFrameTimeFromPos(aTime, aPos); |
|
687 } |
|
688 else |
|
689 { |
|
690 stat = KErrNotSupported; |
|
691 } |
|
692 return stat; |
|
693 } |
|
694 |
|
695 // ----------------------------------------------------------------------------- |
|
696 // CAdvancedAudioUtility::LastFramePos |
|
697 // ----------------------------------------------------------------------------- |
|
698 // |
|
699 EXPORT_C TInt CAdvancedAudioUtility::LastFramePos(TUint& aPos) |
|
700 { |
|
701 TInt stat; |
|
702 if (iDecoder) |
|
703 { |
|
704 stat = iDecoder->LastFramePos(aPos); |
|
705 } |
|
706 else |
|
707 { |
|
708 stat = KErrNotSupported; |
|
709 } |
|
710 return stat; |
|
711 } |
|
712 |
|
713 // ----------------------------------------------------------------------------- |
|
714 // CAdvancedAudioUtility::LastFrameTime |
|
715 // ----------------------------------------------------------------------------- |
|
716 // |
|
717 EXPORT_C TInt CAdvancedAudioUtility::LastFrameTime(TUint& aTimeMs) |
|
718 { |
|
719 TInt stat; |
|
720 if (iDecoder) |
|
721 { |
|
722 stat = iDecoder->LastFrameTime(aTimeMs); |
|
723 } |
|
724 else |
|
725 { |
|
726 stat = KErrNotSupported; |
|
727 } |
|
728 return stat; |
|
729 } |
|
730 |
|
731 // ----------------------------------------------------------------------------- |
|
732 // CAdvancedAudioUtility::ResetTable |
|
733 // ----------------------------------------------------------------------------- |
|
734 // |
|
735 EXPORT_C TInt CAdvancedAudioUtility::ResetTable() |
|
736 { |
|
737 TInt stat; |
|
738 if (iDecoder) |
|
739 { |
|
740 stat = iDecoder->ResetTable(); |
|
741 } |
|
742 else |
|
743 { |
|
744 stat = KErrNotSupported; |
|
745 } |
|
746 return stat; |
|
747 } |
|
748 |
|
749 // ----------------------------------------------------------------------------- |
|
750 // CAdvancedAudioUtility::SeekToTimeMs |
|
751 // ----------------------------------------------------------------------------- |
|
752 // |
|
753 EXPORT_C TInt CAdvancedAudioUtility::SeekToTimeMs(TUint aTimeMs) |
|
754 { |
|
755 TInt stat; |
|
756 if (iDecoder) |
|
757 { |
|
758 stat = iDecoder->SeekToTimeMs(aTimeMs); |
|
759 } |
|
760 else |
|
761 { |
|
762 stat = KErrNotSupported; |
|
763 } |
|
764 return stat; |
|
765 } |
|
766 |
|
767 EXPORT_C TInt CAdvancedAudioUtility::SetPlayWindowEndTimeMs(TUint aTimeMs) |
|
768 { |
|
769 TInt stat; |
|
770 if (iDecoder) |
|
771 { |
|
772 stat = iDecoder->SetPlayWindowEndTimeMs(aTimeMs); |
|
773 } |
|
774 else |
|
775 { |
|
776 stat = KErrNotSupported; |
|
777 } |
|
778 return stat; |
|
779 } |
|
780 |
|
781 // ----------------------------------------------------------------------------- |
|
782 // CAdvancedAudioUtility::RecordTimeStampL |
|
783 // Record time position every time the frame length changes or when the stamp |
|
784 // array is empty. Positioning is accurate up to KMaxScanDuration. After that |
|
785 // the last time stamp is used for estimating the position.. |
|
786 // ----------------------------------------------------------------------------- |
|
787 // |
|
788 EXPORT_C void CAdvancedAudioUtility::RecordTimeStampL( |
|
789 TInt aFrameLength) |
|
790 { |
|
791 // record time position every time the frame length |
|
792 // changes or empty stamp array |
|
793 TInt pos = iScanInvByteCount + iScanByteCount; |
|
794 TInt count = iPosArr->Count(); |
|
795 TTimePos lastEntry(0,0,0); |
|
796 |
|
797 if (count > 0) |
|
798 lastEntry = (*iPosArr)[iPosArr->Count()-1]; |
|
799 |
|
800 DP5(_L("CAdvancedAudioUtility::RecordTimeStampL Count[%d], iScanDuration[%d]millsec, BytePos[%d], aFrameLength[%d], lastEntry.iTimePos[%d]millsec"), count, I64LOW(iScanDuration/1000), pos, aFrameLength, I64LOW(lastEntry.iTimePos/1000)); |
|
801 |
|
802 if (((pos > lastEntry.iBytePos) && aFrameLength != 0 && aFrameLength != iSavedLength) || (count == 0)) |
|
803 { |
|
804 if (iScanDuration <= KMaxScanDuration) |
|
805 { |
|
806 DP0(_L("CAdvancedAudioUtility::RecordTimeStampL, AppendL new entry")); |
|
807 |
|
808 TTimePos timeStamp(I64LOW(iScanDuration), pos, aFrameLength); |
|
809 |
|
810 iPosArr->AppendL(timeStamp); |
|
811 iSavedLength = aFrameLength; |
|
812 } |
|
813 } |
|
814 } |
|
815 |
|
816 // ----------------------------------------------------------------------------- |
|
817 // CAdvancedAudioUtility::MetaDataLength |
|
818 // ----------------------------------------------------------------------------- |
|
819 // |
|
820 EXPORT_C TInt CAdvancedAudioUtility::ID3HeaderLength( |
|
821 const CMMFDataBuffer* aBuf) |
|
822 { |
|
823 TInt lenMetaData; |
|
824 TUint offset = aBuf->Position(); |
|
825 |
|
826 _LIT8 (KTagID3, "ID3"); |
|
827 TPtrC8 searchBuf; |
|
828 |
|
829 // Set search buffer |
|
830 searchBuf.Set(aBuf->Data()); |
|
831 |
|
832 const TUint8* ptr = aBuf->Data().Ptr(); |
|
833 TInt len = aBuf->Data().Length(); |
|
834 searchBuf.Set(ptr+offset, len-offset); |
|
835 |
|
836 TInt startTagPos = searchBuf.Find (KTagID3); |
|
837 if (startTagPos == KErrNotFound || startTagPos != 0) |
|
838 { |
|
839 lenMetaData = 0; |
|
840 } |
|
841 else |
|
842 { |
|
843 lenMetaData = searchBuf[KSizeOfTagOffset]; |
|
844 lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+1] << 1)) >> 1; |
|
845 lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+2] << 1)) >> 1; |
|
846 lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+3] << 1)) >> 1; |
|
847 lenMetaData += 10; |
|
848 } |
|
849 |
|
850 return lenMetaData; |
|
851 } |
|
852 |
|
853 // ----------------------------------------------------------------------------- |
|
854 // CAdvancedAudioUtility::CreateBufferOfSizeLC |
|
855 // ----------------------------------------------------------------------------- |
|
856 // |
|
857 EXPORT_C CMMFDataBuffer* CAdvancedAudioUtility::CreateBufferOfSizeLC( |
|
858 TUint aSize) |
|
859 { |
|
860 CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(aSize); |
|
861 CleanupStack::PushL(buffer); |
|
862 buffer->Data().FillZ(aSize); |
|
863 buffer->SetRequestSizeL(aSize); |
|
864 buffer->Data().SetLength(0); |
|
865 return buffer; |
|
866 } |
|
867 |
|
868 // ----------------------------------------------------------------------------- |
|
869 // CAdvancedAudioUtility::DecodeIntervalEvent |
|
870 // ----------------------------------------------------------------------------- |
|
871 // |
|
872 EXPORT_C void CAdvancedAudioUtility::DecodeIntervalEvent() |
|
873 { |
|
874 if (iObserver) |
|
875 { |
|
876 BitRate(); // updates iBitRate |
|
877 TInt lim = iReferenceBitRate/10; // 10% tolerance |
|
878 if (abs(iReferenceBitRate - iBitRate) > lim) |
|
879 { |
|
880 iObserver->BitRateChanged(); |
|
881 iReferenceBitRate = iBitRate; |
|
882 } |
|
883 } |
|
884 } |
|
885 |
|
886 /* |
|
887 EXPORT_C TInt CAdvancedAudioUtility::IsSeeking(TBool& aIsSeeking) |
|
888 { |
|
889 TInt stat; |
|
890 if (iDecoder) |
|
891 { |
|
892 stat = iDecoder->IsSeeking(aIsSeeking); |
|
893 } |
|
894 else |
|
895 { |
|
896 stat = KErrNotSupported; |
|
897 } |
|
898 return stat; |
|
899 } |
|
900 */ |
|
901 // ----------------------------------------------------------------------------- |
|
902 // CAdvancedAudioDecoder::SeekPositionReached |
|
903 // ----------------------------------------------------------------------------- |
|
904 // |
|
905 EXPORT_C void CAdvancedAudioUtility::SeekPositionReached(TUint aTimeMs) |
|
906 { |
|
907 iObserver->SeekPositionReached(aTimeMs); |
|
908 } |
|
909 |
|
910 // ----------------------------------------------------------------------------- |
|
911 // CAdvancedAudioDecoder::PlayWindowEndPositionReached |
|
912 // ----------------------------------------------------------------------------- |
|
913 // |
|
914 EXPORT_C void CAdvancedAudioUtility::PlayWindowEndPositionReached() |
|
915 { |
|
916 iObserver->PlayWindowEndPositionReached(); |
|
917 } |
|
918 |
|
919 EXPORT_C TInt CAdvancedAudioUtility::GetOffsets(TInt& aOffsets) |
|
920 { |
|
921 aOffsets = iHeaderOffset + iSyncOffset; |
|
922 return KErrNone; |
|
923 } |
|
924 |
|
925 // End of File |
|
926 |