001/* JOrbis
002 * Copyright (C) 2000 ymnk, JCraft,Inc.
003 *  
004 * Written by: 2000 ymnk<ymnk@jcaft.com>
005 *   
006 * Many thanks to 
007 *   Monty <monty@xiph.org> and 
008 *   The XIPHOPHORUS Company http://www.xiph.org/ .
009 * JOrbis has been based on their awesome works, Vorbis codec.
010 *   
011 * This program is free software; you can redistribute it and/or
012 * modify it under the terms of the GNU Library General Public License
013 * as published by the Free Software Foundation; either version 2 of
014 * the License, or (at your option) any later version.
015   
016 * This program is distributed in the hope that it will be useful,
017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
019 * GNU Library General Public License for more details.
020 * 
021 * You should have received a copy of the GNU Library General Public
022 * License along with this program; if not, write to the Free Software
023 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
024 */
025
026package com.jcraft.jorbis;
027
028import com.jcraft.jogg.*;
029
030public class Block{
031  ///necessary stream state for linking to the framing abstraction
032  float[][] pcm=new float[0][]; // this is a pointer into local storage
033  Buffer opb=new Buffer();
034  
035  int lW;
036  int W;
037  int nW;
038  int pcmend;
039  int mode;
040
041  int eofflag;
042  long granulepos;
043  long sequence;
044  DspState vd; // For read-only access of configuration
045
046  // local storage to avoid remallocing; it's up to the mapping to
047  // structure it
048//byte[] localstore;
049//int  localtop;
050//int  localalloc;
051//int  totaluse;
052//AllocChain reap;
053
054  // bitmetrics for the frame
055  int glue_bits;
056  int time_bits;
057  int floor_bits;
058  int res_bits;
059
060  public Block(DspState vd){
061    this.vd=vd;
062//  localalloc=0;
063//  localstore=null;
064    if(vd.analysisp!=0){
065      opb.writeinit();
066    }
067  }
068
069  public void init(DspState vd){
070    this.vd=vd;
071  }
072
073//  int alloc(int bytes){
074//    bytes=(bytes+(8-1))&(~(8-1));
075//    if(bytes+localtop>localalloc){
076//      if(localstore!=null){
077//      AllocChain link=new AllocChain();
078//      totaluse+=localtop;
079//      link.next=reap;
080//      link.ptr=localstore;
081//      reap=link;
082//      }
083//      // highly conservative
084//      localalloc=bytes;
085//      localstore=new byte[localalloc];
086//      localtop=0;
087//    }
088//    {
089//      int foo=localtop;
090//      //void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
091//      localtop+=bytes;
092//      return foo;
093//    }
094//  }
095
096  // reap the chain, pull the ripcord
097//  void ripcord(){
098//    // reap the chain
099//    while(reap!=null){
100//      AllocChain next=reap.next;
101//      //free(reap->ptr);
102//      reap.ptr=null;
103//      //memset(reap,0,sizeof(struct alloc_chain));
104//      //free(reap);
105//      reap=next;
106//    }
107//    // consolidate storage
108//    if(totaluse!=0){
109//      //vb->localstore=realloc(vb->localstore,vb->totaluse+vb->localalloc);
110//      byte[] foo=new byte[totaluse+localalloc];
111//      System.arraycopy(localstore, 0, foo, 0, localstore.length);
112//      localstore=foo;
113//      localalloc+=totaluse;
114//      totaluse=0;
115//    }
116//    // pull the ripcord
117//    localtop=0;
118//    reap=null;
119//  }
120
121  public int clear(){
122    if(vd!=null){
123      if(vd.analysisp!=0){
124        opb.writeclear();
125      }
126    }
127    //ripcord();
128    //if(localstore!=null)
129    //  localstore=null;
130    //memset(vb,0,sizeof(vorbis_block));
131    return(0);
132  }
133
134  public int synthesis(Packet op){
135    Info vi=vd.vi;
136 
137    // first things first.  Make sure decode is ready
138    // ripcord();
139    opb.readinit(op.packet_base, op.packet, op.bytes);
140
141    // Check the packet type
142    if(opb.read(1)!=0){
143      // Oops.  This is not an audio data packet
144      return(-1);
145    }
146
147    // read our mode and pre/post windowsize
148    int _mode=opb.read(vd.modebits);
149    if(_mode==-1)return(-1);
150  
151    mode=_mode;
152    W=vi.mode_param[mode].blockflag;
153    if(W!=0){
154      lW=opb.read(1);
155      nW=opb.read(1);
156      if(nW==-1) return(-1);
157    }
158    else{
159      lW=0;
160      nW=0;
161    }
162  
163    // more setup
164    granulepos=op.granulepos;
165    sequence=op.packetno-3; // first block is third packet
166    eofflag=op.e_o_s;
167
168    // alloc pcm passback storage
169    pcmend=vi.blocksizes[W];
170    //pcm=alloc(vi.channels);
171    if(pcm.length<vi.channels){
172      pcm=new float[vi.channels][];
173    }
174    for(int i=0;i<vi.channels;i++){
175      if(pcm[i]==null || pcm[i].length<pcmend){
176        pcm[i]=new float[pcmend];
177        //pcm[i]=alloc(pcmend);
178      }
179      else{
180        for(int j=0;j<pcmend;j++){ pcm[i][j]=0; }
181      }
182    }
183
184    // unpack_header enforces range checking
185    int type=vi.map_type[vi.mode_param[mode].mapping];
186    return(FuncMapping.mapping_P[type].inverse(this, vd.mode[mode]));
187  }
188}