1159b3361Sopenharmony_ci/*
2159b3361Sopenharmony_ci * layer1.c: Mpeg Layer-1 audio decoder
3159b3361Sopenharmony_ci *
4159b3361Sopenharmony_ci * Copyright (C) 1999-2010 The L.A.M.E. project
5159b3361Sopenharmony_ci *
6159b3361Sopenharmony_ci * Initially written by Michael Hipp, see also AUTHORS and README.
7159b3361Sopenharmony_ci *
8159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or
9159b3361Sopenharmony_ci * modify it under the terms of the GNU Library General Public
10159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either
11159b3361Sopenharmony_ci * version 2 of the License, or (at your option) any later version.
12159b3361Sopenharmony_ci *
13159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful,
14159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
16159b3361Sopenharmony_ci * Library General Public License for more details.
17159b3361Sopenharmony_ci *
18159b3361Sopenharmony_ci * You should have received a copy of the GNU Library General Public
19159b3361Sopenharmony_ci * License along with this library; if not, write to the
20159b3361Sopenharmony_ci * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21159b3361Sopenharmony_ci * Boston, MA 02111-1307, USA.
22159b3361Sopenharmony_ci */
23159b3361Sopenharmony_ci
24159b3361Sopenharmony_ci/* $Id$ */
25159b3361Sopenharmony_ci
26159b3361Sopenharmony_ci#ifdef HAVE_CONFIG_H
27159b3361Sopenharmony_ci# include <config.h>
28159b3361Sopenharmony_ci#endif
29159b3361Sopenharmony_ci
30159b3361Sopenharmony_ci#include <assert.h>
31159b3361Sopenharmony_ci#include "common.h"
32159b3361Sopenharmony_ci#include "decode_i386.h"
33159b3361Sopenharmony_ci
34159b3361Sopenharmony_ci#ifdef WITH_DMALLOC
35159b3361Sopenharmony_ci#include <dmalloc.h>
36159b3361Sopenharmony_ci#endif
37159b3361Sopenharmony_ci
38159b3361Sopenharmony_ci#include "layer1.h"
39159b3361Sopenharmony_ci
40159b3361Sopenharmony_cistatic int gd_are_hip_tables_layer1_initialized = 0;
41159b3361Sopenharmony_ci
42159b3361Sopenharmony_civoid
43159b3361Sopenharmony_cihip_init_tables_layer1(void)
44159b3361Sopenharmony_ci{
45159b3361Sopenharmony_ci    if (gd_are_hip_tables_layer1_initialized) {
46159b3361Sopenharmony_ci        return;
47159b3361Sopenharmony_ci    }
48159b3361Sopenharmony_ci    gd_are_hip_tables_layer1_initialized = 1;
49159b3361Sopenharmony_ci}
50159b3361Sopenharmony_ci
51159b3361Sopenharmony_citypedef struct sideinfo_layer_I_struct
52159b3361Sopenharmony_ci{
53159b3361Sopenharmony_ci    unsigned char allocation[SBLIMIT][2];
54159b3361Sopenharmony_ci    unsigned char scalefactor[SBLIMIT][2];
55159b3361Sopenharmony_ci} sideinfo_layer_I;
56159b3361Sopenharmony_ci
57159b3361Sopenharmony_cistatic int
58159b3361Sopenharmony_ciI_step_one(PMPSTR mp, sideinfo_layer_I* si)
59159b3361Sopenharmony_ci{
60159b3361Sopenharmony_ci    struct frame *fr = &(mp->fr);
61159b3361Sopenharmony_ci    int     jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext << 2) + 4 : 32;
62159b3361Sopenharmony_ci    int     i;
63159b3361Sopenharmony_ci    int     illegal_value_detected = 0;
64159b3361Sopenharmony_ci    unsigned char const ba15 = 15; /* bit pattern not allowed, looks like sync(?) */
65159b3361Sopenharmony_ci    memset(si, 0, sizeof(*si));
66159b3361Sopenharmony_ci    assert(fr->stereo == 1 || fr->stereo == 2);
67159b3361Sopenharmony_ci
68159b3361Sopenharmony_ci    if (fr->stereo == 2) {
69159b3361Sopenharmony_ci        for (i = 0; i < jsbound; i++) {
70159b3361Sopenharmony_ci            unsigned char b0 = get_leq_8_bits(mp, 4);       /* values 0-15 */
71159b3361Sopenharmony_ci            unsigned char b1 = get_leq_8_bits(mp, 4);       /* values 0-15 */
72159b3361Sopenharmony_ci            si->allocation[i][0] = b0;
73159b3361Sopenharmony_ci            si->allocation[i][1] = b1;
74159b3361Sopenharmony_ci            if (b0 == ba15 || b1 == ba15)
75159b3361Sopenharmony_ci                illegal_value_detected = 1;
76159b3361Sopenharmony_ci        }
77159b3361Sopenharmony_ci        for (i = jsbound; i < SBLIMIT; i++) {
78159b3361Sopenharmony_ci            unsigned char b = get_leq_8_bits(mp, 4);        /* values 0-15 */
79159b3361Sopenharmony_ci            si->allocation[i][0] = b;
80159b3361Sopenharmony_ci            si->allocation[i][1] = b;
81159b3361Sopenharmony_ci            if (b == ba15)
82159b3361Sopenharmony_ci                illegal_value_detected =  1;
83159b3361Sopenharmony_ci        }
84159b3361Sopenharmony_ci        for (i = 0; i < SBLIMIT; i++) {
85159b3361Sopenharmony_ci            unsigned char n0 = si->allocation[i][0];
86159b3361Sopenharmony_ci            unsigned char n1 = si->allocation[i][1];
87159b3361Sopenharmony_ci            unsigned char b0 = n0 ? get_leq_8_bits(mp, 6) : 0;  /* values 0-63 */
88159b3361Sopenharmony_ci            unsigned char b1 = n1 ? get_leq_8_bits(mp, 6) : 0;  /* values 0-63 */
89159b3361Sopenharmony_ci            si->scalefactor[i][0] = b0;
90159b3361Sopenharmony_ci            si->scalefactor[i][1] = b1;
91159b3361Sopenharmony_ci        }
92159b3361Sopenharmony_ci    }
93159b3361Sopenharmony_ci    else {
94159b3361Sopenharmony_ci        for (i = 0; i < SBLIMIT; i++) {
95159b3361Sopenharmony_ci            unsigned char b0 =  get_leq_8_bits(mp, 4);          /* values 0-15 */
96159b3361Sopenharmony_ci            si->allocation[i][0] = b0;
97159b3361Sopenharmony_ci            if (b0 == ba15)
98159b3361Sopenharmony_ci                illegal_value_detected = 1;
99159b3361Sopenharmony_ci        }
100159b3361Sopenharmony_ci        for (i = 0; i < SBLIMIT; i++) {
101159b3361Sopenharmony_ci            unsigned char n0 = si->allocation[i][0];
102159b3361Sopenharmony_ci            unsigned char b0 = n0 ? get_leq_8_bits(mp, 6) : 0;  /* values 0-63 */
103159b3361Sopenharmony_ci            si->scalefactor[i][0] = b0;
104159b3361Sopenharmony_ci        }
105159b3361Sopenharmony_ci    }
106159b3361Sopenharmony_ci    return illegal_value_detected;
107159b3361Sopenharmony_ci}
108159b3361Sopenharmony_ci
109159b3361Sopenharmony_cistatic void
110159b3361Sopenharmony_ciI_step_two(PMPSTR mp, sideinfo_layer_I *si, real fraction[2][SBLIMIT])
111159b3361Sopenharmony_ci{
112159b3361Sopenharmony_ci    double  r0, r1;
113159b3361Sopenharmony_ci    struct frame *fr = &(mp->fr);
114159b3361Sopenharmony_ci    int     ds_limit = fr->down_sample_sblimit;
115159b3361Sopenharmony_ci    int     i;
116159b3361Sopenharmony_ci
117159b3361Sopenharmony_ci    assert(fr->stereo == 1 || fr->stereo == 2);
118159b3361Sopenharmony_ci    if (fr->stereo == 2) {
119159b3361Sopenharmony_ci        int     jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext << 2) + 4 : 32;
120159b3361Sopenharmony_ci        for (i = 0; i < jsbound; i++) {
121159b3361Sopenharmony_ci            unsigned char i0 = si->scalefactor[i][0];
122159b3361Sopenharmony_ci            unsigned char i1 = si->scalefactor[i][1];
123159b3361Sopenharmony_ci            unsigned char n0 = si->allocation[i][0];
124159b3361Sopenharmony_ci            unsigned char n1 = si->allocation[i][1];
125159b3361Sopenharmony_ci            assert( i0 < 64 );
126159b3361Sopenharmony_ci            assert( i1 < 64 );
127159b3361Sopenharmony_ci            assert( n0 < 16 );
128159b3361Sopenharmony_ci            assert( n1 < 16 );
129159b3361Sopenharmony_ci            if (n0 > 0) {
130159b3361Sopenharmony_ci                unsigned short v = get_leq_16_bits(mp, n0 + 1); /* 0-65535 */
131159b3361Sopenharmony_ci                r0 = (((-1) << n0) + v + 1) * muls[n0 + 1][i0];
132159b3361Sopenharmony_ci            }
133159b3361Sopenharmony_ci            else {
134159b3361Sopenharmony_ci                r0 = 0;
135159b3361Sopenharmony_ci            }
136159b3361Sopenharmony_ci            if (n1 > 0) {
137159b3361Sopenharmony_ci                unsigned short v = get_leq_16_bits(mp, n1 + 1); /* 0-65535 */
138159b3361Sopenharmony_ci                r1 = (((-1) << n1) + v + 1) * muls[n1 + 1][i1];
139159b3361Sopenharmony_ci            }
140159b3361Sopenharmony_ci            else {
141159b3361Sopenharmony_ci                r1 = 0;
142159b3361Sopenharmony_ci            }
143159b3361Sopenharmony_ci            fraction[0][i] = (real)r0;
144159b3361Sopenharmony_ci            fraction[1][i] = (real)r1;
145159b3361Sopenharmony_ci        }
146159b3361Sopenharmony_ci        for (i = jsbound; i < SBLIMIT; i++) {
147159b3361Sopenharmony_ci            unsigned char i0 = si->scalefactor[i][0];
148159b3361Sopenharmony_ci            unsigned char i1 = si->scalefactor[i][1];
149159b3361Sopenharmony_ci            unsigned char n = si->allocation[i][0];
150159b3361Sopenharmony_ci            assert( i0 < 64 );
151159b3361Sopenharmony_ci            assert( i1 < 64 );
152159b3361Sopenharmony_ci            assert( n < 16 );
153159b3361Sopenharmony_ci            if (n > 0) {
154159b3361Sopenharmony_ci                unsigned short v = get_leq_16_bits(mp, n + 1); /* 0-65535 */
155159b3361Sopenharmony_ci                unsigned int w = (((-1) << n) + v + 1);
156159b3361Sopenharmony_ci                r0 = w * muls[n + 1][i0];
157159b3361Sopenharmony_ci                r1 = w * muls[n + 1][i1];
158159b3361Sopenharmony_ci            }
159159b3361Sopenharmony_ci            else {
160159b3361Sopenharmony_ci                r0 = r1 = 0;
161159b3361Sopenharmony_ci            }
162159b3361Sopenharmony_ci            fraction[0][i] = (real)r0;
163159b3361Sopenharmony_ci            fraction[1][i] = (real)r1;
164159b3361Sopenharmony_ci        }
165159b3361Sopenharmony_ci        for (i = ds_limit; i < SBLIMIT; i++) {
166159b3361Sopenharmony_ci            fraction[0][i] = 0.0;
167159b3361Sopenharmony_ci            fraction[1][i] = 0.0;
168159b3361Sopenharmony_ci        }
169159b3361Sopenharmony_ci    }
170159b3361Sopenharmony_ci    else {
171159b3361Sopenharmony_ci        for (i = 0; i < SBLIMIT; i++) {
172159b3361Sopenharmony_ci            unsigned char n = si->allocation[i][0];
173159b3361Sopenharmony_ci            unsigned char j = si->scalefactor[i][0];
174159b3361Sopenharmony_ci            assert( j < 64 );
175159b3361Sopenharmony_ci            assert( n < 16 );
176159b3361Sopenharmony_ci            if (n > 0) {
177159b3361Sopenharmony_ci                unsigned short v = get_leq_16_bits(mp, n + 1);
178159b3361Sopenharmony_ci                r0 = (((-1) << n) + v + 1) * muls[n + 1][j];
179159b3361Sopenharmony_ci            }
180159b3361Sopenharmony_ci            else {
181159b3361Sopenharmony_ci                r0 = 0;
182159b3361Sopenharmony_ci            }
183159b3361Sopenharmony_ci            fraction[0][i] = (real)r0;
184159b3361Sopenharmony_ci        }
185159b3361Sopenharmony_ci        for (i = ds_limit; i < SBLIMIT; i++) {
186159b3361Sopenharmony_ci            fraction[0][i] = 0.0;
187159b3361Sopenharmony_ci        }
188159b3361Sopenharmony_ci    }
189159b3361Sopenharmony_ci}
190159b3361Sopenharmony_ci
191159b3361Sopenharmony_ciint
192159b3361Sopenharmony_cidecode_layer1_sideinfo(PMPSTR mp)
193159b3361Sopenharmony_ci{
194159b3361Sopenharmony_ci    (void) mp;
195159b3361Sopenharmony_ci    /* FIXME: extract side information and check values */
196159b3361Sopenharmony_ci    return 0;
197159b3361Sopenharmony_ci}
198159b3361Sopenharmony_ci
199159b3361Sopenharmony_ciint
200159b3361Sopenharmony_cidecode_layer1_frame(PMPSTR mp, unsigned char *pcm_sample, int *pcm_point)
201159b3361Sopenharmony_ci{
202159b3361Sopenharmony_ci    real    fraction[2][SBLIMIT]; /* FIXME: change real -> double ? */
203159b3361Sopenharmony_ci    sideinfo_layer_I si;
204159b3361Sopenharmony_ci    struct frame *fr = &(mp->fr);
205159b3361Sopenharmony_ci    int     single = fr->single;
206159b3361Sopenharmony_ci    int     i, clip = 0;
207159b3361Sopenharmony_ci
208159b3361Sopenharmony_ci    if (I_step_one(mp, &si)) {
209159b3361Sopenharmony_ci        lame_report_fnc(mp->report_err, "hip: Aborting layer 1 decode, illegal bit allocation value\n");
210159b3361Sopenharmony_ci        return -1;
211159b3361Sopenharmony_ci    }
212159b3361Sopenharmony_ci    if (fr->stereo == 1 || single == 3)
213159b3361Sopenharmony_ci        single = 0;
214159b3361Sopenharmony_ci
215159b3361Sopenharmony_ci    if (single >= 0) {
216159b3361Sopenharmony_ci        /* decoding one of possibly two channels */
217159b3361Sopenharmony_ci        for (i = 0; i < SCALE_BLOCK; i++) {
218159b3361Sopenharmony_ci            I_step_two(mp, &si, fraction);
219159b3361Sopenharmony_ci            clip += synth_1to1_mono(mp, (real *) fraction[single], pcm_sample, pcm_point);
220159b3361Sopenharmony_ci        }
221159b3361Sopenharmony_ci    }
222159b3361Sopenharmony_ci    else {
223159b3361Sopenharmony_ci        for (i = 0; i < SCALE_BLOCK; i++) {
224159b3361Sopenharmony_ci            int     p1 = *pcm_point;
225159b3361Sopenharmony_ci            I_step_two(mp, &si, fraction);
226159b3361Sopenharmony_ci            clip += synth_1to1(mp, (real *) fraction[0], 0, pcm_sample, &p1);
227159b3361Sopenharmony_ci            clip += synth_1to1(mp, (real *) fraction[1], 1, pcm_sample, pcm_point);
228159b3361Sopenharmony_ci        }
229159b3361Sopenharmony_ci    }
230159b3361Sopenharmony_ci
231159b3361Sopenharmony_ci    return clip;
232159b3361Sopenharmony_ci}
233