private int decodeChannelSfIdx(int chNum){
  Channel chan=ctx.channels[chNum];
  Channel refChan=ctx.channels[0];
  int weightIdx=0;
  chan.fillMode=0;
switch (br.read(2)) {
case 0:
    for (int i=0; i < ctx.usedQuantUnits; i++) {
      chan.quSfIdx[i]=br.read(6);
    }
  break;
case 1:
if (chNum > 0) {
  VLC vlcTab=sf_vlc_tabs[br.read(2)];
  for (int i=0; i < ctx.usedQuantUnits; i++) {
    int delta=vlcTab.getVLC2(br);
    chan.quSfIdx[i]=(refChan.quSfIdx[i] + delta) & 0x3F;
  }
}
 else {
  weightIdx=br.read(2);
  if (weightIdx == 3) {
    unpackSfVqShape(chan.quSfIdx,ctx.usedQuantUnits);
    int numLongVals=br.read(5);
    int deltaBits=br.read(2);
    int minVal=br.read(4) - 7;
    for (int i=0; i < numLongVals; i++) {
      chan.quSfIdx[i]=(chan.quSfIdx[i] + br.read(4) - 7) & 0x3F;
    }
    for (int i=numLongVals; i < ctx.usedQuantUnits; i++) {
      chan.quSfIdx[i]=(chan.quSfIdx[i] + minVal + getDelta(deltaBits)) & 0x3F;
    }
  }
 else {
    int numLongVals=br.read(5);
    int deltaBits=br.read(3);
    int minVal=br.read(6);
    if (numLongVals > ctx.usedQuantUnits || deltaBits == 7) {
      log.error(String.format("SF mode 1: invalid parameters"));
      return AT3P_ERROR;
    }
    for (int i=0; i < numLongVals; i++) {
      chan.quSfIdx[i]=br.read(6);
    }
    for (int i=numLongVals; i < ctx.usedQuantUnits; i++) {
      chan.quSfIdx[i]=(minVal + getDelta(deltaBits)) & 0x3F;
    }
  }
}
break;
case 2:
if (chNum > 0) {
VLC vlcTab=sf_vlc_tabs[br.read(2)];
int delta=vlcTab.getVLC2(br);
chan.quSfIdx[0]=(refChan.quSfIdx[0] + delta) & 0x3F;
for (int i=1; i < ctx.usedQuantUnits; i++) {
int diff=refChan.quSfIdx[i] - refChan.quSfIdx[i - 1];
delta=vlcTab.getVLC2(br);
chan.quSfIdx[i]=(chan.quSfIdx[i - 1] + diff + delta) & 0x3F;
}
}
 else if (chan.numCodedVals > 0) {
VLC vlcTab=sf_vlc_tabs[br.read(2) + 4];
unpackSfVqShape(chan.quSfIdx,ctx.usedQuantUnits);
for (int i=0; i < ctx.usedQuantUnits; i++) {
int delta=vlcTab.getVLC2(br);
chan.quSfIdx[i]=(chan.quSfIdx[i] + signExtend(delta,4)) & 0x3F;
}
}
break;
case 3:
if (chNum > 0) {
for (int i=0; i < ctx.usedQuantUnits; i++) {
chan.quSfIdx[i]=refChan.quSfIdx[i];
}
}
 else {
weightIdx=br.read(2);
int vlcSel=br.read(2);
VLC vlcTab=sf_vlc_tabs[vlcSel];
if (weightIdx == 3) {
vlcTab=sf_vlc_tabs[vlcSel + 4];
unpackSfVqShape(chan.quSfIdx,ctx.usedQuantUnits);
int diff=(br.read(4) + 56) & 0x3F;
chan.quSfIdx[0]=(chan.quSfIdx[0] + diff) & 0x3F;
for (int i=1; i < ctx.usedQuantUnits; i++) {
int delta=vlcTab.getVLC2(br);
diff=(diff + signExtend(delta,4)) & 0x3F;
chan.quSfIdx[i]=(diff + chan.quSfIdx[i]) & 0x3F;
}
}
 else {
chan.quSfIdx[0]=br.read(6);
for (int i=1; i < ctx.usedQuantUnits; i++) {
int delta=vlcTab.getVLC2(br);
chan.quSfIdx[i]=(chan.quSfIdx[i - 1] + delta) & 0x3F;
}
}
}
break;
}
if (weightIdx != 0 && weightIdx < 3) {
return substractSfWeights(chan,weightIdx);
}
return 0;
}

