--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/src/Plugin/Codec/audio/MMFCodecBaseDefinitions.cpp Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,339 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+//
+// Description:
+//
+
+#include "MMFCodecBaseDefinitions.h"
+#include "MMFAudioCodecBase.h"
+#include <mmf/common/mmfpaniccodes.h>
+
+// Base of Audio codecs
+// These T Classes are "wrapped" by derived MMFCodecs, not exposed directly.
+
+
+void Panic(TInt aPanicCode)
+ {
+ _LIT(KMMFCodecBaseDefinitionsPanicCategory, "MMFCodecBaseDefinitions");
+ User::Panic(KMMFCodecBaseDefinitionsPanicCategory, aPanicCode);
+ }
+
+
+void TMMFImaAdpcmBaseCodecOld::ResetBuffer()
+ {
+ iBufferStep = ETrue;
+ iBuffer = 0;
+ }
+
+TBool TMMFImaAdpcmBaseCodecOld::OutputStep()
+ {
+ return !iBufferStep;
+ }
+
+void TMMFImaAdpcmTo16PcmCodecOld::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
+ {
+ TInt delta; // Current adpcm output value
+ TInt step; // Stepsize
+ TInt valpred; // Predicted value
+ TInt vpdiff; // Current change to valpred
+ TInt index; // Current step change index
+
+ TInt channelCount=16;//for stereo only
+
+ aSamples*=iChannels;
+
+ //Read first sample and index from block header
+ iState[0].iPredicted = *aSrc++;
+ iState[0].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
+ iState[0].iIndex = *aSrc++;
+
+ aSrc++; //skip reserved header byte
+
+ valpred = iState[0].iPredicted;
+ index = iState[0].iIndex;
+ TUint8* dst=aDst;
+
+ //Write first sample to dest
+ *aDst++ = STATIC_CAST( TUint8, valpred);
+ *aDst++ = STATIC_CAST( TUint8, valpred >> 8);
+ dst += 2;
+ aSamples --;
+
+ if (iChannels==2)
+ {
+ iState[1].iPredicted = *aSrc++;
+ iState[1].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
+ iState[1].iIndex = *aSrc++;
+ aSrc++;
+
+ *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted);
+ *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted >> 8);
+ dst += 2;
+ aSamples --;
+ }
+
+ for ( ; aSamples > 0 ; aSamples-- )
+ {
+ // Step 1 - get the delta value
+ if (iBufferStep)
+ {
+ iBuffer = *aSrc++;
+ delta = iBuffer & 0xf;
+ }
+ else
+ {
+ delta = (iBuffer >> 4) & 0xf;
+ }
+
+ iBufferStep = !iBufferStep;
+
+ ASSERT(index >= 0);
+ step = iStepSizeTable[index];
+
+ vpdiff = step>>3;
+ if ( delta & 4 )
+ vpdiff += step;
+ if ( delta & 2 )
+ vpdiff += step>>1;
+ if ( delta & 1 )
+ vpdiff += step>>2;
+
+ if ( delta & 8 )
+ valpred -= vpdiff;
+ else
+ valpred += vpdiff;
+
+ if ( valpred > (KClamp - 1) )
+ valpred = (KClamp - 1);
+ else if ( valpred < -KClamp )
+ valpred = -KClamp;
+
+ index += iIndexTable[delta];
+ if ( index < 0 )
+ index = 0;
+ if ( index > KMaxImaAdpcmTableEntries )
+ index = KMaxImaAdpcmTableEntries;
+
+ *dst++ = STATIC_CAST( TUint8, valpred&KAndMask8bit);
+ *dst++ = STATIC_CAST( TUint8, (valpred>>8)&KAndMask8bit);
+
+ if (iChannels==2)
+ {
+ dst+=2;
+ if (--channelCount == 8)
+ {
+ dst=aDst+2; //right channel
+ iState[0].iPredicted=STATIC_CAST(TInt16, valpred);
+ iState[0].iIndex=STATIC_CAST(TUint8,index);
+ valpred = iState[1].iPredicted;
+ index = iState[1].iIndex;
+ }
+ else
+ {
+ if (!channelCount)
+ {
+ aDst+=32;
+ dst=aDst;
+ channelCount=16;
+ iState[1].iPredicted=STATIC_CAST(TInt16, valpred);
+ iState[1].iIndex=STATIC_CAST(TUint8, index);
+ valpred = iState[0].iPredicted;
+ index = iState[0].iIndex;
+ }
+ }
+ }
+ }
+ if (iChannels==1)
+ {
+ iState[0].iPredicted=STATIC_CAST(TInt16,valpred);
+ iState[0].iIndex=STATIC_CAST(TUint8,index);
+ }
+ }
+
+void TMMF16PcmToImaAdpcmCodecOld::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
+ {
+ TInt val; // Current input sample value
+ TInt sign; // Current adpcm sign bit
+ TInt delta; // Current adpcm output value
+ TInt diff; // Difference between val and valprev
+ TInt step; // Stepsize
+ TInt valpred; // Predicted value
+ TInt vpdiff; // Current change to valpred
+ TInt index; // Current step change index
+
+ TInt16* srcPtr=REINTERPRET_CAST(TInt16*, aSrc);
+ TInt16* src=srcPtr;
+
+ TInt bufferCount=16;//for stereo only
+
+ if (iChannels==2)
+ {
+ aSamples*=2;
+ iBufferStep=ETrue;
+ }
+
+ iState[0].iPredicted = *aSrc++;
+ iState[0].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
+
+ valpred = iState[0].iPredicted;
+ index = iState[0].iIndex;
+ ASSERT(index >= 0);
+ step = iStepSizeTable[index];
+
+ //Write block header
+ *aDst++ = STATIC_CAST( TUint8, valpred);
+ *aDst++ = STATIC_CAST( TUint8, valpred >> 8);
+ *aDst++ = STATIC_CAST( TUint8, index);
+ *aDst++ = 0; //reserved byte
+ src++;
+ aSamples --;
+
+ if (iChannels==2)
+ {
+ iState[1].iPredicted = *aSrc++;
+ iState[1].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
+
+ //Write header for second channel
+ *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted);
+ *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted >> 8);
+ *aDst++ = STATIC_CAST( TUint8, iState[1].iIndex);
+ *aDst++ = 0;
+ src ++;
+ aSamples --;
+ }
+
+ for (; aSamples > 0; aSamples--)
+ {
+ val = *src;
+ src += iChannels;
+
+ ASSERT(index >= 0);
+ step = iStepSizeTable[index];
+
+ // Step 1 - compute difference with previous value
+ diff = val - valpred;
+ sign = (diff < 0) ? 8 : 0;
+ if ( sign ) diff = (-diff);
+
+ // Step 2 - Divide and clamp
+ // Note:
+ // This code *approximately* computes:
+ // delta = diff*4/step;
+ // vpdiff = (delta+0.5)*step/4;
+ // but in shift step bits are dropped. The net result of this is
+ // that even if you have fast mul/div hardware you cannot put it to
+ // good use since the fixup would be too expensive.
+ //
+ delta = 0;
+ vpdiff = (step >> 3);
+
+ if ( diff >= step )
+ {
+ delta = 4;
+ diff -= step;
+ vpdiff += step;
+ }
+ step >>= 1;
+ if ( diff >= step )
+ {
+ delta |= 2;
+ diff -= step;
+ vpdiff += step;
+ }
+ step >>= 1;
+ if ( diff >= step )
+ {
+ delta |= 1;
+ vpdiff += step;
+ }
+
+ // Step 3 - Update previous value
+ if ( sign )
+ valpred -= vpdiff;
+ else
+ valpred += vpdiff;
+
+ // Step 4 - Clamp previous value to 16 bits
+ if ( valpred > KClamp - 1 )
+ valpred = KClamp - 1;
+ else if ( valpred < - KClamp )
+ valpred = - KClamp;
+
+ // Step 5 - Assemble value, update index and step values
+ delta |= sign;
+
+ index += iIndexTable[delta];
+ if ( index < 0 ) index = 0;
+ if ( index > 88 ) index = 88;
+
+ // Step 6 - Output value
+ if (iBufferStep)
+ iBuffer = delta & 0x0f;
+ else
+ *aDst++ = STATIC_CAST( TInt8, ((delta << 4) & 0xf0) | iBuffer);
+
+ iBufferStep = !iBufferStep;
+
+ if (iChannels==2)
+ {
+ if (--bufferCount==8)
+ {
+ src=srcPtr+1; //right channel
+ iState[0].iPredicted = STATIC_CAST(TInt16, valpred);
+ iState[0].iIndex = STATIC_CAST(TUint8, index);
+ valpred = iState[1].iPredicted;
+ index = iState[1].iIndex;
+ }
+ else
+ {
+ if (!bufferCount)
+ {
+ iState[1].iPredicted = STATIC_CAST(TInt16, valpred);
+ iState[1].iIndex = STATIC_CAST(TUint8, index);
+ valpred = iState[0].iPredicted;
+ index = iState[0].iIndex;
+ bufferCount=16;
+ srcPtr+=16;//32bytes
+ src=srcPtr;
+ }
+ }
+ }
+ }
+
+ if (iChannels==1)
+ {
+ iState[0].iPredicted = STATIC_CAST(TInt16, valpred);
+ iState[0].iIndex = STATIC_CAST(TUint8, index);
+ }
+ }
+
+// IMA-ADPCM step variation table
+const TInt TMMFImaAdpcmBaseCodecOld::iIndexTable[16] =
+ {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+ -1, -1, -1, -1, 2, 4, 6, 8
+ };
+
+const TInt TMMFImaAdpcmBaseCodecOld::iStepSizeTable[89] =
+ {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+ };
+
+