Git init
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / common / src / gmed_n.cpp
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  Filename: gmed_n.cpp
31
32 ------------------------------------------------------------------------------
33 */
34
35 /*----------------------------------------------------------------------------
36 ; INCLUDES
37 ----------------------------------------------------------------------------*/
38 #include    "gmed_n.h"
39 #include    "typedef.h"
40 #include    "oscl_mem.h"
41
42 /*----------------------------------------------------------------------------
43 ; MACROS
44 ; Define module specific macros here
45 ----------------------------------------------------------------------------*/
46
47
48 /*----------------------------------------------------------------------------
49 ; DEFINES
50 ; Include all pre-processor statements here. Include conditional
51 ; compile variables also.
52 ----------------------------------------------------------------------------*/
53 #define NMAX    9   /* largest N used in median calculation */
54
55 /*----------------------------------------------------------------------------
56 ; LOCAL FUNCTION DEFINITIONS
57 ; Function Prototype declaration
58 ----------------------------------------------------------------------------*/
59
60
61 /*----------------------------------------------------------------------------
62 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
63 ; Variable declaration - defined here and used outside this module
64 ----------------------------------------------------------------------------*/
65
66
67 /*
68 ------------------------------------------------------------------------------
69  FUNCTION NAME: gmed_n
70 ------------------------------------------------------------------------------
71  INPUT AND OUTPUT DEFINITIONS
72
73  Inputs:
74     ind = input values (Word16)
75     n = number of inputs to find the median (Word16)
76
77  Returns:
78     median value.
79
80  Outputs:
81     None.
82
83  Global Variables Used:
84     None.
85
86  Local Variables Needed:
87     None.
88
89 ------------------------------------------------------------------------------
90  FUNCTION DESCRIPTION
91
92  This function calculates N-point median of a data set. This routine is only
93  valid for a odd number of gains (n <= NMAX).
94
95 ------------------------------------------------------------------------------
96  REQUIREMENTS
97
98  None.
99
100 ------------------------------------------------------------------------------
101  REFERENCES
102
103  gmed_n.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
104
105 ------------------------------------------------------------------------------
106  PSEUDO-CODE
107
108 Word16 gmed_n (   // o : The median value (0...N-1)
109     Word16 ind[], // i : Past gain values
110     Word16 n      // i : The number of gains; this routine
111                   //     is only valid for a odd number of gains
112                   //     (n <= NMAX)
113 )
114 {
115     Word16 i, j, ix = 0;
116     Word16 max;
117     Word16 medianIndex;
118     Word16 tmp[NMAX];
119     Word16 tmp2[NMAX];
120
121     for (i = 0; i < n; i++)
122     {
123         tmp2[i] = ind[i];
124     }
125
126     for (i = 0; i < n; i++)
127     {
128         max = -32767;
129         for (j = 0; j < n; j++)
130         {
131             if (sub (tmp2[j], max) >= 0)
132             {
133                 max = tmp2[j];
134                 ix = j;
135             }
136         }
137         tmp2[ix] = -32768;
138         tmp[i] = ix;
139     }
140
141     medianIndex=tmp[ shr(n,1) ];  // account for complex addressing
142     return (ind[medianIndex]);
143 }
144
145 ------------------------------------------------------------------------------
146  CAUTION [optional]
147  [State any special notes, constraints or cautions for users of this function]
148
149 ------------------------------------------------------------------------------
150 */
151
152 OSCL_EXPORT_REF Word16 gmed_n(            /* o : the median value    */
153     Word16 ind[],   /* i : input values        */
154     Word16 n        /* i : number of inputs    */
155 )
156 {
157     register Word16 i, j, ix = 0;
158     register Word16 max;
159     register Word16 medianIndex;
160     Word16  tmp[NMAX];
161     Word16  tmp2[NMAX];
162
163     oscl_memmove(tmp2, ind, n*sizeof(*ind));
164
165     for (i = 0; i < n; i++)
166     {
167         max = -32767;
168         for (j = 0; j < n; j++)
169         {
170             if (*(tmp2 + j) >= max)
171             {
172                 max = *(tmp2 + j);
173                 ix = j;
174             }
175         }
176         *(tmp2 + ix) = -32768;
177         *(tmp + i) = ix;
178     }
179
180     medianIndex = *(tmp + (n >> 1));  /* account for complex addressing */
181
182     return (*(ind + medianIndex));
183 }
184