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
37Input
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----------------------------------------------------------------------------*/
123const 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
134const 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
157void 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