os/mm/mmlibs/mmfw/Codecs/Src/Gsm610CodecCommon/gsm610fr.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2000-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 // Polymorphic DLL implementation of GSM 6.10 full rate (FR) speech coder
    15 // and decoder    objects.
    16 // This codec is based on ANSI C simulation codes. For this implementation
    17 // (polymorphic DLL) the original ANSI C codes have been modified slightly:
    18 // - The original .c files were renamed to .cpp files.
    19 // - All global varibles (codec's state) are now encoder's or decoder's
    20 // private member variables.
    21 // - Because codec's state is in the codec object, an extra variable -
    22 // a pointer codec object - have been added to some original routines.
    23 // - Global tables are now const C++ tables in tables.h header file.
    24 // - VAD and DTX modules have been removed from the original routines.
    25 // - Due to error in GNU tool chain all array indexes of type [i-1] in
    26 // rpeltp.cpp have been removed and changed to [j] type.
    27 // - multr, L_add, L_mac from basicop.cpp inlined
    28 // INCLUDES
    29 // 
    30 //
    31 
    32 #include "gsm610fr.h"
    33 #include "codec.h"
    34 #include <e32uid.h>
    35 
    36 
    37 //  LOCAL FUNCTIONS
    38 //===================================================================
    39 /*
    40 -----------------------------------------------------------------------------
    41 
    42     GSM610FR_Encoder
    43 
    44     ConstructL
    45 
    46     This function implements the second phase construction of GSM610FR_Encoder
    47     class. Function binds the encoder to given input and output streams and
    48     resets encoder.
    49 
    50     Parameters:     RReadStream aInStrm     Handle to input stream (16 bit
    51                                             PCM speech data)
    52                     RWriteStream aOutStrm   Handle to output stream (encoded
    53                                             speech data)
    54 
    55     Return Values:  none
    56 
    57 -----------------------------------------------------------------------------
    58 */
    59 EXPORT_C void CGSM610FR_Encoder::ConstructL()
    60     {
    61     ::reset_encoder(this);
    62     iOddFrame = TRUE;
    63     }
    64 
    65 
    66 /*
    67 -----------------------------------------------------------------------------
    68 
    69     GSM610FR_Encoder
    70 
    71     ~GSM610FR_Encoder
    72 
    73     Empty encoder destructor.
    74 
    75     Parameters:     none
    76     
    77     Return Values:  none
    78 
    79 -----------------------------------------------------------------------------
    80 */
    81 EXPORT_C CGSM610FR_Encoder::~CGSM610FR_Encoder()
    82     {
    83     }
    84 
    85 
    86 /*
    87 -----------------------------------------------------------------------------
    88 
    89     GSM610FR_Encoder
    90 
    91     StartL
    92 
    93     Start encoder object. Initialize codec status.
    94 
    95     Parameters:     none
    96     
    97     Return Values:  none
    98 
    99 -----------------------------------------------------------------------------
   100 */
   101 EXPORT_C void CGSM610FR_Encoder::StartL()
   102     {
   103     ::reset_encoder(this);
   104     iOddFrame = TRUE;
   105     }
   106 
   107 
   108 /*
   109 -----------------------------------------------------------------------------
   110 
   111     GSM610FR_Encoder
   112 
   113     ExecuteL
   114 
   115     Execute encoder object. Read one speech frame from the input stream,
   116     RPELTP encode it and write the encoded frame to output stream.
   117 
   118     Parameters:     none
   119     
   120     Return Values:  none
   121 
   122     Leave Handling:
   123     
   124     If the length of data available in the input stream is less than
   125     FRAMESIZE then the function leaves with KErrEof.
   126 
   127 -----------------------------------------------------------------------------
   128 */
   129 EXPORT_C void CGSM610FR_Encoder::ExecuteL(TUint8* aInBuf, TUint8* aOutBuf)
   130 {
   131 	TInt16* inBufPtr  = (TInt16*) aInBuf;
   132 
   133 
   134 	for (TInt frame = 0; frame < 2; frame++)
   135 	{
   136 	    ::RPELTP_encoder(this, inBufPtr, &iCodeBuf);
   137 
   138 		if ( iOddFrame )
   139 		{
   140 			PackFrame0 (&iCodeBuf, (TInt8*) aOutBuf);
   141 		}
   142 		else
   143 		{
   144 			PackFrame1 (&iCodeBuf, (TInt8*) aOutBuf);
   145 		}
   146 
   147 		iOddFrame = !iOddFrame;
   148 		inBufPtr += FRAMESIZE;
   149 	}
   150 
   151 }
   152 /*
   153 -----------------------------------------------------------------------------
   154 
   155     GSM610FR_Encoder
   156 
   157     StopL
   158 
   159     Stop encoder object. Flush out last frames, if necessary.
   160 
   161     Parameters:     none
   162     
   163     Return Values:  none
   164 
   165 -----------------------------------------------------------------------------
   166 */
   167 EXPORT_C void CGSM610FR_Encoder::StopL()
   168     {
   169     }
   170 
   171 
   172 /*
   173 -----------------------------------------------------------------------------
   174 
   175     GSM610FR_Encoder
   176 
   177     PackFrame0
   178 
   179     Pack the codewords of the even frame into pack buffer.
   180 
   181     Packing as in MS gsm610 encoder.
   182 
   183     Parameters:     struct codes* aCodeBuf    Code words for one speech frame.
   184     
   185     Return Values:  none
   186 
   187 
   188 -----------------------------------------------------------------------------
   189 */
   190 void CGSM610FR_Encoder::PackFrame0(struct codes* aCodeBuf, TInt8* pbuf)
   191     {
   192     TInt16* LAR = aCodeBuf->LARc;
   193     
   194     // pack the LARc[0..7] into the first 4.5 bytes
   195     *pbuf++ = (TUint8)(((LAR[0]     ) & 0x3F) | ((LAR[1] << 6) & 0xC0));
   196     *pbuf++ = (TUint8)(((LAR[1] >> 2) & 0x0F) | ((LAR[2] << 4) & 0xF0));
   197     *pbuf++ = (TUint8)(((LAR[2] >> 4) & 0x01) | ((LAR[3] << 1) & 0x3E) | ((LAR[4] << 6) & 0xC0));
   198     *pbuf++ = (TUint8)(((LAR[4] >> 2) & 0x03) | ((LAR[5] << 2) & 0x3C) | ((LAR[6] << 6) & 0xC0));
   199     *pbuf   = (TUint8)(((LAR[6] >> 2) & 0x01) | ((LAR[7] << 1) & 0x0E));
   200     
   201     // pack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   202     for(TInt i = 0; i < 4; i++)
   203         {
   204         struct sfcodes& c = aCodeBuf->sfc[i];
   205         *pbuf++ |= ((c.Nc << 4) & 0xF0);
   206         *pbuf++ = (TUint8)(((c.Nc >> 4) & 0x07) | ((c.bc << 3) & 0x18) | ((c.Mc << 5) & 0x60) | ((c.xmaxc << 7) & 0x80));
   207         *pbuf++ = (TUint8)(((c.xmaxc >> 1) & 0x1F) | ((c.xMc[0] << 5) & 0xE0));
   208         *pbuf++ = (TUint8)((c.xMc[1] & 0x07) | ((c.xMc[2] << 3) & 0x38) | ((c.xMc[3] << 6) & 0xC0));
   209         *pbuf++ = (TUint8)(((c.xMc[3] >> 2) & 0x01) | ((c.xMc[4] << 1) & 0x0E) | ((c.xMc[5] << 4) & 0x70) | ((c.xMc[6] << 7) & 0x80));
   210         *pbuf++ = (TUint8)(((c.xMc[6] >> 1) & 0x03) | ((c.xMc[7] << 2) & 0x1C) | ((c.xMc[8] << 5) & 0xE0));
   211         *pbuf++ = (TUint8)((c.xMc[9] & 0x07) | ((c.xMc[10] << 3) & 0x38) | ((c.xMc[11] << 6) & 0xC0));
   212         *pbuf   = (TUint8)(((c.xMc[11] >> 2) & 0x01) | ((c.xMc[12] << 1) & 0x0E));
   213         }
   214     }
   215 
   216 
   217 /*
   218 -----------------------------------------------------------------------------
   219 
   220     GSM610FR_Encoder
   221 
   222     PackFrame1
   223 
   224     Pack the codewords of the odd frame into pack buffer.
   225 
   226     Packing as in MS gsm610 encoder.
   227 
   228     Parameters:     struct codes* aCodeBuf    Code words for one speech frame.
   229     
   230     Return Values:  none
   231 
   232 
   233 -----------------------------------------------------------------------------
   234 */
   235 void CGSM610FR_Encoder::PackFrame1(struct codes* aCodeBuf, TInt8* pbuf)
   236     {
   237     TInt16* LAR = aCodeBuf->LARc;
   238     
   239 	pbuf += (PACKSIZE / 2);
   240 	TInt8 pbufZero = pbuf[0];
   241 
   242     // pack the LARc[0..7] into the first 4.5 bytes, starting with the msb of the first byte
   243     *pbuf++ = (TUint8) (pbufZero | ((LAR[0] << 4) & 0xF0));
   244     *pbuf++ = (TUint8)(((LAR[0] >> 4) & 0x03) | ((LAR[1] << 2) & 0xFC));
   245     *pbuf++ = (TUint8)(((LAR[2]     ) & 0x1F) | ((LAR[3] << 5) & 0xE0));
   246     *pbuf++ = (TUint8)(((LAR[3] >> 3) & 0x03) | ((LAR[4] << 2) & 0x3C) | ((LAR[5] << 6) & 0xC0));
   247     *pbuf++ = (TUint8)(((LAR[5] >> 2) & 0x03) | ((LAR[6] << 2) & 0x1C) | ((LAR[7] << 5) & 0xE0));
   248     
   249     // pack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   250     for(TInt i = 0; i < 4; i++)
   251         {
   252         struct sfcodes& c = aCodeBuf->sfc[i];
   253         *pbuf++ = (TUint8)((c.Nc & 0x7F) | ((c.bc << 7) & 0x80));
   254         *pbuf++ = (TUint8)(((c.bc >> 1) & 0x01) | ((c.Mc << 1) & 0x06) | ((c.xmaxc << 3) & 0xF8));
   255         *pbuf++ = (TUint8)(((c.xmaxc >> 5) & 0x01) | ((c.xMc[0] << 1) & 0x0E) | ((c.xMc[1] << 4) & 0x70) | ((c.xMc[2] << 7) & 0x80));
   256         *pbuf++ = (TUint8)(((c.xMc[2] >> 1) & 0x03) | ((c.xMc[3] << 2) & 0x1C) | ((c.xMc[4] << 5) & 0xE0));
   257         *pbuf++ = (TUint8)(((c.xMc[5]) & 0x07) | ((c.xMc[6] << 3) & 0x38) | ((c.xMc[7] << 6) & 0xC0));
   258         *pbuf++ = (TUint8)(((c.xMc[7] >> 2) & 0x01) | ((c.xMc[8] << 1) & 0x0E) | ((c.xMc[9] << 4) & 0x70) | ((c.xMc[10] << 7) & 0x80));
   259         *pbuf++ = (TUint8)(((c.xMc[10] >> 1) & 0x03) | ((c.xMc[11] << 2) & 0x1C) | ((c.xMc[12] << 5) & 0xE0));
   260         }
   261     }
   262 
   263 /*
   264 -----------------------------------------------------------------------------
   265 
   266     GSM610FR_Decoder
   267 
   268     ConstructL
   269 
   270     This function implements the second phase construction of GSM610FR_Decoder
   271     class. Function binds the decoder to given input and output streams and
   272     resets decoder.
   273 
   274     Parameters:     RReadStream aInStrm     Handle to input stream (encoded
   275                                             speech data)
   276                                             
   277                     RWriteStream aOutStrm   Handle to output stream (16 bit
   278                                             PCM speech data)
   279 
   280     Return Values:  none
   281 
   282 -----------------------------------------------------------------------------
   283 */
   284 EXPORT_C void CGSM610FR_Decoder::ConstructL()
   285     {
   286     ::reset_decoder(this);
   287     iOddFrame = TRUE;
   288     }
   289 
   290 
   291 /*
   292 -----------------------------------------------------------------------------
   293 
   294     GSM610FR_Decoder
   295 
   296     ~GSM610FR_Decoder
   297 
   298     Empty decoder destructor.
   299 
   300     Parameters:     none
   301     
   302     Return Values:  none
   303 
   304 -----------------------------------------------------------------------------
   305 */
   306 EXPORT_C CGSM610FR_Decoder::~CGSM610FR_Decoder()
   307     {
   308     }
   309 
   310 
   311 /*
   312 -----------------------------------------------------------------------------
   313 
   314     GSM610FR_Decoder
   315 
   316     StartL
   317 
   318     Start decoder object. Initialize codec status.
   319 
   320     Parameters:     none
   321     
   322     Return Values:  none
   323 
   324 -----------------------------------------------------------------------------
   325 */
   326 EXPORT_C void CGSM610FR_Decoder::StartL()
   327     {
   328     ::reset_decoder(this);
   329     iOddFrame = TRUE;
   330     }
   331 
   332 
   333 /*
   334 -----------------------------------------------------------------------------
   335 
   336     GSM610FR_Decoder
   337 
   338     ExecuteL
   339 
   340     Execute decoder object. Read one encoded speech frame from the input
   341     stream RPELTP decode it and write the decoded frame to output stream.
   342 
   343     Parameters:     none
   344     
   345     Return Values:  none
   346 
   347     Leave Handling:
   348     
   349     If the length of data available in the input stream is less than size
   350     of one encoded speech frame then the function leaves with KErrEof.
   351 
   352 -----------------------------------------------------------------------------
   353 */
   354 EXPORT_C void CGSM610FR_Decoder::ExecuteL(TUint8* aInBuf, TUint8* aOutBuf)
   355 {
   356 
   357 	TInt16* outBufPtr = (TInt16*) aOutBuf;
   358 
   359 
   360 	// Process both odd and even frames
   361 
   362 	for (TInt frame = 0; frame < 2; frame++)
   363 	{
   364 		if ( iOddFrame )
   365 		{
   366 			UnpackFrame0(&iCodeBuf, (TInt8*) aInBuf);
   367         }
   368 	   else
   369         {
   370 			UnpackFrame1(&iCodeBuf, (TInt8*) aInBuf);
   371 		}
   372 
   373 
   374 		::RPELTP_decoder(this, &iCodeBuf, outBufPtr);
   375 
   376 		iOddFrame = !iOddFrame;
   377 		outBufPtr += FRAMESIZE;
   378 
   379 	}
   380 
   381 }
   382 
   383 /*
   384 -----------------------------------------------------------------------------
   385 
   386     GSM610FR_Decoder
   387 
   388     StopL
   389 
   390     Stop decoder object. Flush out last frames, if necessary.
   391 
   392     Parameters:     none
   393     
   394     Return Values:  none
   395 
   396 -----------------------------------------------------------------------------
   397 */
   398 EXPORT_C void CGSM610FR_Decoder::StopL()
   399     {
   400     }
   401 
   402 
   403 /*
   404 -----------------------------------------------------------------------------
   405 
   406     GSM610FR_Decoder
   407 
   408     UnpackFrame0
   409 
   410     Unpack the codewords of the even frame from pack buffer.
   411 
   412     Packing as in MS gsm610 encoder.
   413 
   414     Parameters:     struct codes* aCodeBuf    Code words for one speech frame
   415                                               are unpacked into this structure.
   416     
   417     Return Values:  none
   418 
   419 
   420 -----------------------------------------------------------------------------
   421 */
   422 void CGSM610FR_Decoder::UnpackFrame0(struct codes* aCodeBuf,  TInt8* pbuf)
   423     {
   424     TInt16* LAR = aCodeBuf->LARc;
   425 
   426     // unpack the LAR[0..7] from the first 4.5 bytes
   427     LAR[0] = (TInt16)((pbuf[0] & 0x3F));
   428     LAR[1] = (TInt16)(((pbuf[0] & 0xC0) >> 6) | ((pbuf[1] & 0x0F) << 2));
   429     LAR[2] = (TInt16)(((pbuf[1] & 0xF0) >> 4) | ((pbuf[2] & 0x01) << 4));
   430     LAR[3] = (TInt16)(((pbuf[2] & 0x3E) >> 1));
   431     LAR[4] = (TInt16)(((pbuf[2] & 0xC0) >> 6) | ((pbuf[3] & 0x03) << 2));
   432     LAR[5] = (TInt16)(((pbuf[3] & 0x3C) >> 2));
   433     LAR[6] = (TInt16)(((pbuf[3] & 0xC0) >> 6) | ((pbuf[4] & 0x01) << 2));
   434     LAR[7] = (TInt16)(((pbuf[4] & 0x0E) >> 1));
   435 
   436     // unpack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   437     for(TInt i = 0; i < 4; i++)
   438         {
   439         struct sfcodes& c = aCodeBuf->sfc[i];
   440 #define sfb(x) (pbuf[4+i*7+x])
   441         c.Nc = (TInt16)(((sfb(0) & 0xF0) >> 4) | ((sfb(1) & 0x07) << 4));
   442         c.bc = (TInt16)(((sfb(1) & 0x18) >> 3));
   443         c.Mc = (TInt16)(((sfb(1) & 0x60) >> 5));
   444         c.xmaxc = (TInt16)(((sfb(1) & 0x80) >> 7) | ((sfb(2) & 0x1F) << 1));
   445         c.xMc[0] = (TInt16)(((sfb(2) & 0xE0) >> 5));
   446         c.xMc[1] = (TInt16)((sfb(3) & 0x07));
   447         c.xMc[2] = (TInt16)(((sfb(3) & 0x3C) >> 3));
   448         c.xMc[3] = (TInt16)(((sfb(3) & 0xC0) >> 6) | ((sfb(4) & 0x01) << 2));
   449         c.xMc[4] = (TInt16)(((sfb(4) & 0x0E) >> 1));
   450         c.xMc[5] = (TInt16)(((sfb(4) & 0x70) >> 4));
   451         c.xMc[6] = (TInt16)(((sfb(4) & 0x80) >> 7) | ((sfb(5) & 0x03) << 1));
   452         c.xMc[7] = (TInt16)(((sfb(5) & 0x1C) >> 2));
   453         c.xMc[8] = (TInt16)(((sfb(5) & 0xE0) >> 5));
   454         c.xMc[9] = (TInt16)((sfb(6) & 0x07));
   455         c.xMc[10] = (TInt16)(((sfb(6) & 0x38) >> 3));
   456         c.xMc[11] = (TInt16)(((sfb(6) & 0xC0) >> 6) | ((sfb(7) & 0x01) << 2));
   457         c.xMc[12] = (TInt16)(((sfb(7) & 0x0E) >> 1));
   458 #undef sfb
   459         }
   460     }
   461 
   462 
   463 /*
   464 -----------------------------------------------------------------------------
   465 
   466     GSM610FR_Decoder
   467 
   468     UnpackFrame1
   469 
   470     Unpack the codewords of the odd frame from pack buffer.
   471 
   472     Packing as in MS gsm610 encoder.
   473 
   474     Parameters:     struct codes* aCodeBuf    Code words for one speech frame
   475                                               are unpacked into this structure.
   476     
   477     Return Values:  none
   478 
   479 
   480 -----------------------------------------------------------------------------
   481 */
   482 void CGSM610FR_Decoder::UnpackFrame1(struct codes* aCodeBuf, TInt8* pbuf)
   483 {
   484     TInt16* LAR = aCodeBuf->LARc;
   485 
   486     // unpack the LAR[0..7] from the first 4.5 bytes
   487     LAR[0] = (TInt16)(((pbuf[32] & 0xF0) >> 4) | ((pbuf[33] & 0x03) << 4));
   488     LAR[1] = (TInt16)(((pbuf[33] & 0xFC) >> 2));
   489     LAR[2] = (TInt16)(((pbuf[34] & 0x1F)));
   490     LAR[3] = (TInt16)(((pbuf[34] & 0xE0) >> 5) | ((pbuf[35] & 0x03) << 3));
   491     LAR[4] = (TInt16)(((pbuf[35] & 0x3C) >> 2));
   492     LAR[5] = (TInt16)(((pbuf[35] & 0xC0) >> 6) | ((pbuf[36] & 0x03) << 2));
   493     LAR[6] = (TInt16)(((pbuf[36] & 0x1C) >> 2));
   494     LAR[7] = (TInt16)(((pbuf[36] & 0xE0) >> 5));
   495 
   496     // unpack Nc, bc, Mc, xmaxc, and xMc for each of the 4 sub-frames
   497     for(TInt i = 0; i < 4; i++)
   498         {
   499         struct sfcodes& c = aCodeBuf->sfc[i];
   500 #define sfb(x) (pbuf[37+i*7+x])
   501         c.Nc = (TInt16)(sfb(0) & 0x7F);
   502         c.bc = (TInt16)(((sfb(0) & 0x80) >> 7) | ((sfb(1) & 0x01) << 1));
   503         c.Mc = (TInt16)(((sfb(1) & 0x06) >> 1));
   504         c.xmaxc = (TInt16)(((sfb(1) & 0xF8) >> 3) | ((sfb(2) & 0x01) << 5));
   505         c.xMc[0] = (TInt16)(((sfb(2) & 0x0E) >> 1));
   506         c.xMc[1] = (TInt16)(((sfb(2) & 0x70) >> 4));
   507         c.xMc[2] = (TInt16)(((sfb(2) & 0x80) >> 7) | ((sfb(3) & 0x03) << 1));
   508         c.xMc[3] = (TInt16)(((sfb(3) & 0x1C) >> 2));
   509         c.xMc[4] = (TInt16)(((sfb(3) & 0xE0) >> 5));
   510         c.xMc[5] = (TInt16)(((sfb(4) & 0x07)));
   511         c.xMc[6] = (TInt16)(((sfb(4) & 0x38) >> 3));
   512         c.xMc[7] = (TInt16)(((sfb(4) & 0xC0) >> 6) | ((sfb(5) & 0x01) << 2));
   513         c.xMc[8] = (TInt16)(((sfb(5) & 0x0E) >> 1));
   514         c.xMc[9] = (TInt16)(((sfb(5) & 0x70) >> 4));
   515         c.xMc[10] = (TInt16)(((sfb(5) & 0x80) >> 7) | ((sfb(6) & 0x03) << 1));
   516         c.xMc[11] = (TInt16)(((sfb(6) & 0x1C) >> 2));
   517         c.xMc[12] = (TInt16)(((sfb(6) & 0xE0) >> 5));
   518 
   519 #undef sfb
   520         }
   521     }
   522 
   523 
   524 //-----------------------------------------------------------------------------
   525 //  End of File
   526 //-----------------------------------------------------------------------------