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