os/mm/mmlibs/mmfw/Codecs/Src/Gsm610CodecCommon/gsm610fr.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/mm/mmlibs/mmfw/Codecs/Src/Gsm610CodecCommon/gsm610fr.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,526 @@
     1.4 +// Copyright (c) 2000-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 +// Polymorphic DLL implementation of GSM 6.10 full rate (FR) speech coder
    1.18 +// and decoder    objects.
    1.19 +// This codec is based on ANSI C simulation codes. For this implementation
    1.20 +// (polymorphic DLL) the original ANSI C codes have been modified slightly:
    1.21 +// - The original .c files were renamed to .cpp files.
    1.22 +// - All global varibles (codec's state) are now encoder's or decoder's
    1.23 +// private member variables.
    1.24 +// - Because codec's state is in the codec object, an extra variable -
    1.25 +// a pointer codec object - have been added to some original routines.
    1.26 +// - Global tables are now const C++ tables in tables.h header file.
    1.27 +// - VAD and DTX modules have been removed from the original routines.
    1.28 +// - Due to error in GNU tool chain all array indexes of type [i-1] in
    1.29 +// rpeltp.cpp have been removed and changed to [j] type.
    1.30 +// - multr, L_add, L_mac from basicop.cpp inlined
    1.31 +// INCLUDES
    1.32 +// 
    1.33 +//
    1.34 +
    1.35 +#include "gsm610fr.h"
    1.36 +#include "codec.h"
    1.37 +#include <e32uid.h>
    1.38 +
    1.39 +
    1.40 +//  LOCAL FUNCTIONS
    1.41 +//===================================================================
    1.42 +/*
    1.43 +-----------------------------------------------------------------------------
    1.44 +
    1.45 +    GSM610FR_Encoder
    1.46 +
    1.47 +    ConstructL
    1.48 +
    1.49 +    This function implements the second phase construction of GSM610FR_Encoder
    1.50 +    class. Function binds the encoder to given input and output streams and
    1.51 +    resets encoder.
    1.52 +
    1.53 +    Parameters:     RReadStream aInStrm     Handle to input stream (16 bit
    1.54 +                                            PCM speech data)
    1.55 +                    RWriteStream aOutStrm   Handle to output stream (encoded
    1.56 +                                            speech data)
    1.57 +
    1.58 +    Return Values:  none
    1.59 +
    1.60 +-----------------------------------------------------------------------------
    1.61 +*/
    1.62 +EXPORT_C void CGSM610FR_Encoder::ConstructL()
    1.63 +    {
    1.64 +    ::reset_encoder(this);
    1.65 +    iOddFrame = TRUE;
    1.66 +    }
    1.67 +
    1.68 +
    1.69 +/*
    1.70 +-----------------------------------------------------------------------------
    1.71 +
    1.72 +    GSM610FR_Encoder
    1.73 +
    1.74 +    ~GSM610FR_Encoder
    1.75 +
    1.76 +    Empty encoder destructor.
    1.77 +
    1.78 +    Parameters:     none
    1.79 +    
    1.80 +    Return Values:  none
    1.81 +
    1.82 +-----------------------------------------------------------------------------
    1.83 +*/
    1.84 +EXPORT_C CGSM610FR_Encoder::~CGSM610FR_Encoder()
    1.85 +    {
    1.86 +    }
    1.87 +
    1.88 +
    1.89 +/*
    1.90 +-----------------------------------------------------------------------------
    1.91 +
    1.92 +    GSM610FR_Encoder
    1.93 +
    1.94 +    StartL
    1.95 +
    1.96 +    Start encoder object. Initialize codec status.
    1.97 +
    1.98 +    Parameters:     none
    1.99 +    
   1.100 +    Return Values:  none
   1.101 +
   1.102 +-----------------------------------------------------------------------------
   1.103 +*/
   1.104 +EXPORT_C void CGSM610FR_Encoder::StartL()
   1.105 +    {
   1.106 +    ::reset_encoder(this);
   1.107 +    iOddFrame = TRUE;
   1.108 +    }
   1.109 +
   1.110 +
   1.111 +/*
   1.112 +-----------------------------------------------------------------------------
   1.113 +
   1.114 +    GSM610FR_Encoder
   1.115 +
   1.116 +    ExecuteL
   1.117 +
   1.118 +    Execute encoder object. Read one speech frame from the input stream,
   1.119 +    RPELTP encode it and write the encoded frame to output stream.
   1.120 +
   1.121 +    Parameters:     none
   1.122 +    
   1.123 +    Return Values:  none
   1.124 +
   1.125 +    Leave Handling:
   1.126 +    
   1.127 +    If the length of data available in the input stream is less than
   1.128 +    FRAMESIZE then the function leaves with KErrEof.
   1.129 +
   1.130 +-----------------------------------------------------------------------------
   1.131 +*/
   1.132 +EXPORT_C void CGSM610FR_Encoder::ExecuteL(TUint8* aInBuf, TUint8* aOutBuf)
   1.133 +{
   1.134 +	TInt16* inBufPtr  = (TInt16*) aInBuf;
   1.135 +
   1.136 +
   1.137 +	for (TInt frame = 0; frame < 2; frame++)
   1.138 +	{
   1.139 +	    ::RPELTP_encoder(this, inBufPtr, &iCodeBuf);
   1.140 +
   1.141 +		if ( iOddFrame )
   1.142 +		{
   1.143 +			PackFrame0 (&iCodeBuf, (TInt8*) aOutBuf);
   1.144 +		}
   1.145 +		else
   1.146 +		{
   1.147 +			PackFrame1 (&iCodeBuf, (TInt8*) aOutBuf);
   1.148 +		}
   1.149 +
   1.150 +		iOddFrame = !iOddFrame;
   1.151 +		inBufPtr += FRAMESIZE;
   1.152 +	}
   1.153 +
   1.154 +}
   1.155 +/*
   1.156 +-----------------------------------------------------------------------------
   1.157 +
   1.158 +    GSM610FR_Encoder
   1.159 +
   1.160 +    StopL
   1.161 +
   1.162 +    Stop encoder object. Flush out last frames, if necessary.
   1.163 +
   1.164 +    Parameters:     none
   1.165 +    
   1.166 +    Return Values:  none
   1.167 +
   1.168 +-----------------------------------------------------------------------------
   1.169 +*/
   1.170 +EXPORT_C void CGSM610FR_Encoder::StopL()
   1.171 +    {
   1.172 +    }
   1.173 +
   1.174 +
   1.175 +/*
   1.176 +-----------------------------------------------------------------------------
   1.177 +
   1.178 +    GSM610FR_Encoder
   1.179 +
   1.180 +    PackFrame0
   1.181 +
   1.182 +    Pack the codewords of the even frame into pack buffer.
   1.183 +
   1.184 +    Packing as in MS gsm610 encoder.
   1.185 +
   1.186 +    Parameters:     struct codes* aCodeBuf    Code words for one speech frame.
   1.187 +    
   1.188 +    Return Values:  none
   1.189 +
   1.190 +
   1.191 +-----------------------------------------------------------------------------
   1.192 +*/
   1.193 +void CGSM610FR_Encoder::PackFrame0(struct codes* aCodeBuf, TInt8* pbuf)
   1.194 +    {
   1.195 +    TInt16* LAR = aCodeBuf->LARc;
   1.196 +    
   1.197 +    // pack the LARc[0..7] into the first 4.5 bytes
   1.198 +    *pbuf++ = (TUint8)(((LAR[0]     ) & 0x3F) | ((LAR[1] << 6) & 0xC0));
   1.199 +    *pbuf++ = (TUint8)(((LAR[1] >> 2) & 0x0F) | ((LAR[2] << 4) & 0xF0));
   1.200 +    *pbuf++ = (TUint8)(((LAR[2] >> 4) & 0x01) | ((LAR[3] << 1) & 0x3E) | ((LAR[4] << 6) & 0xC0));
   1.201 +    *pbuf++ = (TUint8)(((LAR[4] >> 2) & 0x03) | ((LAR[5] << 2) & 0x3C) | ((LAR[6] << 6) & 0xC0));
   1.202 +    *pbuf   = (TUint8)(((LAR[6] >> 2) & 0x01) | ((LAR[7] << 1) & 0x0E));
   1.203 +    
   1.204 +    // pack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   1.205 +    for(TInt i = 0; i < 4; i++)
   1.206 +        {
   1.207 +        struct sfcodes& c = aCodeBuf->sfc[i];
   1.208 +        *pbuf++ |= ((c.Nc << 4) & 0xF0);
   1.209 +        *pbuf++ = (TUint8)(((c.Nc >> 4) & 0x07) | ((c.bc << 3) & 0x18) | ((c.Mc << 5) & 0x60) | ((c.xmaxc << 7) & 0x80));
   1.210 +        *pbuf++ = (TUint8)(((c.xmaxc >> 1) & 0x1F) | ((c.xMc[0] << 5) & 0xE0));
   1.211 +        *pbuf++ = (TUint8)((c.xMc[1] & 0x07) | ((c.xMc[2] << 3) & 0x38) | ((c.xMc[3] << 6) & 0xC0));
   1.212 +        *pbuf++ = (TUint8)(((c.xMc[3] >> 2) & 0x01) | ((c.xMc[4] << 1) & 0x0E) | ((c.xMc[5] << 4) & 0x70) | ((c.xMc[6] << 7) & 0x80));
   1.213 +        *pbuf++ = (TUint8)(((c.xMc[6] >> 1) & 0x03) | ((c.xMc[7] << 2) & 0x1C) | ((c.xMc[8] << 5) & 0xE0));
   1.214 +        *pbuf++ = (TUint8)((c.xMc[9] & 0x07) | ((c.xMc[10] << 3) & 0x38) | ((c.xMc[11] << 6) & 0xC0));
   1.215 +        *pbuf   = (TUint8)(((c.xMc[11] >> 2) & 0x01) | ((c.xMc[12] << 1) & 0x0E));
   1.216 +        }
   1.217 +    }
   1.218 +
   1.219 +
   1.220 +/*
   1.221 +-----------------------------------------------------------------------------
   1.222 +
   1.223 +    GSM610FR_Encoder
   1.224 +
   1.225 +    PackFrame1
   1.226 +
   1.227 +    Pack the codewords of the odd frame into pack buffer.
   1.228 +
   1.229 +    Packing as in MS gsm610 encoder.
   1.230 +
   1.231 +    Parameters:     struct codes* aCodeBuf    Code words for one speech frame.
   1.232 +    
   1.233 +    Return Values:  none
   1.234 +
   1.235 +
   1.236 +-----------------------------------------------------------------------------
   1.237 +*/
   1.238 +void CGSM610FR_Encoder::PackFrame1(struct codes* aCodeBuf, TInt8* pbuf)
   1.239 +    {
   1.240 +    TInt16* LAR = aCodeBuf->LARc;
   1.241 +    
   1.242 +	pbuf += (PACKSIZE / 2);
   1.243 +	TInt8 pbufZero = pbuf[0];
   1.244 +
   1.245 +    // pack the LARc[0..7] into the first 4.5 bytes, starting with the msb of the first byte
   1.246 +    *pbuf++ = (TUint8) (pbufZero | ((LAR[0] << 4) & 0xF0));
   1.247 +    *pbuf++ = (TUint8)(((LAR[0] >> 4) & 0x03) | ((LAR[1] << 2) & 0xFC));
   1.248 +    *pbuf++ = (TUint8)(((LAR[2]     ) & 0x1F) | ((LAR[3] << 5) & 0xE0));
   1.249 +    *pbuf++ = (TUint8)(((LAR[3] >> 3) & 0x03) | ((LAR[4] << 2) & 0x3C) | ((LAR[5] << 6) & 0xC0));
   1.250 +    *pbuf++ = (TUint8)(((LAR[5] >> 2) & 0x03) | ((LAR[6] << 2) & 0x1C) | ((LAR[7] << 5) & 0xE0));
   1.251 +    
   1.252 +    // pack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   1.253 +    for(TInt i = 0; i < 4; i++)
   1.254 +        {
   1.255 +        struct sfcodes& c = aCodeBuf->sfc[i];
   1.256 +        *pbuf++ = (TUint8)((c.Nc & 0x7F) | ((c.bc << 7) & 0x80));
   1.257 +        *pbuf++ = (TUint8)(((c.bc >> 1) & 0x01) | ((c.Mc << 1) & 0x06) | ((c.xmaxc << 3) & 0xF8));
   1.258 +        *pbuf++ = (TUint8)(((c.xmaxc >> 5) & 0x01) | ((c.xMc[0] << 1) & 0x0E) | ((c.xMc[1] << 4) & 0x70) | ((c.xMc[2] << 7) & 0x80));
   1.259 +        *pbuf++ = (TUint8)(((c.xMc[2] >> 1) & 0x03) | ((c.xMc[3] << 2) & 0x1C) | ((c.xMc[4] << 5) & 0xE0));
   1.260 +        *pbuf++ = (TUint8)(((c.xMc[5]) & 0x07) | ((c.xMc[6] << 3) & 0x38) | ((c.xMc[7] << 6) & 0xC0));
   1.261 +        *pbuf++ = (TUint8)(((c.xMc[7] >> 2) & 0x01) | ((c.xMc[8] << 1) & 0x0E) | ((c.xMc[9] << 4) & 0x70) | ((c.xMc[10] << 7) & 0x80));
   1.262 +        *pbuf++ = (TUint8)(((c.xMc[10] >> 1) & 0x03) | ((c.xMc[11] << 2) & 0x1C) | ((c.xMc[12] << 5) & 0xE0));
   1.263 +        }
   1.264 +    }
   1.265 +
   1.266 +/*
   1.267 +-----------------------------------------------------------------------------
   1.268 +
   1.269 +    GSM610FR_Decoder
   1.270 +
   1.271 +    ConstructL
   1.272 +
   1.273 +    This function implements the second phase construction of GSM610FR_Decoder
   1.274 +    class. Function binds the decoder to given input and output streams and
   1.275 +    resets decoder.
   1.276 +
   1.277 +    Parameters:     RReadStream aInStrm     Handle to input stream (encoded
   1.278 +                                            speech data)
   1.279 +                                            
   1.280 +                    RWriteStream aOutStrm   Handle to output stream (16 bit
   1.281 +                                            PCM speech data)
   1.282 +
   1.283 +    Return Values:  none
   1.284 +
   1.285 +-----------------------------------------------------------------------------
   1.286 +*/
   1.287 +EXPORT_C void CGSM610FR_Decoder::ConstructL()
   1.288 +    {
   1.289 +    ::reset_decoder(this);
   1.290 +    iOddFrame = TRUE;
   1.291 +    }
   1.292 +
   1.293 +
   1.294 +/*
   1.295 +-----------------------------------------------------------------------------
   1.296 +
   1.297 +    GSM610FR_Decoder
   1.298 +
   1.299 +    ~GSM610FR_Decoder
   1.300 +
   1.301 +    Empty decoder destructor.
   1.302 +
   1.303 +    Parameters:     none
   1.304 +    
   1.305 +    Return Values:  none
   1.306 +
   1.307 +-----------------------------------------------------------------------------
   1.308 +*/
   1.309 +EXPORT_C CGSM610FR_Decoder::~CGSM610FR_Decoder()
   1.310 +    {
   1.311 +    }
   1.312 +
   1.313 +
   1.314 +/*
   1.315 +-----------------------------------------------------------------------------
   1.316 +
   1.317 +    GSM610FR_Decoder
   1.318 +
   1.319 +    StartL
   1.320 +
   1.321 +    Start decoder object. Initialize codec status.
   1.322 +
   1.323 +    Parameters:     none
   1.324 +    
   1.325 +    Return Values:  none
   1.326 +
   1.327 +-----------------------------------------------------------------------------
   1.328 +*/
   1.329 +EXPORT_C void CGSM610FR_Decoder::StartL()
   1.330 +    {
   1.331 +    ::reset_decoder(this);
   1.332 +    iOddFrame = TRUE;
   1.333 +    }
   1.334 +
   1.335 +
   1.336 +/*
   1.337 +-----------------------------------------------------------------------------
   1.338 +
   1.339 +    GSM610FR_Decoder
   1.340 +
   1.341 +    ExecuteL
   1.342 +
   1.343 +    Execute decoder object. Read one encoded speech frame from the input
   1.344 +    stream RPELTP decode it and write the decoded frame to output stream.
   1.345 +
   1.346 +    Parameters:     none
   1.347 +    
   1.348 +    Return Values:  none
   1.349 +
   1.350 +    Leave Handling:
   1.351 +    
   1.352 +    If the length of data available in the input stream is less than size
   1.353 +    of one encoded speech frame then the function leaves with KErrEof.
   1.354 +
   1.355 +-----------------------------------------------------------------------------
   1.356 +*/
   1.357 +EXPORT_C void CGSM610FR_Decoder::ExecuteL(TUint8* aInBuf, TUint8* aOutBuf)
   1.358 +{
   1.359 +
   1.360 +	TInt16* outBufPtr = (TInt16*) aOutBuf;
   1.361 +
   1.362 +
   1.363 +	// Process both odd and even frames
   1.364 +
   1.365 +	for (TInt frame = 0; frame < 2; frame++)
   1.366 +	{
   1.367 +		if ( iOddFrame )
   1.368 +		{
   1.369 +			UnpackFrame0(&iCodeBuf, (TInt8*) aInBuf);
   1.370 +        }
   1.371 +	   else
   1.372 +        {
   1.373 +			UnpackFrame1(&iCodeBuf, (TInt8*) aInBuf);
   1.374 +		}
   1.375 +
   1.376 +
   1.377 +		::RPELTP_decoder(this, &iCodeBuf, outBufPtr);
   1.378 +
   1.379 +		iOddFrame = !iOddFrame;
   1.380 +		outBufPtr += FRAMESIZE;
   1.381 +
   1.382 +	}
   1.383 +
   1.384 +}
   1.385 +
   1.386 +/*
   1.387 +-----------------------------------------------------------------------------
   1.388 +
   1.389 +    GSM610FR_Decoder
   1.390 +
   1.391 +    StopL
   1.392 +
   1.393 +    Stop decoder object. Flush out last frames, if necessary.
   1.394 +
   1.395 +    Parameters:     none
   1.396 +    
   1.397 +    Return Values:  none
   1.398 +
   1.399 +-----------------------------------------------------------------------------
   1.400 +*/
   1.401 +EXPORT_C void CGSM610FR_Decoder::StopL()
   1.402 +    {
   1.403 +    }
   1.404 +
   1.405 +
   1.406 +/*
   1.407 +-----------------------------------------------------------------------------
   1.408 +
   1.409 +    GSM610FR_Decoder
   1.410 +
   1.411 +    UnpackFrame0
   1.412 +
   1.413 +    Unpack the codewords of the even frame from pack buffer.
   1.414 +
   1.415 +    Packing as in MS gsm610 encoder.
   1.416 +
   1.417 +    Parameters:     struct codes* aCodeBuf    Code words for one speech frame
   1.418 +                                              are unpacked into this structure.
   1.419 +    
   1.420 +    Return Values:  none
   1.421 +
   1.422 +
   1.423 +-----------------------------------------------------------------------------
   1.424 +*/
   1.425 +void CGSM610FR_Decoder::UnpackFrame0(struct codes* aCodeBuf,  TInt8* pbuf)
   1.426 +    {
   1.427 +    TInt16* LAR = aCodeBuf->LARc;
   1.428 +
   1.429 +    // unpack the LAR[0..7] from the first 4.5 bytes
   1.430 +    LAR[0] = (TInt16)((pbuf[0] & 0x3F));
   1.431 +    LAR[1] = (TInt16)(((pbuf[0] & 0xC0) >> 6) | ((pbuf[1] & 0x0F) << 2));
   1.432 +    LAR[2] = (TInt16)(((pbuf[1] & 0xF0) >> 4) | ((pbuf[2] & 0x01) << 4));
   1.433 +    LAR[3] = (TInt16)(((pbuf[2] & 0x3E) >> 1));
   1.434 +    LAR[4] = (TInt16)(((pbuf[2] & 0xC0) >> 6) | ((pbuf[3] & 0x03) << 2));
   1.435 +    LAR[5] = (TInt16)(((pbuf[3] & 0x3C) >> 2));
   1.436 +    LAR[6] = (TInt16)(((pbuf[3] & 0xC0) >> 6) | ((pbuf[4] & 0x01) << 2));
   1.437 +    LAR[7] = (TInt16)(((pbuf[4] & 0x0E) >> 1));
   1.438 +
   1.439 +    // unpack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   1.440 +    for(TInt i = 0; i < 4; i++)
   1.441 +        {
   1.442 +        struct sfcodes& c = aCodeBuf->sfc[i];
   1.443 +#define sfb(x) (pbuf[4+i*7+x])
   1.444 +        c.Nc = (TInt16)(((sfb(0) & 0xF0) >> 4) | ((sfb(1) & 0x07) << 4));
   1.445 +        c.bc = (TInt16)(((sfb(1) & 0x18) >> 3));
   1.446 +        c.Mc = (TInt16)(((sfb(1) & 0x60) >> 5));
   1.447 +        c.xmaxc = (TInt16)(((sfb(1) & 0x80) >> 7) | ((sfb(2) & 0x1F) << 1));
   1.448 +        c.xMc[0] = (TInt16)(((sfb(2) & 0xE0) >> 5));
   1.449 +        c.xMc[1] = (TInt16)((sfb(3) & 0x07));
   1.450 +        c.xMc[2] = (TInt16)(((sfb(3) & 0x3C) >> 3));
   1.451 +        c.xMc[3] = (TInt16)(((sfb(3) & 0xC0) >> 6) | ((sfb(4) & 0x01) << 2));
   1.452 +        c.xMc[4] = (TInt16)(((sfb(4) & 0x0E) >> 1));
   1.453 +        c.xMc[5] = (TInt16)(((sfb(4) & 0x70) >> 4));
   1.454 +        c.xMc[6] = (TInt16)(((sfb(4) & 0x80) >> 7) | ((sfb(5) & 0x03) << 1));
   1.455 +        c.xMc[7] = (TInt16)(((sfb(5) & 0x1C) >> 2));
   1.456 +        c.xMc[8] = (TInt16)(((sfb(5) & 0xE0) >> 5));
   1.457 +        c.xMc[9] = (TInt16)((sfb(6) & 0x07));
   1.458 +        c.xMc[10] = (TInt16)(((sfb(6) & 0x38) >> 3));
   1.459 +        c.xMc[11] = (TInt16)(((sfb(6) & 0xC0) >> 6) | ((sfb(7) & 0x01) << 2));
   1.460 +        c.xMc[12] = (TInt16)(((sfb(7) & 0x0E) >> 1));
   1.461 +#undef sfb
   1.462 +        }
   1.463 +    }
   1.464 +
   1.465 +
   1.466 +/*
   1.467 +-----------------------------------------------------------------------------
   1.468 +
   1.469 +    GSM610FR_Decoder
   1.470 +
   1.471 +    UnpackFrame1
   1.472 +
   1.473 +    Unpack the codewords of the odd frame from pack buffer.
   1.474 +
   1.475 +    Packing as in MS gsm610 encoder.
   1.476 +
   1.477 +    Parameters:     struct codes* aCodeBuf    Code words for one speech frame
   1.478 +                                              are unpacked into this structure.
   1.479 +    
   1.480 +    Return Values:  none
   1.481 +
   1.482 +
   1.483 +-----------------------------------------------------------------------------
   1.484 +*/
   1.485 +void CGSM610FR_Decoder::UnpackFrame1(struct codes* aCodeBuf, TInt8* pbuf)
   1.486 +{
   1.487 +    TInt16* LAR = aCodeBuf->LARc;
   1.488 +
   1.489 +    // unpack the LAR[0..7] from the first 4.5 bytes
   1.490 +    LAR[0] = (TInt16)(((pbuf[32] & 0xF0) >> 4) | ((pbuf[33] & 0x03) << 4));
   1.491 +    LAR[1] = (TInt16)(((pbuf[33] & 0xFC) >> 2));
   1.492 +    LAR[2] = (TInt16)(((pbuf[34] & 0x1F)));
   1.493 +    LAR[3] = (TInt16)(((pbuf[34] & 0xE0) >> 5) | ((pbuf[35] & 0x03) << 3));
   1.494 +    LAR[4] = (TInt16)(((pbuf[35] & 0x3C) >> 2));
   1.495 +    LAR[5] = (TInt16)(((pbuf[35] & 0xC0) >> 6) | ((pbuf[36] & 0x03) << 2));
   1.496 +    LAR[6] = (TInt16)(((pbuf[36] & 0x1C) >> 2));
   1.497 +    LAR[7] = (TInt16)(((pbuf[36] & 0xE0) >> 5));
   1.498 +
   1.499 +    // unpack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   1.500 +    for(TInt i = 0; i < 4; i++)
   1.501 +        {
   1.502 +        struct sfcodes& c = aCodeBuf->sfc[i];
   1.503 +#define sfb(x) (pbuf[37+i*7+x])
   1.504 +        c.Nc = (TInt16)(sfb(0) & 0x7F);
   1.505 +        c.bc = (TInt16)(((sfb(0) & 0x80) >> 7) | ((sfb(1) & 0x01) << 1));
   1.506 +        c.Mc = (TInt16)(((sfb(1) & 0x06) >> 1));
   1.507 +        c.xmaxc = (TInt16)(((sfb(1) & 0xF8) >> 3) | ((sfb(2) & 0x01) << 5));
   1.508 +        c.xMc[0] = (TInt16)(((sfb(2) & 0x0E) >> 1));
   1.509 +        c.xMc[1] = (TInt16)(((sfb(2) & 0x70) >> 4));
   1.510 +        c.xMc[2] = (TInt16)(((sfb(2) & 0x80) >> 7) | ((sfb(3) & 0x03) << 1));
   1.511 +        c.xMc[3] = (TInt16)(((sfb(3) & 0x1C) >> 2));
   1.512 +        c.xMc[4] = (TInt16)(((sfb(3) & 0xE0) >> 5));
   1.513 +        c.xMc[5] = (TInt16)(((sfb(4) & 0x07)));
   1.514 +        c.xMc[6] = (TInt16)(((sfb(4) & 0x38) >> 3));
   1.515 +        c.xMc[7] = (TInt16)(((sfb(4) & 0xC0) >> 6) | ((sfb(5) & 0x01) << 2));
   1.516 +        c.xMc[8] = (TInt16)(((sfb(5) & 0x0E) >> 1));
   1.517 +        c.xMc[9] = (TInt16)(((sfb(5) & 0x70) >> 4));
   1.518 +        c.xMc[10] = (TInt16)(((sfb(5) & 0x80) >> 7) | ((sfb(6) & 0x03) << 1));
   1.519 +        c.xMc[11] = (TInt16)(((sfb(6) & 0x1C) >> 2));
   1.520 +        c.xMc[12] = (TInt16)(((sfb(6) & 0xE0) >> 5));
   1.521 +
   1.522 +#undef sfb
   1.523 +        }
   1.524 +    }
   1.525 +
   1.526 +
   1.527 +//-----------------------------------------------------------------------------
   1.528 +//  End of File
   1.529 +//-----------------------------------------------------------------------------