Blame mpglib/layer1.c

Packit 47f805
/* 
Packit 47f805
 * layer1.c: Mpeg Layer-1 audio decoder 
Packit 47f805
 *
Packit 47f805
 * Copyright (C) 1999-2010 The L.A.M.E. project
Packit 47f805
 *
Packit 47f805
 * Initially written by Michael Hipp, see also AUTHORS and README.
Packit 47f805
 *  
Packit 47f805
 * This library is free software; you can redistribute it and/or
Packit 47f805
 * modify it under the terms of the GNU Library General Public
Packit 47f805
 * License as published by the Free Software Foundation; either
Packit 47f805
 * version 2 of the License, or (at your option) any later version.
Packit 47f805
 *
Packit 47f805
 * This library is distributed in the hope that it will be useful,
Packit 47f805
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 47f805
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit 47f805
 * Library General Public License for more details.
Packit 47f805
 *
Packit 47f805
 * You should have received a copy of the GNU Library General Public
Packit 47f805
 * License along with this library; if not, write to the
Packit 47f805
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 47f805
 * Boston, MA 02111-1307, USA.
Packit 47f805
 */
Packit 47f805
Packit 47f805
/* $Id: layer1.c,v 1.31 2017/08/23 13:22:23 robert Exp $ */
Packit 47f805
Packit 47f805
#ifdef HAVE_CONFIG_H
Packit 47f805
# include <config.h>
Packit 47f805
#endif
Packit 47f805
Packit 47f805
#include <assert.h>
Packit 47f805
#include "common.h"
Packit 47f805
#include "decode_i386.h"
Packit 47f805
Packit 47f805
#ifdef WITH_DMALLOC
Packit 47f805
#include <dmalloc.h>
Packit 47f805
#endif
Packit 47f805
Packit 47f805
#include "layer1.h"
Packit 47f805
Packit 47f805
static int gd_are_hip_tables_layer1_initialized = 0;
Packit 47f805
Packit 47f805
void
Packit 47f805
hip_init_tables_layer1(void)
Packit 47f805
{
Packit 47f805
    if (gd_are_hip_tables_layer1_initialized) {
Packit 47f805
        return;
Packit 47f805
    }
Packit 47f805
    gd_are_hip_tables_layer1_initialized = 1;
Packit 47f805
}
Packit 47f805
Packit 47f805
typedef struct sideinfo_layer_I_struct
Packit 47f805
{
Packit 47f805
    unsigned char allocation[SBLIMIT][2]; 
Packit 47f805
    unsigned char scalefactor[SBLIMIT][2];
Packit 47f805
} sideinfo_layer_I;
Packit 47f805
Packit 47f805
static int
Packit 47f805
I_step_one(PMPSTR mp, sideinfo_layer_I* si)
Packit 47f805
{
Packit 47f805
    struct frame *fr = &(mp->fr);
Packit 47f805
    int     jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext << 2) + 4 : 32;
Packit 47f805
    int     i;
Packit 47f805
    int     illegal_value_detected = 0;
Packit 47f805
    unsigned char const ba15 = 15; /* bit pattern not allowed, looks like sync(?) */
Packit 47f805
    memset(si, 0, sizeof(*si));
Packit 47f805
    assert(fr->stereo == 1 || fr->stereo == 2);
