os/mm/mmlibs/mmfw/Codecs/Src/MMFCodecCommon/MMFAudioPcm16ToImaAdpcmCodec.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2003-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 "MMFAudioPcm16ToImaAdpcmCodec.h"
    17 
    18 
    19 EXPORT_C void TMMFAudioPcm16ToImaAdpcmCodec::SetState(const TMMFImaAdpcmCodecState& aState)
    20 	{
    21      iState = aState ;
    22 	}
    23 
    24 EXPORT_C const TMMFImaAdpcmCodecState& TMMFAudioPcm16ToImaAdpcmCodec::GetState()
    25 	{
    26 	return iState;
    27 	}
    28 
    29 /**
    30 *
    31 * Convert
    32 * @param aSrc
    33 * @param aDst
    34 * @param aSamples
    35 *
    36 */
    37 EXPORT_C void TMMFAudioPcm16ToImaAdpcmCodec::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
    38 	{
    39 	TInt val;			// Current input sample value 
    40     TInt sign;			// Current adpcm sign bit 
    41     TInt delta;			// Current adpcm output value 
    42 	TInt diff;			// Difference between val and valprev 
    43 	TInt step;			// Stepsize
    44     TInt valpred;		// Predicted value 
    45     TInt vpdiff;		// Current change to valpred 
    46     TInt index;			// Current step change index 
    47 	
    48 	TInt16* srcPtr=REINTERPRET_CAST(TInt16*, aSrc);
    49 	TInt16* src=srcPtr;
    50 	
    51 	iState.iPredicted = *aSrc++;
    52 	iState.iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
    53 	
    54     valpred = iState.iPredicted;
    55     index = iState.iIndex;
    56     ASSERT(index >= 0);
    57     step = KStepSizeTable[index];
    58 	
    59 	//Write block header
    60 	*aDst++ = STATIC_CAST( TUint8, valpred);
    61 	*aDst++ = STATIC_CAST( TUint8, valpred >> 8);
    62 	*aDst++ = STATIC_CAST( TUint8, index);
    63 	*aDst++ = 0; //reserved byte
    64 	src++;
    65 	aSamples --;	
    66 	
    67 	for (; aSamples > 0; aSamples--) 
    68 		{ 
    69 		val = *src;
    70 		src++;
    71 		
    72 		step = KStepSizeTable[index];
    73 		
    74 		// Step 1 - compute difference with previous value 
    75 		diff = val - valpred;
    76 		sign = (diff < 0) ? 8 : 0;
    77 		if ( sign ) diff = (-diff);
    78 		
    79 		// Step 2 - Divide and clamp 
    80 		// Note:
    81 		// This code *approximately* computes:
    82 		//    delta = diff*4/step;
    83 		//    vpdiff = (delta+0.5)*step/4;
    84 		// but in shift step bits are dropped. The net result of this is
    85 		// that even if you have fast mul/div hardware you cannot put it to
    86 		// good use since the fixup would be too expensive.
    87 		//
    88 		delta = 0;
    89 		vpdiff = (step >> 3);
    90 		
    91 		if ( diff >= step ) 
    92 			{
    93 			delta = 4;
    94 			diff -= step;
    95 			vpdiff += step;
    96 			}
    97 		step >>= 1;
    98 		if ( diff >= step  ) 
    99 			{
   100 			delta |= 2;
   101 			diff -= step;
   102 			vpdiff += step;
   103 			}
   104 		step >>= 1;
   105 		if ( diff >= step ) 
   106 			{
   107 			delta |= 1;
   108 			vpdiff += step;
   109 			}
   110 		
   111 		// Step 3 - Update previous value 
   112 		if ( sign )
   113 			valpred -= vpdiff;
   114 		else
   115 			valpred += vpdiff;
   116 		
   117 		// Step 4 - Clamp previous value to 16 bits 
   118 		if ( valpred > KClamp - 1 )
   119 			valpred = KClamp - 1;
   120 		else if ( valpred < - KClamp )
   121 			valpred = - KClamp;
   122 		
   123 		// Step 5 - Assemble value, update index and step values 
   124 		delta |= sign;
   125 		
   126 		index += KIndexTable[delta];
   127 		if ( index < 0 ) index = 0;
   128 		if ( index > 88 ) index = 88;
   129 		
   130 		// Step 6 - Output value 
   131 		if (iBufferStep) 
   132 			iBuffer = delta & 0x0f;
   133 		else 
   134 			*aDst++ = STATIC_CAST( TInt8, ((delta << 4) & 0xf0) | iBuffer);
   135 		
   136 		iBufferStep = !iBufferStep;
   137 		}
   138 	
   139 	iState.iPredicted = STATIC_CAST(TInt16, valpred);
   140 	iState.iIndex = STATIC_CAST(TUint8, index);
   141 	}
   142 
   143 // IMA-ADPCM step variation table 
   144 const TInt TMMFAudioPcm16ToImaAdpcmCodec::KIndexTable[] =
   145 	{
   146 	-1, -1, -1, -1, 2, 4, 6, 8,
   147 	-1, -1, -1, -1, 2, 4, 6, 8
   148 	};
   149 	
   150 const TInt TMMFAudioPcm16ToImaAdpcmCodec::KStepSizeTable[] = 
   151 	{
   152 	7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
   153 	19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
   154 	50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
   155 	130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
   156 	337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
   157 	876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
   158 	2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
   159 	5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
   160 	15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
   161 	};
   162 	
   163 
   164 
   165