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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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*/
208Word16 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*/
342Word16 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*/
448void 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*/
746Word16 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