1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
9 * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: floor backend 0 implementation
15 last mod: $Id: floor0.c,v 1.15 2000/06/14 01:38:31 xiphmont Exp $
17 ********************************************************************/
22 #include "vorbis/codec.h"
27 #include "bookinternal.h"
28 #include "sharedbook.h"
39 vorbis_info_floor0 *vi;
48 } vorbis_echstate_floor0;
50 static void free_info(vorbis_info_floor *i){
52 memset(i,0,sizeof(vorbis_info_floor0));
57 static void free_look(vorbis_look_floor *i){
58 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
60 if(look->linearmap)free(look->linearmap);
61 lpc_clear(&look->lpclook);
62 memset(look,0,sizeof(vorbis_look_floor0));
67 static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
68 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
70 _oggpack_write(opb,info->order,8);
71 _oggpack_write(opb,info->rate,16);
72 _oggpack_write(opb,info->barkmap,16);
73 _oggpack_write(opb,info->ampbits,6);
74 _oggpack_write(opb,info->ampdB,8);
75 _oggpack_write(opb,info->numbooks-1,4);
76 for(j=0;j<info->numbooks;j++)
77 _oggpack_write(opb,info->books[j],8);
80 static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){
82 vorbis_info_floor0 *info=malloc(sizeof(vorbis_info_floor0));
83 info->order=_oggpack_read(opb,8);
84 info->rate=_oggpack_read(opb,16);
85 info->barkmap=_oggpack_read(opb,16);
86 info->ampbits=_oggpack_read(opb,6);
87 info->ampdB=_oggpack_read(opb,8);
88 info->numbooks=_oggpack_read(opb,4)+1;
90 if(info->order<1)goto err_out;
91 if(info->rate<1)goto err_out;
92 if(info->barkmap<1)goto err_out;
93 if(info->numbooks<1)goto err_out;
95 for(j=0;j<info->numbooks;j++){
96 info->books[j]=_oggpack_read(opb,8);
97 if(info->books[j]<0 || info->books[j]>=vi->books)goto err_out;
105 /* initialize Bark scale and normalization lookups. We could do this
106 with static tables, but Vorbis allows a number of possible
107 combinations, so it's best to do it computationally.
109 The below is authoritative in terms of defining scale mapping.
110 Note that the scale depends on the sampling rate as well as the
111 linear block and mapping sizes */
113 static vorbis_look_floor *look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
114 vorbis_info_floor *i){
117 vorbis_info *vi=vd->vi;
118 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
119 vorbis_look_floor0 *look=malloc(sizeof(vorbis_look_floor0));
121 look->n=vi->blocksizes[mi->blockflag]/2;
122 look->ln=info->barkmap;
124 lpc_init(&look->lpclook,look->ln,look->m);
126 /* we choose a scaling constant so that:
127 floor(bark(rate/2-1)*C)=mapped-1
128 floor(bark(rate/2)*C)=mapped */
129 scale=look->ln/toBARK(info->rate/2.);
131 /* the mapping from a linear scale to a smaller bark scale is
132 straightforward. We do *not* make sure that the linear mapping
133 does not skip bark-scale bins; the decoder simply skips them and
134 the encoder may do what it wishes in filling them. They're
135 necessary in some mapping combinations to keep the scale spacing
137 look->linearmap=malloc(look->n*sizeof(int));
138 for(j=0;j<look->n;j++){
139 int val=floor( toBARK((info->rate/2.)/look->n*j)
140 *scale); /* bark numbers represent band edges */
141 if(val>look->ln)val=look->ln; /* guard against the approximation */
142 look->linearmap[j]=val;
147 static vorbis_echstate_floor *state (vorbis_info_floor *i){
148 vorbis_echstate_floor0 *state=calloc(1,sizeof(vorbis_echstate_floor0));
149 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
151 /* a safe size if usually too big (dim==1) */
152 state->codewords=malloc(info->order*sizeof(long));
153 state->curve=malloc(info->barkmap*sizeof(double));
158 static void free_state (vorbis_echstate_floor *vs){
159 vorbis_echstate_floor0 *state=(vorbis_echstate_floor0 *)vs;
161 free(state->codewords);
163 memset(state,0,sizeof(vorbis_echstate_floor0));
170 double _curve_error(double *curve1,double *curve2,long n){
174 double val=curve1[i]-curve2[i];
180 /* less efficient than the decode side (written for clarity). We're
181 not bottlenecked here anyway */
183 double _curve_to_lpc(double *curve,double *lpc,
184 vorbis_look_floor0 *l,long frameno){
185 /* map the input curve to a bark-scale curve for encoding */
188 double *work=alloca(sizeof(double)*mapped);
192 memset(work,0,sizeof(double)*mapped);
194 /* Only the decode side is behavior-specced; for now in the encoder,
195 we select the maximum value of each band as representative (this
196 helps make sure peaks don't go out of range. In error terms,
197 selecting min would make more sense, but the codebook is trained
198 numerically, so we don't actually lose. We'd still want to
199 use the original curve for error and noise estimation */
202 bark=l->linearmap[i];
203 if(work[bark]<curve[i])work[bark]=curve[i];
205 /* If the bark scale is climbing rapidly, some bins may end up
206 going unused. This isn't a waste actually; it keeps the
207 scale resolution even so that the LPC generator has an easy
208 time. However, if we leave the bins empty we lose energy.
209 So, fill 'em in. The decoder does not do anything with he
210 unused bins, so we can fill them anyway we like to end up
211 with a better spectral curve */
213 /* we'll always have a bin zero, so we don't need to guard init */
216 double del=(double)j/span;
217 work[j+last]=work[bark]*del+work[last]*(1.-del);
223 /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
224 for(i=bark+1;i<mapped;i++)
228 { /******************/
233 sprintf(buffer,"Fmask_%d.m",frameno);
234 of=fopen(buffer,"w");
235 for(i=0;i<mapped;i++)
236 fprintf(of,"%g\n",work[i]);
241 return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
244 /* generate the whole freq response curve of an LPC IIR filter */
246 void _lpc_to_curve(double *curve,double *lpc,double amp,
247 vorbis_look_floor0 *l,char *name,long frameno){
248 /* l->m+1 must be less than l->ln, but guard in case we get a bad stream */
249 double *lcurve=alloca(sizeof(double)*max(l->ln*2,l->m*2+2));
253 memset(curve,0,sizeof(double)*l->n);
256 vorbis_lpc_to_curve(lcurve,lpc,amp,&(l->lpclook));
259 { /******************/
264 sprintf(buffer,"%s_%d.m",name,frameno);
265 of=fopen(buffer,"w");
267 fprintf(of,"%g\n",lcurve[i]);
272 for(i=0;i<l->n;i++)curve[i]=lcurve[l->linearmap[i]];
277 static int forward(vorbis_block *vb,vorbis_look_floor *i,
278 double *in,double *out,vorbis_echstate_floor *vs){
280 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
281 vorbis_info_floor0 *info=look->vi;
282 vorbis_echstate_floor0 *state=(vorbis_echstate_floor0 *)vs;
283 double *work=alloca(look->n*sizeof(double));
287 /* our floor comes in on a linear scale; go to a [-Inf...0] dB
288 scale. The curve has to be positive, so we offset it. */
290 for(j=0;j<look->n;j++)work[j]=todB(in[j])+info->ampdB;
292 /* use 'out' as temp storage */
293 /* Convert our floor to a set of lpc coefficients */
294 amp=sqrt(_curve_to_lpc(work,out,look,seq));
296 /* amp is in the range (0. to ampdB]. Encode that range using
300 long maxval=(1L<<info->ampbits)-1;
302 long val=rint(amp/info->ampdB*maxval);
304 if(val<0)val=0; /* likely */
305 if(val>maxval)val=maxval; /* not bloody likely */
307 _oggpack_write(&vb->opb,val,info->ampbits);
309 amp=(float)val/maxval*info->ampdB;
315 double *refcurve=alloca(sizeof(double)*max(look->ln*2,look->m*2+2));
316 double *newcurve=alloca(sizeof(double)*max(look->ln*2,look->m*2+2));
317 long *codelist=alloca(sizeof(long)*look->m);
321 if(state->frameno == vb->sequence){
322 /* generate a reference curve for testing */
323 vorbis_lpc_to_curve(refcurve,out,1,&(look->lpclook));
326 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
327 vorbis_lpc_to_lsp(out,out,look->m);
334 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
335 of=fopen(buffer,"a");
336 for(j=0;j<look->m;j++)
337 fprintf(of,"%.12g, ",out[j]);
343 /* code the spectral envelope, and keep track of the actual
344 quantized values; we don't want creeping error as each block is
345 nailed to the last quantized value of the previous block. */
347 /* A new development: the code selection is based on error against
348 the LSP coefficients and not the curve it produces. Because
349 the coefficient error is not linearly related to the curve
350 error, the fit we select is usually nonoptimal (but
351 sufficient). This is fine, but flailing about causes a problem
352 in generally consistent spectra... so we add hysterisis. */
354 /* select a new fit, but don't code it. Just grab it for testing */
356 /* the spec supports using one of a number of codebooks. Right
357 now, encode using this lib supports only one */
358 codebook *b=vb->vd->fullbooks+info->books[0];
362 for(k=0;k<b->dim;k++)out[j+k]-=last;
363 codelist[codes++]=vorbis_book_errorv(b,out+j);
364 for(k=0;k<b->dim;k++,j++)out[j]+=last;
368 vorbis_lsp_to_lpc(out,out,look->m);
369 vorbis_lpc_to_curve(newcurve,out,1,&(look->lpclook));
371 /* if we're out of sequence, no hysterisis this frame, else check it */
372 if(state->frameno != vb->sequence ||
373 _curve_error(refcurve,newcurve,look->ln)<
374 _curve_error(refcurve,state->curve,look->ln)){
375 /* new curve is the fit to use. replace the state */
376 memcpy(state->curve,newcurve,sizeof(double)*look->ln);
377 memcpy(state->codewords,codelist,sizeof(long)*codes);
381 /*fprintf(stderr,"X");*/
382 codelist=state->codewords;
386 state->frameno=vb->sequence+1;
388 /* the spec supports using one of a number of codebooks. Right
389 now, encode using this lib supports only one */
390 _oggpack_write(&vb->opb,0,_ilog(info->numbooks));
393 codebook *b=vb->vd->fullbooks+info->books[0];
395 for(l=0,j=0;l<codes;l++){
396 bits+=vorbis_book_encodev(b,codelist[l],out+j,&vb->opb);
397 for(k=0;k<b->dim;k++,j++)out[j]+=last;
402 /* take the coefficients back to a spectral envelope curve */
403 vorbis_lsp_to_lpc(out,out,look->m);
404 _lpc_to_curve(out,out,amp,look,"Ffloor",seq);
405 for(j=0;j<look->n;j++)out[j]= fromdB(out[j]-info->ampdB);
409 memset(out,0,sizeof(double)*look->n);
414 static int inverse(vorbis_block *vb,vorbis_look_floor *i,double *out){
415 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
416 vorbis_info_floor0 *info=look->vi;
419 int ampraw=_oggpack_read(&vb->opb,info->ampbits);
421 long maxval=(1<<info->ampbits)-1;
422 double amp=(float)ampraw/maxval*info->ampdB;
423 int booknum=_oggpack_read(&vb->opb,_ilog(info->numbooks));
424 codebook *b=vb->vd->fullbooks+info->books[booknum];
427 memset(out,0,sizeof(double)*look->m);
429 for(j=0;j<look->m;j+=b->dim)
430 vorbis_book_decodevs(b,out+j,&vb->opb,1,-1);
432 for(k=0;k<b->dim;k++,j++)out[j]+=last;
436 /* take the coefficients back to a spectral envelope curve */
437 vorbis_lsp_to_lpc(out,out,look->m);
438 _lpc_to_curve(out,out,amp,look,"",0);
440 for(j=0;j<look->n;j++)out[j]= fromdB(out[j]-info->ampdB);
443 memset(out,0,sizeof(double)*look->n);
449 vorbis_func_floor floor0_exportbundle={
450 &pack,&unpack,&look,&state,&free_info,&free_look,&free_state,&forward,&inverse