private int decodeChannelSfIdx ( int chNum ) { Channel chan = ctx . channels [ chNum ] ; Channel refChan = ctx . channels [ 0 ] ; int weightIdx = 0 ; chan . fillMode = 0 ; switch ( br . read ( 2 ) ) { case 0 : for ( int i = 0 ; i < ctx . usedQuantUnits ; i ++ ) { chan . quSfIdx [ i ] = br . read ( 6 ) ; } break ; case 1 : if ( chNum > 0 ) { VLC vlcTab = sf_vlc_tabs [ br . read ( 2 ) ] ; for ( int i = 0 ; i < ctx . usedQuantUnits ; i ++ ) { int delta = vlcTab . getVLC2 ( br ) ; chan . quSfIdx [ i ] = ( refChan . quSfIdx [ i ] + delta ) & 0x3F ; } } else { weightIdx = br . read ( 2 ) ; if ( weightIdx == 3 ) { unpackSfVqShape ( chan . quSfIdx , ctx . usedQuantUnits ) ; int numLongVals = br . read ( 5 ) ; int deltaBits = br . read ( 2 ) ; int minVal = br . read ( 4 ) - 7 ; for ( int i = 0 ; i < numLongVals ; i ++ ) { chan . quSfIdx [ i ] = ( chan . quSfIdx [ i ] + br . read ( 4 ) - 7 ) & 0x3F ; } for ( int i = numLongVals ; i < ctx . usedQuantUnits ; i ++ ) { chan . quSfIdx [ i ] = ( chan . quSfIdx [ i ] + minVal + getDelta ( deltaBits ) ) & 0x3F ; } } else { int numLongVals = br . read ( 5 ) ; int deltaBits = br . read ( 3 ) ; int minVal = br . read ( 6 ) ; if ( numLongVals > ctx . usedQuantUnits || deltaBits == 7 ) { log . error ( String . format ( "SF mode 1: invalid parameters" ) ) ; return AT3P_ERROR ; } for ( int i = 0 ; i < numLongVals ; i ++ ) { chan . quSfIdx [ i ] = br . read ( 6 ) ; } for ( int i = numLongVals ; i < ctx . usedQuantUnits ; i ++ ) { chan . quSfIdx [ i ] = ( minVal + getDelta ( deltaBits ) ) & 0x3F ; } } } break ; case 2 : if ( chNum > 0 ) { VLC vlcTab = sf_vlc_tabs [ br . read ( 2 ) ] ; int delta = vlcTab . getVLC2 ( br ) ; chan . quSfIdx [ 0 ] = ( refChan . quSfIdx [ 0 ] + delta ) & 0x3F ; for ( int i = 1 ; i < ctx . usedQuantUnits ; i ++ ) { int diff = refChan . quSfIdx [ i ] - refChan . quSfIdx [ i - 1 ] ; delta = vlcTab . getVLC2 ( br ) ; chan . quSfIdx [ i ] = ( chan . quSfIdx [ i - 1 ] + diff + delta ) & 0x3F ; } } else if ( chan . numCodedVals > 0 ) { VLC vlcTab = sf_vlc_tabs [ br . read ( 2 ) + 4 ] ; unpackSfVqShape ( chan . quSfIdx , ctx . usedQuantUnits ) ; for ( int i = 0 ; i < ctx . usedQuantUnits ; i ++ ) { int delta = vlcTab . getVLC2 ( br ) ; chan . quSfIdx [ i ] = ( chan . quSfIdx [ i ] + signExtend ( delta , 4 ) ) & 0x3F ; } } break ; case 3 : if ( chNum > 0 ) { for ( int i = 0 ; i < ctx . usedQuantUnits ; i ++ ) { chan . quSfIdx [ i ] = refChan . quSfIdx [ i ] ; } } else { weightIdx = br . read ( 2 ) ; int vlcSel = br . read ( 2 ) ; VLC vlcTab = sf_vlc_tabs [ vlcSel ] ; if ( weightIdx == 3 ) { vlcTab = sf_vlc_tabs [ vlcSel + 4 ] ; unpackSfVqShape ( chan . quSfIdx , ctx . usedQuantUnits ) ; int diff = ( br . read ( 4 ) + 56 ) & 0x3F ; chan . quSfIdx [ 0 ] = ( chan . quSfIdx [ 0 ] + diff ) & 0x3F ; for ( int i = 1 ; i < ctx . usedQuantUnits ; i ++ ) { int delta = vlcTab . getVLC2 ( br ) ; diff = ( diff + signExtend ( delta , 4 ) ) & 0x3F ; chan . quSfIdx [ i ] = ( diff + chan . quSfIdx [ i ] ) & 0x3F ; } } else { chan . quSfIdx [ 0 ] = br . read ( 6 ) ; for ( int i = 1 ; i < ctx . usedQuantUnits ; i ++ ) { int delta = vlcTab . getVLC2 ( br ) ; chan . quSfIdx [ i ] = ( chan . quSfIdx [ i - 1 ] + delta ) & 0x3F ; } } } break ; } if ( weightIdx != 0 && weightIdx < 3 ) { return substractSfWeights ( chan , weightIdx ) ; } return 0 ; }
decode scale factor indexes for each quant unit of a channel .
