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 Pathname: ./audio/gsm-amr/c/src/ets_to_if2.c
33 Funtions: ets_to_if2
34
35*/
36
37/*----------------------------------------------------------------------------
38; INCLUDES
39----------------------------------------------------------------------------*/
40#include "frame_type_3gpp.h"
41#include "ets_to_if2.h"
42#include "typedef.h"
43#include "bitreorder_tab.h"
44
45/*----------------------------------------------------------------------------
46; MACROS
47; Define module specific macros here
48----------------------------------------------------------------------------*/
49
50/*----------------------------------------------------------------------------
51; DEFINES
52; Include all pre-processor statements here. Include conditional
53; compile variables also.
54----------------------------------------------------------------------------*/
55
56/*----------------------------------------------------------------------------
57; LOCAL FUNCTION DEFINITIONS
58; Function Prototype declaration
59----------------------------------------------------------------------------*/
60
61/*----------------------------------------------------------------------------
62; LOCAL VARIABLE DEFINITIONS
63; Variable declaration - defined here and used outside this module
64----------------------------------------------------------------------------*/
65
66
67/*
68------------------------------------------------------------------------------
69 FUNCTION NAME: ets_to_if2
70------------------------------------------------------------------------------
71 INPUT AND OUTPUT DEFINITIONS
72
73 Inputs:
74    frame_type_3gpp = decoder speech bit rate (enum Frame_Type_3GPP)
75    ets_input_ptr   = pointer to input encoded speech bits in ETS format (Word16)
76    if2_output_ptr  = pointer to output encoded speech bits in IF2 format (UWord8)
77
78 Outputs:
79    if2_output_ptr  = pointer to encoded speech bits in the IF2 format (UWord8)
80
81 Returns:
82    None
83
84 Global Variables Used:
85    None
86
87 Local Variables Needed:
88    None
89
90------------------------------------------------------------------------------
91 FUNCTION DESCRIPTION
92
93 This function performs a transformation on the data buffers. It converts the
94 data format from ETS (European Telecommunication Standard) to IF2. ETS format
95 has the encoded speech bits each separate with only one bit stored in each
96 word. IF2 is the storage format where the frame type is in the first four bits
97 of the first byte. The upper four bits of that byte contain the first four
98 encoded speech bits for the frame. The following bytes contain the rest of
99 the encoded speech bits. The final byte has padded zeros  to make the frame
100 byte aligned.
101------------------------------------------------------------------------------
102 REQUIREMENTS
103
104 None
105
106------------------------------------------------------------------------------
107 REFERENCES
108
109AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0 Release 4, June 2001
110
111------------------------------------------------------------------------------
112 PSEUDO-CODE
113
114
115
116------------------------------------------------------------------------------
117 RESOURCES USED [optional]
118
119 When the code is written for a specific target processor the
120 the resources used should be documented below.
121
122 HEAP MEMORY USED: x bytes
123
124 STACK MEMORY USED: x bytes
125
126 CLOCK CYCLES: (cycle count equation for this function) + (variable
127                used to represent cycle count for each subroutine
128                called)
129     where: (cycle count variable) = cycle count for [subroutine
130                                     name]
131
132------------------------------------------------------------------------------
133 CAUTION [optional]
134 [State any special notes, constraints or cautions for users of this function]
135
136------------------------------------------------------------------------------
137*/
138
139void ets_to_if2(
140    enum Frame_Type_3GPP frame_type_3gpp,
141    Word16 *ets_input_ptr,
142    UWord8 *if2_output_ptr)
143{
144    Word16  i;
145    Word16  k;
146    Word16  j = 0;
147    Word16 *ptr_temp;
148    Word16  bits_left;
149    UWord8  accum;
150
151    if (frame_type_3gpp < AMR_SID)
152    {
153        if2_output_ptr[j++] = (UWord8)(frame_type_3gpp) |
154                              (ets_input_ptr[reorderBits[frame_type_3gpp][0]] << 4) |
155                              (ets_input_ptr[reorderBits[frame_type_3gpp][1]] << 5) |
156                              (ets_input_ptr[reorderBits[frame_type_3gpp][2]] << 6) |
157                              (ets_input_ptr[reorderBits[frame_type_3gpp][3]] << 7);
158
159        for (i = 4; i < numOfBits[frame_type_3gpp] - 7;)
160        {
161            if2_output_ptr[j]  =
162                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]];
163            if2_output_ptr[j] |=
164                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << 1;
165            if2_output_ptr[j] |=
166                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << 2;
167            if2_output_ptr[j] |=
168                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << 3;
169            if2_output_ptr[j] |=
170                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << 4;
171            if2_output_ptr[j] |=
172                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << 5;
173            if2_output_ptr[j] |=
174                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << 6;
175            if2_output_ptr[j++] |=
176                (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << 7;
177        }
178
179        bits_left = 4 + numOfBits[frame_type_3gpp] -
180                    ((4 + numOfBits[frame_type_3gpp]) & 0xFFF8);
181
182        if (bits_left != 0)
183        {
184            if2_output_ptr[j] = 0;
185
186            for (k = 0; k < bits_left; k++)
187            {
188                if2_output_ptr[j] |=
189                    (UWord8) ets_input_ptr[reorderBits[frame_type_3gpp][i++]] << k;
190            }
191        }
192    }
193    else
194    {
195        if (frame_type_3gpp != AMR_NO_DATA)
196        {
197            /* First octet contains 3GPP frame type and */
198            /* first 4 bits of encoded parameters       */
199            if2_output_ptr[j++] = (UWord8)(frame_type_3gpp) |
200                                  (ets_input_ptr[0] << 4) | (ets_input_ptr[1] << 5) |
201                                  (ets_input_ptr[2] << 6) | (ets_input_ptr[3] << 7);
202            ptr_temp = &ets_input_ptr[4];
203
204            bits_left = ((4 + numOfBits[frame_type_3gpp]) & 0xFFF8);
205
206            for (i = (bits_left - 7) >> 3; i > 0; i--)
207            {
208                accum  = (UWord8) * (ptr_temp++);
209                accum |= (UWord8) * (ptr_temp++) << 1;
210                accum |= (UWord8) * (ptr_temp++) << 2;
211                accum |= (UWord8) * (ptr_temp++) << 3;
212                accum |= (UWord8) * (ptr_temp++) << 4;
213                accum |= (UWord8) * (ptr_temp++) << 5;
214                accum |= (UWord8) * (ptr_temp++) << 6;
215                accum |= (UWord8) * (ptr_temp++) << 7;
216
217                if2_output_ptr[j++] = accum;
218            }
219
220            bits_left = 4 + numOfBits[frame_type_3gpp] - bits_left;
221
222            if (bits_left != 0)
223            {
224                if2_output_ptr[j] = 0;
225
226                for (i = 0; i < bits_left; i++)
227                {
228                    if2_output_ptr[j] |= (ptr_temp[i] << i);
229                }
230            }
231        }
232        else
233        {
234            /* When there is no data, LSnibble of first octet */
235            /* is the 3GPP frame type, MSnibble is zeroed out */
236            if2_output_ptr[j++] = (UWord8)(frame_type_3gpp);
237        }
238
239    }
240
241    return;
242}
243