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