diff -r 000000000000 -r 951a5db380a0 videoeditorengine/audioeditorengine/src/AudProcessorImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/audioeditorengine/src/AudProcessorImpl.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,997 @@ +/* +* 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 "AudProcessorImpl.h" +#include "ProcAMRInFileHandler.h" + +#include "ProcMP4InFileHandler.h" +#include "ProcADTSInFileHandler.h" +#include "ProcMP3InFileHandler.h" +#include "ProcAWBInFileHandler.h" +#include "ProcWAVInFileHandler.h" + + +#include "ProcAMRFrameHandler.h" +#include "ProcAACFrameHandler.h" +#include "ProcMP3FrameHandler.h" +#include "ProcAWBFrameHandler.h" +#include "ProcWAVFrameHandler.h" + + + +#include "AudCommon.h" +#include "ProcTools.h" +#include "AudPanic.h" + +// Debug print macro +#if defined _DEBUG +#include +#define PRINT(x) RDebug::Print x; +#else +#define PRINT(x) +#endif + +const TInt KTimeEstimateTime = 2000; // 1000 ms + +CAudProcessorImpl* CAudProcessorImpl::NewL() + { + + + CAudProcessorImpl* self = new (ELeave) CAudProcessorImpl(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CAudProcessorImpl* CAudProcessorImpl::NewLC() + { + CAudProcessorImpl* self = new (ELeave) CAudProcessorImpl(); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CAudProcessorImpl::~CAudProcessorImpl() + { + + PRINT((_L("CAudProcessorImpl::~CAudProcessorImpl() in"))); + TInt a = 0; + + for (a = 0; a < iInFiles.Count() ; a++) + { + delete iInFiles[a]; + } + iInFiles.Reset(); + + PRINT((_L("CAudProcessorImpl::~CAudProcessorImpl() deleted iInFiles"))); + delete iWAVFrameHandler; + + iClipsWritten.Reset(); + + iProcessingEvents.ResetAndDestroy(); + + PRINT((_L("CAudProcessorImpl::~CAudProcessorImpl() out"))); + } + + +void CAudProcessorImpl::ConstructL() + { + + + + } + +CAudProcessorImpl::CAudProcessorImpl() : iInFiles(8), iSong(0), + iTimeLeft(0), + iCurEvent(0), + iProcessingEvents(8), + iSongDurationMilliSeconds(0), + iSongProcessedMilliSeconds(0) + + { + + + } + +void CAudProcessorImpl::ProcessSongL(const CAudSong* aSong, TInt aRawFrameSize, TBool aGetTimeEstimation) +{ + PRINT((_L("CAudProcessorImpl::ProcessSongL in"))); + + iGetTimeEstimation = aGetTimeEstimation; + + iSilenceStarted = EFalse; + + iSong = aSong; + + TInt clips = aSong->iClipArray.Count(); + + + // bitdepth always 16 + const TInt KBitDepth = 16; + + iWAVFrameHandler = CProcWAVFrameHandler::NewL(KBitDepth); + + // create inFileHandlers for each input clips---> + for (TInt a = 0 ; a < clips ; a++) + { + if (aSong->iClipArray[a]->Info()->Properties().iFileFormat == EAudFormatAMR) + { + PRINT((_L("CAudProcessorImpl::ProcessSongL create AMRNB file handler"))); + CProcInFileHandler* inFileHandler = + CProcAMRInFileHandler::NewL(aSong->iClipArray[a]->Info()->FileName(), + aSong->iClipArray[a]->Info()->FileHandle(), aSong->iClipArray[a], + 4096, iSong->OutputFileProperties().iSamplingRate, + iSong->OutputFileProperties().iChannelMode); + + iInFiles.Insert(inFileHandler, iInFiles.Count()); + inFileHandler->SetPropertiesL(aSong->iClipArray[a]->Info()->Properties()); + inFileHandler->SetPriority(aSong->iClipArray[a]->Priority()); + + inFileHandler->SeekCutInFrame(); + + if (IsDecodingRequired(aSong->OutputFileProperties(), + aSong->iClipArray[a]->Info()->Properties())) + { + inFileHandler->SetDecodingRequired(ETrue); + } + + + + + } + else if (aSong->iClipArray[a]->Info()->Properties().iFileFormat == EAudFormatMP4) + { + PRINT((_L("CAudProcessorImpl::ProcessSongL create MP4 file handler"))); + CProcInFileHandler* inFileHandler = + CProcMP4InFileHandler::NewL(aSong->iClipArray[a]->Info()->FileName(), + aSong->iClipArray[a]->Info()->FileHandle(), + aSong->iClipArray[a], + 4096, iSong->OutputFileProperties().iSamplingRate, + iSong->OutputFileProperties().iChannelMode); + + iInFiles.Insert(inFileHandler, iInFiles.Count()); + TAudFileProperties prororo; + inFileHandler->GetPropertiesL(&prororo); + inFileHandler->SetPriority(aSong->iClipArray[a]->Priority()); + inFileHandler->SeekCutInFrame(); + + if (IsDecodingRequired(aSong->OutputFileProperties(), + aSong->iClipArray[a]->Info()->Properties())) + { + inFileHandler->SetDecodingRequired(ETrue); + } + + + + } + + else if (aSong->iClipArray[a]->Info()->Properties().iFileFormat == EAudFormatAAC_ADTS) + { + PRINT((_L("CAudProcessorImpl::ProcessSongL create AAC ADTS file handler"))); + CProcInFileHandler* inFileHandler = + CProcADTSInFileHandler::NewL(aSong->iClipArray[a]->Info()->FileName(), + aSong->iClipArray[a]->Info()->FileHandle(), + aSong->iClipArray[a], + 8092, iSong->OutputFileProperties().iSamplingRate, + iSong->OutputFileProperties().iChannelMode); + TAudFileProperties pro; + + iInFiles.Insert(inFileHandler, iInFiles.Count()); + inFileHandler->GetPropertiesL(&pro); + inFileHandler->SetPriority(aSong->iClipArray[a]->Priority()); + inFileHandler->SeekCutInFrame(); + + if (IsDecodingRequired(aSong->OutputFileProperties(), + aSong->iClipArray[a]->Info()->Properties())) + { + inFileHandler->SetDecodingRequired(ETrue); + } + + + + } + else if (aSong->iClipArray[a]->Info()->Properties().iFileFormat == EAudFormatMP3) + { + PRINT((_L("CAudProcessorImpl::ProcessSongL create MP3 file handler"))); + CProcInFileHandler* inFileHandler = + CProcMP3InFileHandler::NewL(aSong->iClipArray[a]->Info()->FileName(), + aSong->iClipArray[a]->Info()->FileHandle(), + aSong->iClipArray[a], + 4096, iSong->OutputFileProperties().iSamplingRate, + iSong->OutputFileProperties().iChannelMode); + + iInFiles.Insert(inFileHandler, iInFiles.Count()); + inFileHandler->SetPropertiesL(aSong->iClipArray[a]->Info()->Properties()); + inFileHandler->SetPriority(aSong->iClipArray[a]->Priority()); + inFileHandler->SeekCutInFrame(); + + + if (IsDecodingRequired(aSong->OutputFileProperties(), + aSong->iClipArray[a]->Info()->Properties())) + { + inFileHandler->SetDecodingRequired(ETrue); + } + + } + else if (aSong->iClipArray[a]->Info()->Properties().iFileFormat == EAudFormatAMRWB) + { + PRINT((_L("CAudProcessorImpl::ProcessSongL create AMRWB file handler"))); + CProcInFileHandler* inFileHandler = + CProcAWBInFileHandler::NewL(aSong->iClipArray[a]->Info()->FileName(), + aSong->iClipArray[a]->Info()->FileHandle(), + aSong->iClipArray[a], + 4096, iSong->OutputFileProperties().iSamplingRate, + iSong->OutputFileProperties().iChannelMode); + + iInFiles.Insert(inFileHandler, iInFiles.Count()); + inFileHandler->SetPropertiesL(aSong->iClipArray[a]->Info()->Properties()); + inFileHandler->SetPriority(aSong->iClipArray[a]->Priority()); + inFileHandler->SeekCutInFrame(); + + if (IsDecodingRequired(aSong->OutputFileProperties(), + aSong->iClipArray[a]->Info()->Properties())) + { + inFileHandler->SetDecodingRequired(ETrue); + } + + } + else if (aSong->iClipArray[a]->Info()->Properties().iFileFormat == EAudFormatWAV) + { + PRINT((_L("CAudProcessorImpl::ProcessSongL create WAV file handler"))); + CProcInFileHandler* inFileHandler = + CProcWAVInFileHandler::NewL(aSong->iClipArray[a]->Info()->FileName(), + aSong->iClipArray[a]->Info()->FileHandle(), + aSong->iClipArray[a], + 4096, iSong->OutputFileProperties().iSamplingRate, + iSong->OutputFileProperties().iChannelMode); + + iInFiles.Insert(inFileHandler, iInFiles.Count()); + inFileHandler->SetPropertiesL(aSong->iClipArray[a]->Info()->Properties()); + inFileHandler->SetPriority(aSong->iClipArray[a]->Priority()); + inFileHandler->SeekCutInFrame(); + + if (IsDecodingRequired(aSong->OutputFileProperties(), + aSong->iClipArray[a]->Info()->Properties())) + { + inFileHandler->SetDecodingRequired(ETrue); + } + + } + + } + + + // find the biggest frame size for mixing buffer + TInt maxFrameSize = 0; + for (TInt q = 0 ; q < iInFiles.Count() ; q++) + { + iInFiles[q]->SetRawAudioFrameSize(aRawFrameSize); + + if (iInFiles[q]->GetDecodedFrameSize() > maxFrameSize) + { + maxFrameSize = iInFiles[q]->GetDecodedFrameSize(); + } + + } + + + + GetProcessingEventsL(); + iProcessingEvents[0]->GetAllIndexes(iClipsWritten); + iTimeLeft = iProcessingEvents[1]->iPosition; + iCurEvent = 0; + + + if (iGetTimeEstimation) + { + iTimer.HomeTime(); + + if (iTimeLeft >= KTimeEstimateTime) + { + iTimeEstimateCoefficient = iTimeLeft/KTimeEstimateTime; + + iTimeLeft = KTimeEstimateTime; + } + else + { + iTimeEstimateCoefficient = 1; + } + + } + + + PRINT((_L("CAudProcessorImpl::ProcessSongL out"))); + } + +TBool CAudProcessorImpl::ProcessSyncPieceL(HBufC8*& aFrame, TInt& aProgress, + TTimeIntervalMicroSeconds& aDuration, TBool& aRaw) +{ + + PRINT((_L("CAudProcessorImpl::ProcessSyncPieceL in"))); + aDuration = 0; + + if (iSongProcessedMilliSeconds > iSongDurationMilliSeconds) + { + // processing is ready + StopProcessing(); + PRINT((_L("CAudProcessorImpl::ProcessSyncPieceL stopped processing 1, out"))); + return ETrue; + + } + + + while (iTimeLeft <= 0) + { + + iCurEvent++; + + if (iCurEvent >= iProcessingEvents.Count()-1) + { + + // do we need silence in the end? + if (iSongProcessedMilliSeconds < ProcTools::MilliSeconds(iSong->iSongDuration)) + { + + if (iGetTimeEstimation) + { + StopProcessing(); + PRINT((_L("CAudProcessorImpl::ProcessSyncPieceL stopped processing in time estimate case, out"))); + return ETrue; + + } + + + WriteSilenceL(aFrame, aProgress, aDuration, aRaw); + return EFalse; + } + // processing is ready + StopProcessing(); + PRINT((_L("CAudProcessorImpl::ProcessSyncPieceL stopped processing 2, out"))); + return ETrue; + } + + iClipsWritten.Reset(); + for (TInt tr = 0 ; tr < iProcessingEvents[iCurEvent]->IndexCount() ; tr++) + { + + TInt clipIndex = iProcessingEvents[iCurEvent]->GetIndex(tr); + + + if (clipIndex == -1 || !iSong->Clip(clipIndex, KAllTrackIndices)->Muting()) + { + iClipsWritten.Append(iProcessingEvents[iCurEvent]->GetIndex(tr)); + + } + + } + iTimeLeft = iProcessingEvents[iCurEvent+1]->iPosition - + iProcessingEvents[iCurEvent]->iPosition; + + if (iGetTimeEstimation) + { + + TTime timeNow; + timeNow.HomeTime(); + + // how long has it been from the previous event? + TTimeIntervalMicroSeconds msFromPrev = timeNow.MicroSecondsFrom(iTimer); + + iTimeEstimate += msFromPrev.Int64() * iTimeEstimateCoefficient; + + // set iTimer to home time + iTimer.HomeTime(); + + if (iTimeLeft > KTimeEstimateTime) + { + iTimeEstimateCoefficient = iTimeLeft/KTimeEstimateTime; + iTimeLeft = KTimeEstimateTime; + } + else + { + iTimeEstimateCoefficient = 1; + } + + } + + } + + + if (iClipsWritten.Count() == 1) + { + // if silence + WriteSilenceL(aFrame, aProgress, aDuration, aRaw); + PRINT((_L("CAudProcessorImpl::ProcessSyncPieceL silence, out"))); + return EFalse; + + } + else if (iTimeLeft > 0) + { + + + TInt inClipIndex1 = 0; + TInt inClipIndex2 = 0; + + HighestInFilePriority(inClipIndex1, inClipIndex2); + + CAudClip* clip1 = iSong->iClipArray[iClipsWritten[inClipIndex1]]; + CAudClip* clip2 = iSong->iClipArray[iClipsWritten[inClipIndex2]]; + + CProcInFileHandler* inHandler1 = iInFiles[iClipsWritten[inClipIndex1]]; + CProcInFileHandler* inHandler2 = iInFiles[iClipsWritten[inClipIndex2]]; + + + TBool writeClip1 = ETrue; + TBool writeClip2 = ETrue; + + if (clip1 == clip2) + { + writeClip2 = EFalse; + } + if (clip1->Muting()) + { + writeClip1 = EFalse; + } + if (clip2->Muting()) + { + writeClip2 = EFalse; + } + + + HBufC8* frame1 = 0; + HBufC8* frame2 = 0; + TInt siz1 = 0; + TInt32 tim1 = 0; + TInt siz2 = 0; + TInt32 tim2 = 0; + + TBool getFrameRet1 = EFalse; + TBool getFrameRet2 = EFalse; + // If the clip is muted -> return silence + + if (!writeClip1 && !writeClip2) + { + + getFrameRet1 = inHandler1->GetSilentAudioFrameL(frame1, siz1, tim1, aRaw); + + } + + else if (!writeClip1 && writeClip2) + { + + getFrameRet2 = inHandler2->GetAudioFrameL(frame2, siz2, tim2, aRaw); + + } + else if (writeClip1 && !writeClip2) + { + + getFrameRet1 = inHandler1->GetAudioFrameL(frame1, siz1, tim1, aRaw); + + } + else + { + + TBool decodingRequired1 = inHandler1->DecodingRequired(); + TBool decodingRequired2 = inHandler2->DecodingRequired(); + + // decoding is needed due to mixing + inHandler1->SetDecodingRequired(ETrue); + inHandler2->SetDecodingRequired(ETrue); + + getFrameRet1 = inHandler1->GetAudioFrameL(frame1, siz1, tim1, aRaw); + + // fix to rel2, put frame1 to cleanup stack for the next operation + CleanupStack::PushL(frame1); + getFrameRet2 = inHandler2->GetAudioFrameL(frame2, siz2, tim2, aRaw); + CleanupStack::Pop(); // frame1, will be put to cleanupstack later-> + + + inHandler1->SetDecodingRequired(decodingRequired1); + inHandler2->SetDecodingRequired(decodingRequired2); + + } + + + if(!getFrameRet1 && !getFrameRet2) + { + // no audio frames left -> write silence + + getFrameRet1 = inHandler1->GetSilentAudioFrameL(frame1, siz1, tim1, aRaw); + + } + + if (frame1 != 0) + { + CleanupStack::PushL(frame1); + } + if (frame2 != 0) + { + CleanupStack::PushL(frame2); + } + + + if (getFrameRet1 && getFrameRet2) + { + + // mix the two frames + iWAVFrameHandler->MixL(frame1, frame2, aFrame); + CleanupStack::PopAndDestroy(frame2); + CleanupStack::PopAndDestroy(frame1); + aDuration = TUint(tim1*1000); + + } + else if (getFrameRet1 && !getFrameRet2) + { + aFrame = HBufC8::NewL(frame1->Length()); + aFrame->Des().Copy(frame1->Des()); + CleanupStack::PopAndDestroy(frame1); + aDuration = TUint(tim1*1000); + + + } + else if (!getFrameRet1 && getFrameRet2) + { + + aFrame = HBufC8::NewL(frame2->Length()); + aFrame->Des().Copy(frame2->Des()); + CleanupStack::PopAndDestroy(frame2); + aDuration = TUint(tim2*1000); + + } + else if (!getFrameRet1 && !getFrameRet2) + { + + // shouldn't get here... + + User::Leave(KErrGeneral); + } + + + iTimeLeft -= ProcTools::MilliSeconds(aDuration); + iSongProcessedMilliSeconds += ProcTools::MilliSeconds(aDuration); + + + } + + if (iSongDurationMilliSeconds > 0) + { + + // update progress + aProgress = (iSongProcessedMilliSeconds*100)/iSongDurationMilliSeconds; + + } + PRINT((_L("CAudProcessorImpl::ProcessSyncPieceL out"))); + return EFalse; + + } + + +void CAudProcessorImpl::GetAudFilePropertiesL(const TDesC& aFileName, RFile* aFileHandle, + TAudFileProperties* aProperties) + { + + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL in"))); + + + + PRINT(_L("CAudProcessorImpl::GetAudFilePropertiesL read header from file")); + + TBuf8<10> fileHeader; + + if (!aFileHandle) + { + RFs* fs = new (ELeave) RFs; + CleanupStack::PushL(fs); + User::LeaveIfError( fs->Connect() ); + + RFile file; + TInt error = file.Open(*fs, aFileName, EFileShareReadersOnly | EFileStream | EFileRead);//EFileShareAny | EFileStream | EFileRead); + if (error != KErrNone) + { + error = file.Open(*fs, aFileName, EFileShareAny | EFileStream | EFileRead); + } + if (error == KErrNone) + { + error = file.Read(fileHeader); + } + file.Close(); + fs->Close(); + CleanupStack::PopAndDestroy(fs); + User::LeaveIfError(error); + } + else + { + TInt pos = 0; + + User::LeaveIfError( aFileHandle->Seek(ESeekCurrent, pos) ); + + TInt zero = 0; + User::LeaveIfError( aFileHandle->Seek(ESeekStart, zero) ); + User::LeaveIfError( aFileHandle->Read(fileHeader) ); + + User::LeaveIfError( aFileHandle->Seek(ESeekStart, pos) ); + } + + if (fileHeader.Length() < 10 ) //AMR-WB has 9-byte header, but header-only clips are not accepted. Hence accepting only 10 and more byte clips. + { + PRINT(_L("CAudProcessorImpl::GetAudFilePropertiesL the file has less than 9 bytes, it must be invalid")); + User::Leave(KErrCorrupt); + } + + PRINT(_L("CAudProcessorImpl::GetAudFilePropertiesL interpret the header")); + + TParse fp; + TFileName name; + + if (!aFileHandle) + fp.Set(aFileName, NULL, NULL); + else + { + User::LeaveIfError( aFileHandle->FullName(name) ); + fp.Set(name, NULL, NULL); + } + + if ( fileHeader.Mid(4,4) == _L8("ftyp") ) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL 3gp/mp4/m4a based on ftyp"))); + // 3gp/mp4/m4a; extension-based recognition later + CProcInFileHandler* inFileHandler = CProcMP4InFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + } + else if (fileHeader.Mid(0,6) == _L8("#!AMR\n")) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL AMR-NB based on #!AMR"))); + // AMR-NB + CProcInFileHandler* inFileHandler = CProcAMRInFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + CleanupStack::PushL(inFileHandler); + + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + + } + else if (fileHeader.Mid(0,9) == _L8("#!AMR-WB\n")) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL awb based on #!AMR-WB"))); + CProcInFileHandler* inFileHandler = CProcAWBInFileHandler::NewL(aFileName, aFileHandle,0, 4096); + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + } + else if (fp.Ext().CompareF(_L(".aac")) == 0) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL aac based on extension"))); + CProcInFileHandler* inFileHandler = CProcADTSInFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + } + else if (fp.Ext().CompareF(_L(".3gp")) == 0) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL 3gp based on extension"))); + + CProcInFileHandler* inFileHandler = CProcMP4InFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + + } + + else if (fp.Ext().CompareF(_L(".m4a")) == 0 || + fp.Ext().CompareF(_L(".mp4")) == 0) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL mp4/m4a based on extension"))); + + CProcInFileHandler* inFileHandler = 0; + + inFileHandler = CProcMP4InFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + CleanupStack::PopAndDestroy(inFileHandler); + + } + else if (fp.Ext().CompareF(_L(".amr")) == 0) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL AMR-NB based on extension"))); + // AMR-NB + CProcInFileHandler* inFileHandler = CProcAMRInFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + CleanupStack::PushL(inFileHandler); + + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + } + else if (fp.Ext().CompareF(_L(".awb")) == 0) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL awb based on extension"))); + CProcInFileHandler* inFileHandler = CProcAWBInFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + } + else if (fp.Ext().CompareF(_L(".mp3")) == 0) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL mp3 based on extension"))); + + CProcInFileHandler* inFileHandler = CProcMP3InFileHandler::NewL(aFileName, aFileHandle, 0, 4096); + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + + CleanupStack::PopAndDestroy(inFileHandler); + } + else if (fp.Ext().CompareF(_L(".wav")) == 0) + { + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL wav based on extension"))); + + CProcInFileHandler* inFileHandler = CProcWAVInFileHandler::NewL(aFileName, aFileHandle, 0, 8192); + CleanupStack::PushL(inFileHandler); + inFileHandler->GetPropertiesL(aProperties); + CleanupStack::PopAndDestroy(inFileHandler); + } + else + { + User::Leave(KErrNotSupported); + } + + PRINT((_L("CAudProcessorImpl::GetAudFilePropertiesL out"))); + } + + +TInt64 CAudProcessorImpl::GetFinalTimeEstimate() const + { + return iTimeEstimate; + } + +void CAudProcessorImpl::GetProcessingEventsL() + { + + TInt clips = iSong->iClipArray.Count(); + + CProcessingEvent* newEvent = 0; + + TInt a = 0; + + // create a new processing event from each clips cutIn and cutOut + for (a = 0 ; a < clips ; a++) + { + + + // cut in time: + newEvent = CProcessingEvent::NewL(); + newEvent->iChangedClipIndex = a; + newEvent->iCutIn = ETrue; + TInt32 startTime = iSong->iClipArray[a]->StartTimeMilliSeconds(); + TInt32 cutInTime= iSong->iClipArray[a]->CutInTimeMilliSeconds(); + newEvent->iPosition = startTime+cutInTime; + iProcessingEvents.Insert(newEvent, 0); + + // cut out time + newEvent = CProcessingEvent::NewL(); + newEvent->iChangedClipIndex = a; + newEvent->iCutIn = EFalse; + TInt32 cutOutTime= iSong->iClipArray[a]->CutOutTimeMilliSeconds(); + newEvent->iPosition = startTime+cutOutTime; + iProcessingEvents.Insert(newEvent, 0); + + } + + + + + // order processing events + TLinearOrder order(CProcessingEvent::Compare); + iProcessingEvents.Sort(order); + + // add a new processing events in the beginning to represent silence + // (there is a possibility that the first clip doesn't start from 0 ms) + newEvent = CProcessingEvent::NewL(); + newEvent->iChangedClipIndex = -1; + newEvent->InsertIndex(-1); + newEvent->iCutIn = ETrue; + newEvent->iPosition = 0; + iProcessingEvents.Insert(newEvent, 0); + + // the next for-loop adds indexes of those clips that are supposed to be mixed to + // each processing event + + for (TInt r = 1; r < iProcessingEvents.Count() ; r++) + { + + + for (TInt i = 0 ; i < iProcessingEvents[r-1]->IndexCount() ; i++) + { + iProcessingEvents[r]->InsertIndex(iProcessingEvents[r-1]->GetIndex(i)); + } + + + if (iProcessingEvents[r]->iCutIn) + { + iProcessingEvents[r]->InsertIndex(iProcessingEvents[r]->iChangedClipIndex); + } + else + { + + TInt oldIndexInArray = iProcessingEvents[r]->FindIndex(iProcessingEvents[r]->iChangedClipIndex); + + if (oldIndexInArray >= 0 && oldIndexInArray < iProcessingEvents[r]->IndexCount()) + { + iProcessingEvents[r]->RemoveIndex(oldIndexInArray); + } + + } + + } + + //iSongDurationMilliSeconds = (iSong->iSongDuration.Int64()/1000); + iSongDurationMilliSeconds = ProcTools::MilliSeconds(iSong->iSongDuration); + + //iProcessingEvents[iProcessingEvents.Count()-1]->iPosition; + + + } + + + + +TBool CAudProcessorImpl::StopProcessing() + { + + if (iGetTimeEstimation) + { + + TTime timeNow; + timeNow.HomeTime(); + + // how long has it been from the previous event? + TTimeIntervalMicroSeconds msFromPrev = timeNow.MicroSecondsFrom(iTimer); + + iTimeEstimate += msFromPrev.Int64() * iTimeEstimateCoefficient; + } + + + iProcessingEvents.ResetAndDestroy(); + iInFiles.ResetAndDestroy(); + + return ETrue; + } + +TBool CAudProcessorImpl::WriteSilenceL(HBufC8*& aFrame, TInt& aProgress, + TTimeIntervalMicroSeconds& aDuration, TBool& aRaw) + { + HBufC8* silentFrame = 0; + TInt silSize = 0; + TInt32 silDur = 0; + + if (iSong->iProperties->iAudioType == EAudAAC_MPEG4 && + iSong->iProperties->iChannelMode == EAudSingleChannel) + { + + aDuration = ((1024*1000)/(iSong->iProperties->iSamplingRate))*1000; + + silDur = ProcTools::MilliSeconds(aDuration); + + aFrame = HBufC8::NewL(KSilentMonoAACFrameLenght); + aFrame->Des().Append(KSilentMonoAACFrame, KSilentMonoAACFrameLenght); + + aRaw = EFalse; + + } + else if (iSong->iProperties->iAudioType == EAudAAC_MPEG4 && + iSong->iProperties->iChannelMode == EAudStereo) + { + + aDuration = ((1024*1000)/(iSong->iProperties->iSamplingRate))*1000; + + silDur = ProcTools::MilliSeconds(aDuration); + + aFrame = HBufC8::NewL(KSilentStereoAACFrameLenght); + aFrame->Des().Append(KSilentStereoAACFrame, KSilentStereoAACFrameLenght); + + aRaw = EFalse; + + } + else + { + iInFiles[0]->GetSilentAudioFrameL(silentFrame, silSize, silDur, aRaw); + + aFrame= silentFrame; + aDuration = TUint(silDur*1000); + + } + + iSongProcessedMilliSeconds += silDur; + iTimeLeft -= silDur; + + if (iSongDurationMilliSeconds > 0) + { + aProgress = (iSongProcessedMilliSeconds*100)/iSongDurationMilliSeconds; + } + + return ETrue; + } + + +TBool CAudProcessorImpl::HighestInFilePriority(TInt& aFirst, TInt& aSecond) + { + + aFirst = 1; + aSecond = 1; + + TInt highest = 1; + + TInt secondHighest = 1; + + + for (TInt a = 1 ; a < iClipsWritten.Count() ; a++) + { + if (iInFiles[iClipsWritten[a]]->Priority() >= highest) + { + + // highest priority + aFirst = a; + highest = iInFiles[iClipsWritten[a]]->Priority(); + + } + else if (iInFiles[iClipsWritten[a]]->Priority() >= secondHighest) + { + aSecond = a; + secondHighest = iInFiles[iClipsWritten[a]]->Priority(); + } + + } + + + return ETrue; + } + +TBool CAudProcessorImpl::IsDecodingRequired(const TAudFileProperties& prop1, + const TAudFileProperties& prop2) + { + + TBool decodingNeeded = EFalse; + TAudFileProperties tmpProp1 = prop1; + TAudFileProperties tmpProp2 = prop2; + + + if (tmpProp1.iAudioType != + tmpProp2.iAudioType || + tmpProp1.iSamplingRate != + tmpProp2.iSamplingRate || + tmpProp1.iChannelMode != + tmpProp2.iChannelMode) + { + decodingNeeded = ETrue; + } + + return decodingNeeded; + + + } + + +