Packit 47f805
Packit 47f805
    if (fr->stereo == 2) {
Packit 47f805
        for (i = 0; i < jsbound; i++) {
Packit 47f805
            unsigned char b0 = get_leq_8_bits(mp, 4);       /* values 0-15 */
Packit 47f805
            unsigned char b1 = get_leq_8_bits(mp, 4);       /* values 0-15 */
Packit 47f805
            si->allocation[i][0] = b0;
Packit 47f805
            si->allocation[i][1] = b1;
Packit 47f805
            if (b0 == ba15 || b1 == ba15)
Packit 47f805
                illegal_value_detected = 1;
Packit 47f805
        }
Packit 47f805
        for (i = jsbound; i < SBLIMIT; i++) {
Packit 47f805
            unsigned char b = get_leq_8_bits(mp, 4);        /* values 0-15 */
Packit 47f805
            si->allocation[i][0] = b;
Packit 47f805
            si->allocation[i][1] = b;
Packit 47f805
            if (b == ba15)
Packit 47f805
                illegal_value_detected =  1;
Packit 47f805
        }
Packit 47f805
        for (i = 0; i < SBLIMIT; i++) {
Packit 47f805
            unsigned char n0 = si->allocation[i][0];
Packit 47f805
            unsigned char n1 = si->allocation[i][1];
Packit 47f805
            unsigned char b0 = n0 ? get_leq_8_bits(mp, 6) : 0;  /* values 0-63 */
Packit 47f805
            unsigned char b1 = n1 ? get_leq_8_bits(mp, 6) : 0;  /* values 0-63 */
Packit 47f805
            si->scalefactor[i][0] = b0;
Packit 47f805
            si->scalefactor[i][1] = b1;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        for (i = 0; i < SBLIMIT; i++) {
Packit 47f805
            unsigned char b0 =  get_leq_8_bits(mp, 4);          /* values 0-15 */
Packit 47f805
            si->allocation[i][0] = b0;
Packit 47f805
            if (b0 == ba15)
Packit 47f805
                illegal_value_detected = 1;
Packit 47f805
        }
Packit 47f805
        for (i = 0; i < SBLIMIT; i++) {
Packit 47f805
            unsigned char n0 = si->allocation[i][0];
Packit 47f805
            unsigned char b0 = n0 ? get_leq_8_bits(mp, 6) : 0;  /* values 0-63 */
Packit 47f805
            si->scalefactor[i][0] = b0;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    return illegal_value_detected;
Packit 47f805
}
Packit 47f805
Packit 47f805
static void
Packit 47f805
I_step_two(PMPSTR mp, sideinfo_layer_I *si, real fraction[2][SBLIMIT])
Packit 47f805
{
Packit 47f805
    double  r0, r1;
Packit 47f805
    struct frame *fr = &(mp->fr);
Packit 47f805
    int     ds_limit = fr->down_sample_sblimit;
Packit 47f805
    int     i;
Packit 47f805
Packit 47f805
    assert(fr->stereo == 1 || fr->stereo == 2);
Packit 47f805
    if (fr->stereo == 2) {
Packit 47f805
        int     jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext << 2) + 4 : 32;
Packit 47f805
        for (i = 0; i < jsbound; i++) {
Packit 47f805
            unsigned char i0 = si->scalefactor[i][0];
Packit 47f805
            unsigned char i1 = si->scalefactor[i][1];
Packit 47f805
            unsigned char n0 = si->allocation[i][0];
Packit 47f805
            unsigned char n1 = si->allocation[i][1];
Packit 47f805
            assert( i0 < 64 );
Packit 47f805
            assert( i1 < 64 );
Packit 47f805
            assert( n0 < 16 );
Packit 47f805
            assert( n1 < 16 );
Packit 47f805
            if (n0 > 0) {
Packit 47f805
                unsigned short v = get_leq_16_bits(mp, n0 + 1); /* 0-65535 */
Packit 47f805
                r0 = (((-1) << n0) + v + 1) * muls[n0 + 1][i0];
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                r0 = 0;
Packit 47f805
            }
Packit 47f805
            if (n1 > 0) {
Packit 47f805
                unsigned short v = get_leq_16_bits(mp, n1 + 1); /* 0-65535 */
Packit 47f805
                r1 = (((-1) << n1) + v + 1) * muls[n1 + 1][i1];
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                r1 = 0;
Packit 47f805
            }
Packit 47f805
            fraction[0][i] = (real)r0;
Packit 47f805
            fraction[1][i] = (real)r1;
Packit 47f805
        }
Packit 47f805
        for (i = jsbound; i < SBLIMIT; i++) {
Packit 47f805
            unsigned char i0 = si->scalefactor[i][0];
Packit 47f805
            unsigned char i1 = si->scalefactor[i][1];
Packit 47f805
            unsigned char n = si->allocation[i][0];
Packit 47f805
            assert( i0 < 64 );
Packit 47f805
            assert( i1 < 64 );
Packit 47f805
            assert( n < 16 );
Packit 47f805
            if (n > 0) {
Packit 47f805
                unsigned short v = get_leq_16_bits(mp, n + 1); /* 0-65535 */
Packit 47f805
                unsigned int w = (((-1) << n) + v + 1);
Packit 47f805
                r0 = w * muls[n + 1][i0];
Packit 47f805
                r1 = w * muls[n + 1][i1];
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                r0 = r1 = 0;
Packit 47f805
            }
Packit 47f805
            fraction[0][i] = (real)r0;
Packit 47f805
            fraction[1][i] = (real)r1;
Packit 47f805
        }
Packit 47f805
        for (i = ds_limit; i < SBLIMIT; i++) {
Packit 47f805
            fraction[0][i] = 0.0;
Packit 47f805
            fraction[1][i] = 0.0;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        for (i = 0; i < SBLIMIT; i++) {
Packit 47f805
            unsigned char n = si->allocation[i][0];
Packit 47f805
            unsigned char j = si->scalefactor[i][0];
Packit 47f805
            assert( j < 64 );
Packit 47f805
            assert( n < 16 );
Packit 47f805
            if (n > 0) {
Packit 47f805
                unsigned short v = get_leq_16_bits(mp, n + 1);
Packit 47f805
                r0 = (((-1) << n) + v + 1) * muls[n + 1][j];
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                r0 = 0;
Packit 47f805
            }
Packit 47f805
            fraction[0][i] = (real)r0;
Packit 47f805
        }
Packit 47f805
        for (i = ds_limit; i < SBLIMIT; i++) {
Packit 47f805
            fraction[0][i] = 0.0;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
int
Packit 47f805
decode_layer1_sideinfo(PMPSTR mp)
Packit 47f805
{
Packit 47f805
    (void) mp;
Packit 47f805
    /* FIXME: extract side information and check values */
Packit 47f805
    return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
int
Packit 47f805
decode_layer1_frame(PMPSTR mp, unsigned char *pcm_sample, int *pcm_point)
Packit 47f805
{
Packit 47f805
    real    fraction[2][SBLIMIT]; /* FIXME: change real -> double ? */
Packit 47f805
    sideinfo_layer_I si;
Packit 47f805
    struct frame *fr = &(mp->fr);
Packit 47f805
    int     single = fr->single;
Packit 47f805
    int     i, clip = 0;
Packit 47f805
Packit 47f805
    if (I_step_one(mp, &si)) {
Packit 47f805
        lame_report_fnc(mp->report_err, "hip: Aborting layer 1 decode, illegal bit allocation value\n");
Packit 47f805
        return -1;
Packit 47f805
    }
Packit 47f805
    if (fr->stereo == 1 || single == 3)
Packit 47f805
        single = 0;
Packit 47f805
Packit 47f805
    if (single >= 0) {
Packit 47f805
        /* decoding one of possibly two channels */
Packit 47f805
        for (i = 0; i < SCALE_BLOCK; i++) {
Packit 47f805
            I_step_two(mp, &si, fraction);
Packit 47f805
            clip += synth_1to1_mono(mp, (real *) fraction[single], pcm_sample, pcm_point);
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        for (i = 0; i < SCALE_BLOCK; i++) {
Packit 47f805
            int     p1 = *pcm_point;
Packit 47f805
            I_step_two(mp, &si, fraction);
Packit 47f805
            clip += synth_1to1(mp, (real *) fraction[0], 0, pcm_sample, &p1;;
Packit 47f805
            clip += synth_1to1(mp, (real *) fraction[1], 1, pcm_sample, pcm_point);
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
    return clip;
Packit 47f805
}