videoeditorengine/audioeditorengine/src/AudSong.cpp
branchRCL_3
changeset 3 e0b5df5c0969
parent 0 951a5db380a0
child 5 4c409de21d23
equal deleted inserted replaced
0:951a5db380a0 3:e0b5df5c0969
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:  
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include "AudSong.h"
       
    23 #include "AudClip.h"
       
    24 #include "AudPanic.h"
       
    25 #include "ProcInFileHandler.h"
       
    26 #include "ProcADTSInFileHandler.h"
       
    27 #include "ProcAMRInFileHandler.h"
       
    28 #include "ProcMP4InFileHandler.h"
       
    29 #include "ProcAWBInFileHandler.h"
       
    30 #include "AACConstants.h"
       
    31 #include "audconstants.h"
       
    32 
       
    33 #include "AudProcessor.h"
       
    34 #include "AACApi.h"
       
    35 #include "aedproctimeestimate.h"
       
    36 
       
    37 #include <e32base.h>
       
    38 
       
    39 // Debug print macro
       
    40 #if defined _DEBUG 
       
    41 #include <e32svr.h>
       
    42 #define PRINT(x) RDebug::Print x;
       
    43 #else
       
    44 #define PRINT(x)
       
    45 #endif
       
    46 
       
    47 EXPORT_C CAudSong* CAudSong::NewL(RFs *aFs)
       
    48     {
       
    49     CAudSong* self = NewLC(aFs);
       
    50     CleanupStack::Pop(self);
       
    51     return self;
       
    52     }
       
    53 
       
    54     
       
    55 EXPORT_C CAudSong* CAudSong::NewLC(RFs *aFs)
       
    56     {
       
    57     CAudSong* self = new (ELeave) CAudSong(aFs);
       
    58     CleanupStack::PushL(self);
       
    59     self->ConstructL();
       
    60     return self;
       
    61     }
       
    62  
       
    63 CAudSong::CAudSong(RFs *aFs) : iFs(aFs), iClipArray(32),  iSongDuration(0), 
       
    64                                 iSongDurationManuallySet(EFalse), iObserverArray(16), iNormalize(EFalse)
       
    65     {
       
    66     }
       
    67 
       
    68 
       
    69 void CAudSong::ConstructL()
       
    70     {
       
    71     iProperties = new (ELeave) TAudFileProperties();
       
    72     
       
    73     iProperties->iAudioType = EAudNoAudio;
       
    74     iProperties->iFileFormat = EAudFormatUnrecognized;
       
    75     iProperties->iDuration = 0;
       
    76     iProperties->iFrameCount = 0;
       
    77     iProperties->iFrameLen = 0;
       
    78     iProperties->iFrameDuration = 0;
       
    79 
       
    80 
       
    81     iProcessOperation = CAudSongProcessOperation::NewL(this);
       
    82     iAddOperation = CAudSongAddClipOperation::NewL(this);
       
    83 
       
    84 
       
    85 #ifdef _WRITE_OUTPUT_TO_FILE_
       
    86 
       
    87 
       
    88     TBuf<32> fileName;
       
    89     _LIT(KFn, "C:\\audioEngineOut.");
       
    90     _LIT(KTextFileName, "C:\\audioEngineOut.txt");
       
    91     
       
    92     fileName.Append(KFn);
       
    93     
       
    94     if (iProperties->iAudioType == EAudAMR)
       
    95         {
       
    96         fileName.Append(_L("amr"));
       
    97         }
       
    98     else
       
    99         {
       
   100         fileName.Append(_L("aac"));
       
   101         }
       
   102     
       
   103     
       
   104     User::LeaveIfError(iDebFs.Connect());
       
   105     iDebFs.Delete(fileName);
       
   106     iDebFs.Delete(KTextFileName);
       
   107 
       
   108     iFileOpen = EFalse;
       
   109     TInt err1 = iAudioFile.Create(iDebFs, fileName, EFileWrite);
       
   110     
       
   111     TInt err2 = iTextFile.Create(iDebFs, KTextFileName, EFileWrite);
       
   112     
       
   113     if (err1 == KErrNone && err2 == KErrNone)
       
   114         {
       
   115         iFileOpen = ETrue;
       
   116         }
       
   117         
       
   118     if (iFileOpen && iProperties->iAudioType == EAudAMR)
       
   119         {
       
   120         iAudioFile.Write(_L8("#!AMR"));
       
   121         }
       
   122     
       
   123 #endif
       
   124 
       
   125 
       
   126     }
       
   127 
       
   128 
       
   129 EXPORT_C CAudSong::~CAudSong() 
       
   130     {
       
   131 
       
   132     Reset(EFalse);
       
   133     delete iProperties;
       
   134     iProperties = 0;
       
   135     delete iProcessOperation;
       
   136     iProcessOperation = 0;
       
   137     delete iAddOperation;
       
   138     iAddOperation = 0;
       
   139 
       
   140 
       
   141     iObserverArray.Reset();
       
   142 
       
   143 
       
   144 #ifdef _WRITE_OUTPUT_TO_FILE_
       
   145     iAudioFile.Close();
       
   146     iTextFile.Close();
       
   147     iDebFs.Close();
       
   148     
       
   149 #endif
       
   150 
       
   151     }
       
   152 
       
   153 EXPORT_C TInt CAudSong::GetSizeEstimateL() const
       
   154     {
       
   155     
       
   156     
       
   157     // if there are no clips added yet
       
   158     if (iClipArray.Count() == 0)
       
   159         {
       
   160         return 0;
       
   161         }
       
   162         
       
   163     TInt durationMilli = ProcTools::MilliSeconds(iClipArray[iClipArray.Count()-1]->EndTime());
       
   164     TInt silenceDuration = ProcTools::MilliSeconds(iSongDuration) - durationMilli;
       
   165     
       
   166     if (silenceDuration < 0)
       
   167         {
       
   168         silenceDuration = 0;
       
   169         }
       
   170        
       
   171     TInt sizeInBytes = 0;
       
   172         
       
   173     const TInt KBitrate = iProperties->iBitrate;
       
   174     const TInt KBitsInByte = 8;
       
   175     TInt KByterate = KBitrate/KBitsInByte;
       
   176         
       
   177     // make sure we round up
       
   178     sizeInBytes = (durationMilli/1000+1)*KByterate;
       
   179     
       
   180     TInt frameDurationMilli = 20; // AMR
       
   181     TInt silentFrameLen = 13; // AMR
       
   182     
       
   183     if (iProperties->iAudioType == EAudAAC_MPEG4)
       
   184         {
       
   185         
       
   186         frameDurationMilli = ((1024*1000)/(iProperties->iSamplingRate));
       
   187         
       
   188         if (iProperties->iChannelMode == EAudSingleChannel)
       
   189             {
       
   190             silentFrameLen = KSilentMonoAACFrameLenght;
       
   191             }
       
   192         else
       
   193             {
       
   194             silentFrameLen = KSilentStereoAACFrameLenght;
       
   195             }
       
   196         
       
   197         }
       
   198         
       
   199     if (frameDurationMilli > 0)
       
   200         {
       
   201         TInt silentFrames = silenceDuration/frameDurationMilli;
       
   202         TInt silenceSize = silentFrames*silentFrameLen;
       
   203         sizeInBytes += silenceSize;
       
   204         
       
   205         }
       
   206 
       
   207     return sizeInBytes;
       
   208     
       
   209     }
       
   210     
       
   211 EXPORT_C TInt CAudSong::GetFrameSizeEstimateL(TTimeIntervalMicroSeconds aStartTime, 
       
   212                                               TTimeIntervalMicroSeconds aEndTime) const
       
   213 	{
       
   214 	// if there are no clips added yet
       
   215     if (iClipArray.Count() == 0)
       
   216         {
       
   217         return 0;
       
   218         }
       
   219 	
       
   220 	TInt frameDurationMicro = 20000; // AMR
       
   221     
       
   222     if (iProperties->iAudioType == EAudAAC_MPEG4)
       
   223         {
       
   224         
       
   225         frameDurationMicro = ((1024*1000)/(iProperties->iSamplingRate))*1000;
       
   226         }
       
   227     
       
   228     // just in case to prevent infinite loop    
       
   229     if (frameDurationMicro <= 0)
       
   230         {
       
   231         return 0;
       
   232         }
       
   233 	
       
   234     TInt size = 0;
       
   235     
       
   236     // Calculate the time of the first frame included in the time interval
       
   237     TInt64 firstFrameIndex = aStartTime.Int64() / frameDurationMicro;
       
   238     TInt64 currentTime = firstFrameIndex * frameDurationMicro;
       
   239     
       
   240     while (currentTime + frameDurationMicro <= aEndTime.Int64())        // Make sure the whole frame fits inside the time interval
       
   241         {
       
   242      
       
   243         TBool silence = ETrue;
       
   244     	TInt clipIndex = 0;
       
   245     	TInt overLappingClips = 0;
       
   246     	
       
   247     	for (TInt a = 0 ; a < iClipArray.Count() ; a++)
       
   248     	    {
       
   249     	    if (!iClipArray[a]->Muting())
       
   250     	        {
       
   251     	        
       
   252         	    if ((currentTime >= iClipArray[a]->iStartTime.Int64() + iClipArray[a]->iCutInTime.Int64()) &&
       
   253         	       (currentTime < iClipArray[a]->iStartTime.Int64() + iClipArray[a]->iCutOutTime.Int64()))
       
   254         	        
       
   255         	        {
       
   256         	        silence = EFalse;
       
   257         	        clipIndex = a;
       
   258                     overLappingClips++;
       
   259         	        
       
   260         	        }
       
   261     	        }
       
   262     	    }
       
   263     	    
       
   264     	TInt frameSize = 0;
       
   265     	if (silence)
       
   266     	    {
       
   267     	    
       
   268     	    // if there is no audio around "aTime", just return a silent frame length
       
   269     	    
       
   270     	    if (iProperties->iAudioType == EAudAAC_MPEG4)
       
   271                 {
       
   272                 
       
   273                 if (iProperties->iChannelMode == EAudSingleChannel)
       
   274                     {
       
   275                     frameSize = KSilentMonoAACFrameLenght;
       
   276                     }
       
   277                 else
       
   278                     {
       
   279                     frameSize = KSilentStereoAACFrameLenght;
       
   280                     }
       
   281                 }
       
   282     	    else if (iProperties->iAudioType == EAudAMR)
       
   283     	        {
       
   284     	        
       
   285     	        TInt KSilentFrameLen = 13; // AMR
       
   286     	        frameSize = KSilentFrameLen;
       
   287     	        
       
   288     	        }
       
   289     	        
       
   290     	    size +=frameSize;
       
   291     	    currentTime += frameDurationMicro;
       
   292     	    continue;
       
   293     	    
       
   294     	    }
       
   295     	    
       
   296     	    
       
   297     	    
       
   298     	// if not silent, estimate according to bitrate if transcoding
       
   299     	// if no transcoding is necessary, return the frame length of the original
       
   300     	// input clip
       
   301     	
       
   302     	// input clip is not transcoded if the original clip has the same
       
   303     	// audio properties as the output clip and no mixing is needed
       
   304     	    
       
   305     	TAudFileProperties clipProp = iClipArray[clipIndex]->Info()->Properties();
       
   306     	   
       
   307     	TBool clipTranscoded = EFalse;
       
   308     	    
       
   309     	if (clipProp.iAudioType != 
       
   310             iProperties->iAudioType ||
       
   311             clipProp.iSamplingRate != 
       
   312             iProperties->iSamplingRate ||
       
   313             clipProp.iChannelMode != 
       
   314             iProperties->iChannelMode)
       
   315                 {
       
   316                 clipTranscoded = ETrue;
       
   317                 }
       
   318     	
       
   319     	if (overLappingClips > 1)
       
   320     	    {
       
   321     	    clipTranscoded = ETrue;
       
   322     	    }
       
   323     	
       
   324     	
       
   325     	if (clipTranscoded)
       
   326     	    {
       
   327     	    const TInt KBitrate = iProperties->iBitrate;
       
   328             const TInt KBitsInByte = 8;
       
   329             
       
   330             TInt KByterate = KBitrate/KBitsInByte;    
       
   331         	
       
   332         	TInt frameDurationMilli = 20; // AMR
       
   333             
       
   334             if (iProperties->iAudioType == EAudAAC_MPEG4)
       
   335                 {
       
   336                 
       
   337                 frameDurationMilli = ((1024*1000)/(iProperties->iSamplingRate));
       
   338         	
       
   339         		}
       
   340         	
       
   341         	frameSize = (KByterate/(1000/frameDurationMilli)+1);
       
   342         	    
       
   343     	    }
       
   344     	else
       
   345     	    {
       
   346     	    
       
   347     	    frameSize = clipProp.iFrameLen;
       
   348     	    
       
   349     	    }    
       
   350     	
       
   351     	size +=frameSize;
       
   352     	currentTime += frameDurationMicro;
       
   353     	continue;
       
   354     	
       
   355         }
       
   356         
       
   357     return size;
       
   358 
       
   359 	}
       
   360 
       
   361 EXPORT_C TAudFileProperties CAudSong::OutputFileProperties() const 
       
   362     {
       
   363 
       
   364     return *iProperties;
       
   365     }
       
   366     
       
   367 
       
   368 EXPORT_C TBool CAudSong::GetMP4DecoderSpecificInfoLC(HBufC8*& aDecSpecInfo, TInt aMaxSize) const
       
   369     {
       
   370     
       
   371     if (iClipArray.Count() == 0)
       
   372         {
       
   373         return EFalse;
       
   374         }
       
   375     
       
   376     if (iProperties->iAudioType == EAudAAC_MPEG4)
       
   377         
       
   378         {
       
   379         
       
   380         int16 frameLen = 1024;
       
   381         int32 sampleRate = iProperties->iSamplingRate;
       
   382         uint8 profile = LC_OBJECT;
       
   383         uint8 nChannels = 1;
       
   384         uint8 decSpecInfo[16];
       
   385         int16 nConfigBytes;
       
   386         
       
   387         if (iProperties->iChannelMode == EAudStereo)
       
   388             {
       
   389             nChannels = 2;
       
   390             }
       
   391         
       
   392         
       
   393         //nConfigBytes = AACGetMP4ConfigInfo(&aacInfo, decSpecInfo, 16);
       
   394         nConfigBytes = AACGetMP4ConfigInfo(sampleRate, profile, 
       
   395             nChannels, frameLen, decSpecInfo, aMaxSize);
       
   396 
       
   397 
       
   398         if (nConfigBytes > 0)
       
   399             {
       
   400 
       
   401             aDecSpecInfo = HBufC8::NewLC(nConfigBytes);
       
   402             aDecSpecInfo->Des().Append(decSpecInfo, nConfigBytes);
       
   403 
       
   404             }
       
   405             
       
   406         return ETrue;
       
   407         
       
   408         }
       
   409     else if (iProperties->iAudioType == EAudAMR)
       
   410         {
       
   411         aDecSpecInfo = HBufC8::NewLC(aMaxSize);
       
   412         
       
   413         const TUint8 frameDecSpecInfo[] = {0x14,0x08};    //the decoder specific 
       
   414         const TInt frameSize = 2;  //constant as maximum size of decoderspecific info is 2
       
   415 
       
   416         for (TInt a = 0 ; a < frameSize ; a++)
       
   417             {
       
   418             aDecSpecInfo->Des().Append(frameDecSpecInfo[a]);
       
   419             }
       
   420         
       
   421         
       
   422         return ETrue;
       
   423         }
       
   424       
       
   425     else
       
   426         {
       
   427         return EFalse;
       
   428         }
       
   429     
       
   430 
       
   431     }
       
   432 
       
   433 EXPORT_C TBool CAudSong::GetTimeEstimateL(MAudTimeEstimateObserver& aObserver,
       
   434                                             TAudType aAudType,
       
   435                                             TInt aSamplingRate,
       
   436                                             TChannelMode aChannelMode,
       
   437                                             TInt aBitRate)
       
   438     {
       
   439     
       
   440     
       
   441     if (iClipArray.Count() == 0)
       
   442         {
       
   443         return EFalse;
       
   444         }
       
   445     
       
   446     if (SetOutputFileFormat(aAudType, aSamplingRate, aChannelMode, aBitRate))
       
   447         {
       
   448         return iProcessOperation->GetTimeEstimateL(aObserver);
       
   449         
       
   450         }
       
   451     else
       
   452         {
       
   453         return EFalse;
       
   454         }
       
   455     
       
   456     
       
   457     }
       
   458     
       
   459 EXPORT_C TTimeIntervalMicroSeconds CAudSong::GetTimeEstimateL()
       
   460     {
       
   461     TAudFileProperties prop;
       
   462     TInt64 estimatedTime = TInt64(0);
       
   463     TReal complexityFactor = 0.0;
       
   464     TInt a;
       
   465     
       
   466 	for (a = 0; a < iClipArray.Count() ; a++) 
       
   467 		{		
       
   468 		complexityFactor = 0.0;
       
   469 		
       
   470 		prop = iClipArray[a]->Info()->Properties();
       
   471 		if ( iClipArray[a]->Muting() )
       
   472 		    {
       
   473 		    // the clip is muted
       
   474 		    complexityFactor = KAEDMutingComplFactor;
       
   475 		    }
       
   476 		else if ( (prop.iAudioType != iProperties->iAudioType )
       
   477 		    || (prop.iChannelMode != iProperties->iChannelMode )
       
   478 		    || (prop.iSamplingRate != iProperties->iSamplingRate ) )
       
   479 		    {
       
   480 		    // need transcoding
       
   481 		    
       
   482 		    // decoding
       
   483 		    switch (prop.iAudioType)
       
   484 		        {
       
   485 	            case EAudAMR :
       
   486 	                {
       
   487     		        // AMR decoding
       
   488     		        complexityFactor = KAEDAMRDecComplFactor;
       
   489 	                }
       
   490 	                break;
       
   491 	            case EAudAAC_MPEG4 :
       
   492 	                {
       
   493     		        // AAC decoding
       
   494     		        complexityFactor = KAEDAACDecComplFactor;
       
   495 	                }
       
   496 	                break;
       
   497 	            case EAudAMRWB :
       
   498 	                {
       
   499     		        // AMR-WB decoding
       
   500     		        complexityFactor = KAEDAMRWBDecComplFactor;
       
   501 	                }
       
   502 	                break;
       
   503 	            case EAudMP3 :
       
   504 	                {
       
   505     		        // MP3 decoding
       
   506     		        complexityFactor = KAEDMP3DecComplFactor;
       
   507 	                }
       
   508 	                break;
       
   509                 default:
       
   510                     {
       
   511 	                //EAudWAV
       
   512     		        complexityFactor = KAEDWavDecComplFactor;
       
   513                     }
       
   514 		        }
       
   515 	        if ( prop.iChannelMode == EAudStereo )
       
   516 	            {
       
   517 	            complexityFactor += KAEDAACStereoDecAddComplFactor;
       
   518 	            }
       
   519 	        if ( prop.iSamplingRate > 8000 )
       
   520 	            {
       
   521 	            complexityFactor *= prop.iSamplingRate/16000;
       
   522 	            }
       
   523 		        
       
   524 		        
       
   525 		    // encoding
       
   526 		    if (iProperties->iAudioType == EAudAMR)
       
   527                 {
       
   528 		        // AMR encoding
       
   529 		        complexityFactor += KAEDAMREncComplFactor;
       
   530                 }
       
   531             else
       
   532                 {
       
   533 		        // AAC encoding
       
   534 		        complexityFactor += KAEDAACEncComplFactor;
       
   535 		        if ( iProperties->iChannelMode == EAudStereo )
       
   536 		            {
       
   537 		            complexityFactor += KAEDAACStereoEncAddComplFactor;
       
   538 		            }
       
   539 		        complexityFactor *= iProperties->iSamplingRate/16000;
       
   540                 }
       
   541                 
       
   542                 
       
   543 		    }
       
   544 		else if (iClipArray[a]->DynamicLevelMarkCount() > 0)
       
   545 		    {
       
   546 		    // need bitstream processing (level control etc)
       
   547 		    complexityFactor = KAEDBitstreamProcComplFactor;
       
   548 		    }
       
   549 		else
       
   550 		    {
       
   551 		    // just passing through
       
   552 		    complexityFactor = KAEDPassThroughComplFactor;
       
   553 		    }
       
   554 		    
       
   555 		    
       
   556 		
       
   557         estimatedTime = estimatedTime + TInt64(complexityFactor * I64INT(iClipArray[a]->EditedDuration().Int64()));
       
   558 		}
       
   559 		
       
   560     return estimatedTime;
       
   561     }
       
   562     
       
   563 EXPORT_C TInt CAudSong::GetFrameDurationMicro()
       
   564     {
       
   565     TInt frameDurationMicro = 20000; // AMR
       
   566     
       
   567     if (iProperties->iAudioType == EAudAAC_MPEG4)
       
   568         {
       
   569         frameDurationMicro = ((1024 * 1000) / iProperties->iSamplingRate) * 1000;
       
   570         }
       
   571         
       
   572     return frameDurationMicro;
       
   573     }
       
   574     
       
   575 
       
   576 EXPORT_C TInt CAudSong::ClipCount(TInt aTrackIndex) const 
       
   577     {
       
   578 
       
   579 
       
   580     if (aTrackIndex == KAllTrackIndices)
       
   581         {
       
   582         return iClipArray.Count();
       
   583 
       
   584         }
       
   585 
       
   586     TInt amount = 0;
       
   587     for (TInt a = 0; a < iClipArray.Count() ; a++) 
       
   588         {    
       
   589         if (iClipArray[a]->TrackIndex() == aTrackIndex) amount++;
       
   590 
       
   591         }
       
   592 
       
   593     return amount;
       
   594 
       
   595     }
       
   596 
       
   597 
       
   598 EXPORT_C CAudClip* CAudSong::Clip(TInt aIndex, TInt aTrackIndex) const 
       
   599     {
       
   600     
       
   601     if (aTrackIndex == KAllTrackIndices)
       
   602         {
       
   603         return iClipArray[aIndex];
       
   604         }
       
   605 
       
   606 	
       
   607 	TInt index = 0;
       
   608 	TInt a = 0;
       
   609 	TBool found = EFalse;
       
   610 	
       
   611 	if (aTrackIndex == KAllTrackIndices)
       
   612 	    {
       
   613 	    return iClipArray[aIndex];
       
   614 	    }
       
   615 
       
   616 	for (a = 0; a < iClipArray.Count() ; a++) 
       
   617 		{		
       
   618 		
       
   619 		if (iClipArray[a]->TrackIndex() == aTrackIndex) index++;
       
   620 		
       
   621 		if (index == aIndex+1) 
       
   622 			{
       
   623 			found = ETrue;
       
   624 			break;
       
   625 			}
       
   626 		
       
   627 
       
   628 		}
       
   629 
       
   630 	if (found) 
       
   631 		{
       
   632 		return iClipArray[a];
       
   633 		}
       
   634 	else 
       
   635 		{
       
   636 		TAudPanic::Panic(TAudPanic::EAudioClipIllegalIndex);
       
   637 		}
       
   638 	return NULL;
       
   639 	}
       
   640 
       
   641 
       
   642 
       
   643 EXPORT_C void CAudSong::AddClipL(const TDesC& aFileName,
       
   644         TTimeIntervalMicroSeconds aStartTime, TInt aTrackIndex,
       
   645         TTimeIntervalMicroSeconds aCutInTime,
       
   646         TTimeIntervalMicroSeconds aCutOutTime) 
       
   647     {
       
   648 
       
   649     PRINT((_L("CAudSong::AddClipL in")));
       
   650     if (iAddOperation->iClip != 0) 
       
   651         {
       
   652         TAudPanic::Panic(TAudPanic::ESongAddOperationAlreadyRunning);
       
   653         }
       
   654     if (iProcessOperation->iProcessor != 0 ) 
       
   655         {
       
   656         TAudPanic::Panic(TAudPanic::ESongProcessingOperationAlreadyRunning);
       
   657         }
       
   658 
       
   659     
       
   660     iAddOperation->iClip = CAudClip::NewL(this, aFileName, aStartTime, *iAddOperation, aTrackIndex);
       
   661     iAddOperation->iClip->iCutInTime = aCutInTime;
       
   662     iAddOperation->iClip->iCutOutTime = aCutOutTime;
       
   663 
       
   664     PRINT((_L("CAudSong::AddClipL out")));
       
   665 
       
   666     }
       
   667     
       
   668 
       
   669 EXPORT_C void CAudSong::RemoveClip(TInt aIndex, TInt aTrackIndex) 
       
   670     {
       
   671     PRINT((_L("CAudSong::RemoveClip in")));
       
   672 
       
   673     TInt index = -1;
       
   674     TInt a = 0;
       
   675     TBool found = EFalse;
       
   676 
       
   677     for (a = 0; a < iClipArray.Count() ; a++) 
       
   678         {        
       
   679     
       
   680         
       
   681         if (iClipArray[a]->TrackIndex() == aTrackIndex) index++;
       
   682         
       
   683         if (index == aIndex) 
       
   684             {
       
   685             found = ETrue;
       
   686             break;
       
   687             }
       
   688         
       
   689         }
       
   690     
       
   691     
       
   692     if (found) 
       
   693         {
       
   694         
       
   695         CAudClip* clip = iClipArray[a];
       
   696         iClipArray.Remove(a);
       
   697         delete clip;        
       
   698         UpdateClipIndexes();
       
   699         FireClipRemoved(this, aIndex, aTrackIndex);
       
   700         }
       
   701     else 
       
   702         {
       
   703         TAudPanic::Panic(TAudPanic::EAudioClipIllegalIndex);
       
   704         }
       
   705     
       
   706     PRINT((_L("CAudSong::RemoveClip out")));
       
   707 
       
   708     }
       
   709 
       
   710 
       
   711 EXPORT_C TBool CAudSong::SetOutputFileFormat(TAudType aAudType,
       
   712                                             TInt aSamplingRate,
       
   713                                             TChannelMode aChannelMode,
       
   714                                             TInt aBitRate)
       
   715     {
       
   716     PRINT((_L("CAudSong::SetOutputFileFormat in")));
       
   717     
       
   718     // allow both EAudAAC_MPEG2 and EAudAAC_MPEG4
       
   719     // as inpyt type, but consider all AAC_ MPEG as mpeg4
       
   720     
       
   721     if (aAudType == EAudAAC_MPEG2) 
       
   722         {
       
   723         aAudType = EAudAAC_MPEG4;
       
   724         }
       
   725     
       
   726     // make sure the given parameters are correct
       
   727    
       
   728     if (aBitRate == KAudBitRateDefault)
       
   729         {
       
   730         // the defaut bitrates:
       
   731         PRINT((_L("CAudSong::SetOutputFileFormat use default bitrate")));
       
   732         if (aAudType == EAudAMR)
       
   733             {
       
   734             aBitRate = KAedBitRateAMR;
       
   735             }
       
   736         else if (aAudType == EAudAAC_MPEG4)
       
   737             {
       
   738             if (aSamplingRate == KAedSampleRate16kHz) 
       
   739                 {
       
   740                 aBitRate = KAedBitRateAAC16kHz;
       
   741                 }
       
   742             else 
       
   743                 {
       
   744                 aBitRate = KAedBitRateAAC48kHz;
       
   745                 }
       
   746             }
       
   747         }
       
   748     
       
   749     if (aAudType == EAudAAC_MPEG4)
       
   750         {
       
   751         
       
   752         iProperties->iAudioType = EAudAAC_MPEG4; 
       
   753         iProperties->iAACObjectType = EAudAACObjectTypeLC;
       
   754         
       
   755         TInt channels = (aChannelMode == EAudSingleChannel) ? 1 : 2;
       
   756         
       
   757         // legal sampling rates are 16000 and 48000 Hz      
       
   758         if (aSamplingRate == KAedSampleRate16kHz)
       
   759             {
       
   760             if (aBitRate < KAedAACMinBitRateMultiplier * KAedSampleRate16kHz * channels ||
       
   761                 aBitRate > KAedAACMaxBitRateMultiplier * KAedSampleRate16kHz * channels)
       
   762                 {
       
   763                 // illegal bitrate
       
   764                 PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported bitrate given")));
       
   765                 return EFalse;
       
   766                 }
       
   767             else 
       
   768                 {
       
   769                 iProperties->iSamplingRate = aSamplingRate;
       
   770                 iProperties->iBitrate = aBitRate;
       
   771                 iProperties->iChannelMode = aChannelMode;
       
   772                 }
       
   773             }
       
   774         else if (aSamplingRate == KAedSampleRate48kHz)
       
   775             {
       
   776             if (aBitRate < KAedAACMinBitRateMultiplier * KAedSampleRate48kHz * channels ||
       
   777                 aBitRate > KAedAACMaxBitRateMultiplier * KAedSampleRate48kHz * channels)
       
   778                 {
       
   779                 // illegal bitrate
       
   780                 PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported bitrate given")));
       
   781                 return EFalse;
       
   782                 }
       
   783             else 
       
   784                 {
       
   785                 iProperties->iSamplingRate = aSamplingRate;
       
   786                 iProperties->iBitrate = aBitRate;
       
   787                 iProperties->iChannelMode = aChannelMode;
       
   788                 }
       
   789             }
       
   790         else
       
   791             {
       
   792             PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported sampling rate given")));
       
   793             return EFalse;
       
   794             }
       
   795             
       
   796         }
       
   797         
       
   798     
       
   799     else if (aAudType == EAudAMR)
       
   800         {
       
   801         
       
   802         iProperties->iAudioType = EAudAMR;
       
   803         // for AMR the bitrate is always set to 12200 and sampling rate to 8000
       
   804         iProperties->iSamplingRate = KAedSampleRate8kHz;
       
   805         iProperties->iBitrate = KAedBitRateAMR;
       
   806         iProperties->iChannelMode = EAudSingleChannel;
       
   807         
       
   808         }
       
   809         
       
   810     else 
       
   811         {
       
   812         PRINT((_L("CAudSong::SetOutputFileFormat out, unsupported output format given")));
       
   813         return EFalse;
       
   814         }
       
   815     
       
   816 
       
   817     PRINT((_L("CAudSong::SetOutputFileFormat out")));
       
   818     return ETrue;
       
   819     }
       
   820 
       
   821 EXPORT_C TBool CAudSong::AreOutputPropertiesSupported(const TAudFileProperties& aProperties )
       
   822     {
       
   823     if (   ( aProperties.iAudioType == EAudAAC_MPEG4 )
       
   824         && ((aProperties.iSamplingRate == KAedSampleRate16kHz) 
       
   825         ||  (aProperties.iSamplingRate == KAedSampleRate48kHz)))
       
   826         {
       
   827         return ETrue;
       
   828         }
       
   829     else if ( (aProperties.iAudioType == EAudAMR) 
       
   830         &&    (aProperties.iSamplingRate == KAedSampleRate8kHz))
       
   831         {
       
   832         return ETrue;
       
   833         }
       
   834     else
       
   835         {
       
   836         return EFalse;
       
   837         }
       
   838     }
       
   839     
       
   840 
       
   841 EXPORT_C TBool CAudSong::SyncStartProcessingL()
       
   842     {
       
   843     PRINT((_L("CAudSong::SyncStartProcessingL")));
       
   844     return iProcessOperation->StartSyncProcL();    
       
   845     }
       
   846 
       
   847 EXPORT_C TBool CAudSong::SyncProcessFrameL(HBufC8*& aFrame, TInt& aProgress,
       
   848                                        TTimeIntervalMicroSeconds& aDuration)
       
   849     {
       
   850     PRINT((_L("CAudSong::SyncProcessFrameL in")));
       
   851     
       
   852     aFrame = 0;
       
   853     TBool ret = iProcessOperation->ProcessSyncPieceL(aFrame, aProgress, aDuration);
       
   854     
       
   855 #ifdef _WRITE_OUTPUT_TO_FILE_
       
   856     
       
   857     
       
   858     if (!ret)
       
   859         {
       
   860         
       
   861         if (iFileOpen)
       
   862             {
       
   863         
       
   864         
       
   865         
       
   866             TBuf8<32> mes;
       
   867             mes.Append(_L8("aProgress: "));
       
   868             mes.AppendNum(aProgress);
       
   869             mes.Append(_L8("aDuration: "));
       
   870             mes.AppendNum(I64INT(aDuration.Int64()/1000));
       
   871             mes.Append(_L8("\n"));
       
   872             
       
   873             
       
   874             iTextFile.Write(mes);
       
   875             
       
   876             
       
   877             if (iProperties->iAudioType == EAudAMR)
       
   878                 {
       
   879                 iAudioFile.Write(aFrame->Des());
       
   880                 
       
   881                 }
       
   882             else
       
   883                 {
       
   884                 TBuf8<7> adtsHeader;
       
   885                 
       
   886                 ProcTools::GenerateADTSHeaderL(adtsHeader, aFrame->Size(), *iProperties);
       
   887                 iAudioFile.Write(adtsHeader);
       
   888                 iAudioFile.Write(aFrame->Des());
       
   889                 
       
   890                 }
       
   891             
       
   892             }
       
   893         
       
   894         }
       
   895     
       
   896 #endif
       
   897     
       
   898     PRINT((_L("CAudSong::SyncProcessFrameL out")));
       
   899     return ret;
       
   900 
       
   901     }
       
   902 
       
   903 EXPORT_C void CAudSong::SyncCancelProcess() 
       
   904     {
       
   905     
       
   906     iProcessOperation->Cancel();
       
   907 
       
   908     }
       
   909 
       
   910 
       
   911 EXPORT_C void CAudSong::Reset(TBool aNotify) 
       
   912     {
       
   913     iSongDurationManuallySet = EFalse;
       
   914 
       
   915     iDynamicLevelMarkArray.ResetAndDestroy();
       
   916     iClipArray.ResetAndDestroy();
       
   917 
       
   918     if (aNotify) 
       
   919         {
       
   920         FireSongReseted(*this);
       
   921         }
       
   922     }
       
   923 
       
   924 EXPORT_C TBool CAudSong::SetDuration(TTimeIntervalMicroSeconds aDuration)
       
   925     {
       
   926 
       
   927     if (aDuration.Int64() > 0) 
       
   928         {
       
   929         iSongDuration = aDuration;
       
   930         iSongDurationManuallySet = ETrue;
       
   931         return ETrue;
       
   932         }
       
   933 
       
   934     return EFalse;
       
   935     }
       
   936 
       
   937 
       
   938 EXPORT_C void CAudSong::RegisterSongObserverL(MAudSongObserver* aObserver) 
       
   939     {
       
   940     for (TInt i = 0; i < iObserverArray.Count(); i++)
       
   941         {
       
   942         if (iObserverArray[i] == aObserver)
       
   943             {
       
   944             TAudPanic::Panic(TAudPanic::ESongObserverAlreadyRegistered);
       
   945             }
       
   946         }
       
   947 
       
   948     User::LeaveIfError(iObserverArray.Append(aObserver));
       
   949     }
       
   950 
       
   951 
       
   952 EXPORT_C void CAudSong::UnregisterSongObserver(MAudSongObserver* aObserver) 
       
   953     {
       
   954     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
   955         {
       
   956         if (iObserverArray[i] == aObserver) 
       
   957             {
       
   958             iObserverArray.Remove(i);
       
   959             return;
       
   960             }
       
   961         }
       
   962 
       
   963     TAudPanic::Panic(TAudPanic::ESongObserverNotRegistered);
       
   964     }
       
   965 
       
   966 
       
   967 void CAudSong::UpdateClipIndexes() 
       
   968     {
       
   969 
       
   970     for (TInt i = 0; i < iClipArray.Count() ; i++)
       
   971         {
       
   972         
       
   973         iClipArray[i]->iIndex = Index2IndexOnTrack(i);
       
   974         
       
   975         }
       
   976     
       
   977     }
       
   978 
       
   979 void CAudSong::UpdateClipArray() 
       
   980     {
       
   981 
       
   982     TLinearOrder<CAudClip> order(CAudClip::Compare);
       
   983     iClipArray.Sort(order);
       
   984 
       
   985 
       
   986     }
       
   987 
       
   988 TInt CAudSong::Index2IndexOnTrack(TInt aIndex) 
       
   989     {
       
   990 
       
   991     if (aIndex > iClipArray.Count()) 
       
   992         {
       
   993         TAudPanic::Panic(TAudPanic::EInternal);
       
   994         }
       
   995     TInt indexOnTrack = 0;
       
   996     TInt trackIndex = iClipArray[aIndex]->TrackIndex();
       
   997 
       
   998     for (TInt a = 0; a < aIndex ; a++) 
       
   999         {
       
  1000             
       
  1001         if (iClipArray[a]->TrackIndex() == trackIndex) 
       
  1002             {
       
  1003             indexOnTrack++;
       
  1004             }
       
  1005 
       
  1006         }
       
  1007     return indexOnTrack;
       
  1008     }
       
  1009 
       
  1010 TInt CAudSong::FindClipIndexOnSong(const CAudClip* aClip) const 
       
  1011     {
       
  1012     
       
  1013     for (TInt index = 0 ; index < iClipArray.Count() ; index++) 
       
  1014         {
       
  1015         if (iClipArray[index] == aClip) 
       
  1016             {
       
  1017             return index;
       
  1018             }
       
  1019         }
       
  1020 
       
  1021     // if the clip is not in the array...
       
  1022     TAudPanic::Panic(TAudPanic::EInternal);
       
  1023     return 0;
       
  1024 
       
  1025     }
       
  1026 
       
  1027 void CAudSong::FireClipAdded(CAudSong* aSong, CAudClip* aClip, TInt aIndex, TInt aTrackIndex) 
       
  1028     {
       
  1029 
       
  1030     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1031         {
       
  1032         iObserverArray[i]->NotifyClipAdded(*aSong, *aClip, aIndex, aTrackIndex);
       
  1033         }
       
  1034     }
       
  1035     
       
  1036 void CAudSong::FireClipAddingFailed(CAudSong* aSong, TInt aError, TInt aTrackIndex) 
       
  1037     {
       
  1038 
       
  1039     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1040         {
       
  1041         iObserverArray[i]->NotifyClipAddingFailed(*aSong, aError, aTrackIndex);
       
  1042         }
       
  1043     }
       
  1044 
       
  1045 void CAudSong::FireClipRemoved(CAudSong* aSong, TInt aIndex, TInt aTrackIndex) 
       
  1046     {
       
  1047     
       
  1048     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1049         {
       
  1050         iObserverArray[i]->NotifyClipRemoved(*aSong, aIndex, aTrackIndex);
       
  1051         }
       
  1052 
       
  1053     }
       
  1054 
       
  1055 void CAudSong::FireClipIndicesChanged(CAudSong* aSong, TInt aOldIndex, 
       
  1056                                       TInt aNewIndex, TInt aTrackIndex) 
       
  1057     {
       
  1058     
       
  1059     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1060         {
       
  1061         iObserverArray[i]->NotifyClipIndicesChanged(*aSong, aOldIndex, aNewIndex, aTrackIndex);
       
  1062         }
       
  1063     }
       
  1064 
       
  1065 void CAudSong::FireClipTimingsChanged(CAudSong* aSong, CAudClip* aClip)    
       
  1066     {
       
  1067 
       
  1068     
       
  1069     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1070         {
       
  1071         iObserverArray[i]->NotifyClipTimingsChanged(*aSong, *aClip);
       
  1072         }
       
  1073 
       
  1074     }
       
  1075 
       
  1076     
       
  1077 void CAudSong::FireDynamicLevelMarkInserted(CAudClip& aClip, 
       
  1078         TAudDynamicLevelMark& aMark, 
       
  1079         TInt aIndex) 
       
  1080     {
       
  1081     
       
  1082     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1083         {
       
  1084         iObserverArray[i]->NotifyDynamicLevelMarkInserted(aClip, aMark, aIndex);
       
  1085         }
       
  1086 
       
  1087 
       
  1088     }
       
  1089 
       
  1090 void CAudSong::FireDynamicLevelMarkRemoved(CAudClip& aClip, TInt aIndex) 
       
  1091     {
       
  1092 
       
  1093     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1094         {
       
  1095         iObserverArray[i]->NotifyDynamicLevelMarkRemoved(aClip, aIndex);
       
  1096         }
       
  1097 
       
  1098     }
       
  1099 
       
  1100 void CAudSong::FireSongReseted(CAudSong& aSong) 
       
  1101     {
       
  1102 
       
  1103     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1104         {
       
  1105         iObserverArray[i]->NotifySongReseted(aSong);
       
  1106         }
       
  1107     }
       
  1108 
       
  1109 void CAudSong::FireClipReseted(CAudClip& aClip) 
       
  1110     {
       
  1111 
       
  1112     for (TInt i = 0; i < iObserverArray.Count(); i++) 
       
  1113         {
       
  1114         iObserverArray[i]->NotifyClipReseted(aClip);
       
  1115         }
       
  1116     }
       
  1117 
       
  1118 
       
  1119 
       
  1120 CAudSongProcessOperation* CAudSongProcessOperation::NewL(CAudSong* aSong)
       
  1121     {
       
  1122     CAudSongProcessOperation* self = 
       
  1123         new (ELeave) CAudSongProcessOperation(aSong);
       
  1124     CleanupStack::PushL(self);
       
  1125     self->ConstructL();
       
  1126     CleanupStack::Pop(self);
       
  1127     return self;
       
  1128     }
       
  1129 
       
  1130 
       
  1131 CAudSongProcessOperation::CAudSongProcessOperation(CAudSong* aSong)
       
  1132 : iSong(aSong), iObserver(0), iProcessor(0)
       
  1133     {
       
  1134 
       
  1135     }
       
  1136 
       
  1137 
       
  1138 void CAudSongProcessOperation::ConstructL()
       
  1139     {
       
  1140     }
       
  1141 
       
  1142 CAudSongProcessOperation::~CAudSongProcessOperation()
       
  1143     {
       
  1144 
       
  1145     if (iProcessor != 0)
       
  1146         {
       
  1147         delete iProcessor;
       
  1148         iProcessor = 0;
       
  1149 
       
  1150         }
       
  1151 
       
  1152     }
       
  1153 
       
  1154 
       
  1155 
       
  1156 void CAudSongProcessOperation::NotifyAudioProcessingStartedL() 
       
  1157     {
       
  1158     if (iObserver != 0)
       
  1159         iObserver->NotifyAudioProcessingStartedL(*iSong);
       
  1160 
       
  1161     }
       
  1162 void CAudSongProcessOperation::NotifyAudioProcessingProgressed(TInt aPercentage) 
       
  1163     {
       
  1164     if (iObserver != 0)
       
  1165         iObserver->NotifyAudioProcessingProgressed(*iSong, aPercentage);
       
  1166 
       
  1167     }
       
  1168 void CAudSongProcessOperation::NotifyAudioProcessingCompleted(TInt aError) 
       
  1169     {
       
  1170 
       
  1171     delete iProcessor;
       
  1172     iProcessor = 0;
       
  1173 
       
  1174     MAudSongProcessingObserver* observer = iObserver;
       
  1175     iObserver = 0;
       
  1176     if (observer != 0)
       
  1177         {
       
  1178         observer->NotifyAudioProcessingProgressed(*iSong, 100);
       
  1179         observer->NotifyAudioProcessingCompleted(*iSong, aError);
       
  1180         }
       
  1181     }
       
  1182 
       
  1183 void CAudSongProcessOperation::NotifyTimeEstimateReady(TInt64 aTimeEstimate) 
       
  1184     {
       
  1185 
       
  1186     delete iProcessor;
       
  1187     iProcessor = 0;
       
  1188 
       
  1189     MAudTimeEstimateObserver* observer = iTEObserver;
       
  1190     iTEObserver = 0;
       
  1191     
       
  1192     if (observer != 0)
       
  1193         {
       
  1194         observer->NotifyTimeEstimateReady(aTimeEstimate);
       
  1195         }
       
  1196     }
       
  1197 
       
  1198 
       
  1199 TBool CAudSongProcessOperation::StartSyncProcL()
       
  1200     {
       
  1201 
       
  1202     if (iProcessor != 0) 
       
  1203         {
       
  1204         User::Leave(KErrNotReady);
       
  1205         }
       
  1206 
       
  1207     CAudProcessor* processor = CAudProcessor::NewLC();
       
  1208     TBool ret = processor->StartSyncProcessingL(iSong);
       
  1209     CleanupStack::Pop(processor);
       
  1210     iProcessor = processor;
       
  1211 
       
  1212     return ret;
       
  1213 
       
  1214     }
       
  1215 
       
  1216 TBool CAudSongProcessOperation::ProcessSyncPieceL(HBufC8*& aFrame, TInt& aProgress,
       
  1217                                        TTimeIntervalMicroSeconds& aDuration)
       
  1218     {
       
  1219     TBool ret = iProcessor->ProcessSyncPieceL(aFrame, aProgress, aDuration);
       
  1220     if (!ret) return EFalse;
       
  1221     else
       
  1222         {
       
  1223         delete iProcessor;
       
  1224         iProcessor = 0;
       
  1225         return ETrue;
       
  1226 
       
  1227         }
       
  1228     
       
  1229     }
       
  1230 
       
  1231 
       
  1232 void CAudSongProcessOperation::Cancel() 
       
  1233     {
       
  1234 
       
  1235     if (iProcessor == 0) 
       
  1236         {
       
  1237         TAudPanic::Panic(TAudPanic::ESongProcessingOperationNotRunning);
       
  1238         }
       
  1239     else 
       
  1240         {
       
  1241         iProcessor->CancelProcessing(*this);
       
  1242         }
       
  1243     }
       
  1244 
       
  1245 TBool CAudSongProcessOperation::GetTimeEstimateL(MAudTimeEstimateObserver& aTEObserver)
       
  1246     {
       
  1247     
       
  1248     
       
  1249     
       
  1250     if (iProcessor != 0)
       
  1251         {
       
  1252         User::Leave(KErrNotReady);
       
  1253         }
       
  1254     iTEObserver = &aTEObserver;
       
  1255     
       
  1256     CAudProcessor* processor = CAudProcessor::NewLC();
       
  1257     
       
  1258     
       
  1259     TBool ret = processor->StartTimeEstimateL(iSong, *this);
       
  1260     CleanupStack::Pop(processor);
       
  1261     iProcessor = processor;
       
  1262 
       
  1263     return ret;
       
  1264     
       
  1265     }
       
  1266 
       
  1267 
       
  1268 CAudSongAddClipOperation* CAudSongAddClipOperation::NewL(CAudSong* aSong)
       
  1269     {
       
  1270     CAudSongAddClipOperation* self = 
       
  1271         new (ELeave) CAudSongAddClipOperation(aSong);
       
  1272     CleanupStack::PushL(self);
       
  1273     self->ConstructL();
       
  1274     CleanupStack::Pop(self);
       
  1275     return self;
       
  1276     }
       
  1277 
       
  1278 
       
  1279 CAudSongAddClipOperation::CAudSongAddClipOperation(CAudSong* aSong)
       
  1280         : iSong(aSong), iClip(0)
       
  1281     {
       
  1282     }
       
  1283 
       
  1284 
       
  1285 void CAudSongAddClipOperation::ConstructL()
       
  1286     {
       
  1287     }
       
  1288 
       
  1289 
       
  1290 CAudSongAddClipOperation::~CAudSongAddClipOperation()
       
  1291     {
       
  1292     if (iClip)
       
  1293         {
       
  1294         delete iClip;
       
  1295         iClip = 0;
       
  1296         }
       
  1297 
       
  1298     }
       
  1299 
       
  1300 
       
  1301 void CAudSongAddClipOperation::NotifyClipInfoReady(CAudClipInfo& /*aInfo*/, 
       
  1302                                                          TInt aError)
       
  1303     {
       
  1304 
       
  1305 
       
  1306     iError = aError;
       
  1307     CompleteAddClipOperation();
       
  1308 
       
  1309     }
       
  1310 
       
  1311 
       
  1312 void CAudSongAddClipOperation::CompleteAddClipOperation()
       
  1313     {
       
  1314     PRINT((_L("CAudSongAddClipOperation::CompleteAddClipOperation in")));
       
  1315 
       
  1316 
       
  1317     if (iError != KErrNone)
       
  1318         {
       
  1319         TInt trackIndex = iClip->TrackIndex();
       
  1320         delete iClip;
       
  1321         iClip = 0;
       
  1322         iSong->FireClipAddingFailed(iSong, iError, trackIndex);
       
  1323         PRINT((_L("CAudSong::CompleteAddClipOperation failed, out")));
       
  1324         return;
       
  1325         }
       
  1326     else
       
  1327         {
       
  1328     
       
  1329         TAudFileProperties info = iClip->iInfo->Properties();
       
  1330 
       
  1331         if (iSong->iClipArray.Count() > 0)
       
  1332             {
       
  1333             if (!(info.isCompatible(iSong->iClipArray[0]->Info()->Properties()))) 
       
  1334                 {
       
  1335                 TInt trackIndex = iClip->TrackIndex();
       
  1336         
       
  1337                 delete iClip;
       
  1338                 iClip = 0;
       
  1339                 iSong->FireClipAddingFailed(iSong, KErrNotSupported, trackIndex);
       
  1340                 PRINT((_L("CAudSong::CompleteAddClipOperation failed, out")));
       
  1341                 return;
       
  1342                 }
       
  1343             }
       
  1344         
       
  1345         if (iClip->CutOutTime() == TTimeIntervalMicroSeconds(KClipEndTime))
       
  1346             {
       
  1347     
       
  1348             iClip->iCutOutTime = info.iDuration;
       
  1349             }
       
  1350 
       
  1351             
       
  1352         TInt err = KErrNone;
       
  1353 
       
  1354         TBool added = EFalse;
       
  1355 
       
  1356         // insert clips so that they are always sorted by start time
       
  1357         TInt index = 0;
       
  1358         for (index = 0 ; index < iSong->iClipArray.Count() ; index++) 
       
  1359             {
       
  1360             if (iSong->iClipArray[index]->StartTime() > iClip->StartTime()) 
       
  1361                 {
       
  1362                 err = iSong->iClipArray.Insert(iClip, index);
       
  1363                 added = ETrue;
       
  1364                 break;
       
  1365                 }
       
  1366             }
       
  1367         if (!added) 
       
  1368             {
       
  1369             index = iSong->iClipArray.Count();
       
  1370             err = iSong->iClipArray.Insert(iClip, index);
       
  1371             if (err != KErrNone)
       
  1372                 {
       
  1373                 TInt trackIndex = iClip->TrackIndex();
       
  1374                 delete iClip;
       
  1375                 iClip = 0;
       
  1376                 iSong->FireClipAddingFailed(iSong, KErrGeneral, trackIndex);
       
  1377                 PRINT((_L("CAudSong::CompleteAddClipOperation failed, out")));
       
  1378                 return;
       
  1379                 }
       
  1380             
       
  1381             }
       
  1382         iClip->iIndex = iSong->Index2IndexOnTrack(index);
       
  1383         
       
  1384         if (err != KErrNone) 
       
  1385             {
       
  1386             TInt trackIndex = iClip->TrackIndex();
       
  1387         
       
  1388             delete iClip;
       
  1389             iClip = 0;
       
  1390             iSong->FireClipAddingFailed(iSong, err, trackIndex);            
       
  1391             }
       
  1392         else
       
  1393             {
       
  1394             iSong->UpdateClipIndexes();
       
  1395             CAudClip* clip = iClip;
       
  1396             iClip = 0;
       
  1397             
       
  1398 
       
  1399             if (clip->EndTime() > iSong->iSongDuration)
       
  1400                 {
       
  1401                 iSong->iSongDuration = clip->EndTime();
       
  1402                 }
       
  1403             
       
  1404 
       
  1405             iSong->FireClipAdded(iSong, clip, clip->iIndex, clip->iTrackIndex);
       
  1406 
       
  1407             
       
  1408             }
       
  1409         }
       
  1410     PRINT((_L("CAudSongAddClipOperation::CompleteAddClipOperation out")));
       
  1411     }    
       
  1412     
       
  1413 EXPORT_C void CAudSong::AddClipL(RFile* aFileHandle,
       
  1414         TTimeIntervalMicroSeconds aStartTime, TInt aTrackIndex,
       
  1415         TTimeIntervalMicroSeconds aCutInTime,
       
  1416         TTimeIntervalMicroSeconds aCutOutTime) 
       
  1417     {
       
  1418 
       
  1419     PRINT((_L("CAudSong::AddClipL in")));
       
  1420     if (iAddOperation->iClip != 0) 
       
  1421         {
       
  1422         TAudPanic::Panic(TAudPanic::ESongAddOperationAlreadyRunning);
       
  1423         }
       
  1424     if (iProcessOperation->iProcessor != 0 ) 
       
  1425         {
       
  1426         TAudPanic::Panic(TAudPanic::ESongProcessingOperationAlreadyRunning);
       
  1427         }
       
  1428 
       
  1429     iAddOperation->iClip = CAudClip::NewL(this, aFileHandle, aStartTime, *iAddOperation, aTrackIndex);
       
  1430     iAddOperation->iClip->iCutInTime = aCutInTime;
       
  1431     iAddOperation->iClip->iCutOutTime = aCutOutTime;
       
  1432 
       
  1433     PRINT((_L("CAudSong::AddClipL out")));
       
  1434 
       
  1435     }
       
  1436 
       
  1437 
       
  1438