]> Joshua Wise's Git repositories - patchfork.git/blame - jorbis/src/com/jcraft/jorbis/Mapping0.java
initial import from pitchfork-0.5.5
[patchfork.git] / jorbis / src / com / jcraft / jorbis / Mapping0.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
28import com.jcraft.jogg.*;
29
30class Mapping0 extends FuncMapping{
31 static int seq=0;
32 void free_info(Object imap){};
33 void free_look(Object imap){
34/*
35 LookMapping0 l=(LookMapping0)imap;
36 InfoMapping0 info=l.map;
37 if(l!=null){
38 for(int i=0;i<l.map.submaps;i++){
39 l.time_func[i].free_look(l.time_look[i]);
40 l.floor_func[i].free_look(l.floor_look[i]);
41 l.residue_func[i].free_look(l.residue_look[i]);
42 if(l.psy_look!=null)l.psy_look[i].clear();
43 }
44 }
45
46 if(l.floor_state!=null){
47 for(int i=0;i<l.ch;i++)
48 l.floor_func[info.chmuxlist[i]].free_state(l.floor_state[i]);
49 //free(l.floor_state);
50 }
51
52 if(l.decay!=null){
53 for(int i=0;i<l.ch;i++){
54 //if(l.decay[i])free(l->decay[i]);
55 l.decay[i]=null;
56 }
57 //free(l->decay);
58 l.decay=null;
59 }
60 //free(l->time_func);
61 //free(l->floor_func);
62 //free(l->residue_func);
63 //free(l->time_look);
64 //free(l->floor_look);
65 //free(l->residue_look);
66 //f(l->psy_look)free(l->psy_look);
67 l.time_func=null;
68 l.floor_func=null;
69 l.residue_func=null;
70 l.time_look=null;
71 l.floor_look=null;
72 l.residue_look=null;
73 //memset(l,0,sizeof(vorbis_look_mapping0));
74 //free(l);
75*/
76 }
77
78 Object look(DspState vd, InfoMode vm, Object m){
79//System.err.println("Mapping0.look");
80 Info vi=vd.vi;
81 LookMapping0 look=new LookMapping0();
82 InfoMapping0 info=look.map=(InfoMapping0)m;
83 look.mode=vm;
84
85 look.time_look=new Object[info.submaps];
86 look.floor_look=new Object[info.submaps];
87 look.residue_look=new Object[info.submaps];
88
89/*
90 if(vd.analysisp!=0){
91 look.floor_state=new Object[vi.channels];
92 }
93 if(vi.psys!=0){
94 look.psy_look=new PsyLook[info.submaps];
95 for(int i=0; i<info.submaps; i++){ look.psy_look[i]=new PsyLook(); }
96 }
97*/
98
99 look.time_func=new FuncTime[info.submaps];
100 look.floor_func=new FuncFloor[info.submaps];
101 look.residue_func=new FuncResidue[info.submaps];
102
103 for(int i=0;i<info.submaps;i++){
104 int timenum=info.timesubmap[i];
105 int floornum=info.floorsubmap[i];
106 int resnum=info.residuesubmap[i];
107
108 look.time_func[i]=FuncTime.time_P[vi.time_type[timenum]];
109 look.time_look[i]=look.time_func[i].look(vd,vm,vi.time_param[timenum]);
110 look.floor_func[i]=FuncFloor.floor_P[vi.floor_type[floornum]];
111 look.floor_look[i]=look.floor_func[i].
112 look(vd,vm,vi.floor_param[floornum]);
113 look.residue_func[i]=FuncResidue.residue_P[vi.residue_type[resnum]];
114 look.residue_look[i]=look.residue_func[i].
115 look(vd,vm,vi.residue_param[resnum]);
116
117/*
118 if(vi.psys!=0 && vd.analysisp!=0){
119 int psynum=info.psysubmap[i];
120 look.psy_look[i].init(vi.psy_param[psynum],
121 vi.blocksizes[vm.blockflag]/2,vi.rate);
122 }
123*/
124 }
125
126 if(vi.psys!=0 && vd.analysisp!=0){
127 /*
128 if(info->psy[0] != info->psy[1]){
129
130 int psynum=info->psy[0];
131 look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy));
132 _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
133 ci->psy_g_param,
134 ci->blocksizes[vm->blockflag]/2,vi->rate);
135
136 psynum=info->psy[1];
137 look->psy_look[1]=_ogg_calloc(1,sizeof(vorbis_look_psy));
138 _vp_psy_init(look->psy_look[1],ci->psy_param[psynum],
139 ci->psy_g_param,
140 ci->blocksizes[vm->blockflag]/2,vi->rate);
141 }else{
142
143 int psynum=info->psy[0];
144 look->psy_look[0]=_ogg_calloc(1,sizeof(vorbis_look_psy));
145 look->psy_look[1]=look->psy_look[0];
146 _vp_psy_init(look->psy_look[0],ci->psy_param[psynum],
147 ci->psy_g_param,
148 ci->blocksizes[vm->blockflag]/2,vi->rate);
149
150 }
151 */
152 }
153
154 look.ch=vi.channels;
155// if(vd->analysisp)drft_init(&look->fft_look,ci->blocksizes[vm->blockflag]);
156
157 return(look);
158//return null;
159 }
160
161 void pack(Info vi, Object imap, Buffer opb){
162 InfoMapping0 info=(InfoMapping0)imap;
163
164 /* another 'we meant to do it this way' hack... up to beta 4, we
165 packed 4 binary zeros here to signify one submapping in use. We
166 now redefine that to mean four bitflags that indicate use of
167 deeper features; bit0:submappings, bit1:coupling,
168 bit2,3:reserved. This is backward compatable with all actual uses
169 of the beta code. */
170
171 if(info.submaps>1){
172 opb.write(1,1);
173 opb.write(info.submaps-1,4);
174 }
175 else{
176 opb.write(0,1);
177 }
178
179 if(info.coupling_steps>0){
180 opb.write(1,1);
181 opb.write(info.coupling_steps-1,8);
182 for(int i=0;i<info.coupling_steps;i++){
183 opb.write(info.coupling_mag[i],ilog2(vi.channels));
184 opb.write(info.coupling_ang[i],ilog2(vi.channels));
185 }
186 }
187 else{
188 opb.write(0,1);
189 }
190
191 opb.write(0,2); /* 2,3:reserved */
192
193 /* we don't write the channel submappings if we only have one... */
194 if(info.submaps>1){
195 for(int i=0;i<vi.channels;i++)
196 opb.write(info.chmuxlist[i],4);
197 }
198 for(int i=0;i<info.submaps;i++){
199 opb.write(info.timesubmap[i],8);
200 opb.write(info.floorsubmap[i],8);
201 opb.write(info.residuesubmap[i],8);
202 }
203 }
204
205 // also responsible for range checking
206 Object unpack(Info vi, Buffer opb){
207 InfoMapping0 info=new InfoMapping0();
208
209 // !!!!
210 if(opb.read(1)!=0){
211 info.submaps=opb.read(4)+1;
212 }
213 else{
214 info.submaps=1;
215 }
216
217 if(opb.read(1)!=0){
218 info.coupling_steps=opb.read(8)+1;
219
220 for(int i=0;i<info.coupling_steps;i++){
221 int testM=info.coupling_mag[i]=opb.read(ilog2(vi.channels));
222 int testA=info.coupling_ang[i]=opb.read(ilog2(vi.channels));
223
224 if(testM<0 ||
225 testA<0 ||
226 testM==testA ||
227 testM>=vi.channels ||
228 testA>=vi.channels){
229 //goto err_out;
230 info.free();
231 return(null);
232 }
233 }
234 }
235
236 if(opb.read(2)>0){ /* 2,3:reserved */
237 //goto err_out;
238 info.free();
239 return(null);
240 }
241
242 if(info.submaps>1){
243 for(int i=0;i<vi.channels;i++){
244 info.chmuxlist[i]=opb.read(4);
245 if(info.chmuxlist[i]>=info.submaps){
246 //goto err_out;
247 info.free();
248 return(null);
249 }
250 }
251 }
252
253 for(int i=0;i<info.submaps;i++){
254 info.timesubmap[i]=opb.read(8);
255 if(info.timesubmap[i]>=vi.times){
256 //goto err_out;
257 info.free();
258 return(null);
259 }
260 info.floorsubmap[i]=opb.read(8);
261 if(info.floorsubmap[i]>=vi.floors){
262 //goto err_out;
263 info.free();
264 return(null);
265 }
266 info.residuesubmap[i]=opb.read(8);
267 if(info.residuesubmap[i]>=vi.residues){
268 //goto err_out;
269 info.free();
270 return(null);
271 }
272 }
273 return info;
274 //err_out:
275 //free_info(info);
276 //return(NULL);
277 }
278
279/*
280 // no time mapping implementation for now
281 static int seq=0;
282 int forward(Block vb, Object l){
283 DspState vd=vb.vd;
284 Info vi=vd.vi;
285 LookMapping0 look=(LookMapping0)l;
286 InfoMapping0 info=look.map;
287 InfoMode mode=look.mode;
288 int n=vb.pcmend;
289 float[] window=vd.window[vb.W][vb.lW][vb.nW][mode.windowtype];
290
291 float[][] pcmbundle=new float[vi.channles][];
292 int[] nonzero=new int[vi.channels];
293
294 // time domain pre-window: NONE IMPLEMENTED
295
296 // window the PCM data: takes PCM vector, vb; modifies PCM vector
297
298 for(int i=0;i<vi.channels;i++){
299 float[] pcm=vb.pcm[i];
300 for(int j=0;j<n;j++)
301 pcm[j]*=window[j];
302 }
303
304 // time-domain post-window: NONE IMPLEMENTED
305
306 // transform the PCM data; takes PCM vector, vb; modifies PCM vector
307 // only MDCT right now....
308 for(int i=0;i<vi.channels;i++){
309 float[] pcm=vb.pcm[i];
310 mdct_forward(vd.transform[vb.W][0],pcm,pcm);
311 }
312
313 {
314 float[] floor=_vorbis_block_alloc(vb,n*sizeof(float)/2);
315
316 for(int i=0;i<vi.channels;i++){
317 float[] pcm=vb.pcm[i];
318 float[] decay=look.decay[i];
319 int submap=info.chmuxlist[i];
320
321 // if some other mode/mapping was called last frame, our decay
322 // accumulator is out of date. Clear it.
323 //if(look.lastframe+1 != vb->sequence)
324 // memset(decay,0,n*sizeof(float)/2);
325
326 // perform psychoacoustics; do masking
327 _vp_compute_mask(look.psy_look[submap],pcm,floor,decay);
328
329 _analysis_output("mdct",seq,pcm,n/2,0,1);
330 _analysis_output("lmdct",seq,pcm,n/2,0,0);
331 _analysis_output("prefloor",seq,floor,n/2,0,1);
332
333 // perform floor encoding
334 nonzero[i]=look.floor_func[submap].
335 forward(vb,look.floor_look[submap],floor,floor,look.floor_state[i]);
336
337 _analysis_output("floor",seq,floor,n/2,0,1);
338
339 // apply the floor, do optional noise levelling
340 _vp_apply_floor(look->psy_look+submap,pcm,floor);
341
342 _analysis_output("res",seq++,pcm,n/2,0,0);
343 }
344
345 // perform residue encoding with residue mapping; this is
346 // multiplexed. All the channels belonging to one submap are
347 // encoded (values interleaved), then the next submap, etc
348
349 for(int i=0;i<info.submaps;i++){
350 int ch_in_bundle=0;
351 for(int j=0;j<vi.channels;j++){
352 if(info.chmuxlist[j]==i && nonzero[j]==1){
353 pcmbundle[ch_in_bundle++]=vb.pcm[j];
354 }
355 }
356 look.residue_func[i].forward(vb,look.residue_look[i], pcmbundle,ch_in_bundle);
357 }
358 }
359 look.lastframe=vb.sequence;
360 return(0);
361 }
362*/
363
364 float[][] pcmbundle=null;
365 int[] zerobundle=null;
366 int[] nonzero=null;
367 Object[] floormemo=null;
368
369 synchronized int inverse(Block vb, Object l){
370 //System.err.println("Mapping0.inverse");
371 DspState vd=vb.vd;
372 Info vi=vd.vi;
373 LookMapping0 look=(LookMapping0)l;
374 InfoMapping0 info=look.map;
375 InfoMode mode=look.mode;
376 int n=vb.pcmend=vi.blocksizes[vb.W];
377
378 float[] window=vd.window[vb.W][vb.lW][vb.nW][mode.windowtype];
379 // float[][] pcmbundle=new float[vi.channels][];
380 // int[] nonzero=new int[vi.channels];
381 if(pcmbundle==null || pcmbundle.length<vi.channels){
382 pcmbundle=new float[vi.channels][];
383 nonzero=new int[vi.channels];
384 zerobundle=new int[vi.channels];
385 floormemo=new Object[vi.channels];
386 }
387
388 // time domain information decode (note that applying the
389 // information would have to happen later; we'll probably add a
390 // function entry to the harness for that later
391 // NOT IMPLEMENTED
392
393 // recover the spectral envelope; store it in the PCM vector for now
394 for(int i=0;i<vi.channels;i++){
395 float[] pcm=vb.pcm[i];
396 int submap=info.chmuxlist[i];
397
398 floormemo[i]=look.floor_func[submap].inverse1(vb,look.
399 floor_look[submap],
400 floormemo[i]
401 );
402 if(floormemo[i]!=null){ nonzero[i]=1; }
403 else{ nonzero[i]=0; }
404 for(int j=0; j<n/2; j++){
405 pcm[j]=0;
406 }
407
408 //_analysis_output("ifloor",seq+i,pcm,n/2,0,1);
409 }
410
411 for(int i=0; i<info.coupling_steps; i++){
412 if(nonzero[info.coupling_mag[i]]!=0 ||
413 nonzero[info.coupling_ang[i]]!=0){
414 nonzero[info.coupling_mag[i]]=1;
415 nonzero[info.coupling_ang[i]]=1;
416 }
417 }
418
419 // recover the residue, apply directly to the spectral envelope
420
421 for(int i=0;i<info.submaps;i++){
422 int ch_in_bundle=0;
423 for(int j=0;j<vi.channels;j++){
424 if(info.chmuxlist[j]==i){
425 if(nonzero[j]!=0){
426 zerobundle[ch_in_bundle]=1;
427 }
428 else{
429 zerobundle[ch_in_bundle]=0;
430 }
431 pcmbundle[ch_in_bundle++]=vb.pcm[j];
432 }
433 }
434
435 look.residue_func[i].inverse(vb,look.residue_look[i],
436 pcmbundle,zerobundle,ch_in_bundle);
437 }
438
439
440 for(int i=info.coupling_steps-1;i>=0;i--){
441 float[] pcmM=vb.pcm[info.coupling_mag[i]];
442 float[] pcmA=vb.pcm[info.coupling_ang[i]];
443
444 for(int j=0;j<n/2;j++){
445 float mag=pcmM[j];
446 float ang=pcmA[j];
447
448 if(mag>0){
449 if(ang>0){
450 pcmM[j]=mag;
451 pcmA[j]=mag-ang;
452 }
453 else{
454 pcmA[j]=mag;
455 pcmM[j]=mag+ang;
456 }
457 }
458 else{
459 if(ang>0){
460 pcmM[j]=mag;
461 pcmA[j]=mag+ang;
462 }
463 else{
464 pcmA[j]=mag;
465 pcmM[j]=mag-ang;
466 }
467 }
468 }
469 }
470
471// /* compute and apply spectral envelope */
472
473 for(int i=0;i<vi.channels;i++){
474 float[] pcm=vb.pcm[i];
475 int submap=info.chmuxlist[i];
476 look.floor_func[submap].inverse2(vb,look.floor_look[submap],floormemo[i],pcm);
477 }
478
479 // transform the PCM data; takes PCM vector, vb; modifies PCM vector
480 // only MDCT right now....
481
482 for(int i=0;i<vi.channels;i++){
483 float[] pcm=vb.pcm[i];
484 //_analysis_output("out",seq+i,pcm,n/2,0,0);
485 ((Mdct)vd.transform[vb.W][0]).backward(pcm,pcm);
486 }
487
488 // now apply the decoded pre-window time information
489 // NOT IMPLEMENTED
490
491 // window the data
492 for(int i=0;i<vi.channels;i++){
493 float[] pcm=vb.pcm[i];
494 if(nonzero[i]!=0){
495 for(int j=0;j<n;j++){
496 pcm[j]*=window[j];
497 }
498 }
499 else{
500 for(int j=0;j<n;j++){
501 pcm[j]=0.f;
502 }
503 }
504 //_analysis_output("final",seq++,pcm,n,0,0);
505 }
506
507 // now apply the decoded post-window time information
508 // NOT IMPLEMENTED
509 // all done!
510 return(0);
511 }
512
513
514 private static int ilog2(int v){
515 int ret=0;
516 while(v>1){
517 ret++;
518 v>>>=1;
519 }
520 return(ret);
521 }
522}
523
524class InfoMapping0{
525 int submaps; // <= 16
526 int[] chmuxlist=new int[256]; // up to 256 channels in a Vorbis stream
527
528 int[] timesubmap=new int[16]; // [mux]
529 int[] floorsubmap=new int[16]; // [mux] submap to floors
530 int[] residuesubmap=new int[16];// [mux] submap to residue
531 int[] psysubmap=new int[16]; // [mux]; encode only
532
533 int coupling_steps;
534 int[] coupling_mag=new int[256];
535 int[] coupling_ang=new int[256];
536
537 void free(){
538 chmuxlist=null;
539 timesubmap=null;
540 floorsubmap=null;
541 residuesubmap=null;
542 psysubmap=null;
543
544 coupling_mag=null;
545 coupling_ang=null;
546 }
547}
548
549class LookMapping0{
550 InfoMode mode;
551 InfoMapping0 map;
552 Object[] time_look;
553 Object[] floor_look;
554 Object[] floor_state;
555 Object[] residue_look;
556 PsyLook[] psy_look;
557
558 FuncTime[] time_func;
559 FuncFloor[] floor_func;
560 FuncResidue[] residue_func;
561
562 int ch;
563 float[][] decay;
564 int lastframe; // if a different mode is called, we need to
565 // invalidate decay and floor state
566}
This page took 0.061985 seconds and 4 git commands to generate.