Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /****************************************************************************************
     19 Portions of this file are derived from the following 3GPP standard:
     20 
     21     3GPP TS 26.073
     22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
     23     Available from http://www.3gpp.org
     24 
     25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
     26 Permission to distribute, modify and use this file under the standard license
     27 terms listed above has been obtained from the copyright holder.
     28 ****************************************************************************************/
     29 /*
     30 ------------------------------------------------------------------------------
     31 
     32 
     33 
     34  Filename:  /audio/gsm-amr/c/src/amrencode.c
     35  Functions: AMREncode
     36             AMREncodeInit
     37             AMREncodeReset
     38             AMREncodeExit
     39 
     40      Date: 01/26/2002
     41 
     42 ------------------------------------------------------------------------------
     43  REVISION HISTORY
     44 
     45  Description: Added input_type in the parameter list and updated code to
     46               check the type of output formatting to use.
     47 
     48  Description: Corrected typo in Include section.
     49 
     50  Description: Added code to support ETS format.
     51 
     52  Description: Modified file by adding the return of the number of encoder
     53               frame bytes.
     54 
     55  Description: Added call to sid_sync function to support TX_NO_DATA case.
     56               Added SID type and mode info to ets_output_bfr for ETS SID
     57               frames. Created AMREncodeInit, AMREncodeReset, and AMREncodeExit
     58               functions.
     59 
     60  Description: Modified design of handling of ETS outputs such that the ETS
     61               testvectors could be compared directly to the output of this
     62               function.
     63 
     64  Description: Added conditional compile around calls to AMR Encoder interface
     65               functions to allow amrencode.c to be used in the ETS reference
     66               console.
     67 
     68  Description:  Replaced "int" and/or "char" with OSCL defined types.
     69 
     70  Description:
     71 
     72 ------------------------------------------------------------------------------
     73  MODULE DESCRIPTION
     74 
     75  This file contains the functions required to initialize, reset, exit, and
     76  invoke the ETS 3GPP GSM AMR encoder.
     77 
     78 ------------------------------------------------------------------------------
     79 */
     80 
     81 
     82 /*----------------------------------------------------------------------------
     83 ; INCLUDES
     84 ----------------------------------------------------------------------------*/
     85 #include "cnst.h"
     86 #include "mode.h"
     87 #include "frame_type_3gpp.h"
     88 #include "typedef.h"
     89 
     90 #include "amrencode.h"
     91 #include "ets_to_if2.h"
     92 #include "ets_to_wmf.h"
     93 #include "sid_sync.h"
     94 #include "sp_enc.h"
     95 
     96 /*----------------------------------------------------------------------------
     97 ; MACROS [optional]
     98 ; [Define module specific macros here]
     99 ----------------------------------------------------------------------------*/
    100 
    101 /*----------------------------------------------------------------------------
    102 ; DEFINES [optional]
    103 ; [Include all pre-processor statements here. Include conditional
    104 ; compile variables also.]
    105 ----------------------------------------------------------------------------*/
    106 
    107 /*----------------------------------------------------------------------------
    108 ; LOCAL FUNCTION DEFINITIONS
    109 ; [List function prototypes here]
    110 ----------------------------------------------------------------------------*/
    111 
    112 /*----------------------------------------------------------------------------
    113 ; LOCAL VARIABLE DEFINITIONS
    114 ; [Variable declaration - defined here and used outside this module]
    115 ----------------------------------------------------------------------------*/
    116 
    117 
    118 /*
    119 ------------------------------------------------------------------------------
    120  FUNCTION NAME: AMREncodeInit
    121 ------------------------------------------------------------------------------
    122  INPUT AND OUTPUT DEFINITIONS
    123 
    124  Inputs:
    125     pEncStructure = pointer containing the pointer to a structure used by
    126                     the encoder (void)
    127     pSidSyncStructure = pointer containing the pointer to a structure used for
    128                         SID synchronization (void)
    129     dtx_enable = flag to turn off or turn on DTX (Flag)
    130 
    131  Outputs:
    132     None
    133 
    134  Returns:
    135     init_status = 0, if initialization was successful; -1, otherwise (int)
    136 
    137  Global Variables Used:
    138     None
    139 
    140  Local Variables Needed:
    141     speech_encoder_state = pointer to encoder frame structure
    142                            (Speech_Encode_FrameState)
    143     sid_state = pointer to SID sync structure (sid_syncState)
    144 
    145 ------------------------------------------------------------------------------
    146  FUNCTION DESCRIPTION
    147 
    148  This function initializes the GSM AMR Encoder library by calling
    149  GSMInitEncode and sid_sync_init. If initialization was successful,
    150  init_status is set to zero, otherwise, it is set to -1.
    151 
    152 ------------------------------------------------------------------------------
    153  REQUIREMENTS
    154 
    155  None
    156 
    157 ------------------------------------------------------------------------------
    158  REFERENCES
    159 
    160  None
    161 
    162 ------------------------------------------------------------------------------
    163  PSEUDO-CODE
    164 
    165  // Initialize GSM AMR Encoder
    166  CALL GSMInitEncode(state_data = &pEncStructure,
    167                     dtx = dtx_enable,
    168                     id = char_id            )
    169    MODIFYING(nothing)
    170    RETURNING(return_value = enc_init_status)
    171 
    172  // Initialize SID synchronization
    173  CALL sid_sync_init(state = &pSidSyncStructure)
    174    MODIFYING(nothing)
    175    RETURNING(return_value = sid_sync_init_status)
    176 
    177  IF ((enc_init_status != 0) || (sid_sync_init != 0))
    178  THEN
    179      init_status = -1
    180 
    181  ENDIF
    182 
    183  MODIFY(nothing)
    184  RETURN(init_status)
    185 
    186 ------------------------------------------------------------------------------
    187  RESOURCES USED [optional]
    188 
    189  When the code is written for a specific target processor the
    190  the resources used should be documented below.
    191 
    192  HEAP MEMORY USED: x bytes
    193 
    194  STACK MEMORY USED: x bytes
    195 
    196  CLOCK CYCLES: (cycle count equation for this function) + (variable
    197                 used to represent cycle count for each subroutine
    198                 called)
    199      where: (cycle count variable) = cycle count for [subroutine
    200                                      name]
    201 
    202 ------------------------------------------------------------------------------
    203  CAUTION [optional]
    204  [State any special notes, constraints or cautions for users of this function]
    205 
    206 ------------------------------------------------------------------------------
    207 */
    208 Word16 AMREncodeInit(
    209     void **pEncStructure,
    210     void **pSidSyncStructure,
    211     Flag dtx_enable)
    212 {
    213     Word16 enc_init_status = 0;
    214     Word16 sid_sync_init_status = 0;
    215     Word16 init_status = 0;
    216 
    217     /* Initialize GSM AMR Encoder */
    218 #ifdef CONSOLE_ENCODER_REF
    219     /* Change to original ETS input types */
    220     Speech_Encode_FrameState **speech_encode_frame =
    221         (Speech_Encode_FrameState **)(pEncStructure);
    222 
    223     sid_syncState **sid_sync_state = (sid_syncState **)(pSidSyncStructure);
    224 
    225     /* Use ETS version of sp_enc.c */
    226     enc_init_status = Speech_Encode_Frame_init(speech_encode_frame,
    227                       dtx_enable,
    228                       (Word8*)"encoder");
    229 
    230     /* Initialize SID synchronization */
    231     sid_sync_init_status = sid_sync_init(sid_sync_state);
    232 
    233 #else
    234     /* Use PV version of sp_enc.c */
    235     enc_init_status = GSMInitEncode(pEncStructure,
    236                                     dtx_enable,
    237                                     (Word8*)"encoder");
    238 
    239     /* Initialize SID synchronization */
    240     sid_sync_init_status = sid_sync_init(pSidSyncStructure);
    241 
    242 
    243 #endif
    244 
    245     if ((enc_init_status != 0) || (sid_sync_init_status != 0))
    246     {
    247         init_status = -1;
    248     }
    249 
    250     return(init_status);
    251 }
    252 
    253 
    254 /****************************************************************************/
    255 
    256 /*
    257 ------------------------------------------------------------------------------
    258  FUNCTION NAME: AMREncodeReset
    259 ------------------------------------------------------------------------------
    260  INPUT AND OUTPUT DEFINITIONS
    261 
    262  Inputs:
    263     pEncStructure = pointer to a structure used by the encoder (void)
    264     pSidSyncStructure = pointer to a structure used for SID synchronization
    265                         (void)
    266 
    267  Outputs:
    268     None
    269 
    270  Returns:
    271     reset_status = 0, if reset was successful; -1, otherwise (int)
    272 
    273  Global Variables Used:
    274     None
    275 
    276  Local Variables Needed:
    277     speech_encoder_state = pointer to encoder frame structure
    278                            (Speech_Encode_FrameState)
    279     sid_state = pointer to SID sync structure (sid_syncState)
    280 
    281 ------------------------------------------------------------------------------
    282  FUNCTION DESCRIPTION
    283 
    284  This function resets the state memory used by the Encoder and SID sync
    285  function. If reset was successful, reset_status is set to zero, otherwise,
    286  it is set to -1.
    287 
    288 ------------------------------------------------------------------------------
    289  REQUIREMENTS
    290 
    291  None
    292 
    293 ------------------------------------------------------------------------------
    294  REFERENCES
    295 
    296  None
    297 
    298 ------------------------------------------------------------------------------
    299  PSEUDO-CODE
    300 
    301  // Reset GSM AMR Encoder
    302  CALL Speech_Encode_Frame_reset(state_data = pEncStructure)
    303    MODIFYING(nothing)
    304    RETURNING(return_value = enc_reset_status)
    305 
    306  // Reset SID synchronization
    307  CALL sid_sync_reset(state = pSidSyncStructure)
    308    MODIFYING(nothing)
    309    RETURNING(return_value = sid_sync_reset_status)
    310 
    311  IF ((enc_reset_status != 0) || (sid_sync_reset_status != 0))
    312  THEN
    313      reset_status = -1
    314 
    315  ENDIF
    316 
    317  MODIFY(nothing)
    318  RETURN(reset_status)
    319 
    320 ------------------------------------------------------------------------------
    321  RESOURCES USED [optional]
    322 
    323  When the code is written for a specific target processor the
    324  the resources used should be documented below.
    325 
    326  HEAP MEMORY USED: x bytes
    327 
    328  STACK MEMORY USED: x bytes
    329 
    330  CLOCK CYCLES: (cycle count equation for this function) + (variable
    331                 used to represent cycle count for each subroutine
    332                 called)
    333      where: (cycle count variable) = cycle count for [subroutine
    334                                      name]
    335 
    336 ------------------------------------------------------------------------------
    337  CAUTION [optional]
    338  [State any special notes, constraints or cautions for users of this function]
    339 
    340 ------------------------------------------------------------------------------
    341 */
    342 Word16 AMREncodeReset(
    343     void *pEncStructure,
    344     void *pSidSyncStructure)
    345 {
    346     Word16 enc_reset_status = 0;
    347     Word16 sid_sync_reset_status = 0;
    348     Word16 reset_status = 0;
    349 
    350     /* Reset GSM AMR Encoder */
    351     enc_reset_status = Speech_Encode_Frame_reset(pEncStructure);
    352 
    353 
    354     /* Reset SID synchronization */
    355     sid_sync_reset_status = sid_sync_reset(pSidSyncStructure);
    356 
    357     if ((enc_reset_status != 0) || (sid_sync_reset_status != 0))
    358     {
    359         reset_status = -1;
    360     }
    361 
    362     return(reset_status);
    363 }
    364 
    365 
    366 /****************************************************************************/
    367 
    368 /*
    369 ------------------------------------------------------------------------------
    370  FUNCTION NAME: AMREncodeExit
    371 ------------------------------------------------------------------------------
    372  INPUT AND OUTPUT DEFINITIONS
    373 
    374  Inputs:
    375     pEncStructure = pointer containing the pointer to a structure used by
    376                     the encoder (void)
    377     pSidSyncStructure = pointer containing the pointer to a structure used for
    378                         SID synchronization (void)
    379 
    380  Outputs:
    381     None
    382 
    383  Returns:
    384     None
    385 
    386  Global Variables Used:
    387     None
    388 
    389  Local Variables Needed:
    390     speech_encoder_state = pointer to encoder frame structure
    391                            (Speech_Encode_FrameState)
    392     sid_state = pointer to SID sync structure (sid_syncState)
    393 
    394 ------------------------------------------------------------------------------
    395  FUNCTION DESCRIPTION
    396 
    397  This function frees up the state memory used by the Encoder and SID
    398  synchronization function.
    399 
    400 ------------------------------------------------------------------------------
    401  REQUIREMENTS
    402 
    403  None
    404 
    405 ------------------------------------------------------------------------------
    406  REFERENCES
    407 
    408  None
    409 
    410 ------------------------------------------------------------------------------
    411  PSEUDO-CODE
    412 
    413  // Exit GSM AMR Encoder
    414  CALL GSMEncodeFrameExit(state_data = &pEncStructure)
    415    MODIFYING(nothing)
    416    RETURNING(nothing)
    417 
    418  // Exit SID synchronization
    419  CALL sid_sync_exit(state = &pSidSyncStructure)
    420    MODIFYING(nothing)
    421    RETURNING(nothing)
    422 
    423  MODIFY(nothing)
    424  RETURN(nothing)
    425 
    426 ------------------------------------------------------------------------------
    427  RESOURCES USED [optional]
    428 
    429  When the code is written for a specific target processor the
    430  the resources used should be documented below.
    431 
    432  HEAP MEMORY USED: x bytes
    433 
    434  STACK MEMORY USED: x bytes
    435 
    436  CLOCK CYCLES: (cycle count equation for this function) + (variable
    437                 used to represent cycle count for each subroutine
    438                 called)
    439      where: (cycle count variable) = cycle count for [subroutine
    440                                      name]
    441 
    442 ------------------------------------------------------------------------------
    443  CAUTION [optional]
    444  [State any special notes, constraints or cautions for users of this function]
    445 
    446 ------------------------------------------------------------------------------
    447 */
    448 void AMREncodeExit(
    449     void **pEncStructure,
    450     void **pSidSyncStructure)
    451 {
    452     /* Exit GSM AMR Encoder */
    453 
    454 #ifdef CONSOLE_ENCODER_REF
    455     /* Change to original ETS input types */
    456     Speech_Encode_FrameState ** speech_encode_frame =
    457         (Speech_Encode_FrameState **)(pEncStructure);
    458 
    459     sid_syncState ** sid_sync_state = (sid_syncState **)(pSidSyncStructure);
    460 
    461     /* Use ETS version of sp_enc.c */
    462     Speech_Encode_Frame_exit(speech_encode_frame);
    463 
    464 
    465     /* Exit SID synchronization */
    466     sid_sync_exit(sid_sync_state);
    467 
    468 #else
    469 
    470     /* Use PV version of sp_enc.c */
    471     GSMEncodeFrameExit(pEncStructure);
    472 
    473     /* Exit SID synchronization */
    474     sid_sync_exit(pSidSyncStructure);
    475 
    476 #endif
    477 
    478     return;
    479 }
    480 
    481 
    482 /****************************************************************************/
    483 
    484 /*
    485 ------------------------------------------------------------------------------
    486  FUNCTION NAME: AMREncode
    487 ------------------------------------------------------------------------------
    488  INPUT AND OUTPUT DEFINITIONS
    489 
    490  Inputs:
    491     pEncState = pointer to encoder state structure (void)
    492     pSidSyncState = pointer to SID sync state structure (void)
    493     mode = codec mode (enum Mode)
    494     pEncInput = pointer to the input speech samples (Word16)
    495     pEncOutput = pointer to the encoded bit stream (unsigned char)
    496     p3gpp_frame_type = pointer to the 3GPP frame type (enum Frame_Type_3GPP)
    497     output_format = output format type (Word16); valid values are AMR_WMF,
    498                     AMR_IF2, and AMR_ETS
    499 
    500  Outputs:
    501     pEncOutput buffer contains to the newly encoded bit stream
    502     p3gpp_frame_type store contains the new 3GPP frame type
    503 
    504  Returns:
    505     num_enc_bytes = number of encoded bytes for a particular
    506                     mode or -1, if an error occurred (int)
    507 
    508  Global Variables Used:
    509     WmfEncBytesPerFrame = table containing the number of encoder frame
    510                           data bytes per codec mode for WMF output
    511                           format (const int)
    512     If2EncBytesPerFrame = table containing the number of encoder frame
    513                           data bytes per codec mode for IF2 output
    514                           format (const int)
    515 
    516  Local Variables Needed:
    517     None
    518 
    519 ------------------------------------------------------------------------------
    520  FUNCTION DESCRIPTION
    521 
    522  This function is the top-level entry point to the GSM AMR Encoder library.
    523 
    524  The following describes the encoding process for WMF or IF2 formatted output
    525  data. This functions calls GSMEncodeFrame to encode one frame's worth of
    526  input speech samples, and returns the newly encoded bit stream in the buffer
    527  pointed to by pEncOutput.Then the function sid_sync is called to determine
    528  the transmit frame type. If the transmit frame type is TX_SPEECH_GOOD or
    529  TX_SID_FIRST or TX_SID_UPDATE, p3gpp_frame_type will be set to the encoder
    530  used mode. For SID frames, the SID type information and mode information are
    531  added to the encoded parameter bitstream according to the SID frame format
    532  described in [1]. If the transmit frame type is TX_NO_DATA, the store
    533  pointed to by p3gpp_frame_type will be set to NO_DATA. Then the output
    534  format type (output_format) will be checked to determine the format of the
    535  encoded data.
    536 
    537  If output_format is AMR_TX_WMF, the function ets_to_wmf will be called to
    538  convert from ETS format (1 bit/word, where 1 word = 16 bits, information in
    539  least significant bit) to WMF (aka, non-IF2). The WMF format stores the data
    540  in octets. The least significant 4 bits of the first octet contains the 3GPP
    541  frame type information and the most significant 4 bits are zeroed out. The
    542  succeeding octets contain the packed encoded speech bits. The total number of
    543  WMF bytes encoded is obtained from WmfEncBytesPerFrame table and returned via
    544  num_enc_bytes.
    545 
    546  If output_format is AMR_TX_IF2, the function if2_to_ets will be called to
    547  convert from ETS format to IF2 [1]. The IF2 format stores the data in octets.
    548  The least significant nibble of the first octet contains the 3GPP frame type
    549  and the most significant nibble contains the first 4 encoded speech bits. The
    550  suceeding octets contain the packed encoded speech bits. The total number of
    551  IF2 bytes encoded is obtained from If2EncBytesPerFrame table and returned via
    552  num_enc_bytes.
    553 
    554  If output_format is AMR_TX_ETS, GSMFrameEncode is called to generate the
    555  encoded speech parameters, then, sid_sync is called to determine the transmit
    556  frame type. If the transmit frame type is not TX_NO_DATA, then the transmit
    557  frame type information is saved in the first location of the ets_output_bfr,
    558  followed by the encoded speech parameters. The codec mode information is
    559  stored immediately after the MAX_SERIAL_SIZE encoded speech parameters. If
    560  the transmit frame type is TX_NO_DATA, the transmit frame type, encoded
    561  speech parameters, and codec mode are stored in the same order as before
    562  in ets_output_bfr. However, for the no data case, the codec mode is set to
    563  -1.
    564 
    565  After all the required information is generated, the 16-bit data generated
    566  by the Encoder (in ets_output_bfr) is copied to the buffer pointed to by
    567  pEncOutput in the little endian configuration, i.e., least significant byte,
    568  followed by most significant byte. The num_enc_bytes is set to
    569  2*(MAX_SERIAL_SIZE+2).
    570 
    571  If output_format is invalid, this function flags the error and sets
    572  num_enc_bytes to -1.
    573 
    574 ------------------------------------------------------------------------------
    575  REQUIREMENTS
    576 
    577  None
    578 
    579 ------------------------------------------------------------------------------
    580  REFERENCES
    581 
    582  [1] "AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0
    583      Release 4, June 2001
    584 
    585 ------------------------------------------------------------------------------
    586  PSEUDO-CODE
    587 
    588  IF ((output_format == AMR_TX_WMF) | (output_format == AMR_TX_IF2))
    589  THEN
    590      // Encode one speech frame (20 ms)
    591      CALL GSMEncodeFrame( state_data = pEncState,
    592                           mode = mode,
    593                           new_speech = pEncInput,
    594                           serial = &ets_output_bfr[0],
    595                           usedMode = &usedMode )
    596        MODIFYING(nothing)
    597        RETURNING(return_value = 0)
    598 
    599      // Determine transmit frame type
    600      CALL sid_sync(st = pSidSyncState,
    601                    mode = usedMode
    602                    tx_frame_type = &tx_frame_type)
    603        MODIFYING(nothing)
    604        RETURNING(nothing)
    605 
    606      IF (tx_frame_type != TX_NO_DATA)
    607      THEN
    608          // There is data to transmit
    609          *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode
    610 
    611          // Add SID type and mode info for SID frames
    612          IF (*p3gpp_frame_type == AMR_SID)
    613          THEN
    614              // Add SID type to encoder output buffer
    615              IF (tx_frame_type == TX_SID_FIRST)
    616              THEN
    617                  ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] &= 0x7f
    618 
    619              ELSEIF (tx_frame_type == TX_SID_UPDATE )
    620              THEN
    621                  ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] |= 0x80
    622 
    623              ENDIF
    624 
    625              // Add mode information bits
    626              FOR i = 0 TO NUM_AMRSID_TXMODE_BITS-1
    627 
    628                  ets_output_bfr[AMRSID_TXMODE_BIT_OFFSET+i] = (mode>>i)&&0x0001
    629 
    630              ENDFOR
    631 
    632          ENDIF
    633 
    634      ELSE
    635          // There is no data to transmit
    636          *p3gpp_frame_type = NO_DATA
    637 
    638      ENDIF
    639 
    640      // Determine the output format to use
    641      IF (output_format == AMR_TX_WMF)
    642      THEN
    643          // Change output data format to WMF
    644          CALL ets_to_wmf( frame_type_3gpp = *p3gpp_frame_type,
    645                           ets_input_ptr = &ets_output_bfr[0],
    646                           wmf_output_ptr = pEncOutput         )
    647            MODIFYING(nothing)
    648            RETURNING(nothing)
    649 
    650          // Set up the number of encoded WMF bytes
    651          num_enc_bytes = WmfEncBytesPerFrame[(int) *p3gpp_frame_type]
    652 
    653      ELSEIF (output_format == AMR_TX_IF2)
    654      THEN
    655          // Change output data format to IF2
    656          CALL ets_to_if2( frame_type_3gpp = *p3gpp_frame_type,
    657                           ets_input_ptr = &ets_output_bfr[0],
    658                           if2_output_ptr = pEncOutput         )
    659            MODIFYING(nothing)
    660            RETURNING(nothing)
    661 
    662          // Set up the number of encoded IF2 bytes
    663          num_enc_bytes = If2EncBytesPerFrame[(int) *p3gpp_frame_type]
    664 
    665      ENDIF
    666 
    667  ELSEIF (output_format = AMR_TX_ETS)
    668  THEN
    669      // Encode one speech frame (20 ms)
    670      CALL GSMEncodeFrame( state_data = pEncState,
    671                           mode = mode,
    672                           new_speech = pEncInput,
    673                           serial = &ets_output_bfr[1],
    674                           usedMode = &usedMode )
    675        MODIFYING(nothing)
    676        RETURNING(return_value = 0)
    677 
    678      // Save used mode
    679      *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode
    680 
    681      // Determine transmit frame type
    682      CALL sid_sync(st = pSidSyncState,
    683                    mode = usedMode
    684                    tx_frame_type = &tx_frame_type)
    685        MODIFYING(nothing)
    686        RETURNING(nothing)
    687 
    688      // Put TX frame type in output buffer
    689      ets_output_bfr[0] = tx_frame_type
    690 
    691      // Put mode information after the encoded speech parameters
    692      IF (tx_frame_type != TX_NO_DATA)
    693      THEN
    694          ets_output_bfr[MAX_SERIAL_SIZE+1] = mode
    695 
    696      ELSE
    697          ets_output_bfr[MAX_SERIAL_SIZE+1] = -1
    698 
    699      ENDIF
    700 
    701      // Copy output of encoder to pEncOutput buffer
    702      ets_output_ptr = (unsigned char *) &ets_output_bfr[0]
    703 
    704      // Copy 16-bit data in 8-bit chunks using Little Endian configuration
    705      FOR i = 0 TO (2*(MAX_SERIAL_SIZE+6))-1
    706 
    707          *(pEncOutput+i) = *ets_output_ptr
    708          ets_output_ptr = ets_output_ptr + 1
    709 
    710      ENDFOR
    711 
    712      // Set up number of encoded bytes
    713      num_enc_bytes = 2*(MAX_SERIAL_SIZE+6)
    714 
    715  ELSE
    716      // Invalid output_format, set up error code
    717      num_enc_bytes = -1
    718 
    719  ENDIF
    720 
    721  MODIFY (nothing)
    722  RETURN (num_enc_bytes)
    723 
    724 ------------------------------------------------------------------------------
    725  RESOURCES USED [optional]
    726 
    727  When the code is written for a specific target processor the
    728  the resources used should be documented below.
    729 
    730  HEAP MEMORY USED: x bytes
    731 
    732  STACK MEMORY USED: x bytes
    733 
    734  CLOCK CYCLES: (cycle count equation for this function) + (variable
    735                 used to represent cycle count for each subroutine
    736                 called)
    737      where: (cycle count variable) = cycle count for [subroutine
    738                                      name]
    739 
    740 ------------------------------------------------------------------------------
    741  CAUTION [optional]
    742  [State any special notes, constraints or cautions for users of this function]
    743 
    744 ------------------------------------------------------------------------------
    745 */
    746 Word16 AMREncode(
    747     void *pEncState,
    748     void *pSidSyncState,
    749     enum Mode mode,
    750     Word16 *pEncInput,
    751     UWord8 *pEncOutput,
    752     enum Frame_Type_3GPP *p3gpp_frame_type,
    753     Word16 output_format
    754 )
    755 {
    756     Word16 ets_output_bfr[MAX_SERIAL_SIZE+2];
    757     UWord8 *ets_output_ptr;
    758     Word16 num_enc_bytes = -1;
    759     Word16 i;
    760     enum TXFrameType tx_frame_type;
    761     enum Mode usedMode = MR475;
    762 
    763     /* Encode WMF or IF2 frames */
    764     if ((output_format == AMR_TX_WMF) | (output_format == AMR_TX_IF2))
    765     {
    766         /* Encode one speech frame (20 ms) */
    767 
    768 #ifndef CONSOLE_ENCODER_REF
    769 
    770         /* Use PV version of sp_enc.c */
    771         GSMEncodeFrame(pEncState, mode, pEncInput, ets_output_bfr, &usedMode);
    772 
    773 #else
    774         /* Use ETS version of sp_enc.c */
    775         Speech_Encode_Frame(pEncState, mode, pEncInput, ets_output_bfr, &usedMode);
    776 
    777 #endif
    778 
    779         /* Determine transmit frame type */
    780         sid_sync(pSidSyncState, usedMode, &tx_frame_type);
    781 
    782         if (tx_frame_type != TX_NO_DATA)
    783         {
    784             /* There is data to transmit */
    785             *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode;
    786 
    787             /* Add SID type and mode info for SID frames */
    788             if (*p3gpp_frame_type == AMR_SID)
    789             {
    790                 /* Add SID type to encoder output buffer */
    791                 if (tx_frame_type == TX_SID_FIRST)
    792                 {
    793                     ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] &= 0x0000;
    794                 }
    795                 else if (tx_frame_type == TX_SID_UPDATE)
    796                 {
    797                     ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] |= 0x0001;
    798                 }
    799 
    800                 /* Add mode information bits */
    801                 for (i = 0; i < NUM_AMRSID_TXMODE_BITS; i++)
    802                 {
    803                     ets_output_bfr[AMRSID_TXMODE_BIT_OFFSET+i] =
    804                         (mode >> i) & 0x0001;
    805                 }
    806             }
    807         }
    808         else
    809         {
    810             /* This is no data to transmit */
    811             *p3gpp_frame_type = (enum Frame_Type_3GPP)AMR_NO_DATA;
    812         }
    813 
    814         /* At this point, output format is ETS */
    815         /* Determine the output format to use */
    816         if (output_format == AMR_TX_WMF)
    817         {
    818             /* Change output data format to WMF */
    819             ets_to_wmf(*p3gpp_frame_type, ets_output_bfr, pEncOutput);
    820 
    821             /* Set up the number of encoded WMF bytes */
    822             num_enc_bytes = WmfEncBytesPerFrame[(Word16) *p3gpp_frame_type];
    823 
    824         }
    825         else if (output_format == AMR_TX_IF2)
    826         {
    827             /* Change output data format to IF2 */
    828             ets_to_if2(*p3gpp_frame_type, ets_output_bfr, pEncOutput);
    829 
    830             /* Set up the number of encoded IF2 bytes */
    831             num_enc_bytes = If2EncBytesPerFrame[(Word16) *p3gpp_frame_type];
    832 
    833         }
    834     }
    835 
    836     /* Encode ETS frames */
    837     else if (output_format == AMR_TX_ETS)
    838     {
    839         /* Encode one speech frame (20 ms) */
    840 
    841 #ifndef CONSOLE_ENCODER_REF
    842 
    843         /* Use PV version of sp_enc.c */
    844         GSMEncodeFrame(pEncState, mode, pEncInput, &ets_output_bfr[1], &usedMode);
    845 
    846 #else
    847         /* Use ETS version of sp_enc.c */
    848         Speech_Encode_Frame(pEncState, mode, pEncInput, &ets_output_bfr[1], &usedMode);
    849 
    850 #endif
    851 
    852         /* Save used mode */
    853         *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode;
    854 
    855         /* Determine transmit frame type */
    856         sid_sync(pSidSyncState, usedMode, &tx_frame_type);
    857 
    858         /* Put TX frame type in output buffer */
    859         ets_output_bfr[0] = tx_frame_type;
    860 
    861         /* Put mode information after the encoded speech parameters */
    862         if (tx_frame_type != TX_NO_DATA)
    863         {
    864             ets_output_bfr[1+MAX_SERIAL_SIZE] = (Word16) mode;
    865         }
    866         else
    867         {
    868             ets_output_bfr[1+MAX_SERIAL_SIZE] = -1;
    869         }
    870 
    871         /* Copy output of encoder to pEncOutput buffer */
    872         ets_output_ptr = (UWord8 *) & ets_output_bfr[0];
    873 
    874         /* Copy 16-bit data in 8-bit chunks  */
    875         /* using Little Endian configuration */
    876         for (i = 0; i < 2*(MAX_SERIAL_SIZE + 2); i++)
    877         {
    878             *(pEncOutput + i) = *ets_output_ptr;
    879             ets_output_ptr += 1;
    880         }
    881 
    882         /* Set up the number of encoded bytes */
    883         num_enc_bytes = 2 * (MAX_SERIAL_SIZE + 2);
    884 
    885     }
    886 
    887     /* Invalid frame format */
    888     else
    889     {
    890         /* Invalid output format, set up error code */
    891         num_enc_bytes = -1;
    892     }
    893 
    894     return(num_enc_bytes);
    895 }
    896 
    897 
    898