--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/audioeditorengine/src/AudSong.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,1438 @@
+/*
+* 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 "AudSong.h"
+#include "AudClip.h"
+#include "AudPanic.h"
+#include "ProcInFileHandler.h"
+#include "ProcADTSInFileHandler.h"
+#include "ProcAMRInFileHandler.h"
+#include "ProcMP4InFileHandler.h"
+#include "ProcAWBInFileHandler.h"
+#include "AACConstants.h"
+#include "audconstants.h"
+
+#include "AudProcessor.h"
+#include "AACApi.h"
+#include "aedproctimeestimate.h"
+
+#include <e32base.h>
+
+// Debug print macro
+#if defined _DEBUG
+#include <e32svr.h>
+#define PRINT(x) RDebug::Print x;
+#else
+#define PRINT(x)
+#endif
+
+EXPORT_C CAudSong* CAudSong::NewL(RFs *aFs)
+ {
+ CAudSong* self = NewLC(aFs);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+EXPORT_C CAudSong* CAudSong::NewLC(RFs *aFs)
+ {
+ CAudSong* self = new (ELeave) CAudSong(aFs);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+CAudSong::CAudSong(RFs *aFs) : iFs(aFs), iClipArray(32), iSongDuration(0),
+ iSongDurationManuallySet(EFalse), iObserverArray(16), iNormalize(EFalse)
+ {
+ }
+
+
+void CAudSong::ConstructL()
+ {
+ iProperties = new (ELeave) TAudFileProperties();
+
+ iProperties->iAudioType = EAudNoAudio;
+ iProperties->iFileFormat = EAudFormatUnrecognized;
+ iProperties->iDuration = 0;
+ iProperties->iFrameCount = 0;
+ iProperties->iFrameLen = 0;
+ iProperties->iFrameDuration = 0;
+
+
+ iProcessOperation = CAudSongProcessOperation::NewL(this);
+ iAddOperation = CAudSongAddClipOperation::NewL(this);
+
+
+#ifdef _WRITE_OUTPUT_TO_FILE_
+
+
+ TBuf<32> fileName;
+ _LIT(KFn, "C:\\audioEngineOut.");
+ _LIT(KTextFileName, "C:\\audioEngineOut.txt");
+
+ fileName.Append(KFn);
+
+ if (iProperties->iAudioType == EAudAMR)
+ {
+ fileName.Append(_L("amr"));
+ }
+ else
+ {
+ fileName.Append(_L("aac"));
+ }
+
+
+ User::LeaveIfError(iDebFs.Connect());
+ iDebFs.Delete(fileName);
+ iDebFs.Delete(KTextFileName);
+
+ iFileOpen = EFalse;
+ TInt err1 = iAudioFile.Create(iDebFs, fileName, EFileWrite);
+
+ TInt err2 = iTextFile.Create(iDebFs, KTextFileName, EFileWrite);
+
+ if (err1 == KErrNone && err2 == KErrNone)
+ {
+ iFileOpen = ETrue;
+ }
+
+ if (iFileOpen && iProperties->iAudioType == EAudAMR)
+ {
+ iAudioFile.Write(_L8("#!AMR"));
+ }
+
+#endif
+
+
+ }
+
+
+EXPORT_C CAudSong::~CAudSong()
+ {
+
+ Reset(EFalse);
+ delete iProperties;
+ iProperties = 0;
+ delete iProcessOperation;
+ iProcessOperation = 0;
+ delete iAddOperation;
+ iAddOperation = 0;
+
+
+ iObserverArray.Reset();
+
+
+#ifdef _WRITE_OUTPUT_TO_FILE_
+ iAudioFile.Close();
+ iTextFile.Close();
+ iDebFs.Close();
+
+#endif
+
+ }
+
+EXPORT_C TInt CAudSong::GetSizeEstimateL() const
+ {
+
+
+ // if there are no clips added yet
+ if (iClipArray.Count() == 0)
+ {
+ return 0;
+ }
+
+ TInt durationMilli = ProcTools::MilliSeconds(iClipArray[iClipArray.Count()-1]->EndTime());
+ TInt silenceDuration = ProcTools::MilliSeconds(iSongDuration) - durationMilli;
+
+ if (silenceDuration < 0)
+ {
+ silenceDuration = 0;
+ }
+
+ TInt sizeInBytes = 0;
+
+ const TInt KBitrate = iProperties->iBitrate;
+ const TInt KBitsInByte = 8;
+ TInt KByterate = KBitrate/KBitsInByte;
+
+ // make sure we round up
+ sizeInBytes = (durationMilli/1000+1)*KByterate;
+
+ TInt frameDurationMilli = 20; // AMR
+ TInt silentFrameLen = 13; // AMR
+
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ frameDurationMilli = ((1024*1000)/(iProperties->iSamplingRate));
+
+ if (iProperties->iChannelMode == EAudSingleChannel)
+ {
+ silentFrameLen = KSilentMonoAACFrameLenght;
+ }
+ else
+ {
+ silentFrameLen = KSilentStereoAACFrameLenght;
+ }
+
+ }
+
+ if (frameDurationMilli > 0)
+ {
+ TInt silentFrames = silenceDuration/frameDurationMilli;
+ TInt silenceSize = silentFrames*silentFrameLen;
+ sizeInBytes += silenceSize;
+
+ }
+
+ return sizeInBytes;
+
+ }
+
+EXPORT_C TInt CAudSong::GetFrameSizeEstimateL(TTimeIntervalMicroSeconds aStartTime,
+ TTimeIntervalMicroSeconds aEndTime) const
+ {
+ // if there are no clips added yet
+ if (iClipArray.Count() == 0)
+ {
+ return 0;
+ }
+
+ TInt frameDurationMicro = 20000; // AMR
+
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ frameDurationMicro = ((1024*1000)/(iProperties->iSamplingRate))*1000;
+ }
+
+ // just in case to prevent infinite loop
+ if (frameDurationMicro <= 0)
+ {
+ return 0;
+ }
+
+ TInt size = 0;
+
+ // Calculate the time of the first frame included in the time interval
+ TInt64 firstFrameIndex = aStartTime.Int64() / frameDurationMicro;
+ TInt64 currentTime = firstFrameIndex * frameDurationMicro;
+
+ while (currentTime + frameDurationMicro <= aEndTime.Int64()) // Make sure the whole frame fits inside the time interval
+ {
+
+ TBool silence = ETrue;
+ TInt clipIndex = 0;
+ TInt overLappingClips = 0;
+
+ for (TInt a = 0 ; a < iClipArray.Count() ; a++)
+ {
+ if (!iClipArray[a]->Muting())
+ {
+
+ if ((currentTime >= iClipArray[a]->iStartTime.Int64() + iClipArray[a]->iCutInTime.Int64()) &&
+ (currentTime < iClipArray[a]->iStartTime.Int64() + iClipArray[a]->iCutOutTime.Int64()))
+
+ {
+ silence = EFalse;
+ clipIndex = a;
+ overLappingClips++;
+
+ }
+ }
+ }
+
+ TInt frameSize = 0;
+ if (silence)
+ {
+
+ // if there is no audio around "aTime", just return a silent frame length
+
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ if (iProperties->iChannelMode == EAudSingleChannel)
+ {
+ frameSize = KSilentMonoAACFrameLenght;
+ }
+ else
+ {
+ frameSize = KSilentStereoAACFrameLenght;
+ }
+ }
+ else if (iProperties->iAudioType == EAudAMR)
+ {
+
+ TInt KSilentFrameLen = 13; // AMR
+ frameSize = KSilentFrameLen;
+
+ }
+
+ size +=frameSize;
+ currentTime += frameDurationMicro;
+ continue;
+
+ }
+
+
+
+ // if not silent, estimate according to bitrate if transcoding
+ // if no transcoding is necessary, return the frame length of the original
+ // input clip
+
+ // input clip is not transcoded if the original clip has the same
+ // audio properties as the output clip and no mixing is needed
+
+ TAudFileProperties clipProp = iClipArray[clipIndex]->Info()->Properties();
+
+ TBool clipTranscoded = EFalse;
+
+ if (clipProp.iAudioType !=
+ iProperties->iAudioType ||
+ clipProp.iSamplingRate !=
+ iProperties->iSamplingRate ||
+ clipProp.iChannelMode !=
+ iProperties->iChannelMode)
+ {
+ clipTranscoded = ETrue;
+ }
+
+ if (overLappingClips > 1)
+ {
+ clipTranscoded = ETrue;
+ }
+
+
+ if (clipTranscoded)
+ {
+ const TInt KBitrate = iProperties->iBitrate;
+ const TInt KBitsInByte = 8;
+
+ TInt KByterate = KBitrate/KBitsInByte;
+
+ TInt frameDurationMilli = 20; // AMR
+
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+ {
+
+ frameDurationMilli = ((1024*1000)/(iProperties->iSamplingRate));
+
+ }
+
+ frameSize = (KByterate/(1000/frameDurationMilli)+1);
+
+ }
+ else
+ {
+
+ frameSize = clipProp.iFrameLen;
+
+ }
+
+ size +=frameSize;
+ currentTime += frameDurationMicro;
+ continue;
+
+ }
+
+ return size;
+
+ }
+
+EXPORT_C TAudFileProperties CAudSong::OutputFileProperties() const
+ {
+
+ return *iProperties;
+ }
+
+
+EXPORT_C TBool CAudSong::GetMP4DecoderSpecificInfoLC(HBufC8*& aDecSpecInfo, TInt aMaxSize) const
+ {
+
+ if (iClipArray.Count() == 0)
+ {
+ return EFalse;
+ }
+
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+
+ {
+
+ int16 frameLen = 1024;
+ int32 sampleRate = iProperties->iSamplingRate;
+ uint8 profile = LC_OBJECT;
+ uint8 nChannels = 1;
+ uint8 decSpecInfo[16];
+ int16 nConfigBytes;
+
+ if (iProperties->iChannelMode == EAudStereo)
+ {
+ nChannels = 2;
+ }
+
+
+ //nConfigBytes = AACGetMP4ConfigInfo(&aacInfo, decSpecInfo, 16);
+ nConfigBytes = AACGetMP4ConfigInfo(sampleRate, profile,
+ nChannels, frameLen, decSpecInfo, aMaxSize);
+
+
+ if (nConfigBytes > 0)
+ {
+
+ aDecSpecInfo = HBufC8::NewLC(nConfigBytes);
+ aDecSpecInfo->Des().Append(decSpecInfo, nConfigBytes);
+
+ }
+
+ return ETrue;
+
+ }
+ else if (iProperties->iAudioType == EAudAMR)
+ {
+ aDecSpecInfo = HBufC8::NewLC(aMaxSize);
+
+ const TUint8 frameDecSpecInfo[] = {0x14,0x08}; //the decoder specific
+ const TInt frameSize = 2; //constant as maximum size of decoderspecific info is 2
+
+ for (TInt a = 0 ; a < frameSize ; a++)
+ {
+ aDecSpecInfo->Des().Append(frameDecSpecInfo[a]);
+ }
+
+
+ return ETrue;
+ }
+
+ else
+ {
+ return EFalse;
+ }
+
+
+ }
+
+EXPORT_C TBool CAudSong::GetTimeEstimateL(MAudTimeEstimateObserver& aObserver,
+ TAudType aAudType,
+ TInt aSamplingRate,
+ TChannelMode aChannelMode,
+ TInt aBitRate)
+ {
+
+
+ if (iClipArray.Count() == 0)
+ {
+ return EFalse;
+ }
+
+ if (SetOutputFileFormat(aAudType, aSamplingRate, aChannelMode, aBitRate))
+ {
+ return iProcessOperation->GetTimeEstimateL(aObserver);
+
+ }
+ else
+ {
+ return EFalse;
+ }
+
+
+ }
+
+EXPORT_C TTimeIntervalMicroSeconds CAudSong::GetTimeEstimateL()
+ {
+ TAudFileProperties prop;
+ TInt64 estimatedTime = TInt64(0);
+ TReal complexityFactor = 0.0;
+ TInt a;
+
+ for (a = 0; a < iClipArray.Count() ; a++)
+ {
+ complexityFactor = 0.0;
+
+ prop = iClipArray[a]->Info()->Properties();
+ if ( iClipArray[a]->Muting() )
+ {
+ // the clip is muted
+ complexityFactor = KAEDMutingComplFactor;
+ }
+ else if ( (prop.iAudioType != iProperties->iAudioType )
+ || (prop.iChannelMode != iProperties->iChannelMode )
+ || (prop.iSamplingRate != iProperties->iSamplingRate ) )
+ {
+ // need transcoding
+
+ // decoding
+ switch (prop.iAudioType)
+ {
+ case EAudAMR :
+ {
+ // AMR decoding
+ complexityFactor = KAEDAMRDecComplFactor;
+ }
+ break;
+ case EAudAAC_MPEG4 :
+ {
+ // AAC decoding
+ complexityFactor = KAEDAACDecComplFactor;
+ }
+ break;
+ case EAudAMRWB :
+ {
+ // AMR-WB decoding
+ complexityFactor = KAEDAMRWBDecComplFactor;
+ }
+ break;
+ case EAudMP3 :
+ {
+ // MP3 decoding
+ complexityFactor = KAEDMP3DecComplFactor;
+ }
+ break;
+ default:
+ {
+ //EAudWAV
+ complexityFactor = KAEDWavDecComplFactor;
+ }
+ }
+ if ( prop.iChannelMode == EAudStereo )
+ {
+ complexityFactor += KAEDAACStereoDecAddComplFactor;
+ }
+ if ( prop.iSamplingRate > 8000 )
+ {
+ complexityFactor *= prop.iSamplingRate/16000;
+ }
+
+
+ // encoding
+ if (iProperties->iAudioType == EAudAMR)
+ {
+ // AMR encoding
+ complexityFactor += KAEDAMREncComplFactor;
+ }
+ else
+ {
+ // AAC encoding
+ complexityFactor += KAEDAACEncComplFactor;
+ if ( iProperties->iChannelMode == EAudStereo )
+ {
+ complexityFactor += KAEDAACStereoEncAddComplFactor;
+ }
+ complexityFactor *= iProperties->iSamplingRate/16000;
+ }
+
+
+ }
+ else if (iClipArray[a]->DynamicLevelMarkCount() > 0)
+ {
+ // need bitstream processing (level control etc)
+ complexityFactor = KAEDBitstreamProcComplFactor;
+ }
+ else
+ {
+ // just passing through
+ complexityFactor = KAEDPassThroughComplFactor;
+ }
+
+
+
+ estimatedTime = estimatedTime + TInt64(complexityFactor * I64INT(iClipArray[a]->EditedDuration().Int64()));
+ }
+
+ return estimatedTime;
+ }
+
+EXPORT_C TInt CAudSong::GetFrameDurationMicro()
+ {
+ TInt frameDurationMicro = 20000; // AMR
+
+ if (iProperties->iAudioType == EAudAAC_MPEG4)
+ {
+ frameDurationMicro = ((1024 * 1000) / iProperties->iSamplingRate) * 1000;
+ }
+
+ return frameDurationMicro;
+ }
+
+
+EXPORT_C TInt CAudSong::ClipCount(TInt aTrackIndex) const
+ {
+
+
+ if (aTrackIndex == KAllTrackIndices)
+ {
+ return iClipArray.Count();
+
+ }
+
+ TInt amount = 0;
+ for (TInt a = 0; a < iClipArray.Count() ; a++)
+ {
+ if (iClipArray[a]->TrackIndex() == aTrackIndex) amount++;
+
+ }
+
+ return amount;
+
+ }
+
+
+EXPORT_C CAudClip* CAudSong::Clip(TInt aIndex, TInt aTrackIndex) const
+ {
+
+ if (aTrackIndex == KAllTrackIndices)
+ {
+ return iClipArray[aIndex];
+ }
+
+
+ TInt index = 0;
+ TInt a = 0;
+ TBool found = EFalse;
+
+ if (aTrackIndex == KAllTrackIndices)
+ {
+ return iClipArray[aIndex];
+ }
+
+ for (a = 0; a < iClipArray.Count() ; a++)
+ {
+
+ if (iClipArray[a]->TrackIndex() == aTrackIndex) index++;
+
+ if (index == aIndex+1)
+ {
+ found = ETrue;
+ break;
+ }
+
+
+ }
+
+ if (found)
+ {
+ return iClipArray[a];
+ }
+ else
+ {
+ TAudPanic::Panic(TAudPanic::EAudioClipIllegalIndex);
+ }
+ return NULL;
+ }
+
+
+
+EXPORT_C void CAudSong::AddClipL(const TDesC& aFileName,
+ TTimeIntervalMicroSeconds aStartTime, TInt aTrackIndex,
+ TTimeIntervalMicroSeconds aCutInTime,
+ TTimeIntervalMicroSeconds aCutOutTime)
+ {
+
+ PRINT((_L("CAudSong::AddClipL in")));
+ if (iAddOperation->iClip != 0)
+ {
+ TAudPanic::Panic(TAudPanic::ESongAddOperationAlreadyRunning);
+ }
+ if (iProcessOperation->iProcessor != 0 )
+ {
+ TAudPanic::Panic(TAudPanic::ESongProcessingOperationAlreadyRunning);
+ }
+
+
+ iAddOperation->iClip = CAudClip::NewL(this, aFileName, aStartTime, *iAddOperation, aTrackIndex);
+ iAddOperation->iClip->iCutInTime = aCutInTime;
+ iAddOperation->iClip->iCutOutTime = aCutOutTime;
+
+ PRINT((_L("CAudSong::AddClipL out")));
+
+ }
+
+
+EXPORT_C void CAudSong::RemoveClip(TInt aIndex, TInt aTrackIndex)
+ {
+ PRINT((_L("CAudSong::RemoveClip in")));
+
+ TInt index = -1;
+ TInt a = 0;
+ TBool found = EFalse;
+
+ for (a = 0; a < iClipArray.Count() ; a++)
+ {
+
+
+ if (iClipArray[a]->TrackIndex() == aTrackIndex) index++;
+
+ if (index == aIndex)
+ {
+ found = ETrue;
+ break;
+ }
+
+ }
+
+
+ if (found)
+ {
+
+ CAudClip* clip = iClipArray[a];
+ iClipArray.Remove(a);
+ delete clip;
+ UpdateClipIndexes();
+ FireClipRemoved(this, aIndex, aTrackIndex);
+ }
+ else
+ {
+ TAudPanic::Panic(TAudPanic::EAudioClipIllegalIndex);
+ }
+
+ PRINT((_L("CAudSong::RemoveClip out")));
+
+ }
+
+
+EXPORT_C TBool CAudSong::SetOutputFileFormat(TAudType aAudType,
+ TInt aSamplingRate,
+ TChannelMode aChannelMode,
+ TInt aBitRate)
+ {
+ PRINT((_L("CAudSong::SetOutputFileFormat in")));
+
+ // allow both EAudAAC_MPEG2 and EAudAAC_MPEG4
+ // as inpyt type, but consider all AAC_ MPEG as mpeg4
+
+ if (aAudType == EAudAAC_MPEG2)
+ {
+ aAudType = EAudAAC_MPEG4;
+ }
+
+ // make sure the given parameters are correct
+
+ if (aBitRate == KAudBitRateDefault)
+ {
+ // the defaut bitrates:
+ PRINT((_L("CAudSong::SetOutputFileFormat use default bitrate")));
+ if (aAudType == EAudAMR)
+ {
+ aBitRate = KAedBitRateAMR;
+ }
+ else if (aAudType == EAudAAC_MPEG4)
+ {
+ if (aSamplingRate == KAedSampleRate16kHz)
+ {
+ aBitRate = KAedBitRateAAC16kHz;
+ }
+ else
+ {
+ aBitRate = KAedBitRateAAC48kHz;
+ }
+ }
+ }
+
+ if (aAudType == EAudAAC_MPEG4)
+ {
+
+ iProperties->iAudioType = EAudAAC_MPEG4;
+ iProperties->iAACObjectType = EAudAACObjectTypeLC;
+
+ TInt channels = (aChannelMode == EAudSingleChannel) ? 1 : 2;
+
+ // legal sampling rates are 16000 and 48000 Hz
+ if (aSamplingRate == KAedSampleRate16kHz)
+ {
+ if (aBitRate < KAedAACMinBitRateMultiplier * KAedSampleRate16kHz * channels ||
+ aBitRate > KAedAACMaxBitRateMultiplier * KAedSampleRate16kHz * channels)
+ {
+ // illegal bitrate
+ PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported bitrate given")));
+ return EFalse;
+ }
+ else
+ {
+ iProperties->iSamplingRate = aSamplingRate;
+ iProperties->iBitrate = aBitRate;
+ iProperties->iChannelMode = aChannelMode;
+ }
+ }
+ else if (aSamplingRate == KAedSampleRate48kHz)
+ {
+ if (aBitRate < KAedAACMinBitRateMultiplier * KAedSampleRate48kHz * channels ||
+ aBitRate > KAedAACMaxBitRateMultiplier * KAedSampleRate48kHz * channels)
+ {
+ // illegal bitrate
+ PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported bitrate given")));
+ return EFalse;
+ }
+ else
+ {
+ iProperties->iSamplingRate = aSamplingRate;
+ iProperties->iBitrate = aBitRate;
+ iProperties->iChannelMode = aChannelMode;
+ }
+ }
+ else
+ {
+ PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported sampling rate given")));
+ return EFalse;
+ }
+
+ }
+
+
+ else if (aAudType == EAudAMR)
+ {
+
+ iProperties->iAudioType = EAudAMR;
+ // for AMR the bitrate is always set to 12200 and sampling rate to 8000
+ iProperties->iSamplingRate = KAedSampleRate8kHz;
+ iProperties->iBitrate = KAedBitRateAMR;
+ iProperties->iChannelMode = EAudSingleChannel;
+
+ }
+
+ else
+ {
+ PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported output format given")));
+ return EFalse;
+ }
+
+
+ PRINT((_L("CAudSong::SetOutputFileFormat out")));
+ return ETrue;
+ }
+
+EXPORT_C TBool CAudSong::AreOutputPropertiesSupported(const TAudFileProperties& aProperties )
+ {
+ if ( ( aProperties.iAudioType == EAudAAC_MPEG4 )
+ && ((aProperties.iSamplingRate == KAedSampleRate16kHz)
+ || (aProperties.iSamplingRate == KAedSampleRate48kHz)))
+ {
+ return ETrue;
+ }
+ else if ( (aProperties.iAudioType == EAudAMR)
+ && (aProperties.iSamplingRate == KAedSampleRate8kHz))
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+
+EXPORT_C TBool CAudSong::SyncStartProcessingL()
+ {
+ PRINT((_L("CAudSong::SyncStartProcessingL")));
+ return iProcessOperation->StartSyncProcL();
+ }
+
+EXPORT_C TBool CAudSong::SyncProcessFrameL(HBufC8*& aFrame, TInt& aProgress,
+ TTimeIntervalMicroSeconds& aDuration)
+ {
+ PRINT((_L("CAudSong::SyncProcessFrameL in")));
+
+ aFrame = 0;
+ TBool ret = iProcessOperation->ProcessSyncPieceL(aFrame, aProgress, aDuration);
+
+#ifdef _WRITE_OUTPUT_TO_FILE_
+
+
+ if (!ret)
+ {
+
+ if (iFileOpen)
+ {
+
+
+
+ TBuf8<32> mes;
+ mes.Append(_L8("aProgress: "));
+ mes.AppendNum(aProgress);
+ mes.Append(_L8("aDuration: "));
+ mes.AppendNum(I64INT(aDuration.Int64()/1000));
+ mes.Append(_L8("\n"));
+
+
+ iTextFile.Write(mes);
+
+
+ if (iProperties->iAudioType == EAudAMR)
+ {
+ iAudioFile.Write(aFrame->Des());
+
+ }
+ else
+ {
+ TBuf8<7> adtsHeader;
+
+ ProcTools::GenerateADTSHeaderL(adtsHeader, aFrame->Size(), *iProperties);
+ iAudioFile.Write(adtsHeader);
+ iAudioFile.Write(aFrame->Des());
+
+ }
+
+ }
+
+ }
+
+#endif
+
+ PRINT((_L("CAudSong::SyncProcessFrameL out")));
+ return ret;
+
+ }
+
+EXPORT_C void CAudSong::SyncCancelProcess()
+ {
+
+ iProcessOperation->Cancel();
+
+ }
+
+
+EXPORT_C void CAudSong::Reset(TBool aNotify)
+ {
+ iSongDurationManuallySet = EFalse;
+
+ iDynamicLevelMarkArray.ResetAndDestroy();
+ iClipArray.ResetAndDestroy();
+
+ if (aNotify)
+ {
+ FireSongReseted(*this);
+ }
+ }
+
+EXPORT_C TBool CAudSong::SetDuration(TTimeIntervalMicroSeconds aDuration)
+ {
+
+ if (aDuration.Int64() > 0)
+ {
+ iSongDuration = aDuration;
+ iSongDurationManuallySet = ETrue;
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+
+EXPORT_C void CAudSong::RegisterSongObserverL(MAudSongObserver* aObserver)
+ {
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ if (iObserverArray[i] == aObserver)
+ {
+ TAudPanic::Panic(TAudPanic::ESongObserverAlreadyRegistered);
+ }
+ }
+
+ User::LeaveIfError(iObserverArray.Append(aObserver));
+ }
+
+
+EXPORT_C void CAudSong::UnregisterSongObserver(MAudSongObserver* aObserver)
+ {
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ if (iObserverArray[i] == aObserver)
+ {
+ iObserverArray.Remove(i);
+ return;
+ }
+ }
+
+ TAudPanic::Panic(TAudPanic::ESongObserverNotRegistered);
+ }
+
+
+void CAudSong::UpdateClipIndexes()
+ {
+
+ for (TInt i = 0; i < iClipArray.Count() ; i++)
+ {
+
+ iClipArray[i]->iIndex = Index2IndexOnTrack(i);
+
+ }
+
+ }
+
+void CAudSong::UpdateClipArray()
+ {
+
+ TLinearOrder<CAudClip> order(CAudClip::Compare);
+ iClipArray.Sort(order);
+
+
+ }
+
+TInt CAudSong::Index2IndexOnTrack(TInt aIndex)
+ {
+
+ if (aIndex > iClipArray.Count())
+ {
+ TAudPanic::Panic(TAudPanic::EInternal);
+ }
+ TInt indexOnTrack = 0;
+ TInt trackIndex = iClipArray[aIndex]->TrackIndex();
+
+ for (TInt a = 0; a < aIndex ; a++)
+ {
+
+ if (iClipArray[a]->TrackIndex() == trackIndex)
+ {
+ indexOnTrack++;
+ }
+
+ }
+ return indexOnTrack;
+ }
+
+TInt CAudSong::FindClipIndexOnSong(const CAudClip* aClip) const
+ {
+
+ for (TInt index = 0 ; index < iClipArray.Count() ; index++)
+ {
+ if (iClipArray[index] == aClip)
+ {
+ return index;
+ }
+ }
+
+ // if the clip is not in the array...
+ TAudPanic::Panic(TAudPanic::EInternal);
+ return 0;
+
+ }
+
+void CAudSong::FireClipAdded(CAudSong* aSong, CAudClip* aClip, TInt aIndex, TInt aTrackIndex)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyClipAdded(*aSong, *aClip, aIndex, aTrackIndex);
+ }
+ }
+
+void CAudSong::FireClipAddingFailed(CAudSong* aSong, TInt aError, TInt aTrackIndex)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyClipAddingFailed(*aSong, aError, aTrackIndex);
+ }
+ }
+
+void CAudSong::FireClipRemoved(CAudSong* aSong, TInt aIndex, TInt aTrackIndex)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyClipRemoved(*aSong, aIndex, aTrackIndex);
+ }
+
+ }
+
+void CAudSong::FireClipIndicesChanged(CAudSong* aSong, TInt aOldIndex,
+ TInt aNewIndex, TInt aTrackIndex)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyClipIndicesChanged(*aSong, aOldIndex, aNewIndex, aTrackIndex);
+ }
+ }
+
+void CAudSong::FireClipTimingsChanged(CAudSong* aSong, CAudClip* aClip)
+ {
+
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyClipTimingsChanged(*aSong, *aClip);
+ }
+
+ }
+
+
+void CAudSong::FireDynamicLevelMarkInserted(CAudClip& aClip,
+ TAudDynamicLevelMark& aMark,
+ TInt aIndex)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyDynamicLevelMarkInserted(aClip, aMark, aIndex);
+ }
+
+
+ }
+
+void CAudSong::FireDynamicLevelMarkRemoved(CAudClip& aClip, TInt aIndex)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyDynamicLevelMarkRemoved(aClip, aIndex);
+ }
+
+ }
+
+void CAudSong::FireSongReseted(CAudSong& aSong)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifySongReseted(aSong);
+ }
+ }
+
+void CAudSong::FireClipReseted(CAudClip& aClip)
+ {
+
+ for (TInt i = 0; i < iObserverArray.Count(); i++)
+ {
+ iObserverArray[i]->NotifyClipReseted(aClip);
+ }
+ }
+
+
+
+CAudSongProcessOperation* CAudSongProcessOperation::NewL(CAudSong* aSong)
+ {
+ CAudSongProcessOperation* self =
+ new (ELeave) CAudSongProcessOperation(aSong);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+CAudSongProcessOperation::CAudSongProcessOperation(CAudSong* aSong)
+: iSong(aSong), iObserver(0), iProcessor(0)
+ {
+
+ }
+
+
+void CAudSongProcessOperation::ConstructL()
+ {
+ }
+
+CAudSongProcessOperation::~CAudSongProcessOperation()
+ {
+
+ if (iProcessor != 0)
+ {
+ delete iProcessor;
+ iProcessor = 0;
+
+ }
+
+ }
+
+
+
+void CAudSongProcessOperation::NotifyAudioProcessingStartedL()
+ {
+ if (iObserver != 0)
+ iObserver->NotifyAudioProcessingStartedL(*iSong);
+
+ }
+void CAudSongProcessOperation::NotifyAudioProcessingProgressed(TInt aPercentage)
+ {
+ if (iObserver != 0)
+ iObserver->NotifyAudioProcessingProgressed(*iSong, aPercentage);
+
+ }
+void CAudSongProcessOperation::NotifyAudioProcessingCompleted(TInt aError)
+ {
+
+ delete iProcessor;
+ iProcessor = 0;
+
+ MAudSongProcessingObserver* observer = iObserver;
+ iObserver = 0;
+ if (observer != 0)
+ {
+ observer->NotifyAudioProcessingProgressed(*iSong, 100);
+ observer->NotifyAudioProcessingCompleted(*iSong, aError);
+ }
+ }
+
+void CAudSongProcessOperation::NotifyTimeEstimateReady(TInt64 aTimeEstimate)
+ {
+
+ delete iProcessor;
+ iProcessor = 0;
+
+ MAudTimeEstimateObserver* observer = iTEObserver;
+ iTEObserver = 0;
+
+ if (observer != 0)
+ {
+ observer->NotifyTimeEstimateReady(aTimeEstimate);
+ }
+ }
+
+
+TBool CAudSongProcessOperation::StartSyncProcL()
+ {
+
+ if (iProcessor != 0)
+ {
+ User::Leave(KErrNotReady);
+ }
+
+ CAudProcessor* processor = CAudProcessor::NewLC();
+ TBool ret = processor->StartSyncProcessingL(iSong);
+ CleanupStack::Pop(processor);
+ iProcessor = processor;
+
+ return ret;
+
+ }
+
+TBool CAudSongProcessOperation::ProcessSyncPieceL(HBufC8*& aFrame, TInt& aProgress,
+ TTimeIntervalMicroSeconds& aDuration)
+ {
+ TBool ret = iProcessor->ProcessSyncPieceL(aFrame, aProgress, aDuration);
+ if (!ret) return EFalse;
+ else
+ {
+ delete iProcessor;
+ iProcessor = 0;
+ return ETrue;
+
+ }
+
+ }
+
+
+void CAudSongProcessOperation::Cancel()
+ {
+
+ if (iProcessor == 0)
+ {
+ TAudPanic::Panic(TAudPanic::ESongProcessingOperationNotRunning);
+ }
+ else
+ {
+ iProcessor->CancelProcessing(*this);
+ }
+ }
+
+TBool CAudSongProcessOperation::GetTimeEstimateL(MAudTimeEstimateObserver& aTEObserver)
+ {
+
+
+
+ if (iProcessor != 0)
+ {
+ User::Leave(KErrNotReady);
+ }
+ iTEObserver = &aTEObserver;
+
+ CAudProcessor* processor = CAudProcessor::NewLC();
+
+
+ TBool ret = processor->StartTimeEstimateL(iSong, *this);
+ CleanupStack::Pop(processor);
+ iProcessor = processor;
+
+ return ret;
+
+ }
+
+
+CAudSongAddClipOperation* CAudSongAddClipOperation::NewL(CAudSong* aSong)
+ {
+ CAudSongAddClipOperation* self =
+ new (ELeave) CAudSongAddClipOperation(aSong);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+CAudSongAddClipOperation::CAudSongAddClipOperation(CAudSong* aSong)
+ : iSong(aSong), iClip(0)
+ {
+ }
+
+
+void CAudSongAddClipOperation::ConstructL()
+ {
+ }
+
+
+CAudSongAddClipOperation::~CAudSongAddClipOperation()
+ {
+ if (iClip)
+ {
+ delete iClip;
+ iClip = 0;
+ }
+
+ }
+
+
+void CAudSongAddClipOperation::NotifyClipInfoReady(CAudClipInfo& /*aInfo*/,
+ TInt aError)
+ {
+
+
+ iError = aError;
+ CompleteAddClipOperation();
+
+ }
+
+
+void CAudSongAddClipOperation::CompleteAddClipOperation()
+ {
+ PRINT((_L("CAudSongAddClipOperation::CompleteAddClipOperation in")));
+
+
+ if (iError != KErrNone)
+ {
+ TInt trackIndex = iClip->TrackIndex();
+ delete iClip;
+ iClip = 0;
+ iSong->FireClipAddingFailed(iSong, iError, trackIndex);
+ PRINT((_L("CAudSong::CompleteAddClipOperation failed, out")));
+ return;
+ }
+ else
+ {
+
+ TAudFileProperties info = iClip->iInfo->Properties();
+
+ if (iSong->iClipArray.Count() > 0)
+ {
+ if (!(info.isCompatible(iSong->iClipArray[0]->Info()->Properties())))
+ {
+ TInt trackIndex = iClip->TrackIndex();
+
+ delete iClip;
+ iClip = 0;
+ iSong->FireClipAddingFailed(iSong, KErrNotSupported, trackIndex);
+ PRINT((_L("CAudSong::CompleteAddClipOperation failed, out")));
+ return;
+ }
+ }
+
+ if (iClip->CutOutTime() == TTimeIntervalMicroSeconds(KClipEndTime))
+ {
+
+ iClip->iCutOutTime = info.iDuration;
+ }
+
+
+ TInt err = KErrNone;
+
+ TBool added = EFalse;
+
+ // insert clips so that they are always sorted by start time
+ TInt index = 0;
+ for (index = 0 ; index < iSong->iClipArray.Count() ; index++)
+ {
+ if (iSong->iClipArray[index]->StartTime() > iClip->StartTime())
+ {
+ err = iSong->iClipArray.Insert(iClip, index);
+ added = ETrue;
+ break;
+ }
+ }
+ if (!added)
+ {
+ index = iSong->iClipArray.Count();
+ err = iSong->iClipArray.Insert(iClip, index);
+ if (err != KErrNone)
+ {
+ TInt trackIndex = iClip->TrackIndex();
+ delete iClip;
+ iClip = 0;
+ iSong->FireClipAddingFailed(iSong, KErrGeneral, trackIndex);
+ PRINT((_L("CAudSong::CompleteAddClipOperation failed, out")));
+ return;
+ }
+
+ }
+ iClip->iIndex = iSong->Index2IndexOnTrack(index);
+
+ if (err != KErrNone)
+ {
+ TInt trackIndex = iClip->TrackIndex();
+
+ delete iClip;
+ iClip = 0;
+ iSong->FireClipAddingFailed(iSong, err, trackIndex);
+ }
+ else
+ {
+ iSong->UpdateClipIndexes();
+ CAudClip* clip = iClip;
+ iClip = 0;
+
+
+ if (clip->EndTime() > iSong->iSongDuration)
+ {
+ iSong->iSongDuration = clip->EndTime();
+ }
+
+
+ iSong->FireClipAdded(iSong, clip, clip->iIndex, clip->iTrackIndex);
+
+
+ }
+ }
+ PRINT((_L("CAudSongAddClipOperation::CompleteAddClipOperation out")));
+ }
+
+EXPORT_C void CAudSong::AddClipL(RFile* aFileHandle,
+ TTimeIntervalMicroSeconds aStartTime, TInt aTrackIndex,
+ TTimeIntervalMicroSeconds aCutInTime,
+ TTimeIntervalMicroSeconds aCutOutTime)
+ {
+
+ PRINT((_L("CAudSong::AddClipL in")));
+ if (iAddOperation->iClip != 0)
+ {
+ TAudPanic::Panic(TAudPanic::ESongAddOperationAlreadyRunning);
+ }
+ if (iProcessOperation->iProcessor != 0 )
+ {
+ TAudPanic::Panic(TAudPanic::ESongProcessingOperationAlreadyRunning);
+ }
+
+ iAddOperation->iClip = CAudClip::NewL(this, aFileHandle, aStartTime, *iAddOperation, aTrackIndex);
+ iAddOperation->iClip->iCutInTime = aCutInTime;
+ iAddOperation->iClip->iCutOutTime = aCutOutTime;
+
+ PRINT((_L("CAudSong::AddClipL out")));
+
+ }
+
+
+