videoeditorengine/audioeditorengine/src/ProcTools.cpp
author Mikael Laine <mikael.laine@ixonos.com>
Fri, 29 Jan 2010 14:08:33 +0200
changeset 0 951a5db380a0
permissions -rw-r--r--
Committing the Video Editor package under the Eclipse Public License

/*
* 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 "ProcTools.h"
#include "AudPanic.h"

#include "mime_io.h"


TBool ProcTools::Dec2Bin(TUint8 aDec, TBuf8<8>& aBinary) 
    {

    // clear aBinary just in case
    aBinary.Delete(0, aBinary.Length());

    aBinary.AppendNum(aDec, EBinary);

    TInt zerosNeeded = 0;
    if (aBinary.Length() == 8) 
        {
        // the MSB is one -> no padding needed
        }
    else 
        {
            
        zerosNeeded = 8 - aBinary.Length();
        for(TInt as = 0 ; as < zerosNeeded ; as++) 
            {
            aBinary.AppendNum(0);
            }

        for (TInt tr = 8 - 1 ; tr >= 0 ; tr--) 
            {

            if (tr >= zerosNeeded) 
                { 
                aBinary[tr] = aBinary[tr-zerosNeeded];
                }
            else 
                {
                aBinary[tr] = '0';
                }
        
            }
        }


    return ETrue;
    }

TBool ProcTools::Dec2BinL(TUint32 aDec, HBufC8*& aBin)
    {
    
    // 32 bits, the leftmost is one
    TUint32 bitMask = 0x80000000;

    TBool onlyZeros = ETrue;
    for (TInt a = 32 ; a > 0 ; a--)
        {
        TUint32 res = bitMask & aDec;
        
        if (res > 0 && onlyZeros)
            {
            // the first one from left found
            onlyZeros = EFalse;
            aBin = HBufC8::NewL(a);
            aBin->Des().Append('1');
            }
        else if (res > 0 && !onlyZeros)
            {
            aBin->Des().Append('1');
            }
        else if (res == 0 && !onlyZeros)
            {    
            aBin->Des().Append('0');
        
            }
        bitMask >>= 1;
        }

    return ETrue;

    }

TBool ProcTools::Bin2Dec(const TDesC8& aBin, TUint& aDec) 
    {

    TLex8 leks(aBin);

    if (leks.Val(aDec, EBinary) != KErrNone) 
        {
        return EFalse;
        }
    return ETrue;

    }

TBool ProcTools::Des2Dec(TDesC8& aDes, TUint& aDec) 
    {

    TLex8 leks(aDes);

    if (leks.Val(aDec, EDecimal) != KErrNone) 
        {
        return EFalse;
        }
    return ETrue;


    }

TBool ProcTools::Des2BinL(const TDesC8& aDes, HBufC8*& aBin) 
    {

    aBin = HBufC8::NewL(aDes.Length()*8);
    // clear aBinary just in case
    
    for (TInt a = 0 ; a < aDes.Length() ; a++) 
        {
    
        TUint8 chDec = aDes[a];

        aBin->Des().AppendNum(chDec, EBinary);
        
        TInt zerosNeeded = 0;
        if (aBin->Des().Length() == (a+1)*8) 
            {
            // the MSB is one -> no padding needed
            }
        else 
            {
            
            zerosNeeded = (a+1)*8 - aBin->Des().Length();
            for(TInt as = 0 ; as < zerosNeeded ; as++) 
                {
                aBin->Des().Insert(a*8, _L8("0"));
                //AppendNum(0);
                }
           
            }
        }


    return ETrue;

    }
    
TInt ProcTools::MilliSeconds(TTimeIntervalMicroSeconds aMicroSeconds)
    {
    
#ifndef EKA2
    return (aMicroSeconds.Int64()/1000).GetTInt();
#else
    return (aMicroSeconds.Int64()/1000);
#endif
    
    }

TTimeIntervalMicroSeconds ProcTools::MicroSeconds(TInt aMilliSeconds)
    {
    
    TTimeIntervalMicroSeconds mic(aMilliSeconds*1000);
    return mic;
    }
    
TInt ProcTools::GetTInt(TInt64 aTInt64)
    {

#ifndef EKA2
    return aTInt64.GetTInt();
#else        
    return aTInt64;
#endif
        
    }

TInt ProcTools::GetValueFromShuffledFrame(const HBufC8* aFrame, 
                                          const TUint8 aBitPositions[], 
                                          const TInt aSize) 
    {

    HBufC8* inBytes = 0;
    TRAPD(err, inBytes = HBufC8::NewL(aSize));
    if (err != KErrNone)
        {
        inBytes = 0;
        return -1;
        }
    
    
    _LIT8(KZero, "0");
    _LIT8(KOne, "1");


    for (TInt a = 0 ; a < aSize ; a++) 
        {
        
        TUint8 mask = 0x80; // 1000 0000b
        TUint byteNumber = aBitPositions[a]/8;
        TUint bitNumber = aBitPositions[a]%8;
        
        const TUint8 byteNow = (*aFrame)[byteNumber];

        mask >>= bitNumber;

        //TUint8 masked = byteNow & mask;
        // why casting is needed, dunno?

        TUint8 masked = static_cast<TUint8>(byteNow & mask);

        if (masked == 0) 
            {
            inBytes->Des().Append(KZero);
            }
        else 
            {
            inBytes->Des().Append(KOne);
            }
        }
    TUint dec = 0;
    Bin2Dec(inBytes->Des(), dec);
    delete inBytes;
    inBytes = 0;
    return dec;


    }



TInt ProcTools::GetValueFromShuffledAWBFrameL(const HBufC8* aFrame, TInt aBitRate, TInt aBitPosition, TInt aLength)
    {

    HBufC8* inBytes = HBufC8::NewLC(aLength);
    
    
    _LIT8(KZero, "0");
    _LIT8(KOne, "1");

    const TInt* table = 0;
    TInt tableSize = 0;

    switch(aBitRate)
        {
        case(23850):
            {
            table = sort_2385;
            tableSize = 477;
            break;
            }
        case(23050):
            {
            table = sort_2305;
            tableSize = 461;
            break;
            }
        case(19850):
            {
            table = sort_1985;
            tableSize = 397;
            break;
            }
        case(18250):
            {
            table = sort_1825;
            tableSize = 365;
            break;
            }
        case(15850):
            {
            table = sort_1585;
            tableSize = 317;
            break;
            }
        case(14250):
            {
            table = sort_1425;
            tableSize = 285;
            break;
            }
        case(12650):
            {
            table = sort_1265;
            tableSize = 253;
            break;
            }
        case(8850):
            {
            table = sort_885;
            tableSize = 177;
            break;
            }
        case(6600):
            {
            table = sort_660;
            tableSize = 132;
            break;
            }
        default:
            {
            // illegal bitrate
            CleanupStack::PopAndDestroy(inBytes);
            return -1;
            }

        }


    for (TInt a = 0 ; a < aLength ; a++) 
        {
        TInt bitIndex = FindIndex(aBitPosition+a, table, tableSize)+8;

        TUint8 mask = 0x80; // 1000 0000b
        TUint byteNumber = bitIndex/8;
        TUint bitNumber = bitIndex%8;
        
        const TUint8 byteNow = (*aFrame)[byteNumber];

        mask >>= bitNumber;

        //TUint8 masked = byteNow & mask;
        // why casting is needed, dunno?

        TUint8 masked = static_cast<TUint8>(byteNow & mask);

        if (masked == 0) 
            {
            inBytes->Des().Append(KZero);
            }
        else 
            {
            inBytes->Des().Append(KOne);
            }
        }

    TUint dec = 0;
    Bin2Dec(inBytes->Des(), dec);
    CleanupStack::PopAndDestroy(inBytes);

    inBytes = 0;
    return dec;

    }


TBool ProcTools::SetValueToShuffledAWBFrame(TUint8 aNewValue, HBufC8* aFrame, 
                                            TInt aBitRate, TInt aBitPosition, TInt aLength)
    {

    const TInt* table = 0;
    TInt tableSize = 0;

    switch(aBitRate)
        {
        case(23850):
            {
            table = sort_2385;
            tableSize = 477;
            
            break;
            }
        case(23050):
            {
            table = sort_2305;
            tableSize = 461;
            
            break;
            }
        case(19850):
            {
            table = sort_1985;
            tableSize = 397;
            
            break;
            }
        case(18250):
            {
            table = sort_1825;
            tableSize = 365;
            
            break;
            }
        case(15850):
            {
            table = sort_1585;
            tableSize = 317;
            
            break;
            }
        case(14250):
            {
            table = sort_1425;
            tableSize = 285;
            
            break;
            }
        case(12650):
            {
            table = sort_1265;
            tableSize = 253;
            
            break;
            }
        case(8850):
            {
            table = sort_885;
            tableSize = 177;
            
            break;
            }
        case(6600):
            {
            table = sort_660;
            tableSize = 132;
            
            break;
            }
        default:
            {
            // illegal bitrate
            return -1;
            }

        }


    _LIT8(KZero, "0");

    TBuf8<8> newValueBin;
    Dec2Bin(aNewValue, newValueBin);
    // remove leading zeros
    newValueBin.Delete(0, 8-aLength);



    TPtr8 framePtr(aFrame->Des());

    for (TInt a = 0 ; a < newValueBin.Size() ; a++) 
        {

        TInt bitIndex = FindIndex(aBitPosition+a, table, tableSize)+8;

        TUint8 bitPositionInByte = static_cast<TUint8>(bitIndex%8);
        TUint byteNumber = bitIndex/8;

        if (newValueBin.Mid(a,1).Compare(KZero) == 0) 
            {

            TUint8 mask = 0x80; // 0111 1111b
            mask >>= bitPositionInByte;
            mask = static_cast<TUint8>(~mask);

            //--->
//            TUint8 oldByte = framePtr[byteNumber];
    //        TUint8 newByte = oldByte & mask;
            //<--

            framePtr[byteNumber] = static_cast<TUint8>(framePtr[byteNumber] & mask);  
    
            }
        else 
            {

            TUint8 mask = 0x80; // 1000 0000b
            mask >>= bitPositionInByte;
            
            //--->
//            TUint8 oldByte = framePtr[byteNumber];
//            TUint8 newByte = oldByte & mask;
            //<--
            framePtr[byteNumber] = static_cast<TUint8>(framePtr[byteNumber] | mask);

            }
        
        }

    return EFalse;
    }

TBool ProcTools::SetValueToShuffledFrame(HBufC8* aFrame, TUint8 aNewValue, 
                                         const TUint8 aBitPositions[], 
                                         TInt aSize) 
    {

    
    _LIT8(KZero, "0");
    
    TBuf8<8> newValueBin;
    Dec2Bin(aNewValue, newValueBin);
    newValueBin.Delete(0, 8-aSize);

    TPtr8 framePtr(aFrame->Des());

    for (TInt a = 0 ; a < aSize ; a++) 
        {

        TUint8 bitPosition = static_cast<TUint8>(aBitPositions[a]%8);
        TUint byteNumber = aBitPositions[a]/8;

        if (newValueBin.Mid(a,1).Compare(KZero) == 0) 
            {

            TUint8 mask = 0x80; // 0111 1111b
            mask >>= bitPosition;
            mask = static_cast<TUint8>(~mask);

            //--->
//            TUint8 oldByte = framePtr[byteNumber];
    //        TUint8 newByte = oldByte & mask;
            //<--

            framePtr[byteNumber] = static_cast<TUint8>(framePtr[byteNumber] & mask);  
    
            }
        else 
            {

            TUint8 mask = 0x80; // 1000 0000b
            mask >>= bitPosition;
            
            //--->
//            TUint8 oldByte = framePtr[byteNumber];
//            TUint8 newByte = oldByte & mask;
            //<--
            framePtr[byteNumber] = static_cast<TUint8>(framePtr[byteNumber] | mask);

            }


        
        }
    
    return ETrue;

    }



TBool ProcTools::WriteValuesToFileL(const RArray<TInt>& aArray, const TDesC& aFilename) 
    {

    RFs fs;
    User::LeaveIfError(fs.Connect());

    RFile file;
    TInt err=file.Open(fs, aFilename, EFileWrite);
    
    if (err==KErrNotFound) 
        {
        err=file.Create(fs, aFilename, EFileWrite);
        }
    TInt nolla = 0;
    file.Seek(ESeekEnd, nolla);
    for (TInt a = 0; a < aArray.Count() ; a++) 
        {
        TBuf8<8> num;
        num.AppendNum(aArray[a]);
        file.Write(num);
        file.Write(_L8("\n"));


        }

    file.Close();
    fs.Close();

    return ETrue;
    }


TUint8 ProcTools::FindNewIndexSQ(TInt aNewGain, const TInt aGainTable[], TInt aTableSize) 
    {

    if (aTableSize > 256)
        {
        TAudPanic::Panic(TAudPanic::EInternal);
        }

    TUint8 tableSize = static_cast<TUint8>(aTableSize-1);

    TInt minimum = 0xFFFF;
    TUint8 indexFound = 0;

    for (TUint a = 0 ; a <= tableSize ; a++) 
        {
            
        if (Abs(aGainTable[a]-aNewGain) < minimum) 
            {
            minimum = Abs(aGainTable[a]-aNewGain);
            indexFound = static_cast<TUint8>(a);
            }
        }

    return indexFound;

    }

TUint8 ProcTools::FindNewIndexVQ(TInt aNewGain, TInt aOldPitch, const TInt aGainTable[], TInt aTableSize) 
    {

    if (aTableSize > 256)
        {
        TAudPanic::Panic(TAudPanic::EInternal);
        }

    TUint8 tableSize = static_cast<TUint8>(aTableSize-1);



    TInt minimum = KMaxTInt;
    TUint8 indexFound = 0;

    for (TUint a = 0 ; a <= tableSize ; a+=2) 
        {

        // gpitch: Q14 , 2^14 = 16384
        TInt distance_pitch = (100*(Abs(aGainTable[a]-aOldPitch)))/16384;

        // g_fac: Q12 , 2^12 = 4096
        TInt distance_fc = (100*Abs(aGainTable[a+1]-aNewGain))/4096;
        

        TInt distance = distance_pitch*distance_pitch + distance_fc*distance_fc;
        
        if (distance < minimum) 
            {
            minimum = distance;
            indexFound = static_cast<TUint8>(a);
            }
        }

    return static_cast<TUint8>(indexFound/2);

    }

TUint8 ProcTools::FindNewIndexVQ2(TInt aNewGain, TInt aOldPitch, const TInt aGainTable[], TInt aTableSize)
    {

    if (aTableSize > 256)
        {
        TAudPanic::Panic(TAudPanic::EInternal);
        }

    TUint8 tableSize = static_cast<TUint8>(aTableSize-1);

    TInt minimum = KMaxTInt;
    TUint8 indexFound = 0;

    for (TUint a = 0 ; a <= tableSize ; a+=2) 
        {

        // gpitch: Q14 , 2^14 = 16384
        TInt distance_pitch = (100*(Abs(aGainTable[a]-aOldPitch)))/16384;

        // g_fac: Q11 , 2^11 = 2048
        TInt distance_fc = (100*Abs(aGainTable[a+1]-aNewGain))/2048;
        

        TInt distance = distance_pitch*distance_pitch + distance_fc*distance_fc;
        
        if (distance < minimum) 
            {
            minimum = distance;
            indexFound = static_cast<TUint8>(a);
            }
        }

    return static_cast<TUint8>(indexFound/2);

    


    }


TUint8 ProcTools::FindNewIndex475VQ(TInt aNewGain0, TInt aOldPitch0, TInt aNewGain1, TInt aOldPitch1)
    {

    TInt minimum = KMaxTInt;
    TInt indexFound = -1;

    TInt tableSize = 256*4;


    for (TInt a = 0 ; a < tableSize-3 ; a+=4) 
        {

        // gpitch: Q14 , 2^14 = 16384
        TInt distance_pitch0 = (100*(Abs(KAmrGainTable475[a]-aOldPitch0)))/16384;
        TInt distance_pitch1 = (100*(Abs(KAmrGainTable475[a+2]-aOldPitch1)))/16384;

        // g_fac: Q12 , 2^12 = 4096
        TInt distance_fc0 = (100*Abs(KAmrGainTable475[a+1]-aNewGain0))/4096;
        TInt distance_fc1 = (100*Abs(KAmrGainTable475[a+3]-aNewGain1))/4096;        

        TInt distance = distance_pitch0*distance_pitch0 + distance_fc0*distance_fc0 +
                        distance_pitch1*distance_pitch1 + distance_fc1*distance_fc1;
        
        if (distance < minimum) 
            {
            minimum = distance;
            indexFound = a;
            }
        }

    return static_cast<TUint8>(indexFound/4);

    }

TInt ProcTools::FindIndex(TInt aKey, const TInt aBitPositions[], TInt aTableLength)
    {
    
    for (TInt a = 0 ; a < aTableLength ; a++)
        {
        if (aBitPositions[a] == aKey) return a;
        }

    return -1;

    }

TBool ProcTools::GenerateADTSHeaderL(TBuf8<7>& aHeader, TInt aFrameLength, TAudFileProperties aProperties)
    {
    TUint8 byte1 = 0xFF;

    TUint8 byte2 = 0x0;
    if (aProperties.iAudioType == EAudAAC_MPEG2)
        {
        byte2 = 0xF9;
        }
    else if (aProperties.iAudioType == EAudAAC_MPEG4)
        {
        byte2 = 0xF1;
        }
    else return EFalse;
    TBuf8<8> byte3b(8);
    TBuf8<8> byte4b(8);
    TBuf8<8> byte5b(8);
    TBuf8<8> byte6b(8);
    TBuf8<8> byte7b(8);

    byte3b.Fill('0');
    byte4b.Fill('0');
    byte5b.Fill('0');
    byte6b.Fill('0');
    byte7b.Fill('0');

    
    const TInt KAAC_SAMPLING_RATES[16] = {96000,88200,64000,48000,44100,32000,24000,
                                            22050,16000,12000,11025,8000,0,0,0,0};
    
    TBool srFound = EFalse;
    TUint8 srIndex = 0; 
    for (srIndex = 0 ; srIndex < 14 ; srIndex++)
        {
        if (KAAC_SAMPLING_RATES[srIndex] == aProperties.iSamplingRate) 
            {
            srFound = ETrue;
            break;
            }
        }

    if (srFound)
        {
        TBuf8<8> srB;
        ProcTools::Dec2Bin(srIndex, srB);
    
        // Sampling rate
        byte3b[2] = srB[4];
        byte3b[3] = srB[5];
        byte3b[4] = srB[6];
        byte3b[5] = srB[7];

        }

    

    // private bit
    byte3b[6] = '0';

    // channel configuration
    byte3b[7] = '0';
    if (aProperties.iChannelMode == EAudStereo)
        {
        byte4b[0] = '1';
        byte4b[1] = '0';

        }
    else if(aProperties.iChannelMode == EAudSingleChannel)
        {
        byte4b[0] = '0';
        byte4b[1] = '1';

        }
    else
        {
        return EFalse;
        }

    //original/copy & home
    byte4b[2] = '0';
    byte4b[3] = '0';
    // copyright identification & start
    byte4b[4] = '0';
    byte4b[5] = '0';

    HBufC8* lenBin = 0;
    if (ProcTools::Dec2BinL(aFrameLength+7, lenBin))
        {

        TInt fromRight = 0;
        for(TInt i = lenBin->Size()-1 ; i >= 0 ; i--)
            {
            if (fromRight < 3)
                {
                // byte7
                byte6b[2-fromRight] = lenBin->Des()[i];    
                }
            else if (fromRight < 11)
                {
                // byte6
                byte5b[10-fromRight] = lenBin->Des()[i];

                }
            else if (fromRight < 13)
                {
                // byte5
                byte4b[18-fromRight] = lenBin->Des()[i];
                }

            fromRight++;
            }

        delete lenBin;
        }
    
    TInt bitInd = 0; 
    for (bitInd = 3 ; bitInd < 8 ; bitInd++)
    {
        byte6b[bitInd] = '1';
    }
    for (bitInd = 0 ; bitInd < 6 ; bitInd++)
    {
        byte7b[bitInd] = '1';
    }
    
    
    aHeader.Append(byte1);
    aHeader.Append(byte2);

    TUint tmpByte = 0;
    ProcTools::Bin2Dec(byte3b, tmpByte);
    
    // profile
    TUint8 bitMask = aProperties.iAACObjectType;
    bitMask <<= 6;
    tmpByte = tmpByte | bitMask;

    aHeader.Append(static_cast<TUint8>(tmpByte));

    ProcTools::Bin2Dec(byte4b, tmpByte);
    aHeader.Append(static_cast<TUint8>(tmpByte));

    ProcTools::Bin2Dec(byte5b, tmpByte);
    aHeader.Append(static_cast<TUint8>(tmpByte));

    ProcTools::Bin2Dec(byte6b, tmpByte);
    aHeader.Append(static_cast<TUint8>(tmpByte));

    ProcTools::Bin2Dec(byte7b, tmpByte);
    aHeader.Append(static_cast<TUint8>(tmpByte));

    return ETrue;

    }

TInt ProcTools::GetNextAMRFrameLength(const HBufC8* aFrame, TInt aPosNow)
    {


    if (aPosNow >= aFrame->Size()) return -1;


    const TUint8 ch = (*aFrame)[aPosNow];

    TUint dec_mode = (enum Mode)((ch & 0x0078) >> 3);
    
    switch (dec_mode)
        {
        case 0:
            {
            return 12+1;
            }
            
        case 1:
            {
            return 13+1;
            }
            
        case 2:
            {
            return 15+1;
            }
            
        case 3:
            {
            return 17+1;
            }
            
        case 4:
            {
            return 19+1;
            }
            
        case 5:
            {
            return 20+1;
            }
            
        case 6:
            {
            return 26+1;
            }
            
        case 7:
            {
            return 31+1;
            }
            
        case 8:
            {
            return 5+1;
            }
            
        case 15:
            {
            return 0+1;
            }
            
        default:
            return 0+1;
            
        };
    

    }


CProcessingEvent* CProcessingEvent::NewL()
    {
    CProcessingEvent* self = new (ELeave) CProcessingEvent();
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;

    }

void CProcessingEvent::ConstructL()
    {
    }

CProcessingEvent::~CProcessingEvent()
    {
    iAllIndexes.Close();
    }


CProcessingEvent::CProcessingEvent()
    {
    }

void CProcessingEvent::InsertIndex(TInt aIndex)
        {
        iAllIndexes.Append(aIndex);
        }

TInt CProcessingEvent::GetIndex(TInt aProcessingEventIndex)
    {
    return iAllIndexes[aProcessingEventIndex];
    }

TBool CProcessingEvent::GetAllIndexes(RArray<TInt>& aAllIndexes)
    {
    for (TInt a = 0 ; a < iAllIndexes.Count() ; a++)
        {
        aAllIndexes.Append(iAllIndexes[a]);

        }
    return ETrue;
    }

TInt CProcessingEvent::IndexCount()
    {
    return iAllIndexes.Count();
    }

TInt CProcessingEvent::FindIndex(TInt aClipIndex)
    {
    return iAllIndexes.Find(aClipIndex);
    }

void CProcessingEvent::RemoveIndex(TInt aProcessingEventIndex)
    {
    iAllIndexes.Remove(aProcessingEventIndex);
    }

    
TInt CProcessingEvent::Compare(const CProcessingEvent& c1, const CProcessingEvent& c2) 
    {
                
    if (c1.iPosition > c2.iPosition) 
        {
        return 1;
        }
    else if (c1.iPosition < c2.iPosition) 
        {
        return -1;
        }
    else 
        {
        return 0;
        }
    }