diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-07-11 15:42:37 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-07-11 15:42:37 +0000 |
commit | 9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e (patch) | |
tree | 4c304cd4151020bd5494d279ee68a105ae3a5a3a /songdbj/com/jcraft/jorbis/DspState.java | |
parent | dfa8ecbe609ca8ea194d08560a44fb9a92e94b4b (diff) | |
download | rockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.tar.gz rockbox-9fee0ec4ca0c5b7a334cc29dbb58e76c7a4c736e.zip |
Songdb java version, source. only 1.5 compatible
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7101 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'songdbj/com/jcraft/jorbis/DspState.java')
-rw-r--r-- | songdbj/com/jcraft/jorbis/DspState.java | 459 |
1 files changed, 459 insertions, 0 deletions
diff --git a/songdbj/com/jcraft/jorbis/DspState.java b/songdbj/com/jcraft/jorbis/DspState.java new file mode 100644 index 0000000000..5676f640c1 --- /dev/null +++ b/songdbj/com/jcraft/jorbis/DspState.java | |||
@@ -0,0 +1,459 @@ | |||
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 | |||
26 | package com.jcraft.jorbis; | ||
27 | |||
28 | public 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 | } | ||