1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmlibs/mmfw/src/Plugin/Codec/audio/MMFCodecBaseDefinitions.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,339 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "MMFCodecBaseDefinitions.h"
1.20 +#include "MMFAudioCodecBase.h"
1.21 +#include <mmf/common/mmfpaniccodes.h>
1.22 +
1.23 +// Base of Audio codecs
1.24 +// These T Classes are "wrapped" by derived MMFCodecs, not exposed directly.
1.25 +
1.26 +
1.27 +void Panic(TInt aPanicCode)
1.28 + {
1.29 + _LIT(KMMFCodecBaseDefinitionsPanicCategory, "MMFCodecBaseDefinitions");
1.30 + User::Panic(KMMFCodecBaseDefinitionsPanicCategory, aPanicCode);
1.31 + }
1.32 +
1.33 +
1.34 +void TMMFImaAdpcmBaseCodecOld::ResetBuffer()
1.35 + {
1.36 + iBufferStep = ETrue;
1.37 + iBuffer = 0;
1.38 + }
1.39 +
1.40 +TBool TMMFImaAdpcmBaseCodecOld::OutputStep()
1.41 + {
1.42 + return !iBufferStep;
1.43 + }
1.44 +
1.45 +void TMMFImaAdpcmTo16PcmCodecOld::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
1.46 + {
1.47 + TInt delta; // Current adpcm output value
1.48 + TInt step; // Stepsize
1.49 + TInt valpred; // Predicted value
1.50 + TInt vpdiff; // Current change to valpred
1.51 + TInt index; // Current step change index
1.52 +
1.53 + TInt channelCount=16;//for stereo only
1.54 +
1.55 + aSamples*=iChannels;
1.56 +
1.57 + //Read first sample and index from block header
1.58 + iState[0].iPredicted = *aSrc++;
1.59 + iState[0].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
1.60 + iState[0].iIndex = *aSrc++;
1.61 +
1.62 + aSrc++; //skip reserved header byte
1.63 +
1.64 + valpred = iState[0].iPredicted;
1.65 + index = iState[0].iIndex;
1.66 + TUint8* dst=aDst;
1.67 +
1.68 + //Write first sample to dest
1.69 + *aDst++ = STATIC_CAST( TUint8, valpred);
1.70 + *aDst++ = STATIC_CAST( TUint8, valpred >> 8);
1.71 + dst += 2;
1.72 + aSamples --;
1.73 +
1.74 + if (iChannels==2)
1.75 + {
1.76 + iState[1].iPredicted = *aSrc++;
1.77 + iState[1].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
1.78 + iState[1].iIndex = *aSrc++;
1.79 + aSrc++;
1.80 +
1.81 + *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted);
1.82 + *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted >> 8);
1.83 + dst += 2;
1.84 + aSamples --;
1.85 + }
1.86 +
1.87 + for ( ; aSamples > 0 ; aSamples-- )
1.88 + {
1.89 + // Step 1 - get the delta value
1.90 + if (iBufferStep)
1.91 + {
1.92 + iBuffer = *aSrc++;
1.93 + delta = iBuffer & 0xf;
1.94 + }
1.95 + else
1.96 + {
1.97 + delta = (iBuffer >> 4) & 0xf;
1.98 + }
1.99 +
1.100 + iBufferStep = !iBufferStep;
1.101 +
1.102 + ASSERT(index >= 0);
1.103 + step = iStepSizeTable[index];
1.104 +
1.105 + vpdiff = step>>3;
1.106 + if ( delta & 4 )
1.107 + vpdiff += step;
1.108 + if ( delta & 2 )
1.109 + vpdiff += step>>1;
1.110 + if ( delta & 1 )
1.111 + vpdiff += step>>2;
1.112 +
1.113 + if ( delta & 8 )
1.114 + valpred -= vpdiff;
1.115 + else
1.116 + valpred += vpdiff;
1.117 +
1.118 + if ( valpred > (KClamp - 1) )
1.119 + valpred = (KClamp - 1);
1.120 + else if ( valpred < -KClamp )
1.121 + valpred = -KClamp;
1.122 +
1.123 + index += iIndexTable[delta];
1.124 + if ( index < 0 )
1.125 + index = 0;
1.126 + if ( index > KMaxImaAdpcmTableEntries )
1.127 + index = KMaxImaAdpcmTableEntries;
1.128 +
1.129 + *dst++ = STATIC_CAST( TUint8, valpred&KAndMask8bit);
1.130 + *dst++ = STATIC_CAST( TUint8, (valpred>>8)&KAndMask8bit);
1.131 +
1.132 + if (iChannels==2)
1.133 + {
1.134 + dst+=2;
1.135 + if (--channelCount == 8)
1.136 + {
1.137 + dst=aDst+2; //right channel
1.138 + iState[0].iPredicted=STATIC_CAST(TInt16, valpred);
1.139 + iState[0].iIndex=STATIC_CAST(TUint8,index);
1.140 + valpred = iState[1].iPredicted;
1.141 + index = iState[1].iIndex;
1.142 + }
1.143 + else
1.144 + {
1.145 + if (!channelCount)
1.146 + {
1.147 + aDst+=32;
1.148 + dst=aDst;
1.149 + channelCount=16;
1.150 + iState[1].iPredicted=STATIC_CAST(TInt16, valpred);
1.151 + iState[1].iIndex=STATIC_CAST(TUint8, index);
1.152 + valpred = iState[0].iPredicted;
1.153 + index = iState[0].iIndex;
1.154 + }
1.155 + }
1.156 + }
1.157 + }
1.158 + if (iChannels==1)
1.159 + {
1.160 + iState[0].iPredicted=STATIC_CAST(TInt16,valpred);
1.161 + iState[0].iIndex=STATIC_CAST(TUint8,index);
1.162 + }
1.163 + }
1.164 +
1.165 +void TMMF16PcmToImaAdpcmCodecOld::Convert(TUint8* aSrc, TUint8* aDst, TInt aSamples)
1.166 + {
1.167 + TInt val; // Current input sample value
1.168 + TInt sign; // Current adpcm sign bit
1.169 + TInt delta; // Current adpcm output value
1.170 + TInt diff; // Difference between val and valprev
1.171 + TInt step; // Stepsize
1.172 + TInt valpred; // Predicted value
1.173 + TInt vpdiff; // Current change to valpred
1.174 + TInt index; // Current step change index
1.175 +
1.176 + TInt16* srcPtr=REINTERPRET_CAST(TInt16*, aSrc);
1.177 + TInt16* src=srcPtr;
1.178 +
1.179 + TInt bufferCount=16;//for stereo only
1.180 +
1.181 + if (iChannels==2)
1.182 + {
1.183 + aSamples*=2;
1.184 + iBufferStep=ETrue;
1.185 + }
1.186 +
1.187 + iState[0].iPredicted = *aSrc++;
1.188 + iState[0].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
1.189 +
1.190 + valpred = iState[0].iPredicted;
1.191 + index = iState[0].iIndex;
1.192 + ASSERT(index >= 0);
1.193 + step = iStepSizeTable[index];
1.194 +
1.195 + //Write block header
1.196 + *aDst++ = STATIC_CAST( TUint8, valpred);
1.197 + *aDst++ = STATIC_CAST( TUint8, valpred >> 8);
1.198 + *aDst++ = STATIC_CAST( TUint8, index);
1.199 + *aDst++ = 0; //reserved byte
1.200 + src++;
1.201 + aSamples --;
1.202 +
1.203 + if (iChannels==2)
1.204 + {
1.205 + iState[1].iPredicted = *aSrc++;
1.206 + iState[1].iPredicted |= STATIC_CAST(TInt16, ((*aSrc++) << 8));
1.207 +
1.208 + //Write header for second channel
1.209 + *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted);
1.210 + *aDst++ = STATIC_CAST( TUint8, iState[1].iPredicted >> 8);
1.211 + *aDst++ = STATIC_CAST( TUint8, iState[1].iIndex);
1.212 + *aDst++ = 0;
1.213 + src ++;
1.214 + aSamples --;
1.215 + }
1.216 +
1.217 + for (; aSamples > 0; aSamples--)
1.218 + {
1.219 + val = *src;
1.220 + src += iChannels;
1.221 +
1.222 + ASSERT(index >= 0);
1.223 + step = iStepSizeTable[index];
1.224 +
1.225 + // Step 1 - compute difference with previous value
1.226 + diff = val - valpred;
1.227 + sign = (diff < 0) ? 8 : 0;
1.228 + if ( sign ) diff = (-diff);
1.229 +
1.230 + // Step 2 - Divide and clamp
1.231 + // Note:
1.232 + // This code *approximately* computes:
1.233 + // delta = diff*4/step;
1.234 + // vpdiff = (delta+0.5)*step/4;
1.235 + // but in shift step bits are dropped. The net result of this is
1.236 + // that even if you have fast mul/div hardware you cannot put it to
1.237 + // good use since the fixup would be too expensive.
1.238 + //
1.239 + delta = 0;
1.240 + vpdiff = (step >> 3);
1.241 +
1.242 + if ( diff >= step )
1.243 + {
1.244 + delta = 4;
1.245 + diff -= step;
1.246 + vpdiff += step;
1.247 + }
1.248 + step >>= 1;
1.249 + if ( diff >= step )
1.250 + {
1.251 + delta |= 2;
1.252 + diff -= step;
1.253 + vpdiff += step;
1.254 + }
1.255 + step >>= 1;
1.256 + if ( diff >= step )
1.257 + {
1.258 + delta |= 1;
1.259 + vpdiff += step;
1.260 + }
1.261 +
1.262 + // Step 3 - Update previous value
1.263 + if ( sign )
1.264 + valpred -= vpdiff;
1.265 + else
1.266 + valpred += vpdiff;
1.267 +
1.268 + // Step 4 - Clamp previous value to 16 bits
1.269 + if ( valpred > KClamp - 1 )
1.270 + valpred = KClamp - 1;
1.271 + else if ( valpred < - KClamp )
1.272 + valpred = - KClamp;
1.273 +
1.274 + // Step 5 - Assemble value, update index and step values
1.275 + delta |= sign;
1.276 +
1.277 + index += iIndexTable[delta];
1.278 + if ( index < 0 ) index = 0;
1.279 + if ( index > 88 ) index = 88;
1.280 +
1.281 + // Step 6 - Output value
1.282 + if (iBufferStep)
1.283 + iBuffer = delta & 0x0f;
1.284 + else
1.285 + *aDst++ = STATIC_CAST( TInt8, ((delta << 4) & 0xf0) | iBuffer);
1.286 +
1.287 + iBufferStep = !iBufferStep;
1.288 +
1.289 + if (iChannels==2)
1.290 + {
1.291 + if (--bufferCount==8)
1.292 + {
1.293 + src=srcPtr+1; //right channel
1.294 + iState[0].iPredicted = STATIC_CAST(TInt16, valpred);
1.295 + iState[0].iIndex = STATIC_CAST(TUint8, index);
1.296 + valpred = iState[1].iPredicted;
1.297 + index = iState[1].iIndex;
1.298 + }
1.299 + else
1.300 + {
1.301 + if (!bufferCount)
1.302 + {
1.303 + iState[1].iPredicted = STATIC_CAST(TInt16, valpred);
1.304 + iState[1].iIndex = STATIC_CAST(TUint8, index);
1.305 + valpred = iState[0].iPredicted;
1.306 + index = iState[0].iIndex;
1.307 + bufferCount=16;
1.308 + srcPtr+=16;//32bytes
1.309 + src=srcPtr;
1.310 + }
1.311 + }
1.312 + }
1.313 + }
1.314 +
1.315 + if (iChannels==1)
1.316 + {
1.317 + iState[0].iPredicted = STATIC_CAST(TInt16, valpred);
1.318 + iState[0].iIndex = STATIC_CAST(TUint8, index);
1.319 + }
1.320 + }
1.321 +
1.322 +// IMA-ADPCM step variation table
1.323 +const TInt TMMFImaAdpcmBaseCodecOld::iIndexTable[16] =
1.324 + {
1.325 + -1, -1, -1, -1, 2, 4, 6, 8,
1.326 + -1, -1, -1, -1, 2, 4, 6, 8
1.327 + };
1.328 +
1.329 +const TInt TMMFImaAdpcmBaseCodecOld::iStepSizeTable[89] =
1.330 + {
1.331 + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
1.332 + 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
1.333 + 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
1.334 + 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
1.335 + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
1.336 + 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
1.337 + 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
1.338 + 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
1.339 + 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
1.340 + };
1.341 +
1.342 +