1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "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 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 #include "ProcAMRInFileHandler.h" |
|
22 #include "ProcAMRFrameHandler.h" |
|
23 #include "ProcTools.h" |
|
24 #include "AudPanic.h" |
|
25 |
|
26 |
|
27 CProcAMRInFileHandler* CProcAMRInFileHandler::NewL(const TDesC& aFileName, |
|
28 RFile* aFileHandle, |
|
29 CAudClip* aClip, |
|
30 TInt aReadBufferSize, |
|
31 TInt aTargetSampleRate, |
|
32 TChannelMode aChannelMode) |
|
33 { |
|
34 |
|
35 CProcAMRInFileHandler* self = NewLC(aFileName, aFileHandle, aClip, aReadBufferSize, |
|
36 aTargetSampleRate, aChannelMode); |
|
37 CleanupStack::Pop(self); |
|
38 return self; |
|
39 } |
|
40 |
|
41 CProcAMRInFileHandler* CProcAMRInFileHandler::NewLC(const TDesC& aFileName, |
|
42 RFile* aFileHandle, |
|
43 CAudClip* aClip, |
|
44 TInt aReadBufferSize, |
|
45 TInt aTargetSampleRate, |
|
46 TChannelMode aChannelMode) |
|
47 { |
|
48 |
|
49 CProcAMRInFileHandler* self = new (ELeave) CProcAMRInFileHandler(); |
|
50 CleanupStack::PushL(self); |
|
51 self->ConstructL(aFileName, aFileHandle, aClip, aReadBufferSize, |
|
52 aTargetSampleRate, aChannelMode); |
|
53 return self; |
|
54 } |
|
55 |
|
56 CProcAMRInFileHandler::CProcAMRInFileHandler() : CProcInFileHandler() |
|
57 { |
|
58 |
|
59 |
|
60 } |
|
61 |
|
62 void CProcAMRInFileHandler::GetPropertiesL(TAudFileProperties* aProperties) |
|
63 { |
|
64 |
|
65 if (iProperties != 0) |
|
66 { |
|
67 *aProperties = *iProperties; |
|
68 return; |
|
69 } |
|
70 aProperties->iAudioTypeExtension = EAudExtensionTypeNoExtension; |
|
71 if (iFileOpen) |
|
72 { |
|
73 aProperties->iFileFormat = EAudFormatAMR; |
|
74 |
|
75 TInt oldPos = iFilePos; |
|
76 |
|
77 TInt fileSize = 0; |
|
78 iFile.Size(fileSize); |
|
79 |
|
80 TBuf8<6> header; |
|
81 //iFile.Read(0, header); |
|
82 BufferedFileRead(0, header); |
|
83 if (header.Compare(_L8("#!AMR\n")) == 0) |
|
84 { |
|
85 aProperties->iAudioType = EAudAMR; |
|
86 aProperties->iSamplingRate = 8000; |
|
87 aProperties->iChannelMode = EAudSingleChannel; |
|
88 aProperties->iBitrateMode = EAudVariable; |
|
89 |
|
90 TBuf8<1> buf; |
|
91 // iFile.Read(6, buf); |
|
92 BufferedFileRead(6, buf); |
|
93 TUint dec_mode = (enum Mode)((buf[0] & 0x0078) >> 3); |
|
94 |
|
95 aProperties->iBitrate = KAmrBitRates[dec_mode]; |
|
96 TInt durationMilli = 0; |
|
97 TInt frameAmount = 0; |
|
98 TInt frameDuration = 0; |
|
99 TInt frameSize = 0; |
|
100 |
|
101 GetFrameInfo(durationMilli, frameAmount, frameDuration, frameSize); |
|
102 |
|
103 TInt64 tmp = (TInt64)(TInt)durationMilli*1000; |
|
104 // milliseconds->microseconds |
|
105 TTimeIntervalMicroSeconds durationMicro(tmp); |
|
106 aProperties->iDuration = durationMicro; |
|
107 aProperties->iFrameCount = frameAmount; |
|
108 |
|
109 tmp = (TInt64)(TInt)frameDuration*1000; |
|
110 TTimeIntervalMicroSeconds frameDurationMicro(tmp); |
|
111 aProperties->iFrameDuration = frameDurationMicro; |
|
112 aProperties->iFrameLen = frameSize; |
|
113 |
|
114 |
|
115 } |
|
116 BufferedFileSetFilePos(oldPos); |
|
117 } |
|
118 else |
|
119 { |
|
120 TAudPanic::Panic(TAudPanic::EInternal); |
|
121 } |
|
122 |
|
123 if (iProperties == 0) |
|
124 { |
|
125 iProperties = new (ELeave) TAudFileProperties; |
|
126 *iProperties = *aProperties; |
|
127 } |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 } |
|
134 |
|
135 TBool CProcAMRInFileHandler::SeekAudioFrame(TInt32 aTime) |
|
136 { |
|
137 |
|
138 |
|
139 if (!iFileOpen) |
|
140 { |
|
141 TAudPanic::Panic(TAudPanic::EInternal); |
|
142 } |
|
143 |
|
144 TInt fileSize = 0; |
|
145 iFile.Size(fileSize); |
|
146 |
|
147 |
|
148 TInt firstModeByte = 6; |
|
149 TInt readSize = 0; |
|
150 TBuf8<1> modeByte; |
|
151 iCurrentTimeMilliseconds = 0; |
|
152 |
|
153 TUint dec_mode; |
|
154 //iFile.Seek(ESeekStart, firstModeByte); |
|
155 BufferedFileSetFilePos(firstModeByte); |
|
156 |
|
157 while(iCurrentTimeMilliseconds < aTime) |
|
158 { |
|
159 |
|
160 //iFile.Read(modeByte, 1); |
|
161 BufferedFileRead(modeByte); |
|
162 if (modeByte.Size() == 0) |
|
163 { |
|
164 return EFalse; |
|
165 } |
|
166 |
|
167 dec_mode = (enum Mode)((modeByte[0] & 0x0078) >> 3); |
|
168 |
|
169 switch (dec_mode) |
|
170 { |
|
171 case 0: |
|
172 readSize = 12; |
|
173 break; |
|
174 case 1: |
|
175 readSize = 13; |
|
176 break; |
|
177 case 2: |
|
178 readSize = 15; |
|
179 break; |
|
180 case 3: |
|
181 readSize = 17; |
|
182 break; |
|
183 case 4: |
|
184 readSize = 19; |
|
185 break; |
|
186 case 5: |
|
187 readSize = 20; |
|
188 break; |
|
189 case 6: |
|
190 readSize = 26; |
|
191 break; |
|
192 case 7: |
|
193 readSize = 31; |
|
194 break; |
|
195 case 8: |
|
196 readSize = 5; |
|
197 break; |
|
198 case 15: |
|
199 readSize = 0; |
|
200 break; |
|
201 default: |
|
202 readSize = 0; |
|
203 break; |
|
204 }; |
|
205 // read the next audio frame |
|
206 //iFile.Read(audioFrame, read_size); |
|
207 //if (iFile.Seek(ESeekCurrent, readSize) != KErrNone) { |
|
208 // return EFalse; |
|
209 //} |
|
210 if (!(BufferedFileSetFilePos(BufferedFileGetFilePos()+readSize))) |
|
211 { |
|
212 |
|
213 // EOF |
|
214 return EFalse; |
|
215 } |
|
216 iCurrentTimeMilliseconds += 20; |
|
217 } |
|
218 return ETrue; |
|
219 } |
|
220 |
|
221 TBool CProcAMRInFileHandler::SeekCutInFrame() |
|
222 { |
|
223 |
|
224 iCurrentTimeMilliseconds = iCutInTime; |
|
225 return SeekAudioFrame(iCutInTime); |
|
226 } |
|
227 |
|
228 |
|
229 |
|
230 |
|
231 void CProcAMRInFileHandler::ConstructL(const TDesC& aFileName, |
|
232 RFile* aFileHandle, |
|
233 CAudClip* aClip, |
|
234 TInt aReadBufferSize, |
|
235 TInt aTargetSampleRate, |
|
236 TChannelMode aChannelMode) |
|
237 { |
|
238 |
|
239 |
|
240 |
|
241 iTargetSampleRate = aTargetSampleRate; |
|
242 iChannelMode = aChannelMode; |
|
243 |
|
244 InitAndOpenFileL(aFileName, aFileHandle, aReadBufferSize); |
|
245 |
|
246 |
|
247 if (aClip != 0) |
|
248 { |
|
249 iCutInTime = ProcTools::MilliSeconds(aClip->CutInTime()); |
|
250 |
|
251 } |
|
252 |
|
253 const TInt KSilentFrameSize = 13; |
|
254 |
|
255 TUint8 silentFrame[KSilentFrameSize]= |
|
256 { |
|
257 0x04,0x63,0x3C,0xC7,0xF0,0x03,0x04,0x39,0xFF,0xE0, |
|
258 0x00,0x00,0x00 |
|
259 |
|
260 }; |
|
261 |
|
262 |
|
263 iSilentFrame = HBufC8::NewL(KSilentFrameSize); |
|
264 iSilentFrame->Des().Append(silentFrame, KSilentFrameSize); |
|
265 iSilentFrameDuration = 20; |
|
266 |
|
267 |
|
268 iClip = aClip; |
|
269 |
|
270 TAudFileProperties prop; |
|
271 GetPropertiesL(&prop); |
|
272 |
|
273 iDecoder = CProcDecoder::NewL(); |
|
274 |
|
275 iDecodingPossible = iDecoder->InitL(prop, aTargetSampleRate, aChannelMode); |
|
276 |
|
277 |
|
278 // Generate a frame handler ---------------------> |
|
279 |
|
280 iFrameHandler = CProcAMRFrameHandler::NewL(); |
|
281 |
|
282 if (iClip != 0 && iClip->Normalizing()) |
|
283 { |
|
284 SetNormalizingGainL(iFrameHandler); |
|
285 } |
|
286 |
|
287 |
|
288 } |
|
289 |
|
290 TBool CProcAMRInFileHandler::GetEncAudioFrameL(HBufC8*& aFrame, TInt& aSize, TInt32& aTime) |
|
291 { |
|
292 if (!iFileOpen) |
|
293 { |
|
294 TAudPanic::Panic(TAudPanic::EInternal); |
|
295 } |
|
296 |
|
297 aFrame = NULL; |
|
298 TInt readSize = 0; |
|
299 TBuf8<1> modeByte; |
|
300 // TBuf8<32> audioFrame; |
|
301 TUint dec_mode; |
|
302 |
|
303 |
|
304 //iFile.Read(modeByte); |
|
305 BufferedFileRead(modeByte); |
|
306 if (modeByte.Size() == 0) |
|
307 { |
|
308 return EFalse; |
|
309 } |
|
310 |
|
311 dec_mode = (enum Mode)((modeByte[0] & 0x0078) >> 3); |
|
312 |
|
313 switch (dec_mode) |
|
314 { |
|
315 case 0: |
|
316 readSize = 12; |
|
317 break; |
|
318 case 1: |
|
319 readSize = 13; |
|
320 break; |
|
321 case 2: |
|
322 readSize = 15; |
|
323 break; |
|
324 case 3: |
|
325 readSize = 17; |
|
326 break; |
|
327 case 4: |
|
328 readSize = 19; |
|
329 break; |
|
330 case 5: |
|
331 readSize = 20; |
|
332 break; |
|
333 case 6: |
|
334 readSize = 26; |
|
335 break; |
|
336 case 7: |
|
337 readSize = 31; |
|
338 break; |
|
339 case 8: |
|
340 readSize = 5; |
|
341 break; |
|
342 case 15: |
|
343 readSize = 0; |
|
344 break; |
|
345 default: |
|
346 readSize = 0; |
|
347 break; |
|
348 }; |
|
349 |
|
350 HBufC8* audioFrame = HBufC8::NewL(readSize+1); |
|
351 |
|
352 TPtr8 tmpDes((TPtr8)audioFrame->Des()); |
|
353 |
|
354 BufferedFileRead((TPtr8&) tmpDes, readSize); |
|
355 audioFrame->Des().Insert(0, modeByte); |
|
356 |
|
357 aFrame = audioFrame; |
|
358 |
|
359 TRAPD(err, ManipulateGainL(aFrame)); |
|
360 |
|
361 if (err != KErrNone) |
|
362 { |
|
363 // something went wrong with the gain manipulation |
|
364 // continue by returning the original frame |
|
365 } |
|
366 |
|
367 |
|
368 aSize = aFrame->Size(); |
|
369 aTime = 20; |
|
370 iCurrentTimeMilliseconds += 20; |
|
371 |
|
372 return ETrue; |
|
373 } |
|
374 |
|
375 |
|
376 |
|
377 CProcAMRInFileHandler::~CProcAMRInFileHandler() |
|
378 { |
|
379 |
|
380 if (iSilentFrame != 0) delete iSilentFrame; |
|
381 |
|
382 ResetAndCloseFile(); |
|
383 |
|
384 delete iDecoder; |
|
385 |
|
386 delete iFrameHandler; |
|
387 |
|
388 } |
|
389 |
|
390 |
|
391 TBool CProcAMRInFileHandler::GetFrameInfo(TInt& aSongDuration, |
|
392 TInt& aFrameAmount, |
|
393 TInt& aAverageFrameDuration, |
|
394 TInt& aAverageFrameSize) |
|
395 { |
|
396 |
|
397 |
|
398 |
|
399 |
|
400 if (!iFileOpen) |
|
401 { |
|
402 TAudPanic::Panic(TAudPanic::EInternal); |
|
403 } |
|
404 |
|
405 TInt fileSize = 0; |
|
406 iFile.Size(fileSize); |
|
407 |
|
408 |
|
409 TInt firstModeByte = 6; |
|
410 TInt frameIndex = 1; |
|
411 TInt readSize = 0; |
|
412 TBuf8<1> modeByte; |
|
413 |
|
414 TInt32 frameSizeSum = 0; |
|
415 |
|
416 TInt filePos = iFilePos; |
|
417 |
|
418 TUint dec_mode; |
|
419 |
|
420 BufferedFileSetFilePos(firstModeByte); |
|
421 |
|
422 while(frameIndex < 180000) // 1 hour |
|
423 { |
|
424 |
|
425 BufferedFileRead(modeByte); |
|
426 if (modeByte.Size() == 0) |
|
427 { |
|
428 break; |
|
429 } |
|
430 |
|
431 dec_mode = (enum Mode)((modeByte[0] & 0x0078) >> 3); |
|
432 |
|
433 switch (dec_mode) |
|
434 { |
|
435 case 0: |
|
436 readSize = 12; |
|
437 break; |
|
438 case 1: |
|
439 readSize = 13; |
|
440 break; |
|
441 case 2: |
|
442 readSize = 15; |
|
443 break; |
|
444 case 3: |
|
445 readSize = 17; |
|
446 break; |
|
447 case 4: |
|
448 readSize = 19; |
|
449 break; |
|
450 case 5: |
|
451 readSize = 20; |
|
452 break; |
|
453 case 6: |
|
454 readSize = 26; |
|
455 break; |
|
456 case 7: |
|
457 readSize = 31; |
|
458 break; |
|
459 case 8: |
|
460 readSize = 5; |
|
461 break; |
|
462 case 15: |
|
463 readSize = 0; |
|
464 break; |
|
465 default: |
|
466 readSize = 0; |
|
467 break; |
|
468 }; |
|
469 if (!(BufferedFileSetFilePos(BufferedFileGetFilePos()+readSize))) |
|
470 { |
|
471 |
|
472 break; // EOF |
|
473 } |
|
474 frameSizeSum += readSize; |
|
475 aSongDuration += 20; |
|
476 frameIndex++; |
|
477 } |
|
478 |
|
479 aAverageFrameSize = frameSizeSum/frameIndex; |
|
480 aFrameAmount = frameIndex; |
|
481 aAverageFrameDuration = aSongDuration/aFrameAmount; |
|
482 BufferedFileSetFilePos(filePos); |
|
483 return ETrue; |
|
484 |
|
485 |
|
486 } |
|
487 |
|
488 |
|
489 TBool CProcAMRInFileHandler::SetNormalizingGainL(const CProcFrameHandler* aFrameHandler) |
|
490 { |
|
491 |
|
492 HBufC8* point = 0; |
|
493 TInt siz; |
|
494 TInt32 tim = 0; |
|
495 TInt8 margin = 0; |
|
496 TInt minMargin = KMaxTInt; |
|
497 TInt tmpGain = 0; |
|
498 TInt frameCounter = 0; |
|
499 while(GetEncAudioFrameL(point, siz, tim)) |
|
500 |
|
501 { |
|
502 aFrameHandler->GetNormalizingMargin(point, margin); |
|
503 tmpGain += margin; |
|
504 |
|
505 delete point; |
|
506 point = 0; |
|
507 frameCounter++; |
|
508 if (frameCounter > 1) |
|
509 { |
|
510 tmpGain = tmpGain/3; |
|
511 |
|
512 if (tmpGain < minMargin) |
|
513 { |
|
514 minMargin = tmpGain; |
|
515 } |
|
516 |
|
517 frameCounter = 0; |
|
518 tmpGain = 0; |
|
519 } |
|
520 } |
|
521 |
|
522 iNormalizingMargin = static_cast<TInt8>(minMargin); |
|
523 |
|
524 return ETrue; |
|
525 } |
|
526 |
|