diff -r 000000000000 -r 951a5db380a0 videoeditorengine/audioeditorengine/codecs/WAV/src/ProcWAVInFileHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/audioeditorengine/codecs/WAV/src/ProcWAVInFileHandler.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,473 @@ +/* +* Copyright (c) 2010 Ixonos Plc. +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - Initial contribution +* +* Contributors: +* Ixonos Plc +* +* Description: +* +*/ + + + +#include "ProcWAVInFileHandler.h" +#include "ProcWAVFrameHandler.h" +#include "AudPanic.h" +#include "ProcTools.h" +#include "audconstants.h" + + + +CProcWAVInFileHandler* CProcWAVInFileHandler::NewL(const TDesC& aFileName, + RFile* aFileHandle, + CAudClip* aClip, + TInt aReadBufferSize, + TInt aTargetSampleRate, + TChannelMode aChannelMode) + { + + CProcWAVInFileHandler* self = NewLC(aFileName, aFileHandle, aClip, + aReadBufferSize, aTargetSampleRate, aChannelMode); + CleanupStack::Pop(self); + return self; + } + +CProcWAVInFileHandler* CProcWAVInFileHandler::NewLC(const TDesC& aFileName, + RFile* aFileHandle, + CAudClip* aClip, + TInt aReadBufferSize, + TInt aTargetSampleRate, + TChannelMode aChannelMode) + { + + CProcWAVInFileHandler* self = new (ELeave) CProcWAVInFileHandler(); + CleanupStack::PushL(self); + self->ConstructL(aFileName, aFileHandle, aClip, aReadBufferSize, aTargetSampleRate, aChannelMode); + return self; + } + +CProcWAVInFileHandler::CProcWAVInFileHandler() : CProcInFileHandler(), iNumberofSamplesInFrame(1) + { + + + } + +void CProcWAVInFileHandler::GetPropertiesL(TAudFileProperties* aProperties) + { + + if (iProperties != 0) + { + *aProperties = *iProperties; + return; + } + + + const TInt KFrameDurationMilli = 20; + const TInt KFramesPerSecond = 50; + + if (iFileOpen) + { + aProperties->iFileFormat = EAudFormatUnrecognized; + aProperties->iAudioType = EAudTypeUnrecognized; + aProperties->iAudioTypeExtension = EAudExtensionTypeNoExtension; + aProperties->iBitrate = 0; + aProperties->iBitrateMode = EAudBitrateModeNotRecognized; + aProperties->iChannelMode = EAudChannelModeNotRecognized; + aProperties->iDuration = 0; + aProperties->iSamplingRate = 0; + aProperties->iFrameLen = 0; + aProperties->iFrameCount = 0; + + TInt oldPos = iFilePos; + + // check the validity of WAVE header + + TBuf8<4> chunckID; + TBuf8<4> format; + TBuf8<4> fmt; + TBuf8<4> data; + + TBuf8<1> audioFormat; + + BufferedFileRead(0, chunckID); + BufferedFileRead(8, format); + BufferedFileRead(12, fmt); + BufferedFileRead(20, audioFormat); + BufferedFileRead(36, data); + + + if (chunckID.Compare(_L8("RIFF")) == 0 && + format.Compare(_L8("WAVE")) == 0 && + fmt.Compare(_L8("fmt ")) == 0 && + data.Compare(_L8("data")) == 0 && + audioFormat[0] == 0x01) + { + aProperties->iFileFormat = EAudFormatWAV; + aProperties->iAudioType = EAudWAV; + } + else + { + aProperties->iFileFormat = EAudFormatUnrecognized; + User::Leave(KErrNotSupported); + return; + + } + + TBuf8<1> numChannels; + BufferedFileRead(22, numChannels); + if (numChannels[0] == 0x01) + { + aProperties->iChannelMode = EAudSingleChannel; + } + else if (numChannels[0] == 0x02) + { + aProperties->iChannelMode = EAudStereo; + } + else + { + aProperties->iFileFormat = EAudFormatUnrecognized; + User::Leave(KErrNotSupported); + return; + } + + TBuf8<4> sr; + BufferedFileRead(24, sr); + + TBuf8<8> tmpBin; + TBuf8<8*4> srBin; + + // little endian: + for (TInt a = 3 ; a >= 0; a--) + { + ProcTools::Dec2Bin(sr[a], tmpBin); + srBin.Append(tmpBin); + } + + TUint srDec = 0; + ProcTools::Bin2Dec(srBin, srDec); + + aProperties->iSamplingRate = srDec; + + // Check that the sample rate is supported + if( (aProperties->iSamplingRate != KAedSampleRate8kHz) && + (aProperties->iSamplingRate != KAedSampleRate11kHz) && + (aProperties->iSamplingRate != KAedSampleRate16kHz) && + (aProperties->iSamplingRate != KAedSampleRate22kHz) && + (aProperties->iSamplingRate != KAedSampleRate24kHz) && + (aProperties->iSamplingRate != KAedSampleRate32kHz) && + (aProperties->iSamplingRate != KAedSampleRate44kHz) && + (aProperties->iSamplingRate != KAedSampleRate48kHz) ) + { + User::Leave(KErrNotSupported); + } + + iNumberofSamplesInFrame = srDec/(KFramesPerSecond/numChannels[0]); + if (iNumberofSamplesInFrame%2 != 0) iNumberofSamplesInFrame++; + + tmpBin.Delete(0, tmpBin.Length()); + + TBuf8<4> byteRate; + TBuf8<8*4> byteRateBin; + TUint byteRateDec = 0; + + BufferedFileRead(28, byteRate); + for (TInt b = 3 ; b >= 0; b--) + { + ProcTools::Dec2Bin(byteRate[b], tmpBin); + byteRateBin.Append(tmpBin); + } + ProcTools::Bin2Dec(byteRateBin, byteRateDec); + + aProperties->iBitrate = byteRateDec*8; + + TBuf8<1> numberOfBitsPerSample; + BufferedFileRead(34, numberOfBitsPerSample); + aProperties->iNumberOfBitsPerSample = numberOfBitsPerSample[0]; + + // other bit depths can be added later if (ever) needed + if (aProperties->iNumberOfBitsPerSample != 16 && + aProperties->iNumberOfBitsPerSample != 8) + { + aProperties->iFileFormat = EAudFormatUnrecognized; + User::Leave(KErrNotSupported); + return; + } + + if (aProperties->iNumberOfBitsPerSample == 16) + { + iNumberofSamplesInFrame *= 2; + } + + TBuf8<4> dataSize; + BufferedFileRead(40, dataSize); + + TBuf8<8*4> dataSizeBin; + TUint dataSizeDec = 0; + tmpBin.Delete(0, tmpBin.Length()); + + for (TInt c = 3 ; c >= 0; c--) + { + ProcTools::Dec2Bin(dataSize[c], tmpBin); + dataSizeBin.Append(tmpBin); + } + ProcTools::Bin2Dec(dataSizeBin, dataSizeDec); + + TTimeIntervalMicroSeconds durationMicro((TInt64)(TInt)((TReal(dataSizeDec)/byteRateDec)*1000000)); + + aProperties->iDuration = durationMicro; + aProperties->iBitrateMode = EAudConstant; + aProperties->iFrameLen = iNumberofSamplesInFrame; + + aProperties->iFrameDuration = KFrameDurationMilli*1000; + + aProperties->iFrameCount = (TInt)dataSizeDec/iNumberofSamplesInFrame; + aProperties->iNumFramesPerSample = 1; + + + + BufferedFileSetFilePos(oldPos); + } + else + { + TAudPanic::Panic(TAudPanic::EInternal); + } + + + if (iProperties == 0) + { + iProperties = new (ELeave) TAudFileProperties; + *iProperties = *aProperties; + } + + + } + +TBool CProcWAVInFileHandler::SeekAudioFrame(TInt32 aTime) + { + + TInt frameLengthMilliSeconds = ProcTools::MilliSeconds(iProperties->iFrameDuration); + + TInt framesFromStart = aTime/frameLengthMilliSeconds; + + TInt bytesFromStart = framesFromStart*iNumberofSamplesInFrame; + + const TInt KWAVHeaderLength = 44; + + BufferedFileSetFilePos(bytesFromStart+KWAVHeaderLength); + + if (!iFileOpen) + { + TAudPanic::Panic(TAudPanic::EInternal); + } + + iCurrentTimeMilliseconds = aTime; + + return ETrue; + } + +TBool CProcWAVInFileHandler::SeekCutInFrame() + { + + iCurrentTimeMilliseconds = iCutInTime; + return SeekAudioFrame(iCutInTime); + } + + + +void CProcWAVInFileHandler::ConstructL(const TDesC& aFileName, + RFile* aFileHandle, + CAudClip* aClip, + TInt aReadBufferSize, + TInt aTargetSampleRate, + TChannelMode aChannelMode) + { + + + + + + iTargetSampleRate = aTargetSampleRate; + iChannelMode = aChannelMode; + + InitAndOpenFileL(aFileName, aFileHandle, aReadBufferSize); + + + if (aClip != 0) + { + iCutInTime = ProcTools::MilliSeconds(aClip->CutInTime()); + + } + + + TAudFileProperties prop; + GetPropertiesL(&prop); + + if (iProperties != 0) + { + TInt samplesIn20ms = ((iProperties->iSamplingRate) * + (iProperties->iNumberOfBitsPerSample)/8)/50; + + if (iProperties->iChannelMode == EAudStereo) + { + samplesIn20ms *= 2; + + } + if (samplesIn20ms % 2 != 0) samplesIn20ms--; + + iSilentFrame = HBufC8::NewL(samplesIn20ms); + + if (iProperties->iNumberOfBitsPerSample == 16) + { + iSilentFrame->Des().SetLength(samplesIn20ms); + iSilentFrame->Des().Fill(0); + + } + else if(iProperties->iNumberOfBitsPerSample == 8) + { + iSilentFrame->Des().SetLength(samplesIn20ms); + iSilentFrame->Des().Fill(128); + + } + iSilentFrameDuration = 20; + } + else + { + User::Leave(KErrNotSupported); + } + + iClip = aClip; + + iFrameHandler = CProcWAVFrameHandler::NewL(iProperties->iNumberOfBitsPerSample); + + // Generate a decoder -----------------------> + + iDecoder = CProcDecoder::NewL(); + + iDecodingPossible = iDecoder->InitL(*iProperties, aTargetSampleRate, aChannelMode); + + + // <----------------------- Generate a decoder + + if (iClip != 0 && iClip->Normalizing()) + { + SetNormalizingGainL(iFrameHandler); + } + + } + + +TBool CProcWAVInFileHandler::GetEncAudioFrameL(HBufC8*& aFrame, TInt& aSize, TInt32& aTime) + { + + if (!iFileOpen) + { + TAudPanic::Panic(TAudPanic::EInternal); + } + + TInt numberOfBytesInFrame = iNumberofSamplesInFrame; + TInt bufferSize = numberOfBytesInFrame; + if (iProperties->iNumberOfBitsPerSample == 8) + { + // need to expand to 16 bits per sample since encoders and MMF sample rate converter assumes 16-bit signed input + bufferSize *= 2; + } + + + aFrame = HBufC8::NewL(bufferSize); + + TPtr8 tmpDes((TPtr8)aFrame->Des()); + + BufferedFileRead((TPtr8&)tmpDes , numberOfBytesInFrame); + + if (aFrame->Des().Length() < numberOfBytesInFrame) + { + delete aFrame; + aFrame = 0; + return EFalse; + } + aTime = ProcTools::MilliSeconds(iProperties->iFrameDuration); + iCurrentTimeMilliseconds += aTime; + + TRAPD(err, ManipulateGainL(aFrame)); + + if (err != KErrNone) + { + // something went wrong with the gain manipulation + // continue by returning the original frame + } + + if (iProperties->iNumberOfBitsPerSample == 8) + { + // need to expand to 16 bits per sample since encoders and MMF sample rate converter assumes 16-bit signed input + TUint8* buffer = const_cast(aFrame->Ptr()); + // start from the end to avoid overlapping + for ( TInt i = numberOfBytesInFrame-1; i >= 0 ; i-- ) + { + buffer[i*2+1] = TInt8(buffer[i]) - 128; // 8-bit Wav's are unsigned, 16-bit Wav's are signed + buffer[i*2] = 0; + } + tmpDes.SetLength(bufferSize); + + } + aSize = aFrame->Length(); + + + return ETrue; + + } + + + + +CProcWAVInFileHandler::~CProcWAVInFileHandler() + { + + ResetAndCloseFile(); + + if (iSilentFrame != 0) delete iSilentFrame; + + delete iFrameHandler; + + delete iDecoder; + + } + + +TBool CProcWAVInFileHandler::SetNormalizingGainL(const CProcFrameHandler* aFrameHandler) + { + + HBufC8* point = 0; + TInt siz; + TInt32 tim = 0; + TInt8 margin = 0; + TInt minMargin = KMaxTInt; + + while(GetEncAudioFrameL(point, siz, tim)) + + { + aFrameHandler->GetNormalizingMargin(point, margin); + + delete point; + point = 0; + + if (minMargin > margin) + { + minMargin = margin; + } + + } + + iNormalizingMargin = static_cast(minMargin); + + return ETrue; + + } +