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.14 2000/05/08 20:49:48 xiphmont Exp $
17 ********************************************************************/
22 #include "vorbis/codec.h"
27 #include "bookinternal.h"
28 #include "sharedbook.h"
39 vorbis_info_floor0 *vi;
43 static void free_info(vorbis_info_floor *i){
45 memset(i,0,sizeof(vorbis_info_floor0));
50 static void free_look(vorbis_look_floor *i){
51 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
53 if(look->linearmap)free(look->linearmap);
54 lpc_clear(&look->lpclook);
55 memset(look,0,sizeof(vorbis_look_floor0));
60 static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
61 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
63 _oggpack_write(opb,info->order,8);
64 _oggpack_write(opb,info->rate,16);
65 _oggpack_write(opb,info->barkmap,16);
66 _oggpack_write(opb,info->ampbits,6);
67 _oggpack_write(opb,info->ampdB,8);
68 _oggpack_write(opb,info->numbooks-1,4);
69 for(j=0;j<info->numbooks;j++)
70 _oggpack_write(opb,info->books[j],8);
73 static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){
75 vorbis_info_floor0 *info=malloc(sizeof(vorbis_info_floor0));
76 info->order=_oggpack_read(opb,8);
77 info->rate=_oggpack_read(opb,16);
78 info->barkmap=_oggpack_read(opb,16);
79 info->ampbits=_oggpack_read(opb,6);
80 info->ampdB=_oggpack_read(opb,8);
81 info->numbooks=_oggpack_read(opb,4)+1;
83 if(info->order<1)goto err_out;
84 if(info->rate<1)goto err_out;
85 if(info->barkmap<1)goto err_out;
86 if(info->numbooks<1)goto err_out;
88 for(j=0;j<info->numbooks;j++){
89 info->books[j]=_oggpack_read(opb,8);
90 if(info->books[j]<0 || info->books[j]>=vi->books)goto err_out;
98 /* initialize Bark scale and normalization lookups. We could do this
99 with static tables, but Vorbis allows a number of possible
100 combinations, so it's best to do it computationally.
102 The below is authoritative in terms of defining scale mapping.
103 Note that the scale depends on the sampling rate as well as the
104 linear block and mapping sizes */
106 static vorbis_look_floor *look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
107 vorbis_info_floor *i){
110 vorbis_info *vi=vd->vi;
111 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
112 vorbis_look_floor0 *look=malloc(sizeof(vorbis_look_floor0));
114 look->n=vi->blocksizes[mi->blockflag]/2;
115 look->ln=info->barkmap;
117 lpc_init(&look->lpclook,look->ln,look->m);
119 /* we choose a scaling constant so that:
120 floor(bark(rate/2-1)*C)=mapped-1
121 floor(bark(rate/2)*C)=mapped */
122 scale=look->ln/toBARK(info->rate/2.);
124 /* the mapping from a linear scale to a smaller bark scale is
125 straightforward. We do *not* make sure that the linear mapping
126 does not skip bark-scale bins; the decoder simply skips them and
127 the encoder may do what it wishes in filling them. They're
128 necessary in some mapping combinations to keep the scale spacing
130 look->linearmap=malloc(look->n*sizeof(int));
131 for(j=0;j<look->n;j++){
132 int val=floor( toBARK((info->rate/2.)/look->n*j)
133 *scale); /* bark numbers represent band edges */
134 if(val>look->ln)val=look->ln; /* guard against the approximation */
135 look->linearmap[j]=val;
143 /* less efficient than the decode side (written for clarity). We're
144 not bottlenecked here anyway */
145 double _curve_to_lpc(double *curve,double *lpc,vorbis_look_floor0 *l,
147 /* map the input curve to a bark-scale curve for encoding */
150 double *work=alloca(sizeof(double)*mapped);
153 memset(work,0,sizeof(double)*mapped);
155 /* Only the decode side is behavior-specced; for now in the encoder,
156 we select the maximum value of each band as representative (this
157 helps make sure peaks don't go out of range. In error terms,
158 selecting min would make more sense, but the codebook is trained
159 numerically, so we don't actually lose. We'd still want to
160 use the original curve for error and noise estimation */
163 int bark=l->linearmap[i];
164 if(work[bark]<curve[i])work[bark]=curve[i];
166 /* If the bark scale is climbing rapidly, some bins may end up
167 going unused. This isn't a waste actually; it keeps the
168 scale resolution even so that the LPC generator has an easy
169 time. However, if we leave the bins empty we lose energy.
170 So, fill 'em in. The decoder does not do anything with he
171 unused bins, so we can fill them anyway we like to end up
172 with a better spectral curve */
174 /* we'll always have a bin zero, so we don't need to guard init */
177 double del=(double)j/span;
178 work[j+last]=work[bark]*del+work[last]*(1.-del);
185 { /******************/
190 sprintf(buffer,"Fmask_%d.m",frameno);
191 of=fopen(buffer,"w");
192 for(i=0;i<mapped;i++)
193 fprintf(of,"%g\n",work[i]);
198 return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
201 /* generate the whole freq response curve of an LPC IIR filter */
203 void _lpc_to_curve(double *curve,double *lpc,double amp,
204 vorbis_look_floor0 *l,char *name,long frameno){
205 double *lcurve=alloca(sizeof(double)*(l->ln*2));
209 memset(curve,0,sizeof(double)*l->n);
212 vorbis_lpc_to_curve(lcurve,lpc,amp,&(l->lpclook));
215 { /******************/
220 sprintf(buffer,"%s_%d.m",name,frameno);
221 of=fopen(buffer,"w");
223 fprintf(of,"%g\n",lcurve[i]);
228 for(i=0;i<l->n;i++)curve[i]=lcurve[l->linearmap[i]];
233 static int forward(vorbis_block *vb,vorbis_look_floor *i,
234 double *in,double *out){
236 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
237 vorbis_info_floor0 *info=look->vi;
238 double *work=alloca(look->n*sizeof(double));
242 /* our floor comes in on a linear scale; go to a [-Inf...0] dB
243 scale. The curve has to be positive, so we offset it. */
244 for(j=0;j<look->n;j++)work[j]=todB(in[j])+info->ampdB;
246 /* use 'out' as temp storage */
247 /* Convert our floor to a set of lpc coefficients */
248 amp=sqrt(_curve_to_lpc(work,out,look,vb->sequence));
250 /* amp is in the range (0. to ampdB]. Encode that range using
254 long maxval=(1<<info->ampbits)-1;
256 long val=rint(amp/info->ampdB*maxval);
258 if(val<0)val=0; /* likely */
259 if(val>maxval)val=maxval; /* not bloody likely */
261 _oggpack_write(&vb->opb,val,info->ampbits);
263 amp=(float)val/maxval*info->ampdB;
270 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
271 vorbis_lpc_to_lsp(out,out,look->m);
273 if(vb->mode==0)_analysis_output("lsp",seq++,out,look->m,0,0);
280 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
281 of=fopen(buffer,"a");
282 for(j=0;j<look->m;j++)
283 fprintf(of,"%g, ",out[j]);
290 { /******************/
291 vorbis_lsp_to_lpc(out,work,look->m);
292 _lpc_to_curve(work,work,amp,look,"Fprefloor",vb->sequence);
296 /* code the spectral envelope, and keep track of the actual
297 quantized values; we don't want creeping error as each block is
298 nailed to the last quantized value of the previous block. */
300 /* the spec supports using one of a number of codebooks. Right
301 now, encode using this lib supports only one */
302 _oggpack_write(&vb->opb,0,_ilog(info->numbooks));
305 codebook *b=vb->vd->fullbooks+info->books[0];
308 for(k=0;k<b->dim;k++)out[j+k]-=last;
309 bits+=vorbis_book_encodev(b,out+j,&vb->opb);
310 for(k=0;k<b->dim;k++,j++)out[j]+=last;
315 /* take the coefficients back to a spectral envelope curve */
316 vorbis_lsp_to_lpc(out,out,look->m);
317 _lpc_to_curve(out,out,amp,look,"Ffloor",vb->sequence);
318 for(j=0;j<look->n;j++)out[j]= fromdB(out[j]-info->ampdB);
322 memset(out,0,sizeof(double)*look->n);
326 static int inverse(vorbis_block *vb,vorbis_look_floor *i,double *out){
327 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
328 vorbis_info_floor0 *info=look->vi;
331 int ampraw=_oggpack_read(&vb->opb,info->ampbits);
333 long maxval=(1<<info->ampbits)-1;
334 double amp=(float)ampraw/maxval*info->ampdB;
335 int booknum=_oggpack_read(&vb->opb,_ilog(info->numbooks));
336 codebook *b=vb->vd->fullbooks+info->books[booknum];
339 memset(out,0,sizeof(double)*look->m);
341 for(j=0;j<look->m;j+=b->dim)
342 vorbis_book_decodevs(b,out+j,&vb->opb,1,-1);
344 for(k=0;k<b->dim;k++,j++)out[j]+=last;
348 /* take the coefficients back to a spectral envelope curve */
349 vorbis_lsp_to_lpc(out,out,look->m);
350 _lpc_to_curve(out,out,amp,look,"",0);
352 for(j=0;j<look->n;j++)out[j]= fromdB(out[j]-info->ampdB);
355 memset(out,0,sizeof(double)*look->n);
361 vorbis_func_floor floor0_exportbundle={
362 &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse