1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
34 Filename: amrencode.cpp
40 ------------------------------------------------------------------------------
43 This file contains the functions required to initialize, reset, exit, and
44 invoke the ETS 3GPP GSM AMR encoder.
46 ------------------------------------------------------------------------------
50 /*----------------------------------------------------------------------------
52 ----------------------------------------------------------------------------*/
55 #include "frame_type_3gpp.h"
58 #include "amrencode.h"
59 #include "ets_to_if2.h"
60 #include "ets_to_wmf.h"
64 /*----------------------------------------------------------------------------
66 ; [Define module specific macros here]
67 ----------------------------------------------------------------------------*/
69 /*----------------------------------------------------------------------------
71 ; [Include all pre-processor statements here. Include conditional
72 ; compile variables also.]
73 ----------------------------------------------------------------------------*/
75 /*----------------------------------------------------------------------------
76 ; LOCAL FUNCTION DEFINITIONS
77 ; [List function prototypes here]
78 ----------------------------------------------------------------------------*/
80 /*----------------------------------------------------------------------------
81 ; LOCAL VARIABLE DEFINITIONS
82 ; [Variable declaration - defined here and used outside this module]
83 ----------------------------------------------------------------------------*/
87 ------------------------------------------------------------------------------
88 FUNCTION NAME: AMREncodeInit
89 ------------------------------------------------------------------------------
90 INPUT AND OUTPUT DEFINITIONS
93 pEncStructure = pointer containing the pointer to a structure used by
95 pSidSyncStructure = pointer containing the pointer to a structure used for
96 SID synchronization (void)
97 dtx_enable = flag to turn off or turn on DTX (Flag)
103 init_status = 0, if initialization was successful; -1, otherwise (int)
105 Global Variables Used:
108 Local Variables Needed:
109 speech_encoder_state = pointer to encoder frame structure
110 (Speech_Encode_FrameState)
111 sid_state = pointer to SID sync structure (sid_syncState)
113 ------------------------------------------------------------------------------
116 This function initializes the GSM AMR Encoder library by calling
117 GSMInitEncode and sid_sync_init. If initialization was successful,
118 init_status is set to zero, otherwise, it is set to -1.
120 ------------------------------------------------------------------------------
125 ------------------------------------------------------------------------------
130 ------------------------------------------------------------------------------
133 // Initialize GSM AMR Encoder
134 CALL GSMInitEncode(state_data = &pEncStructure,
138 RETURNING(return_value = enc_init_status)
140 // Initialize SID synchronization
141 CALL sid_sync_init(state = &pSidSyncStructure)
143 RETURNING(return_value = sid_sync_init_status)
145 IF ((enc_init_status != 0) || (sid_sync_init != 0))
154 ------------------------------------------------------------------------------
156 [State any special notes, constraints or cautions for users of this function]
158 ------------------------------------------------------------------------------
160 Word16 AMREncodeInit(
161 void **pEncStructure,
162 void **pSidSyncStructure,
165 Word16 enc_init_status = 0;
166 Word16 sid_sync_init_status = 0;
167 Word16 init_status = 0;
169 /* Initialize GSM AMR Encoder */
170 #ifdef CONSOLE_ENCODER_REF
171 /* Change to original ETS input types */
172 Speech_Encode_FrameState **speech_encode_frame =
173 (Speech_Encode_FrameState **)(pEncStructure);
175 sid_syncState **sid_sync_state = (sid_syncState **)(pSidSyncStructure);
177 /* Use ETS version of sp_enc.c */
178 enc_init_status = Speech_Encode_Frame_init(speech_encode_frame,
182 /* Initialize SID synchronization */
183 sid_sync_init_status = sid_sync_init(sid_sync_state);
186 /* Use PV version of sp_enc.c */
187 enc_init_status = GSMInitEncode(pEncStructure,
191 /* Initialize SID synchronization */
192 sid_sync_init_status = sid_sync_init(pSidSyncStructure);
197 if ((enc_init_status != 0) || (sid_sync_init_status != 0))
206 /****************************************************************************/
209 ------------------------------------------------------------------------------
210 FUNCTION NAME: AMREncodeReset
211 ------------------------------------------------------------------------------
212 INPUT AND OUTPUT DEFINITIONS
215 pEncStructure = pointer to a structure used by the encoder (void)
216 pSidSyncStructure = pointer to a structure used for SID synchronization
223 reset_status = 0, if reset was successful; -1, otherwise (int)
225 Global Variables Used:
228 Local Variables Needed:
229 speech_encoder_state = pointer to encoder frame structure
230 (Speech_Encode_FrameState)
231 sid_state = pointer to SID sync structure (sid_syncState)
233 ------------------------------------------------------------------------------
236 This function resets the state memory used by the Encoder and SID sync
237 function. If reset was successful, reset_status is set to zero, otherwise,
240 ------------------------------------------------------------------------------
245 ------------------------------------------------------------------------------
250 ------------------------------------------------------------------------------
253 // Reset GSM AMR Encoder
254 CALL Speech_Encode_Frame_reset(state_data = pEncStructure)
256 RETURNING(return_value = enc_reset_status)
258 // Reset SID synchronization
259 CALL sid_sync_reset(state = pSidSyncStructure)
261 RETURNING(return_value = sid_sync_reset_status)
263 IF ((enc_reset_status != 0) || (sid_sync_reset_status != 0))
272 ------------------------------------------------------------------------------
274 [State any special notes, constraints or cautions for users of this function]
276 ------------------------------------------------------------------------------
278 Word16 AMREncodeReset(
280 void *pSidSyncStructure)
282 Word16 enc_reset_status = 0;
283 Word16 sid_sync_reset_status = 0;
284 Word16 reset_status = 0;
286 /* Reset GSM AMR Encoder */
287 enc_reset_status = Speech_Encode_Frame_reset(pEncStructure);
290 /* Reset SID synchronization */
291 sid_sync_reset_status = sid_sync_reset(pSidSyncStructure);
293 if ((enc_reset_status != 0) || (sid_sync_reset_status != 0))
298 return(reset_status);
302 /****************************************************************************/
305 ------------------------------------------------------------------------------
306 FUNCTION NAME: AMREncodeExit
307 ------------------------------------------------------------------------------
308 INPUT AND OUTPUT DEFINITIONS
311 pEncStructure = pointer containing the pointer to a structure used by
313 pSidSyncStructure = pointer containing the pointer to a structure used for
314 SID synchronization (void)
322 Global Variables Used:
325 Local Variables Needed:
326 speech_encoder_state = pointer to encoder frame structure
327 (Speech_Encode_FrameState)
328 sid_state = pointer to SID sync structure (sid_syncState)
330 ------------------------------------------------------------------------------
333 This function frees up the state memory used by the Encoder and SID
334 synchronization function.
336 ------------------------------------------------------------------------------
341 ------------------------------------------------------------------------------
346 ------------------------------------------------------------------------------
349 // Exit GSM AMR Encoder
350 CALL GSMEncodeFrameExit(state_data = &pEncStructure)
354 // Exit SID synchronization
355 CALL sid_sync_exit(state = &pSidSyncStructure)
362 ------------------------------------------------------------------------------
364 [State any special notes, constraints or cautions for users of this function]
366 ------------------------------------------------------------------------------
369 void **pEncStructure,
370 void **pSidSyncStructure)
372 /* Exit GSM AMR Encoder */
374 #ifdef CONSOLE_ENCODER_REF
375 /* Change to original ETS input types */
376 Speech_Encode_FrameState ** speech_encode_frame =
377 (Speech_Encode_FrameState **)(pEncStructure);
379 sid_syncState ** sid_sync_state = (sid_syncState **)(pSidSyncStructure);
381 /* Use ETS version of sp_enc.c */
382 Speech_Encode_Frame_exit(speech_encode_frame);
385 /* Exit SID synchronization */
386 sid_sync_exit(sid_sync_state);
390 /* Use PV version of sp_enc.c */
391 GSMEncodeFrameExit(pEncStructure);
393 /* Exit SID synchronization */
394 sid_sync_exit(pSidSyncStructure);
402 /****************************************************************************/
405 ------------------------------------------------------------------------------
406 FUNCTION NAME: AMREncode
407 ------------------------------------------------------------------------------
408 INPUT AND OUTPUT DEFINITIONS
411 pEncState = pointer to encoder state structure (void)
412 pSidSyncState = pointer to SID sync state structure (void)
413 mode = codec mode (enum Mode)
414 pEncInput = pointer to the input speech samples (Word16)
415 pEncOutput = pointer to the encoded bit stream (unsigned char)
416 p3gpp_frame_type = pointer to the 3GPP frame type (enum Frame_Type_3GPP)
417 output_format = output format type (Word16); valid values are AMR_WMF,
421 pEncOutput buffer contains to the newly encoded bit stream
422 p3gpp_frame_type store contains the new 3GPP frame type
425 num_enc_bytes = number of encoded bytes for a particular
426 mode or -1, if an error occurred (int)
428 Global Variables Used:
429 WmfEncBytesPerFrame = table containing the number of encoder frame
430 data bytes per codec mode for WMF output
432 If2EncBytesPerFrame = table containing the number of encoder frame
433 data bytes per codec mode for IF2 output
436 Local Variables Needed:
439 ------------------------------------------------------------------------------
442 This function is the top-level entry point to the GSM AMR Encoder library.
444 The following describes the encoding process for WMF or IF2 formatted output
445 data. This functions calls GSMEncodeFrame to encode one frame's worth of
446 input speech samples, and returns the newly encoded bit stream in the buffer
447 pointed to by pEncOutput.Then the function sid_sync is called to determine
448 the transmit frame type. If the transmit frame type is TX_SPEECH_GOOD or
449 TX_SID_FIRST or TX_SID_UPDATE, p3gpp_frame_type will be set to the encoder
450 used mode. For SID frames, the SID type information and mode information are
451 added to the encoded parameter bitstream according to the SID frame format
452 described in [1]. If the transmit frame type is TX_NO_DATA, the store
453 pointed to by p3gpp_frame_type will be set to NO_DATA. Then the output
454 format type (output_format) will be checked to determine the format of the
457 If output_format is AMR_TX_WMF, the function ets_to_wmf will be called to
458 convert from ETS format (1 bit/word, where 1 word = 16 bits, information in
459 least significant bit) to WMF (aka, non-IF2). The WMF format stores the data
460 in octets. The least significant 4 bits of the first octet contains the 3GPP
461 frame type information and the most significant 4 bits are zeroed out. The
462 succeeding octets contain the packed encoded speech bits. The total number of
463 WMF bytes encoded is obtained from WmfEncBytesPerFrame table and returned via
466 If output_format is AMR_TX_IF2, the function if2_to_ets will be called to
467 convert from ETS format to IF2 [1]. The IF2 format stores the data in octets.
468 The least significant nibble of the first octet contains the 3GPP frame type
469 and the most significant nibble contains the first 4 encoded speech bits. The
470 suceeding octets contain the packed encoded speech bits. The total number of
471 IF2 bytes encoded is obtained from If2EncBytesPerFrame table and returned via
474 If output_format is AMR_TX_ETS, GSMFrameEncode is called to generate the
475 encoded speech parameters, then, sid_sync is called to determine the transmit
476 frame type. If the transmit frame type is not TX_NO_DATA, then the transmit
477 frame type information is saved in the first location of the ets_output_bfr,
478 followed by the encoded speech parameters. The codec mode information is
479 stored immediately after the MAX_SERIAL_SIZE encoded speech parameters. If
480 the transmit frame type is TX_NO_DATA, the transmit frame type, encoded
481 speech parameters, and codec mode are stored in the same order as before
482 in ets_output_bfr. However, for the no data case, the codec mode is set to
485 After all the required information is generated, the 16-bit data generated
486 by the Encoder (in ets_output_bfr) is copied to the buffer pointed to by
487 pEncOutput in the little endian configuration, i.e., least significant byte,
488 followed by most significant byte. The num_enc_bytes is set to
489 2*(MAX_SERIAL_SIZE+2).
491 If output_format is invalid, this function flags the error and sets
494 ------------------------------------------------------------------------------
499 ------------------------------------------------------------------------------
502 [1] "AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0
505 ------------------------------------------------------------------------------
508 IF ((output_format == AMR_TX_WMF) | (output_format == AMR_TX_IF2))
510 // Encode one speech frame (20 ms)
511 CALL GSMEncodeFrame( state_data = pEncState,
513 new_speech = pEncInput,
514 serial = &ets_output_bfr[0],
515 usedMode = &usedMode )
517 RETURNING(return_value = 0)
519 // Determine transmit frame type
520 CALL sid_sync(st = pSidSyncState,
522 tx_frame_type = &tx_frame_type)
526 IF (tx_frame_type != TX_NO_DATA)
528 // There is data to transmit
529 *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode
531 // Add SID type and mode info for SID frames
532 IF (*p3gpp_frame_type == AMR_SID)
534 // Add SID type to encoder output buffer
535 IF (tx_frame_type == TX_SID_FIRST)
537 ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] &= 0x7f
539 ELSEIF (tx_frame_type == TX_SID_UPDATE )
541 ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] |= 0x80
545 // Add mode information bits
546 FOR i = 0 TO NUM_AMRSID_TXMODE_BITS-1
548 ets_output_bfr[AMRSID_TXMODE_BIT_OFFSET+i] = (mode>>i)&&0x0001
555 // There is no data to transmit
556 *p3gpp_frame_type = NO_DATA
560 // Determine the output format to use
561 IF (output_format == AMR_TX_WMF)
563 // Change output data format to WMF
564 CALL ets_to_wmf( frame_type_3gpp = *p3gpp_frame_type,
565 ets_input_ptr = &ets_output_bfr[0],
566 wmf_output_ptr = pEncOutput )
570 // Set up the number of encoded WMF bytes
571 num_enc_bytes = WmfEncBytesPerFrame[(int) *p3gpp_frame_type]
573 ELSEIF (output_format == AMR_TX_IF2)
575 // Change output data format to IF2
576 CALL ets_to_if2( frame_type_3gpp = *p3gpp_frame_type,
577 ets_input_ptr = &ets_output_bfr[0],
578 if2_output_ptr = pEncOutput )
582 // Set up the number of encoded IF2 bytes
583 num_enc_bytes = If2EncBytesPerFrame[(int) *p3gpp_frame_type]
587 ELSEIF (output_format = AMR_TX_ETS)
589 // Encode one speech frame (20 ms)
590 CALL GSMEncodeFrame( state_data = pEncState,
592 new_speech = pEncInput,
593 serial = &ets_output_bfr[1],
594 usedMode = &usedMode )
596 RETURNING(return_value = 0)
599 *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode
601 // Determine transmit frame type
602 CALL sid_sync(st = pSidSyncState,
604 tx_frame_type = &tx_frame_type)
608 // Put TX frame type in output buffer
609 ets_output_bfr[0] = tx_frame_type
611 // Put mode information after the encoded speech parameters
612 IF (tx_frame_type != TX_NO_DATA)
614 ets_output_bfr[MAX_SERIAL_SIZE+1] = mode
617 ets_output_bfr[MAX_SERIAL_SIZE+1] = -1
621 // Copy output of encoder to pEncOutput buffer
622 ets_output_ptr = (unsigned char *) &ets_output_bfr[0]
624 // Copy 16-bit data in 8-bit chunks using Little Endian configuration
625 FOR i = 0 TO (2*(MAX_SERIAL_SIZE+6))-1
627 *(pEncOutput+i) = *ets_output_ptr
628 ets_output_ptr = ets_output_ptr + 1
632 // Set up number of encoded bytes
633 num_enc_bytes = 2*(MAX_SERIAL_SIZE+6)
636 // Invalid output_format, set up error code
642 RETURN (num_enc_bytes)
644 ------------------------------------------------------------------------------
646 [State any special notes, constraints or cautions for users of this function]
648 ------------------------------------------------------------------------------
656 enum Frame_Type_3GPP *p3gpp_frame_type,
660 Word16 ets_output_bfr[MAX_SERIAL_SIZE+2];
661 UWord8 *ets_output_ptr;
662 Word16 num_enc_bytes = -1;
664 enum TXFrameType tx_frame_type;
665 enum Mode usedMode = MR475;
667 /* Encode WMF or IF2 frames */
668 if ((output_format == AMR_TX_WMF) | (output_format == AMR_TX_IF2)
669 | (output_format == AMR_TX_IETF))
671 /* Encode one speech frame (20 ms) */
673 #ifndef CONSOLE_ENCODER_REF
675 /* Use PV version of sp_enc.c */
676 GSMEncodeFrame(pEncState, mode, pEncInput, ets_output_bfr, &usedMode);
679 /* Use ETS version of sp_enc.c */
680 Speech_Encode_Frame(pEncState, mode, pEncInput, ets_output_bfr, &usedMode);
684 /* Determine transmit frame type */
685 sid_sync(pSidSyncState, usedMode, &tx_frame_type);
687 if (tx_frame_type != TX_NO_DATA)
689 /* There is data to transmit */
690 *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode;
692 /* Add SID type and mode info for SID frames */
693 if (*p3gpp_frame_type == AMR_SID)
695 /* Add SID type to encoder output buffer */
696 if (tx_frame_type == TX_SID_FIRST)
698 ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] &= 0x0000;
700 else if (tx_frame_type == TX_SID_UPDATE)
702 ets_output_bfr[AMRSID_TXTYPE_BIT_OFFSET] |= 0x0001;
705 /* Add mode information bits */
706 for (i = 0; i < NUM_AMRSID_TXMODE_BITS; i++)
708 ets_output_bfr[AMRSID_TXMODE_BIT_OFFSET+i] =
709 (mode >> i) & 0x0001;
715 /* This is no data to transmit */
716 *p3gpp_frame_type = (enum Frame_Type_3GPP)AMR_NO_DATA;
719 /* At this point, output format is ETS */
720 /* Determine the output format to use */
721 if (output_format == AMR_TX_IETF)
723 /* Change output data format to WMF */
724 ets_to_ietf(*p3gpp_frame_type, ets_output_bfr, pEncOutput, &(((Speech_Encode_FrameState*)pEncState)->cod_amr_state->common_amr_tbls));
726 /* Set up the number of encoded WMF bytes */
727 num_enc_bytes = WmfEncBytesPerFrame[(Word16) *p3gpp_frame_type];
730 else if (output_format == AMR_TX_WMF)
732 /* Change output data format to WMF */
733 ets_to_wmf(*p3gpp_frame_type, ets_output_bfr, pEncOutput, &(((Speech_Encode_FrameState*)pEncState)->cod_amr_state->common_amr_tbls));
735 /* Set up the number of encoded WMF bytes */
736 num_enc_bytes = WmfEncBytesPerFrame[(Word16) *p3gpp_frame_type];
739 else if (output_format == AMR_TX_IF2)
741 /* Change output data format to IF2 */
742 ets_to_if2(*p3gpp_frame_type, ets_output_bfr, pEncOutput, &(((Speech_Encode_FrameState*)pEncState)->cod_amr_state->common_amr_tbls));
744 /* Set up the number of encoded IF2 bytes */
745 num_enc_bytes = If2EncBytesPerFrame[(Word16) *p3gpp_frame_type];
750 /* Encode ETS frames */
751 else if (output_format == AMR_TX_ETS)
753 /* Encode one speech frame (20 ms) */
755 #ifndef CONSOLE_ENCODER_REF
757 /* Use PV version of sp_enc.c */
758 GSMEncodeFrame(pEncState, mode, pEncInput, &ets_output_bfr[1], &usedMode);
761 /* Use ETS version of sp_enc.c */
762 Speech_Encode_Frame(pEncState, mode, pEncInput, &ets_output_bfr[1], &usedMode);
767 *p3gpp_frame_type = (enum Frame_Type_3GPP) usedMode;
769 /* Determine transmit frame type */
770 sid_sync(pSidSyncState, usedMode, &tx_frame_type);
772 /* Put TX frame type in output buffer */
773 ets_output_bfr[0] = tx_frame_type;
775 /* Put mode information after the encoded speech parameters */
776 if (tx_frame_type != TX_NO_DATA)
778 ets_output_bfr[1+MAX_SERIAL_SIZE] = (Word16) mode;
782 ets_output_bfr[1+MAX_SERIAL_SIZE] = -1;
785 /* Copy output of encoder to pEncOutput buffer */
786 ets_output_ptr = (UWord8 *) & ets_output_bfr[0];
788 /* Copy 16-bit data in 8-bit chunks */
789 /* using Little Endian configuration */
790 for (i = 0; i < 2*(MAX_SERIAL_SIZE + 2); i++)
792 *(pEncOutput + i) = *ets_output_ptr;
796 /* Set up the number of encoded bytes */
797 num_enc_bytes = 2 * (MAX_SERIAL_SIZE + 2);
801 /* Invalid frame format */
804 /* Invalid output format, set up error code */
808 return(num_enc_bytes);