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