All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jcraft.jorbis.StaticCodeBook Maven / Gradle / Ivy

/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/* JOrbis
 * Copyright (C) 2000 ymnk, JCraft,Inc.
 *  
 * Written by: 2000 ymnk
 *   
 * Many thanks to 
 *   Monty  and 
 *   The XIPHOPHORUS Company http://www.xiph.org/ .
 * JOrbis has been based on their awesome works, Vorbis codec.
 *   
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public License
 * as published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
   
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package com.jcraft.jorbis;

import com.jcraft.jogg.Buffer;

class StaticCodeBook{
  int dim; // codebook dimensions (elements per vector)
  int entries; // codebook entries
  int[] lengthlist; // codeword lengths in bits

  // mapping
  int maptype; // 0=none
  // 1=implicitly populated values from map column 
  // 2=listed arbitrary values

  // The below does a linear, single monotonic sequence mapping.
  int q_min; // packed 32 bit float; quant value 0 maps to minval
  int q_delta; // packed 32 bit float; val 1 - val 0 == delta
  int q_quant; // bits: 0 < quant <= 16
  int q_sequencep; // bitflag

  // additional information for log (dB) mapping; the linear mapping
  // is assumed to actually be values in dB.  encodebias is used to
  // assign an error weight to 0 dB. We have two additional flags:
  // zeroflag indicates if entry zero is to represent -Inf dB; negflag
  // indicates if we're to represent negative linear values in a
  // mirror of the positive mapping.

  int[] quantlist; // map == 1: (int)(entries/dim) element column map
  // map == 2: list of dim*entries quantized entry vals

  StaticCodeBook(){
  }

  int pack(Buffer opb){
    int i;
    boolean ordered=false;

    opb.write(0x564342, 24);
    opb.write(dim, 16);
    opb.write(entries, 24);

    // pack the codewords.  There are two packings; length ordered and
    // length random.  Decide between the two now.

    for(i=1; i_last){
          for(int j=_last; j<_this; j++){
            opb.write(i-count, Util.ilog(entries-count));
            count=i;
          }
        }
      }
      opb.write(i-count, Util.ilog(entries-count));
    }
    else{
      // length random.  Again, we don't code the codeword itself, just
      // the length.  This time, though, we have to encode each length
      opb.write(0, 1); // unordered

      // algortihmic mapping has use for 'unused entries', which we tag
      // here.  The algorithmic mapping happens as usual, but the unused
      // entry has no codeword.
      for(i=0; ientries/c->dim) quantized values for
              // building a full value list algorithmically (square lattice)
              quantvals=maptype1_quantvals();
              break;
            case 2:
              // every value (c->entries*c->dim total) specified explicitly
              quantvals=entries*dim;
              break;
          }

          // quantized values
          for(i=0; ibim <= b->entries
    // treat the above as an initial guess
    while(true){
      int acc=1;
      int acc1=1;
      for(int i=0; ientries){
        return (vals);
      }
      else{
        if(acc>entries){
          vals--;
        }
        else{
          vals++;
        }
      }
    }
  }

  void clear(){
  }

  // unpack the quantized list of values for encode/decode
  // we need to deal with two map types: in map type 1, the values are
  // generated algorithmically (each column of the vector counts through
  // the values in the quant vector). in map type 2, all the values came
  // in in an explicit list.  Both value lists must be unpacked
  float[] unquantize(){

    if(maptype==1||maptype==2){
      int quantvals;
      float mindel=float32_unpack(q_min);
      float delta=float32_unpack(q_delta);
      float[] r=new float[entries*dim];

      // maptype 1 and 2 both use a quantized value vector, but
      // different sizes
      switch(maptype){
        case 1:
          // most of the time, entries%dimensions == 0, but we need to be
          // well defined.  We define that the possible vales at each
          // scalar is values == entries/dim.  If entries%dim != 0, we'll
          // have 'too few' values (values*dim "+val+" | ");}
              val=Math.abs(val)*delta+mindel+last;
              if(q_sequencep!=0)
                last=val;
              r[j*dim+k]=val;
              //if((j*dim+k)==0){System.err.println(" $ r[0] -> "+r[0]+" | ");}
            }
          }
          //System.err.println("\nr[0]="+r[0]);
      }
      return (r);
    }
    return (null);
  }

  // 32 bit float (not IEEE; nonnormalized mantissa +
  // biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm 
  // Why not IEEE?  It's just not that important here.

  static final int VQ_FEXP=10;
  static final int VQ_FMAN=21;
  static final int VQ_FEXP_BIAS=768; // bias toward values smaller than 1.

  // doesn't currently guard under/overflow 
  static long float32_pack(float val){
    int sign=0;
    int exp;
    int mant;
    if(val<0){
      sign=0x80000000;
      val=-val;
    }
    exp=(int)Math.floor(Math.log(val)/Math.log(2));
    mant=(int)Math.rint(Math.pow(val, (VQ_FMAN-1)-exp));
    exp=(exp+VQ_FEXP_BIAS)<>>VQ_FMAN;
    if((val&0x80000000)!=0)
      mant=-mant;
    return (ldexp(mant, ((int)exp)-(VQ_FMAN-1)-VQ_FEXP_BIAS));
  }

  static float ldexp(float foo, int e){
    return (float)(foo*Math.pow(2, e));
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy