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 ------------------------------------------------------------------------------
20 
21    PacketVideo Corp.
22    MP3 Decoder Library
23 
24    Filename: pvmp3_alias_reduction.cpp
25 
26      Date: 09/21/2007
27 
28 ------------------------------------------------------------------------------
29  REVISION HISTORY
30 
31 
32  Description:
33 
34 ------------------------------------------------------------------------------
35  INPUT AND OUTPUT DEFINITIONS
36 
37 Input
38     int32 *input_buffer,          Ptr to fequency lines of current channel
39     struct gr_info_s *gr_info,    structure with granuke information for the
40                                   input
41     mp3Header *info               mp3 header information
42 
43 ------------------------------------------------------------------------------
44  FUNCTION DESCRIPTION
45 
46     Alias Reduction
47 
48 
49 
50     Alias reduction before processing by the IMDCT
51 
52                    Csi  +
53      >---------0---------0-------->
54                 \       / -
55              Cai \     /
56                   \   /
57                    \ /
58                     \
59                   /  \
60              Cai /    \
61                /       \  +
62      >--------0---------0---------->
63                   Csi  +
64 
65       Aliasing Butterfly
66       Alias reduction is not applied to short blocks
67 
68 ------------------------------------------------------------------------------
69  REQUIREMENTS
70 
71 
72 ------------------------------------------------------------------------------
73  REFERENCES
74 
75  [1] ISO MPEG Audio Subgroup Software Simulation Group (1996)
76      ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension
77 
78 ------------------------------------------------------------------------------
79  PSEUDO-CODE
80                 1                                ci
81   csi = ----------------           csi = ----------------
82         sqrt( 1 + (ci^2))                sqrt( 1 + (ci^2))
83 
84 
85   ci = -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037
86 
87  ------------------------------------------------------------------------------
88 */
89 
90 
91 /*----------------------------------------------------------------------------
92 ; INCLUDES
93 ----------------------------------------------------------------------------*/
94 
95 #include "pvmp3_alias_reduction.h"
96 #include "pv_mp3dec_fxd_op.h"
97 
98 
99 /*----------------------------------------------------------------------------
100 ; MACROS
101 ; Define module specific macros here
102 ----------------------------------------------------------------------------*/
103 
104 
105 /*----------------------------------------------------------------------------
106 ; DEFINES
107 ; Include all pre-processor statements here. Include conditional
108 ; compile variables also.
109 ----------------------------------------------------------------------------*/
110 #define NUM_BUTTERFLIES 8
111 
112 #define Q31_fmt(a)    (int32(double(0x7FFFFFFF)*a))
113 
114 /*----------------------------------------------------------------------------
115 ; LOCAL FUNCTION DEFINITIONS
116 ; Function Prototype declaration
117 ----------------------------------------------------------------------------*/
118 
119 /*----------------------------------------------------------------------------
120 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
121 ; Variable declaration - defined here and used outside this module
122 ----------------------------------------------------------------------------*/
123 const int32 c_signal [ NUM_BUTTERFLIES ] =
124 {
125 
126     Q31_fmt(0.85749292571254f), Q31_fmt(0.88174199731771f),
127     Q31_fmt(0.94962864910273f), Q31_fmt(0.98331459249179f),
128     Q31_fmt(0.99551781606759f), Q31_fmt(0.99916055817815f),
129     Q31_fmt(0.99989919524445f), Q31_fmt(0.99999315507028f)
130 
131 };
132 
133 
134 const int32 c_alias [ NUM_BUTTERFLIES ] =
135 {
136 
137     Q31_fmt(-0.51449575542753f), Q31_fmt(-0.47173196856497f),
138     Q31_fmt(-0.31337745420390f), Q31_fmt(-0.18191319961098f),
139     Q31_fmt(-0.09457419252642f), Q31_fmt(-0.04096558288530f),
140     Q31_fmt(-0.01419856857247f), Q31_fmt(-0.00369997467376f)
141 };
142 
143 /*----------------------------------------------------------------------------
144 ; EXTERNAL FUNCTION REFERENCES
145 ; Declare functions defined elsewhere and referenced in this module
146 ----------------------------------------------------------------------------*/
147 
148 /*----------------------------------------------------------------------------
149 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
150 ; Declare variables used in this module but defined elsewhere
151 ----------------------------------------------------------------------------*/
152 
153 /*----------------------------------------------------------------------------
154 ; FUNCTION CODE
155 ----------------------------------------------------------------------------*/
156 
pvmp3_alias_reduction(int32 * input_buffer,granuleInfo * gr_info,int32 * used_freq_lines,mp3Header * info)157 void pvmp3_alias_reduction(int32 *input_buffer,         /* Ptr to spec values of current channel */
158                            granuleInfo *gr_info,
159                            int32  *used_freq_lines,
160                            mp3Header *info)
161 {
162     int32 *ptr1;
163     int32 *ptr2;
164     int32 *ptr3;
165     int32 *ptr4;
166     const int32 *ptr_csi;
167     const int32 *ptr_csa;
168     int32  sblim;
169 
170     int32 i, j;
171 
172     *used_freq_lines = fxp_mul32_Q32(*used_freq_lines << 16, (int32)(0x7FFFFFFF / (float)18 - 1.0f)) >> 15;
173 
174 
175     if (gr_info->window_switching_flag &&  gr_info->block_type == 2)
176     {
177         if (gr_info->mixed_block_flag)
178         {
179             sblim = ((info->version_x == MPEG_2_5) && (info->sampling_frequency == 2)) ? 3 : 1;
180         }
181         else
182         {
183             return;  /* illegal parameter */
184         }
185     }
186     else
187     {
188         sblim = *used_freq_lines + 1;
189 
190         if (sblim > SUBBANDS_NUMBER - 1)
191         {
192             sblim = SUBBANDS_NUMBER - 1;  /* default */
193         }
194 
195     }
196 
197 
198     ptr3 = &input_buffer[17];
199     ptr4 = &input_buffer[18];
200     ptr_csi = c_signal;
201     ptr_csa = c_alias;
202 
203     /*   NUM_BUTTERFLIES (=8) butterflies between each pair of sub-bands*/
204 
205     for (i = NUM_BUTTERFLIES >> 1; i != 0; i--)
206     {
207         int32 csi1  = *ptr_csi++;
208         int32 csi2  = *ptr_csi++;
209         int32 csa1  = *ptr_csa++;
210         int32 csa2  = *ptr_csa++;
211 
212         ptr1 = ptr3;
213         ptr3 -= 2;
214         ptr2 = ptr4;
215         ptr4 += 2;
216 
217         /*
218          *  "sblim"  alias-reduction operations between each
219          *  pair of sub-bands
220          */
221 
222         for (j = sblim >> 1; j != 0; j--)
223         {
224             int32 y = *ptr2;
225             int32 x = *ptr1 << 1;
226             *ptr1--  = fxp_msb32_Q32(fxp_mul32_Q32(x, csi1), y << 1, csa1);
227             *ptr2++  = fxp_mac32_Q32(fxp_mul32_Q32(y << 1, csi1), x, csa1);
228             y = *ptr2;
229             x = *ptr1 << 1;
230             *ptr1    = fxp_msb32_Q32(fxp_mul32_Q32(x, csi2), y << 1, csa2);
231             *ptr2    = fxp_mac32_Q32(fxp_mul32_Q32(y << 1, csi2), x, csa2);
232             ptr1 += 19;
233             ptr2 += 17;
234             y = *ptr2;
235             x = *ptr1 << 1;
236             *ptr1--  = fxp_msb32_Q32(fxp_mul32_Q32(x, csi1), y << 1, csa1);
237             *ptr2++  = fxp_mac32_Q32(fxp_mul32_Q32(y << 1, csi1), x, csa1);
238             y = *ptr2;
239             x = *ptr1 << 1;
240             *ptr1    = fxp_msb32_Q32(fxp_mul32_Q32(x, csi2), y << 1, csa2);
241             *ptr2    = fxp_mac32_Q32(fxp_mul32_Q32(y << 1, csi2), x, csa2);
242             ptr1 += 19;
243             ptr2 += 17;
244 
245         }
246 
247         if (sblim & 1)
248         {
249             int32 x = *ptr1 << 1;
250             int32 y = *ptr2;
251             *ptr1--  = fxp_msb32_Q32(fxp_mul32_Q32(x, csi1), y << 1, csa1);
252             *ptr2++  = fxp_mac32_Q32(fxp_mul32_Q32(y << 1, csi1), x, csa1);
253 
254             x = *ptr1 << 1;
255             y = *ptr2;
256             *ptr1    = fxp_msb32_Q32(fxp_mul32_Q32(x, csi2), y << 1, csa2);
257             *ptr2    = fxp_mac32_Q32(fxp_mul32_Q32(y << 1, csi2), x, csa2);
258         }
259     }
260 
261 }
262