mmlibs/mmfw/src/Plugin/Codec/audio/MMFCodecBaseDefinitions.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "MMFCodecBaseDefinitions.h"
       
    17 #include "MMFAudioCodecBase.h"
       
    18 #include <mmf/common/mmfpaniccodes.h>
       
    19 
       
    20 // Base of Audio codecs
       
    21 // These T Classes are "wrapped" by derived MMFCodecs, not exposed directly.
       
    22 
       
    23 
       
    24 void Panic(TInt aPanicCode)
       
    25 	{
       
    26 	_LIT(KMMFCodecBaseDefinitionsPanicCategory, "MMFCodecBaseDefinitions");
       
    27 	User::Panic(KMMFCodecBaseDefinitionsPanicCategory, aPanicCode);
       
    28 	}
       
    29 
       
    30 
       
    31 void TMMFImaAdpcmBaseCodecOld::ResetBuffer()
       
    32 	{
       
    33 	iBufferStep = ETrue;
       
    34 	iBuffer = 0;
       
    35 	}
       
    36 
       
    37 TBool TMMFImaAdpcmBaseCodecOld::OutputStep()
       
    38 	{
       
    39 	return !iBufferStep;
       
    40 	}
       
    41 
       
    42 void TMMFImaAdpcmTo16PcmCodecOld::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
       
    43 	{
       
    44     TInt delta;			// Current adpcm output value 
       
    45     TInt step;			// Stepsize
       
    46     TInt valpred;		// Predicted value 
       
    47     TInt vpdiff;		// Current change to valpred 
       
    48     TInt index;			// Current step change index 
       
    49 
       
    50 	TInt channelCount=16;//for stereo only
       
    51 
       
    52 	aSamples*=iChannels;
       
    53 
       
    54 	//Read first sample and index from block header
       
    55 	iState[0].iPredicted = *aSrc++;
       
    56 	iState[0].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
       
    57 	iState[0].iIndex = *aSrc++;
       
    58 
       
    59 	aSrc++; //skip reserved header byte
       
    60 
       
    61 	valpred = iState[0].iPredicted;
       
    62 	index = iState[0].iIndex;
       
    63 	TUint8* dst=aDst;
       
    64 
       
    65 	//Write first sample to dest
       
    66 	*aDst++ = STATIC_CAST( TUint8, valpred);
       
    67 	*aDst++ = STATIC_CAST( TUint8, valpred >> 8);
       
    68 	dst += 2;
       
    69 	aSamples --;
       
    70 
       
    71 	if (iChannels==2)
       
    72 		{
       
    73 		iState[1].iPredicted = *aSrc++;
       
    74 		iState[1].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
       
    75 		iState[1].iIndex = *aSrc++;
       
    76 		aSrc++;
       
    77 
       
    78 		*aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted);
       
    79 		*aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted >> 8);
       
    80 		dst += 2;
       
    81 		aSamples --;
       
    82 		}
       
    83 
       
    84     for ( ; aSamples > 0 ; aSamples-- ) 
       
    85 		{ 
       
    86 		// Step 1 - get the delta value
       
    87 		if (iBufferStep) 
       
    88 			{
       
    89 			iBuffer = *aSrc++;
       
    90 			delta = iBuffer & 0xf;
       
    91 			} 
       
    92 		else 
       
    93 			{
       
    94 			delta = (iBuffer >> 4) & 0xf;
       
    95 			}
       
    96 
       
    97 		iBufferStep = !iBufferStep;
       
    98 
       
    99 		ASSERT(index >= 0);
       
   100 		step = iStepSizeTable[index];
       
   101 
       
   102 		vpdiff = step>>3;
       
   103 		if ( delta & 4 ) 
       
   104 			vpdiff += step;
       
   105 		if ( delta & 2 ) 
       
   106 			vpdiff += step>>1;
       
   107 		if ( delta & 1 ) 
       
   108 			vpdiff += step>>2;
       
   109 
       
   110 		if ( delta & 8 )
       
   111 			valpred -= vpdiff;
       
   112 		else
       
   113 			valpred += vpdiff;
       
   114 
       
   115 		if ( valpred > (KClamp - 1) )
       
   116 			valpred = (KClamp - 1);
       
   117 		else if ( valpred < -KClamp )
       
   118 			valpred = -KClamp;
       
   119 
       
   120 		index += iIndexTable[delta];
       
   121 		if ( index < 0 ) 
       
   122 			index = 0;
       
   123 		if ( index > KMaxImaAdpcmTableEntries ) 
       
   124 			index = KMaxImaAdpcmTableEntries;
       
   125 
       
   126 		*dst++ = STATIC_CAST( TUint8, valpred&KAndMask8bit);
       
   127 		*dst++ = STATIC_CAST( TUint8, (valpred>>8)&KAndMask8bit);
       
   128 
       
   129 		if (iChannels==2)
       
   130 			{
       
   131 			dst+=2;
       
   132 			if (--channelCount == 8)
       
   133 				{
       
   134 				dst=aDst+2;	//right channel
       
   135 				iState[0].iPredicted=STATIC_CAST(TInt16, valpred);
       
   136 				iState[0].iIndex=STATIC_CAST(TUint8,index);
       
   137 				valpred = iState[1].iPredicted;
       
   138 				index = iState[1].iIndex;
       
   139 				}
       
   140 			else
       
   141 				{
       
   142 				if (!channelCount)
       
   143 					{
       
   144 					aDst+=32;
       
   145 					dst=aDst;
       
   146 					channelCount=16;
       
   147 					iState[1].iPredicted=STATIC_CAST(TInt16, valpred);
       
   148 					iState[1].iIndex=STATIC_CAST(TUint8, index);
       
   149 					valpred = iState[0].iPredicted;
       
   150 					index = iState[0].iIndex;
       
   151 					}
       
   152 				}
       
   153 			}
       
   154 		}
       
   155 	if (iChannels==1)
       
   156 		{
       
   157 		iState[0].iPredicted=STATIC_CAST(TInt16,valpred);
       
   158 		iState[0].iIndex=STATIC_CAST(TUint8,index);
       
   159 		}
       
   160 	}
       
   161 
       
   162 void TMMF16PcmToImaAdpcmCodecOld::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
       
   163 	{
       
   164 	TInt val;			// Current input sample value 
       
   165     TInt sign;			// Current adpcm sign bit 
       
   166     TInt delta;			// Current adpcm output value 
       
   167 	TInt diff;			// Difference between val and valprev 
       
   168 	TInt step;			// Stepsize
       
   169     TInt valpred;		// Predicted value 
       
   170     TInt vpdiff;		// Current change to valpred 
       
   171     TInt index;			// Current step change index 
       
   172 	
       
   173 	TInt16* srcPtr=REINTERPRET_CAST(TInt16*, aSrc);
       
   174 	TInt16* src=srcPtr;
       
   175 
       
   176 	TInt bufferCount=16;//for stereo only
       
   177 
       
   178 	if (iChannels==2)
       
   179 		{
       
   180 		aSamples*=2;
       
   181 		iBufferStep=ETrue;
       
   182 		}
       
   183 
       
   184 	iState[0].iPredicted = *aSrc++;
       
   185 	iState[0].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
       
   186 
       
   187     valpred = iState[0].iPredicted;
       
   188     index = iState[0].iIndex;
       
   189     ASSERT(index >= 0);
       
   190     step = iStepSizeTable[index];
       
   191 
       
   192 	//Write block header
       
   193 	*aDst++ = STATIC_CAST( TUint8, valpred);
       
   194 	*aDst++ = STATIC_CAST( TUint8, valpred >> 8);
       
   195 	*aDst++ = STATIC_CAST( TUint8, index);
       
   196 	*aDst++ = 0; //reserved byte
       
   197 	src++;
       
   198 	aSamples --;	
       
   199 
       
   200 	if (iChannels==2)
       
   201 		{
       
   202 		iState[1].iPredicted = *aSrc++;
       
   203 		iState[1].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
       
   204 
       
   205 		//Write header for second channel
       
   206 		*aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted);
       
   207 		*aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted >> 8);
       
   208 		*aDst++ = STATIC_CAST( TUint8, iState[1].iIndex);
       
   209 		*aDst++ = 0;
       
   210 		src ++;
       
   211 		aSamples --;
       
   212 		}
       
   213 
       
   214 	for (; aSamples > 0; aSamples--) 
       
   215 		{ 
       
   216 		val = *src;
       
   217 		src += iChannels;
       
   218 
       
   219 		ASSERT(index >= 0);
       
   220 	    step = iStepSizeTable[index];
       
   221 
       
   222 		// Step 1 - compute difference with previous value 
       
   223 		diff = val - valpred;
       
   224 		sign = (diff < 0) ? 8 : 0;
       
   225 		if ( sign ) diff = (-diff);
       
   226 
       
   227 		// Step 2 - Divide and clamp 
       
   228 		// Note:
       
   229 		// This code *approximately* computes:
       
   230 		//    delta = diff*4/step;
       
   231 		//    vpdiff = (delta+0.5)*step/4;
       
   232 		// but in shift step bits are dropped. The net result of this is
       
   233 		// that even if you have fast mul/div hardware you cannot put it to
       
   234 		// good use since the fixup would be too expensive.
       
   235 		//
       
   236 		delta = 0;
       
   237 		vpdiff = (step >> 3);
       
   238 		
       
   239 		if ( diff >= step ) 
       
   240 			{
       
   241 			delta = 4;
       
   242 			diff -= step;
       
   243 			vpdiff += step;
       
   244 			}
       
   245 		step >>= 1;
       
   246 		if ( diff >= step  ) 
       
   247 			{
       
   248 			delta |= 2;
       
   249 			diff -= step;
       
   250 			vpdiff += step;
       
   251 			}
       
   252 		step >>= 1;
       
   253 		if ( diff >= step ) 
       
   254 			{
       
   255 			delta |= 1;
       
   256 			vpdiff += step;
       
   257 			}
       
   258 
       
   259 		// Step 3 - Update previous value 
       
   260 		if ( sign )
       
   261 		  valpred -= vpdiff;
       
   262 		else
       
   263 		  valpred += vpdiff;
       
   264 
       
   265 		// Step 4 - Clamp previous value to 16 bits 
       
   266 		if ( valpred > KClamp - 1 )
       
   267 		  valpred = KClamp - 1;
       
   268 		else if ( valpred < - KClamp )
       
   269 		  valpred = - KClamp;
       
   270 
       
   271 		// Step 5 - Assemble value, update index and step values 
       
   272 		delta |= sign;
       
   273 		
       
   274 		index += iIndexTable[delta];
       
   275 		if ( index < 0 ) index = 0;
       
   276 		if ( index > 88 ) index = 88;
       
   277 
       
   278 		// Step 6 - Output value 
       
   279 		if (iBufferStep) 
       
   280 			iBuffer = delta & 0x0f;
       
   281 		else 
       
   282 			*aDst++ = STATIC_CAST( TInt8, ((delta << 4) & 0xf0) | iBuffer);
       
   283 
       
   284 		iBufferStep = !iBufferStep;
       
   285 		
       
   286 		if (iChannels==2)
       
   287 			{
       
   288 			if (--bufferCount==8)
       
   289 				{
       
   290 				src=srcPtr+1;	//right channel
       
   291 				iState[0].iPredicted = STATIC_CAST(TInt16, valpred);
       
   292 				iState[0].iIndex = STATIC_CAST(TUint8, index);
       
   293 				valpred = iState[1].iPredicted;
       
   294 				index = iState[1].iIndex;
       
   295 				}
       
   296 			else
       
   297 				{
       
   298 				if (!bufferCount)
       
   299 					{
       
   300 					iState[1].iPredicted = STATIC_CAST(TInt16, valpred);
       
   301 					iState[1].iIndex = STATIC_CAST(TUint8, index);
       
   302 					valpred = iState[0].iPredicted;
       
   303 					index = iState[0].iIndex;
       
   304 					bufferCount=16;
       
   305 					srcPtr+=16;//32bytes
       
   306 					src=srcPtr;
       
   307 					}
       
   308 				}
       
   309 			}
       
   310 		}
       
   311 
       
   312 	if (iChannels==1)
       
   313 		{
       
   314 		iState[0].iPredicted = STATIC_CAST(TInt16, valpred);
       
   315 		iState[0].iIndex = STATIC_CAST(TUint8, index);
       
   316 		}
       
   317 	}
       
   318 
       
   319 // IMA-ADPCM step variation table 
       
   320 const TInt TMMFImaAdpcmBaseCodecOld::iIndexTable[16] =
       
   321  	{
       
   322     -1, -1, -1, -1, 2, 4, 6, 8,
       
   323     -1, -1, -1, -1, 2, 4, 6, 8
       
   324 	};
       
   325 
       
   326 const TInt TMMFImaAdpcmBaseCodecOld::iStepSizeTable[89] = 
       
   327 	{
       
   328     7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
       
   329     19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
       
   330     50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
       
   331     130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
       
   332     337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
       
   333     876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
       
   334     2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
       
   335     5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
       
   336     15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
       
   337 	};
       
   338 
       
   339