]> Joshua Wise's Git repositories - patchfork.git/blame - jorbis/src/com/jcraft/jorbis/DspState.java
initial import from pitchfork-0.5.5
[patchfork.git] / jorbis / src / com / jcraft / jorbis / DspState.java
CommitLineData
964dd0bc
JW
1/* JOrbis
2 * Copyright (C) 2000 ymnk, JCraft,Inc.
3 *
4 * Written by: 2000 ymnk<ymnk@jcraft.com>
5 *
6 * Many thanks to
7 * Monty <monty@xiph.org> and
8 * The XIPHOPHORUS Company http://www.xiph.org/ .
9 * JOrbis has been based on their awesome works, Vorbis codec.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public License
13 * as published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * You should have received a copy of the GNU Library General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26package com.jcraft.jorbis;
27
28public class DspState{
29 static final float M_PI=3.1415926539f;
30 static final int VI_TRANSFORMB=1;
31 static final int VI_WINDOWB=1;
32
33 int analysisp;
34 Info vi;
35 int modebits;
36
37 float[][] pcm;
38 //float[][] pcmret;
39 int pcm_storage;
40 int pcm_current;
41 int pcm_returned;
42
43 float[] multipliers;
44 int envelope_storage;
45 int envelope_current;
46
47 int eofflag;
48
49 int lW;
50 int W;
51 int nW;
52 int centerW;
53
54 long granulepos;
55 long sequence;
56
57 long glue_bits;
58 long time_bits;
59 long floor_bits;
60 long res_bits;
61
62 // local lookup storage
63//!! Envelope ve=new Envelope(); // envelope
64//float **window[2][2][2]; // block, leadin, leadout, type
65 float[][][][][] window; // block, leadin, leadout, type
66 //vorbis_look_transform **transform[2]; // block, type
67 Object[][] transform;
68 CodeBook[] fullbooks;
69 // backend lookups are tied to the mode, not the backend or naked mapping
70 Object[] mode;
71
72 // local storage, only used on the encoding side. This way the
73 // application does not need to worry about freeing some packets'
74 // memory and not others'; packet storage is always tracked.
75 // Cleared next call to a _dsp_ function
76 byte[] header;
77 byte[] header1;
78 byte[] header2;
79
80 public DspState(){
81 transform=new Object[2][];
82 window=new float[2][][][][];
83 window[0]=new float[2][][][];
84 window[0][0]=new float[2][][];
85 window[0][1]=new float[2][][];
86 window[0][0][0]=new float[2][];
87 window[0][0][1]=new float[2][];
88 window[0][1][0]=new float[2][];
89 window[0][1][1]=new float[2][];
90 window[1]=new float[2][][][];
91 window[1][0]=new float[2][][];
92 window[1][1]=new float[2][][];
93 window[1][0][0]=new float[2][];
94 window[1][0][1]=new float[2][];
95 window[1][1][0]=new float[2][];
96 window[1][1][1]=new float[2][];
97 }
98
99 private static int ilog2(int v){
100 int ret=0;
101 while(v>1){
102 ret++;
103 v>>>=1;
104 }
105 return(ret);
106 }
107
108 static float[] window(int type, int window, int left, int right){
109 float[] ret=new float[window];
110 switch(type){
111 case 0:
112 // The 'vorbis window' (window 0) is sin(sin(x)*sin(x)*2pi)
113 {
114 int leftbegin=window/4-left/2;
115 int rightbegin=window-window/4-right/2;
116
117 for(int i=0;i<left;i++){
118 float x=(float)((i+.5)/left*M_PI/2.);
119 x=(float)Math.sin(x);
120 x*=x;
121 x*=M_PI/2.;
122 x=(float)Math.sin(x);
123 ret[i+leftbegin]=x;
124 }
125
126 for(int i=leftbegin+left;i<rightbegin;i++){
127 ret[i]=1.f;
128 }
129
130 for(int i=0;i<right;i++){
131 float x=(float)((right-i-.5)/right*M_PI/2.);
132 x=(float)Math.sin(x);
133 x*=x;
134 x*=M_PI/2.;
135 x=(float)Math.sin(x);
136 ret[i+rightbegin]=x;
137 }
138 }
139 break;
140 default:
141 //free(ret);
142 return(null);
143 }
144 return(ret);
145 }
146
147 // Analysis side code, but directly related to blocking. Thus it's
148 // here and not in analysis.c (which is for analysis transforms only).
149 // The init is here because some of it is shared
150
151 int init(Info vi, boolean encp){
152//System.err.println("DspState.init: vi="+vi+", encp="+encp);
153 //memset(v,0,sizeof(vorbis_dsp_state));
154 this.vi=vi;
155 modebits=ilog2(vi.modes);
156
157 transform[0]=new Object[VI_TRANSFORMB];
158 transform[1]=new Object[VI_TRANSFORMB];
159
160 // MDCT is tranform 0
161
162 transform[0][0]=new Mdct();
163 transform[1][0]=new Mdct();
164 ((Mdct)transform[0][0]).init(vi.blocksizes[0]);
165 ((Mdct)transform[1][0]).init(vi.blocksizes[1]);
166
167 window[0][0][0]=new float[VI_WINDOWB][];
168 window[0][0][1]=window[0][0][0];
169 window[0][1][0]=window[0][0][0];
170 window[0][1][1]=window[0][0][0];
171 window[1][0][0]=new float[VI_WINDOWB][];
172 window[1][0][1]=new float[VI_WINDOWB][];
173 window[1][1][0]=new float[VI_WINDOWB][];
174 window[1][1][1]=new float[VI_WINDOWB][];
175
176 for(int i=0;i<VI_WINDOWB;i++){
177 window[0][0][0][i]=
178 window(i,vi.blocksizes[0],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
179 window[1][0][0][i]=
180 window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[0]/2);
181 window[1][0][1][i]=
182 window(i,vi.blocksizes[1],vi.blocksizes[0]/2,vi.blocksizes[1]/2);
183 window[1][1][0][i]=
184 window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[0]/2);
185 window[1][1][1][i]=
186 window(i,vi.blocksizes[1],vi.blocksizes[1]/2,vi.blocksizes[1]/2);
187 }
188
189// if(encp){ // encode/decode differ here
190// // finish the codebooks
191// fullbooks=new CodeBook[vi.books];
192// for(int i=0;i<vi.books;i++){
193// fullbooks[i]=new CodeBook();
194// fullbooks[i].init_encode(vi.book_param[i]);
195// }
196// analysisp=1;
197// }
198// else{
199 // finish the codebooks
200 fullbooks=new CodeBook[vi.books];
201 for(int i=0;i<vi.books;i++){
202 fullbooks[i]=new CodeBook();
203 fullbooks[i].init_decode(vi.book_param[i]);
204 }
205// }
206
207 // initialize the storage vectors to a decent size greater than the
208 // minimum
209
210 pcm_storage=8192; // we'll assume later that we have
211 // a minimum of twice the blocksize of
212 // accumulated samples in analysis
213 pcm=new float[vi.channels][];
214 //pcmret=new float[vi.channels][];
215 {
216 for(int i=0;i<vi.channels;i++){
217 pcm[i]=new float[pcm_storage];
218 }
219 }
220
221 // all 1 (large block) or 0 (small block)
222 // explicitly set for the sake of clarity
223 lW=0; // previous window size
224 W=0; // current window size
225
226 // all vector indexes; multiples of samples_per_envelope_step
227 centerW=vi.blocksizes[1]/2;
228
229 pcm_current=centerW;
230
231 // initialize all the mapping/backend lookups
232 mode=new Object[vi.modes];
233 for(int i=0;i<vi.modes;i++){
234 int mapnum=vi.mode_param[i].mapping;
235 int maptype=vi.map_type[mapnum];
236 mode[i]=FuncMapping.mapping_P[maptype].look(this,vi.mode_param[i],
237 vi.map_param[mapnum]);
238 }
239 return(0);
240 }
241
242 public int synthesis_init(Info vi){
243 init(vi, false);
244 // Adjust centerW to allow an easier mechanism for determining output
245 pcm_returned=centerW;
246 centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
247 granulepos=-1;
248 sequence=-1;
249 return(0);
250 }
251
252 DspState(Info vi){
253 this();
254 init(vi, false);
255 // Adjust centerW to allow an easier mechanism for determining output
256 pcm_returned=centerW;
257 centerW-= vi.blocksizes[W]/4+vi.blocksizes[lW]/4;
258 granulepos=-1;
259 sequence=-1;
260 }
261
262 // Unike in analysis, the window is only partially applied for each
263 // block. The time domain envelope is not yet handled at the point of
264 // calling (as it relies on the previous block).
265
266 public int synthesis_blockin(Block vb){
267 // Shift out any PCM/multipliers that we returned previously
268 // centerW is currently the center of the last block added
269 if(centerW>vi.blocksizes[1]/2 && pcm_returned>8192){
270 // don't shift too much; we need to have a minimum PCM buffer of
271 // 1/2 long block
272
273 int shiftPCM=centerW-vi.blocksizes[1]/2;
274 shiftPCM=(pcm_returned<shiftPCM?pcm_returned:shiftPCM);
275
276 pcm_current-=shiftPCM;
277 centerW-=shiftPCM;
278 pcm_returned-=shiftPCM;
279 if(shiftPCM!=0){
280 for(int i=0;i<vi.channels;i++){
281 System.arraycopy(pcm[i], shiftPCM, pcm[i], 0, pcm_current);
282 }
283 }
284 }
285
286 lW=W;
287 W=vb.W;
288 nW=-1;
289
290 glue_bits+=vb.glue_bits;
291 time_bits+=vb.time_bits;
292 floor_bits+=vb.floor_bits;
293 res_bits+=vb.res_bits;
294
295 if(sequence+1 != vb.sequence)granulepos=-1; // out of sequence; lose count
296
297 sequence=vb.sequence;
298
299 {
300 int sizeW=vi.blocksizes[W];
301 int _centerW=centerW+vi.blocksizes[lW]/4+sizeW/4;
302 int beginW=_centerW-sizeW/2;
303 int endW=beginW+sizeW;
304 int beginSl=0;
305 int endSl=0;
306
307 // Do we have enough PCM/mult storage for the block?
308 if(endW>pcm_storage){
309 // expand the storage
310 pcm_storage=endW+vi.blocksizes[1];
311 for(int i=0;i<vi.channels;i++){
312 float[] foo=new float[pcm_storage];
313 System.arraycopy(pcm[i], 0, foo, 0, pcm[i].length);
314 pcm[i]=foo;
315 }
316 }
317
318 // overlap/add PCM
319 switch(W){
320 case 0:
321 beginSl=0;
322 endSl=vi.blocksizes[0]/2;
323 break;
324 case 1:
325 beginSl=vi.blocksizes[1]/4-vi.blocksizes[lW]/4;
326 endSl=beginSl+vi.blocksizes[lW]/2;
327 break;
328 }
329
330 for(int j=0;j<vi.channels;j++){
331 int _pcm=beginW;
332 // the overlap/add section
333 int i=0;
334 for(i=beginSl;i<endSl;i++){
335 pcm[j][_pcm+i]+=vb.pcm[j][i];
336 }
337 // the remaining section
338 for(;i<sizeW;i++){
339 pcm[j][_pcm+i]=vb.pcm[j][i];
340 }
341 }
342
343 // track the frame number... This is for convenience, but also
344 // making sure our last packet doesn't end with added padding. If
345 // the last packet is partial, the number of samples we'll have to
346 // return will be past the vb->granulepos.
347 //
348 // This is not foolproof! It will be confused if we begin
349 // decoding at the last page after a seek or hole. In that case,
350 // we don't have a starting point to judge where the last frame
351 // is. For this reason, vorbisfile will always try to make sure
352 // it reads the last two marked pages in proper sequence
353
354 if(granulepos==-1){
355 granulepos=vb.granulepos;
356 }
357 else{
358 granulepos+=(_centerW-centerW);
359 if(vb.granulepos!=-1 && granulepos!=vb.granulepos){
360 if(granulepos>vb.granulepos && vb.eofflag!=0){
361 // partial last frame. Strip the padding off
362 _centerW-=(granulepos-vb.granulepos);
363 }// else{ Shouldn't happen *unless* the bitstream is out of
364 // spec. Either way, believe the bitstream }
365 granulepos=vb.granulepos;
366 }
367 }
368
369 // Update, cleanup
370
371 centerW=_centerW;
372 pcm_current=endW;
373 if(vb.eofflag!=0)eofflag=1;
374 }
375 return(0);
376 }
377
378 // pcm==NULL indicates we just want the pending samples, no more
379 public int synthesis_pcmout(float[][][] _pcm, int[] index){
380 if(pcm_returned<centerW){
381 if(_pcm!=null){
382 for(int i=0;i<vi.channels;i++){
383// pcmret[i]=pcm[i]+v.pcm_returned;
384//!!!!!!!!
385 index[i]=pcm_returned;
386 }
387 _pcm[0]=pcm;
388 }
389 return(centerW-pcm_returned);
390 }
391 return(0);
392 }
393
394 public int synthesis_read(int bytes){
395 if(bytes!=0 && pcm_returned+bytes>centerW)return(-1);
396 pcm_returned+=bytes;
397 return(0);
398 }
399
400 public void clear(){
401/*
402 if(window[0][0][0]!=0){
403 for(i=0;i<VI_WINDOWB;i++)
404 if(v->window[0][0][0][i])free(v->window[0][0][0][i]);
405 free(v->window[0][0][0]);
406
407 for(j=0;j<2;j++)
408 for(k=0;k<2;k++){
409 for(i=0;i<VI_WINDOWB;i++)
410 if(v->window[1][j][k][i])free(v->window[1][j][k][i]);
411 free(v->window[1][j][k]);
412 }
413 }
414
415 if(v->pcm){
416 for(i=0;i<vi->channels;i++)
417 if(v->pcm[i])free(v->pcm[i]);
418 free(v->pcm);
419 if(v->pcmret)free(v->pcmret);
420 }
421 if(v->multipliers)free(v->multipliers);
422
423 _ve_envelope_clear(&v->ve);
424 if(v->transform[0]){
425 mdct_clear(v->transform[0][0]);
426 free(v->transform[0][0]);
427 free(v->transform[0]);
428 }
429 if(v->transform[1]){
430 mdct_clear(v->transform[1][0]);
431 free(v->transform[1][0]);
432 free(v->transform[1]);
433 }
434
435 // free mode lookups; these are actually vorbis_look_mapping structs
436 if(vi){
437 for(i=0;i<vi->modes;i++){
438 int mapnum=vi->mode_param[i]->mapping;
439 int maptype=vi->map_type[mapnum];
440 _mapping_P[maptype]->free_look(v->mode[i]);
441 }
442 // free codebooks
443 for(i=0;i<vi->books;i++)
444 vorbis_book_clear(v->fullbooks+i);
445 }
446
447 if(v->mode)free(v->mode);
448 if(v->fullbooks)free(v->fullbooks);
449
450 // free header, header1, header2
451 if(v->header)free(v->header);
452 if(v->header1)free(v->header1);
453 if(v->header2)free(v->header2);
454
455 memset(v,0,sizeof(vorbis_dsp_state));
456 }
457*/
458}
459}
This page took 0.062115 seconds and 4 git commands to generate.