Line | Count | Source |
1 | | /******************************************************************** |
2 | | * * |
3 | | * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * |
4 | | * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
5 | | * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
6 | | * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
7 | | * * |
8 | | * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * |
9 | | * by the Xiph.Org Foundation https://xiph.org/ * |
10 | | * * |
11 | | ******************************************************************** |
12 | | |
13 | | function: residue backend 0, 1 and 2 implementation |
14 | | |
15 | | ********************************************************************/ |
16 | | |
17 | | /* Slow, slow, slow, simpleminded and did I mention it was slow? The |
18 | | encode/decode loops are coded for clarity and performance is not |
19 | | yet even a nagging little idea lurking in the shadows. Oh and BTW, |
20 | | it's slow. */ |
21 | | |
22 | | #include <stdlib.h> |
23 | | #include <string.h> |
24 | | #include <math.h> |
25 | | #include <ogg/ogg.h> |
26 | | #include "vorbis/codec.h" |
27 | | #include "codec_internal.h" |
28 | | #include "registry.h" |
29 | | #include "codebook.h" |
30 | | #include "misc.h" |
31 | | #include "os.h" |
32 | | |
33 | | #if defined(TRAIN_RES) || defined (TRAIN_RESAUX) |
34 | | #include <stdio.h> |
35 | | #endif |
36 | | |
37 | | typedef struct { |
38 | | vorbis_info_residue0 *info; |
39 | | |
40 | | int parts; |
41 | | int stages; |
42 | | codebook *fullbooks; |
43 | | dec_codebook *decbooks; |
44 | | int phrasebook; |
45 | | int **partbooks; |
46 | | |
47 | | int partvals; |
48 | | int **decodemap; |
49 | | |
50 | | long postbits; |
51 | | long phrasebits; |
52 | | long frames; |
53 | | |
54 | | #if defined(TRAIN_RES) || defined(TRAIN_RESAUX) |
55 | | int train_seq; |
56 | | long *training_data[8][64]; |
57 | | float training_max[8][64]; |
58 | | float training_min[8][64]; |
59 | | float tmin; |
60 | | float tmax; |
61 | | int submap; |
62 | | #endif |
63 | | |
64 | | } vorbis_look_residue0; |
65 | | |
66 | 15.1k | void res0_free_info(vorbis_info_residue *i){ |
67 | 15.1k | vorbis_info_residue0 *info=(vorbis_info_residue0 *)i; |
68 | 15.1k | if(info){ |
69 | 15.1k | memset(info,0,sizeof(*info)); |
70 | 15.1k | _ogg_free(info); |
71 | 15.1k | } |
72 | 15.1k | } |
73 | | |
74 | 14.6k | void res0_free_look(vorbis_look_residue *i){ |
75 | 14.6k | int j; |
76 | 14.6k | if(i){ |
77 | | |
78 | 14.6k | vorbis_look_residue0 *look=(vorbis_look_residue0 *)i; |
79 | | |
80 | | #ifdef TRAIN_RES |
81 | | { |
82 | | int j,k,l; |
83 | | for(j=0;j<look->parts;j++){ |
84 | | /*fprintf(stderr,"partition %d: ",j);*/ |
85 | | for(k=0;k<8;k++) |
86 | | if(look->training_data[k][j]){ |
87 | | char buffer[80]; |
88 | | FILE *of; |
89 | | codebook *statebook=look->fullbooks+look->partbooks[j][k]; |
90 | | |
91 | | /* long and short into the same bucket by current convention */ |
92 | | sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k); |
93 | | of=fopen(buffer,"a"); |
94 | | |
95 | | for(l=0;l<statebook->entries;l++) |
96 | | fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]); |
97 | | |
98 | | fclose(of); |
99 | | |
100 | | /*fprintf(stderr,"%d(%.2f|%.2f) ",k, |
101 | | look->training_min[k][j],look->training_max[k][j]);*/ |
102 | | |
103 | | _ogg_free(look->training_data[k][j]); |
104 | | look->training_data[k][j]=NULL; |
105 | | } |
106 | | /*fprintf(stderr,"\n");*/ |
107 | | } |
108 | | } |
109 | | fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax); |
110 | | |
111 | | /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n", |
112 | | (float)look->phrasebits/look->frames, |
113 | | (float)look->postbits/look->frames, |
114 | | (float)(look->postbits+look->phrasebits)/look->frames);*/ |
115 | | #endif |
116 | | |
117 | | |
118 | | /*vorbis_info_residue0 *info=look->info; |
119 | | |
120 | | fprintf(stderr, |
121 | | "%ld frames encoded in %ld phrasebits and %ld residue bits " |
122 | | "(%g/frame) \n",look->frames,look->phrasebits, |
123 | | look->resbitsflat, |
124 | | (look->phrasebits+look->resbitsflat)/(float)look->frames); |
125 | | |
126 | | for(j=0;j<look->parts;j++){ |
127 | | long acc=0; |
128 | | fprintf(stderr,"\t[%d] == ",j); |
129 | | for(k=0;k<look->stages;k++) |
130 | | if((info->secondstages[j]>>k)&1){ |
131 | | fprintf(stderr,"%ld,",look->resbits[j][k]); |
132 | | acc+=look->resbits[j][k]; |
133 | | } |
134 | | |
135 | | fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j], |
136 | | acc?(float)acc/(look->resvals[j]*info->grouping):0); |
137 | | } |
138 | | fprintf(stderr,"\n");*/ |
139 | | |
140 | 70.9k | for(j=0;j<look->parts;j++) |
141 | 56.2k | if(look->partbooks[j])_ogg_free(look->partbooks[j]); |
142 | 14.6k | _ogg_free(look->partbooks); |
143 | 444k | for(j=0;j<look->partvals;j++) |
144 | 429k | _ogg_free(look->decodemap[j]); |
145 | 14.6k | _ogg_free(look->decodemap); |
146 | | |
147 | 14.6k | memset(look,0,sizeof(*look)); |
148 | 14.6k | _ogg_free(look); |
149 | 14.6k | } |
150 | 14.6k | } |
151 | | |
152 | 58.3k | static int icount(unsigned int v){ |
153 | 58.3k | int ret=0; |
154 | 189k | while(v){ |
155 | 130k | ret+=v&1; |
156 | 130k | v>>=1; |
157 | 130k | } |
158 | 58.3k | return(ret); |
159 | 58.3k | } |
160 | | |
161 | | |
162 | 4.02k | void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){ |
163 | 4.02k | vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; |
164 | 4.02k | int j,acc=0; |
165 | 4.02k | oggpack_write(opb,info->begin,24); |
166 | 4.02k | oggpack_write(opb,info->end,24); |
167 | | |
168 | 4.02k | oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and |
169 | | code with a partitioned book */ |
170 | 4.02k | oggpack_write(opb,info->partitions-1,6); /* possible partition choices */ |
171 | 4.02k | oggpack_write(opb,info->groupbook,8); /* group huffman book */ |
172 | | |
173 | | /* secondstages is a bitmask; as encoding progresses pass by pass, a |
174 | | bitmask of one indicates this partition class has bits to write |
175 | | this pass */ |
176 | 41.5k | for(j=0;j<info->partitions;j++){ |
177 | 37.5k | if(ov_ilog(info->secondstages[j])>3){ |
178 | | /* yes, this is a minor hack due to not thinking ahead */ |
179 | 0 | oggpack_write(opb,info->secondstages[j],3); |
180 | 0 | oggpack_write(opb,1,1); |
181 | 0 | oggpack_write(opb,info->secondstages[j]>>3,5); |
182 | 0 | }else |
183 | 37.5k | oggpack_write(opb,info->secondstages[j],4); /* trailing zero */ |
184 | 37.5k | acc+=icount(info->secondstages[j]); |
185 | 37.5k | } |
186 | 55.1k | for(j=0;j<acc;j++) |
187 | 51.1k | oggpack_write(opb,info->booklist[j],8); |
188 | | |
189 | 4.02k | } |
190 | | |
191 | | /* vorbis_info is for range checking */ |
192 | 11.1k | vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){ |
193 | 11.1k | int j,acc=0; |
194 | 11.1k | vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info)); |
195 | 11.1k | codec_setup_info *ci=vi->codec_setup; |
196 | | |
197 | 11.1k | info->begin=oggpack_read(opb,24); |
198 | 11.1k | info->end=oggpack_read(opb,24); |
199 | 11.1k | info->grouping=oggpack_read(opb,24)+1; |
200 | 11.1k | info->partitions=oggpack_read(opb,6)+1; |
201 | 11.1k | info->groupbook=oggpack_read(opb,8); |
202 | | |
203 | | /* check for premature EOP */ |
204 | 11.1k | if(info->groupbook<0)goto errout; |
205 | | |
206 | 31.8k | for(j=0;j<info->partitions;j++){ |
207 | 20.7k | int cascade=oggpack_read(opb,3); |
208 | 20.7k | int cflag=oggpack_read(opb,1); |
209 | 20.7k | if(cflag<0) goto errout; |
210 | 20.7k | if(cflag){ |
211 | 4.40k | int c=oggpack_read(opb,5); |
212 | 4.40k | if(c<0) goto errout; |
213 | 4.40k | cascade|=(c<<3); |
214 | 4.40k | } |
215 | 20.7k | info->secondstages[j]=cascade; |
216 | | |
217 | 20.7k | acc+=icount(cascade); |
218 | 20.7k | } |
219 | 28.4k | for(j=0;j<acc;j++){ |
220 | 17.3k | int book=oggpack_read(opb,8); |
221 | 17.3k | if(book<0) goto errout; |
222 | 17.3k | info->booklist[j]=book; |
223 | 17.3k | } |
224 | | |
225 | 11.0k | if(info->groupbook>=ci->books)goto errout; |
226 | 27.7k | for(j=0;j<acc;j++){ |
227 | 16.6k | if(info->booklist[j]>=ci->books)goto errout; |
228 | 16.6k | if(ci->decbooks[info->booklist[j]].maptype==0)goto errout; |
229 | 16.6k | } |
230 | | |
231 | | /* verify the phrasebook is not specifying an impossible or |
232 | | inconsistent partitioning scheme. */ |
233 | | /* modify the phrasebook ranging check from r16327; an early beta |
234 | | encoder had a bug where it used an oversized phrasebook by |
235 | | accident. These files should continue to be playable, but don't |
236 | | allow an exploit */ |
237 | 11.0k | { |
238 | 11.0k | int entries = ci->decbooks[info->groupbook].entries; |
239 | 11.0k | int dim = ci->decbooks[info->groupbook].dim; |
240 | 11.0k | int partvals = 1; |
241 | 11.0k | if (dim<1) goto errout; |
242 | 210k | while(dim>0){ |
243 | 199k | partvals *= info->partitions; |
244 | 199k | if(partvals > entries) goto errout; |
245 | 199k | dim--; |
246 | 199k | } |
247 | 11.0k | info->partvals = partvals; |
248 | 11.0k | } |
249 | | |
250 | 0 | return(info); |
251 | 91 | errout: |
252 | 91 | res0_free_info(info); |
253 | 91 | return(NULL); |
254 | 11.0k | } |
255 | | |
256 | | vorbis_look_residue *res0_look(vorbis_dsp_state *vd, |
257 | 14.6k | vorbis_info_residue *vr){ |
258 | 14.6k | vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr; |
259 | 14.6k | vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look)); |
260 | 14.6k | codec_setup_info *ci=vd->vi->codec_setup; |
261 | | |
262 | 14.6k | int j,k,acc=0; |
263 | 14.6k | int dim; |
264 | 14.6k | int maxstage=0; |
265 | 14.6k | look->info=info; |
266 | | |
267 | 14.6k | look->parts=info->partitions; |
268 | 14.6k | look->fullbooks=ci->fullbooks; |
269 | 14.6k | look->decbooks=ci->decbooks; |
270 | 14.6k | look->phrasebook=info->groupbook; |
271 | 14.6k | dim=look->fullbooks? |
272 | 10.6k | look->fullbooks[look->phrasebook].dim:look->decbooks[look->phrasebook].dim; |
273 | | |
274 | 14.6k | look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks)); |
275 | | |
276 | 70.9k | for(j=0;j<look->parts;j++){ |
277 | 56.2k | int stages=ov_ilog(info->secondstages[j]); |
278 | 56.2k | if(stages){ |
279 | 42.1k | if(stages>maxstage)maxstage=stages; |
280 | 42.1k | look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j])); |
281 | 167k | for(k=0;k<stages;k++) |
282 | 125k | if(info->secondstages[j]&(1<<k)){ |
283 | 66.8k | look->partbooks[j][k]=info->booklist[acc++]; |
284 | | #ifdef TRAIN_RES |
285 | | look->training_data[k][j]=_ogg_calloc( |
286 | | look->fullbooks[look->partbooks[j][k]].entries, |
287 | | sizeof(***look->training_data)); |
288 | | #endif |
289 | 66.8k | }else{ |
290 | 58.9k | look->partbooks[j][k]=-1; |
291 | 58.9k | } |
292 | 42.1k | } |
293 | 56.2k | } |
294 | | |
295 | 14.6k | look->partvals=1; |
296 | 212k | for(j=0;j<dim;j++) |
297 | 197k | look->partvals*=look->parts; |
298 | | |
299 | 14.6k | look->stages=maxstage; |
300 | 14.6k | look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap)); |
301 | 444k | for(j=0;j<look->partvals;j++){ |
302 | 429k | long val=j; |
303 | 429k | long mult=look->partvals/look->parts; |
304 | 429k | look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j])); |
305 | 1.60M | for(k=0;k<dim;k++){ |
306 | 1.17M | long deco=val/mult; |
307 | 1.17M | val-=deco*mult; |
308 | 1.17M | mult/=look->parts; |
309 | 1.17M | look->decodemap[j][k]=deco; |
310 | 1.17M | } |
311 | 429k | } |
312 | | #if defined(TRAIN_RES) || defined (TRAIN_RESAUX) |
313 | | { |
314 | | static int train_seq=0; |
315 | | look->train_seq=train_seq++; |
316 | | } |
317 | | #endif |
318 | 14.6k | return(look); |
319 | 14.6k | } |
320 | | |
321 | | /* break an abstraction and copy some code for performance purposes */ |
322 | 10.6M | static int local_book_besterror(codebook *book,int *a){ |
323 | 10.6M | int dim=book->dim; |
324 | 10.6M | int i,j,o; |
325 | 10.6M | int minval=book->minval; |
326 | 10.6M | int del=book->delta; |
327 | 10.6M | int qv=book->quantvals; |
328 | 10.6M | int ze=(qv>>1); |
329 | 10.6M | int index=0; |
330 | | /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */ |
331 | 10.6M | int p[8]={0,0,0,0,0,0,0,0}; |
332 | | |
333 | 10.6M | if(del!=1){ |
334 | 13.6M | for(i=0,o=dim;i<dim;i++){ |
335 | 9.38M | int v = (a[--o]-minval+(del>>1))/del; |
336 | 9.38M | int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1)); |
337 | 9.38M | index = index*qv+ (m<0?0:(m>=qv?qv-1:m)); |
338 | 9.38M | p[o]=v*del+minval; |
339 | 9.38M | } |
340 | 6.34M | }else{ |
341 | 20.4M | for(i=0,o=dim;i<dim;i++){ |
342 | 14.1M | int v = a[--o]-minval; |
343 | 14.1M | int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1)); |
344 | 14.1M | index = index*qv+ (m<0?0:(m>=qv?qv-1:m)); |
345 | 14.1M | p[o]=v*del+minval; |
346 | 14.1M | } |
347 | 6.34M | } |
348 | | |
349 | 10.6M | if(book->c->lengthlist[index]<=0){ |
350 | 429 | const static_codebook *c=book->c; |
351 | 429 | int best=-1; |
352 | | /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */ |
353 | 429 | int e[8]={0,0,0,0,0,0,0,0}; |
354 | 429 | int maxval = book->minval + book->delta*(book->quantvals-1); |
355 | 204k | for(i=0;i<book->entries;i++){ |
356 | 203k | if(c->lengthlist[i]>0){ |
357 | 201k | int this=0; |
358 | 961k | for(j=0;j<dim;j++){ |
359 | 760k | int val=(e[j]-a[j]); |
360 | 760k | this+=val*val; |
361 | 760k | } |
362 | 201k | if(best==-1 || this<best){ |
363 | 6.84k | memcpy(p,e,sizeof(p)); |
364 | 6.84k | best=this; |
365 | 6.84k | index=i; |
366 | 6.84k | } |
367 | 201k | } |
368 | | /* assumes the value patterning created by the tools in vq/ */ |
369 | 203k | j=0; |
370 | 250k | while(e[j]>=maxval) |
371 | 46.9k | e[j++]=0; |
372 | 203k | if(e[j]>=0) |
373 | 102k | e[j]+=book->delta; |
374 | 203k | e[j]= -e[j]; |
375 | 203k | } |
376 | 429 | } |
377 | | |
378 | 10.6M | if(index>-1){ |
379 | 34.1M | for(i=0;i<dim;i++) |
380 | 23.4M | *a++ -= p[i]; |
381 | 10.6M | } |
382 | | |
383 | 10.6M | return(index); |
384 | 10.6M | } |
385 | | |
386 | | #ifdef TRAIN_RES |
387 | | static int _encodepart(oggpack_buffer *opb,int *vec, int n, |
388 | | codebook *book,long *acc){ |
389 | | #else |
390 | | static int _encodepart(oggpack_buffer *opb,int *vec, int n, |
391 | 1.11M | codebook *book){ |
392 | 1.11M | #endif |
393 | 1.11M | int i,bits=0; |
394 | 1.11M | int dim=book->dim; |
395 | 1.11M | int step=n/dim; |
396 | | |
397 | 11.7M | for(i=0;i<step;i++){ |
398 | 10.6M | int entry=local_book_besterror(book,vec+i*dim); |
399 | | |
400 | | #ifdef TRAIN_RES |
401 | | if(entry>=0) |
402 | | acc[entry]++; |
403 | | #endif |
404 | | |
405 | 10.6M | bits+=vorbis_book_encode(book,entry,opb); |
406 | | |
407 | 10.6M | } |
408 | | |
409 | 1.11M | return(bits); |
410 | 1.11M | } |
411 | | |
412 | | static long **_01class(vorbis_block *vb,vorbis_look_residue *vl, |
413 | 57.0k | int **in,int ch){ |
414 | 57.0k | long i,j,k; |
415 | 57.0k | vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; |
416 | 57.0k | vorbis_info_residue0 *info=look->info; |
417 | | |
418 | | /* move all this setup out later */ |
419 | 57.0k | int samples_per_partition=info->grouping; |
420 | 57.0k | int possible_partitions=info->partitions; |
421 | 57.0k | int n=info->end-info->begin; |
422 | | |
423 | 57.0k | int partvals=n/samples_per_partition; |
424 | 57.0k | long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword)); |
425 | 57.0k | float scale=100./samples_per_partition; |
426 | | |
427 | | /* we find the partition type for each partition of each |
428 | | channel. We'll go back and do the interleaved encoding in a |
429 | | bit. For now, clarity */ |
430 | | |
431 | 150k | for(i=0;i<ch;i++){ |
432 | 93.3k | partword[i]=_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(*partword[i])); |
433 | 93.3k | memset(partword[i],0,n/samples_per_partition*sizeof(*partword[i])); |
434 | 93.3k | } |
435 | | |
436 | 450k | for(i=0;i<partvals;i++){ |
437 | 393k | int offset=i*samples_per_partition+info->begin; |
438 | 1.08M | for(j=0;j<ch;j++){ |
439 | 693k | int max=0; |
440 | 693k | int ent=0; |
441 | 16.0M | for(k=0;k<samples_per_partition;k++){ |
442 | 15.3M | if(abs(in[j][offset+k])>max)max=abs(in[j][offset+k]); |
443 | 15.3M | ent+=abs(in[j][offset+k]); |
444 | 15.3M | } |
445 | 693k | ent*=scale; |
446 | | |
447 | 4.03M | for(k=0;k<possible_partitions-1;k++) |
448 | 3.98M | if(max<=info->classmetric1[k] && |
449 | 763k | (info->classmetric2[k]<0 || ent<info->classmetric2[k])) |
450 | 643k | break; |
451 | | |
452 | 693k | partword[j][i]=k; |
453 | 693k | } |
454 | 393k | } |
455 | | |
456 | | #ifdef TRAIN_RESAUX |
457 | | { |
458 | | FILE *of; |
459 | | char buffer[80]; |
460 | | |
461 | | for(i=0;i<ch;i++){ |
462 | | sprintf(buffer,"resaux_%d.vqd",look->train_seq); |
463 | | of=fopen(buffer,"a"); |
464 | | for(j=0;j<partvals;j++) |
465 | | fprintf(of,"%ld, ",partword[i][j]); |
466 | | fprintf(of,"\n"); |
467 | | fclose(of); |
468 | | } |
469 | | } |
470 | | #endif |
471 | 57.0k | look->frames++; |
472 | | |
473 | 57.0k | return(partword); |
474 | 57.0k | } |
475 | | |
476 | | /* designed for stereo or other modes where the partition size is an |
477 | | integer multiple of the number of channels encoded in the current |
478 | | submap */ |
479 | | static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in, |
480 | 4.15k | int ch){ |
481 | 4.15k | long i,j,k,l; |
482 | 4.15k | vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; |
483 | 4.15k | vorbis_info_residue0 *info=look->info; |
484 | | |
485 | | /* move all this setup out later */ |
486 | 4.15k | int samples_per_partition=info->grouping; |
487 | 4.15k | int possible_partitions=info->partitions; |
488 | 4.15k | int n=info->end-info->begin; |
489 | | |
490 | 4.15k | int partvals=n/samples_per_partition; |
491 | 4.15k | long **partword=_vorbis_block_alloc(vb,sizeof(*partword)); |
492 | | |
493 | | #if defined(TRAIN_RES) || defined (TRAIN_RESAUX) |
494 | | FILE *of; |
495 | | char buffer[80]; |
496 | | #endif |
497 | | |
498 | 4.15k | partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0])); |
499 | 4.15k | memset(partword[0],0,partvals*sizeof(*partword[0])); |
500 | | |
501 | 68.4k | for(i=0,l=info->begin/ch;i<partvals;i++){ |
502 | 64.2k | int magmax=0; |
503 | 64.2k | int angmax=0; |
504 | 850k | for(j=0;j<samples_per_partition;j+=ch){ |
505 | 786k | if(abs(in[0][l])>magmax)magmax=abs(in[0][l]); |
506 | 1.57M | for(k=1;k<ch;k++) |
507 | 786k | if(abs(in[k][l])>angmax)angmax=abs(in[k][l]); |
508 | 786k | l++; |
509 | 786k | } |
510 | | |
511 | 357k | for(j=0;j<possible_partitions-1;j++) |
512 | 353k | if(magmax<=info->classmetric1[j] && |
513 | 84.1k | angmax<=info->classmetric2[j]) |
514 | 61.0k | break; |
515 | | |
516 | 64.2k | partword[0][i]=j; |
517 | | |
518 | 64.2k | } |
519 | | |
520 | | #ifdef TRAIN_RESAUX |
521 | | sprintf(buffer,"resaux_%d.vqd",look->train_seq); |
522 | | of=fopen(buffer,"a"); |
523 | | for(i=0;i<partvals;i++) |
524 | | fprintf(of,"%ld, ",partword[0][i]); |
525 | | fprintf(of,"\n"); |
526 | | fclose(of); |
527 | | #endif |
528 | | |
529 | 4.15k | look->frames++; |
530 | | |
531 | 4.15k | return(partword); |
532 | 4.15k | } |
533 | | |
534 | | static int _01forward(oggpack_buffer *opb, |
535 | | vorbis_look_residue *vl, |
536 | | int **in,int ch, |
537 | | long **partword, |
538 | | #ifdef TRAIN_RES |
539 | | int (*encode)(oggpack_buffer *,int *,int, |
540 | | codebook *,long *), |
541 | | int submap |
542 | | #else |
543 | | int (*encode)(oggpack_buffer *,int *,int, |
544 | | codebook *) |
545 | | #endif |
546 | 61.2k | ){ |
547 | 61.2k | long i,j,k,s; |
548 | 61.2k | vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; |
549 | 61.2k | vorbis_info_residue0 *info=look->info; |
550 | 61.2k | codebook *phrasebook=look->fullbooks+look->phrasebook; |
551 | | |
552 | | #ifdef TRAIN_RES |
553 | | look->submap=submap; |
554 | | #endif |
555 | | |
556 | | /* move all this setup out later */ |
557 | 61.2k | int samples_per_partition=info->grouping; |
558 | 61.2k | int possible_partitions=info->partitions; |
559 | 61.2k | int partitions_per_word=phrasebook->dim; |
560 | 61.2k | int n=info->end-info->begin; |
561 | | |
562 | 61.2k | int partvals=n/samples_per_partition; |
563 | 61.2k | long resbits[128]; |
564 | 61.2k | long resvals[128]; |
565 | | |
566 | | #ifdef TRAIN_RES |
567 | | for(i=0;i<ch;i++) |
568 | | for(j=info->begin;j<info->end;j++){ |
569 | | if(in[i][j]>look->tmax)look->tmax=in[i][j]; |
570 | | if(in[i][j]<look->tmin)look->tmin=in[i][j]; |
571 | | } |
572 | | #endif |
573 | | |
574 | 61.2k | memset(resbits,0,sizeof(resbits)); |
575 | 61.2k | memset(resvals,0,sizeof(resvals)); |
576 | | |
577 | | /* we code the partition words for each channel, then the residual |
578 | | words for a partition per channel until we've written all the |
579 | | residual words for that partition word. Then write the next |
580 | | partition channel words... */ |
581 | | |
582 | 244k | for(s=0;s<look->stages;s++){ |
583 | | |
584 | 882k | for(i=0;i<partvals;){ |
585 | | |
586 | | /* first we encode a partition codeword for each channel */ |
587 | 698k | if(s==0){ |
588 | 618k | for(j=0;j<ch;j++){ |
589 | 385k | long val=partword[j][i]; |
590 | 770k | for(k=1;k<partitions_per_word;k++){ |
591 | 385k | val*=possible_partitions; |
592 | 385k | if(i+k<partvals) |
593 | 372k | val+=partword[j][i+k]; |
594 | 385k | } |
595 | | |
596 | | /* training hack */ |
597 | 385k | if(val<phrasebook->entries) |
598 | 385k | look->phrasebits+=vorbis_book_encode(phrasebook,val,opb); |
599 | | #if 0 /*def TRAIN_RES*/ |
600 | | else |
601 | | fprintf(stderr,"!"); |
602 | | #endif |
603 | | |
604 | 385k | } |
605 | 232k | } |
606 | | |
607 | | /* now we encode interleaved residual values for the partitions */ |
608 | 2.07M | for(k=0;k<partitions_per_word && i<partvals;k++,i++){ |
609 | 1.37M | long offset=i*samples_per_partition+info->begin; |
610 | | |
611 | 3.64M | for(j=0;j<ch;j++){ |
612 | 2.27M | if(s==0)resvals[partword[j][i]]+=samples_per_partition; |
613 | 2.27M | if(info->secondstages[partword[j][i]]&(1<<s)){ |
614 | 1.11M | int statebooknum=look->partbooks[partword[j][i]][s]; |
615 | 1.11M | if(statebooknum>=0){ |
616 | 1.11M | codebook *statebook=look->fullbooks+statebooknum; |
617 | 1.11M | int ret; |
618 | | #ifdef TRAIN_RES |
619 | | long *accumulator=NULL; |
620 | | accumulator=look->training_data[s][partword[j][i]]; |
621 | | { |
622 | | int l; |
623 | | int *samples=in[j]+offset; |
624 | | for(l=0;l<samples_per_partition;l++){ |
625 | | if(samples[l]<look->training_min[s][partword[j][i]]) |
626 | | look->training_min[s][partword[j][i]]=samples[l]; |
627 | | if(samples[l]>look->training_max[s][partword[j][i]]) |
628 | | look->training_max[s][partword[j][i]]=samples[l]; |
629 | | } |
630 | | } |
631 | | ret=encode(opb,in[j]+offset,samples_per_partition, |
632 | | statebook,accumulator); |
633 | | #else |
634 | 1.11M | ret=encode(opb,in[j]+offset,samples_per_partition, |
635 | 1.11M | statebook); |
636 | 1.11M | #endif |
637 | | |
638 | 1.11M | look->postbits+=ret; |
639 | 1.11M | resbits[partword[j][i]]+=ret; |
640 | 1.11M | } |
641 | 1.11M | } |
642 | 2.27M | } |
643 | 1.37M | } |
644 | 698k | } |
645 | 183k | } |
646 | | |
647 | 61.2k | return(0); |
648 | 61.2k | } |
649 | | |
650 | | /* a truncated packet here just means 'stop working'; it's not an error */ |
651 | | static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl, |
652 | | float **in,int ch, |
653 | | long (*decodepart)(dec_codebook *, float *, |
654 | 28.3k | oggpack_buffer *,int)){ |
655 | | |
656 | 28.3k | long i,j,k,l,s; |
657 | 28.3k | vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; |
658 | 28.3k | vorbis_info_residue0 *info=look->info; |
659 | 28.3k | dec_codebook *phrasebook=look->decbooks+look->phrasebook; |
660 | | |
661 | | /* move all this setup out later */ |
662 | 28.3k | int samples_per_partition=info->grouping; |
663 | 28.3k | int partitions_per_word=phrasebook->dim; |
664 | 28.3k | int max=vb->pcmend>>1; |
665 | 28.3k | int end=(info->end<max?info->end:max); |
666 | 28.3k | int n=end-info->begin; |
667 | | |
668 | 28.3k | if(n>0){ |
669 | 20.4k | int partvals=n/samples_per_partition; |
670 | 20.4k | int partwords=(partvals+partitions_per_word-1)/partitions_per_word; |
671 | 20.4k | int ***partword=alloca(ch*sizeof(*partword)); |
672 | | |
673 | 107k | for(j=0;j<ch;j++) |
674 | 86.7k | partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j])); |
675 | | |
676 | 38.5k | for(s=0;s<look->stages;s++){ |
677 | | |
678 | | /* each loop decodes on partition codeword containing |
679 | | partitions_per_word partitions */ |
680 | 176k | for(i=0,l=0;i<partvals;l++){ |
681 | 158k | if(s==0){ |
682 | | /* fetch the partition word for each channel */ |
683 | 413k | for(j=0;j<ch;j++){ |
684 | 281k | int temp=vorbis_book_decode(phrasebook,&vb->opb); |
685 | | |
686 | 281k | if(temp==-1 || temp>=info->partvals)goto eopbreak; |
687 | 273k | partword[j][l]=look->decodemap[temp]; |
688 | 273k | if(partword[j][l]==NULL)goto errout; |
689 | 273k | } |
690 | 140k | } |
691 | | |
692 | | /* now we decode residual values for the partitions */ |
693 | 563k | for(k=0;k<partitions_per_word && i<partvals;k++,i++) |
694 | 1.38M | for(j=0;j<ch;j++){ |
695 | 971k | long offset=info->begin+i*samples_per_partition; |
696 | 971k | if(info->secondstages[partword[j][l][k]]&(1<<s)){ |
697 | 726k | int stagebooknum=look->partbooks[partword[j][l][k]][s]; |
698 | 726k | if(stagebooknum>=0){ |
699 | 726k | dec_codebook *stagebook=look->decbooks+stagebooknum; |
700 | 726k | if(decodepart(stagebook,in[j]+offset,&vb->opb, |
701 | 726k | samples_per_partition)==-1)goto eopbreak; |
702 | 726k | } |
703 | 726k | } |
704 | 971k | } |
705 | 150k | } |
706 | 26.7k | } |
707 | 20.4k | } |
708 | 19.6k | errout: |
709 | 28.3k | eopbreak: |
710 | 28.3k | return(0); |
711 | 19.6k | } |
712 | | |
713 | | int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl, |
714 | 76.6k | float **in,int *nonzero,int ch){ |
715 | 76.6k | int i,used=0; |
716 | 1.36M | for(i=0;i<ch;i++) |
717 | 1.28M | if(nonzero[i]) |
718 | 94.3k | in[used++]=in[i]; |
719 | 76.6k | if(used) |
720 | 25.1k | return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add)); |
721 | 51.5k | else |
722 | 51.5k | return(0); |
723 | 76.6k | } |
724 | | |
725 | | int res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl, |
726 | 57.7k | int **in,int *nonzero,int ch, long **partword, int submap){ |
727 | 57.7k | int i,used=0; |
728 | 57.7k | (void)vb; |
729 | 154k | for(i=0;i<ch;i++) |
730 | 96.5k | if(nonzero[i]) |
731 | 93.3k | in[used++]=in[i]; |
732 | | |
733 | 57.7k | if(used){ |
734 | | #ifdef TRAIN_RES |
735 | | return _01forward(opb,vl,in,used,partword,_encodepart,submap); |
736 | | #else |
737 | 57.0k | (void)submap; |
738 | 57.0k | return _01forward(opb,vl,in,used,partword,_encodepart); |
739 | 57.0k | #endif |
740 | 57.0k | }else{ |
741 | 678 | return(0); |
742 | 678 | } |
743 | 57.7k | } |
744 | | |
745 | | long **res1_class(vorbis_block *vb,vorbis_look_residue *vl, |
746 | 57.7k | int **in,int *nonzero,int ch){ |
747 | 57.7k | int i,used=0; |
748 | 154k | for(i=0;i<ch;i++) |
749 | 96.5k | if(nonzero[i]) |
750 | 93.3k | in[used++]=in[i]; |
751 | 57.7k | if(used) |
752 | 57.0k | return(_01class(vb,vl,in,used)); |
753 | 678 | else |
754 | 678 | return(0); |
755 | 57.7k | } |
756 | | |
757 | | int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl, |
758 | 7.26k | float **in,int *nonzero,int ch){ |
759 | 7.26k | int i,used=0; |
760 | 305k | for(i=0;i<ch;i++) |
761 | 298k | if(nonzero[i]) |
762 | 8.92k | in[used++]=in[i]; |
763 | 7.26k | if(used) |
764 | 3.20k | return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add)); |
765 | 4.05k | else |
766 | 4.05k | return(0); |
767 | 7.26k | } |
768 | | |
769 | | long **res2_class(vorbis_block *vb,vorbis_look_residue *vl, |
770 | 4.65k | int **in,int *nonzero,int ch){ |
771 | 4.65k | int i,used=0; |
772 | 13.9k | for(i=0;i<ch;i++) |
773 | 9.31k | if(nonzero[i])used++; |
774 | 4.65k | if(used) |
775 | 4.15k | return(_2class(vb,vl,in,ch)); |
776 | 508 | else |
777 | 508 | return(0); |
778 | 4.65k | } |
779 | | |
780 | | /* res2 is slightly more different; all the channels are interleaved |
781 | | into a single vector and encoded. */ |
782 | | |
783 | | int res2_forward(oggpack_buffer *opb, |
784 | | vorbis_block *vb,vorbis_look_residue *vl, |
785 | 4.65k | int **in,int *nonzero,int ch, long **partword,int submap){ |
786 | 4.65k | long i,j,k,n=vb->pcmend/2,used=0; |
787 | | |
788 | | /* don't duplicate the code; use a working vector hack for now and |
789 | | reshape ourselves into a single channel res1 */ |
790 | | /* ugly; reallocs for each coupling pass :-( */ |
791 | 4.65k | int *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work)); |
792 | 13.9k | for(i=0;i<ch;i++){ |
793 | 9.31k | int *pcm=in[i]; |
794 | 9.31k | if(nonzero[i])used++; |
795 | 1.98M | for(j=0,k=i;j<n;j++,k+=ch) |
796 | 1.97M | work[k]=pcm[j]; |
797 | 9.31k | } |
798 | | |
799 | 4.65k | if(used){ |
800 | | #ifdef TRAIN_RES |
801 | | return _01forward(opb,vl,&work,1,partword,_encodepart,submap); |
802 | | #else |
803 | 4.15k | (void)submap; |
804 | 4.15k | return _01forward(opb,vl,&work,1,partword,_encodepart); |
805 | 4.15k | #endif |
806 | 4.15k | }else{ |
807 | 508 | return(0); |
808 | 508 | } |
809 | 4.65k | } |
810 | | |
811 | | /* duplicate code here as speed is somewhat more important */ |
812 | | int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl, |
813 | 32.5k | float **in,int *nonzero,int ch){ |
814 | 32.5k | long i,k,l,s; |
815 | 32.5k | vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl; |
816 | 32.5k | vorbis_info_residue0 *info=look->info; |
817 | 32.5k | dec_codebook *phrasebook=look->decbooks+look->phrasebook; |
818 | | |
819 | | /* move all this setup out later */ |
820 | 32.5k | int samples_per_partition=info->grouping; |
821 | 32.5k | int partitions_per_word=phrasebook->dim; |
822 | 32.5k | int max=(vb->pcmend*ch)>>1; |
823 | 32.5k | int end=(info->end<max?info->end:max); |
824 | 32.5k | int n=end-info->begin; |
825 | | |
826 | 32.5k | if(n>0){ |
827 | 16.0k | int partvals=n/samples_per_partition; |
828 | 16.0k | int partwords=(partvals+partitions_per_word-1)/partitions_per_word; |
829 | 16.0k | int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword)); |
830 | | |
831 | 145k | for(i=0;i<ch;i++)if(nonzero[i])break; |
832 | 16.0k | if(i==ch)return(0); /* no nonzero vectors */ |
833 | | |
834 | 24.2k | for(s=0;s<look->stages;s++){ |
835 | 257k | for(i=0,l=0;i<partvals;l++){ |
836 | | |
837 | 240k | if(s==0){ |
838 | | /* fetch the partition word */ |
839 | 64.6k | int temp=vorbis_book_decode(phrasebook,&vb->opb); |
840 | 64.6k | if(temp==-1 || temp>=info->partvals)goto eopbreak; |
841 | 61.7k | partword[l]=look->decodemap[temp]; |
842 | 61.7k | if(partword[l]==NULL)goto errout; |
843 | 61.7k | } |
844 | | |
845 | | /* now we decode residual values for the partitions */ |
846 | 592k | for(k=0;k<partitions_per_word && i<partvals;k++,i++) |
847 | 355k | if(info->secondstages[partword[l][k]]&(1<<s)){ |
848 | 101k | int stagebooknum=look->partbooks[partword[l][k]][s]; |
849 | | |
850 | 101k | if(stagebooknum>=0){ |
851 | 101k | dec_codebook *stagebook=look->decbooks+stagebooknum; |
852 | 101k | if(vorbis_book_decodevv_add(stagebook,in, |
853 | 101k | i*samples_per_partition+info->begin,ch, |
854 | 101k | &vb->opb,samples_per_partition)==-1) |
855 | 1.59k | goto eopbreak; |
856 | 101k | } |
857 | 101k | } |
858 | 238k | } |
859 | 21.0k | } |
860 | 7.74k | } |
861 | 19.6k | errout: |
862 | 24.2k | eopbreak: |
863 | 24.2k | return(0); |
864 | 19.6k | } |
865 | | |
866 | | |
867 | | const vorbis_func_residue residue0_exportbundle={ |
868 | | NULL, |
869 | | &res0_unpack, |
870 | | &res0_look, |
871 | | &res0_free_info, |
872 | | &res0_free_look, |
873 | | NULL, |
874 | | NULL, |
875 | | &res0_inverse |
876 | | }; |
877 | | |
878 | | const vorbis_func_residue residue1_exportbundle={ |
879 | | &res0_pack, |
880 | | &res0_unpack, |
881 | | &res0_look, |
882 | | &res0_free_info, |
883 | | &res0_free_look, |
884 | | &res1_class, |
885 | | &res1_forward, |
886 | | &res1_inverse |
887 | | }; |
888 | | |
889 | | const vorbis_func_residue residue2_exportbundle={ |
890 | | &res0_pack, |
891 | | &res0_unpack, |
892 | | &res0_look, |
893 | | &res0_free_info, |
894 | | &res0_free_look, |
895 | | &res2_class, |
896 | | &res2_forward, |
897 | | &res2_inverse |
898 | | }; |