videoeditorengine/audioeditorengine/src/AudProcessorImpl.cpp
changeset 0 951a5db380a0
--- /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 <e32svr.h>
+#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<CProcessingEvent> 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;
+    
+    
+    }
+
+    
+