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.23 2000/08/23 10:16:56 xiphmont Exp $
17 ********************************************************************/
22 #include "vorbis/codec.h"
27 #include "bookinternal.h"
28 #include "sharedbook.h"
42 vorbis_info_floor0 *vi;
48 /* infrastructure for finding fit */
49 static long _f0_fit(codebook *book,
54 double norm,base=0.,err=0.;
56 double *lsp=workfit+cursor;
58 if(cursor)base=workfit[cursor-1];
59 norm=orig[cursor+dim-1]-base;
62 lsp[i]=(orig[i+cursor]-base);
63 best=_best(book,lsp,1);
65 memcpy(lsp,book->valuelist+best*dim,dim*sizeof(double));
71 /***********************************************/
73 static void free_info(vorbis_info_floor *i){
75 memset(i,0,sizeof(vorbis_info_floor0));
80 static void free_look(vorbis_look_floor *i){
81 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
83 if(look->linearmap)free(look->linearmap);
84 if(look->lsp_look)free(look->lsp_look);
85 lpc_clear(&look->lpclook);
86 memset(look,0,sizeof(vorbis_look_floor0));
91 static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
92 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
94 _oggpack_write(opb,info->order,8);
95 _oggpack_write(opb,info->rate,16);
96 _oggpack_write(opb,info->barkmap,16);
97 _oggpack_write(opb,info->ampbits,6);
98 _oggpack_write(opb,info->ampdB,8);
99 _oggpack_write(opb,info->numbooks-1,4);
100 for(j=0;j<info->numbooks;j++)
101 _oggpack_write(opb,info->books[j],8);
104 static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){
106 vorbis_info_floor0 *info=malloc(sizeof(vorbis_info_floor0));
107 info->order=_oggpack_read(opb,8);
108 info->rate=_oggpack_read(opb,16);
109 info->barkmap=_oggpack_read(opb,16);
110 info->ampbits=_oggpack_read(opb,6);
111 info->ampdB=_oggpack_read(opb,8);
112 info->numbooks=_oggpack_read(opb,4)+1;
114 if(info->order<1)goto err_out;
115 if(info->rate<1)goto err_out;
116 if(info->barkmap<1)goto err_out;
117 if(info->numbooks<1)goto err_out;
119 for(j=0;j<info->numbooks;j++){
120 info->books[j]=_oggpack_read(opb,8);
121 if(info->books[j]<0 || info->books[j]>=vi->books)goto err_out;
129 /* initialize Bark scale and normalization lookups. We could do this
130 with static tables, but Vorbis allows a number of possible
131 combinations, so it's best to do it computationally.
133 The below is authoritative in terms of defining scale mapping.
134 Note that the scale depends on the sampling rate as well as the
135 linear block and mapping sizes */
137 static vorbis_look_floor *look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
138 vorbis_info_floor *i){
141 vorbis_info *vi=vd->vi;
142 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
143 vorbis_look_floor0 *look=calloc(1,sizeof(vorbis_look_floor0));
145 look->n=vi->blocksizes[mi->blockflag]/2;
146 look->ln=info->barkmap;
150 lpc_init(&look->lpclook,look->ln,look->m);
152 /* we choose a scaling constant so that:
153 floor(bark(rate/2-1)*C)=mapped-1
154 floor(bark(rate/2)*C)=mapped */
155 scale=look->ln/toBARK(info->rate/2.);
157 /* the mapping from a linear scale to a smaller bark scale is
158 straightforward. We do *not* make sure that the linear mapping
159 does not skip bark-scale bins; the decoder simply skips them and
160 the encoder may do what it wishes in filling them. They're
161 necessary in some mapping combinations to keep the scale spacing
163 look->linearmap=malloc(look->n*sizeof(int));
164 for(j=0;j<look->n;j++){
165 int val=floor( toBARK((info->rate/2.)/look->n*j)
166 *scale); /* bark numbers represent band edges */
167 if(val>look->ln)val=look->ln; /* guard against the approximation */
168 look->linearmap[j]=val;
171 look->lsp_look=malloc(look->ln*sizeof(double));
172 for(j=0;j<look->ln;j++)
173 look->lsp_look[j]=2*cos(M_PI/look->ln*j);
178 /* less efficient than the decode side (written for clarity). We're
179 not bottlenecked here anyway */
181 double _curve_to_lpc(double *curve,double *lpc,
182 vorbis_look_floor0 *l,long frameno){
183 /* map the input curve to a bark-scale curve for encoding */
186 double *work=alloca(sizeof(double)*mapped);
190 memset(work,0,sizeof(double)*mapped);
192 /* Only the decode side is behavior-specced; for now in the encoder,
193 we select the maximum value of each band as representative (this
194 helps make sure peaks don't go out of range. In error terms,
195 selecting min would make more sense, but the codebook is trained
196 numerically, so we don't actually lose. We'd still want to
197 use the original curve for error and noise estimation */
200 bark=l->linearmap[i];
201 if(work[bark]<curve[i])work[bark]=curve[i];
203 /* If the bark scale is climbing rapidly, some bins may end up
204 going unused. This isn't a waste actually; it keeps the
205 scale resolution even so that the LPC generator has an easy
206 time. However, if we leave the bins empty we lose energy.
207 So, fill 'em in. The decoder does not do anything with he
208 unused bins, so we can fill them anyway we like to end up
209 with a better spectral curve */
211 /* we'll always have a bin zero, so we don't need to guard init */
214 double del=(double)j/span;
215 work[j+last]=work[bark]*del+work[last]*(1.-del);
221 /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
222 for(i=bark+1;i<mapped;i++)
226 { /******************/
231 sprintf(buffer,"Fmask_%d.m",frameno);
232 of=fopen(buffer,"w");
233 for(i=0;i<mapped;i++)
234 fprintf(of,"%g\n",work[i]);
239 return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
242 /* generate the whole freq response curve of an LPC IIR filter */
244 void _lsp_to_curve(double *curve,double *lsp,double amp,
245 vorbis_look_floor0 *l,char *name,long frameno){
246 /* l->m+1 must be less than l->ln, but guard in case we get a bad stream */
247 double *lcurve=alloca(sizeof(double)*l->ln);
251 memset(curve,0,sizeof(double)*l->n);
254 vorbis_lsp_to_curve(lcurve,l->ln,lsp,l->m,amp,l->lsp_look);
256 for(i=0;i<l->n;i++)curve[i]=lcurve[l->linearmap[i]];
261 static int forward(vorbis_block *vb,vorbis_look_floor *i,
262 double *in,double *out){
264 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
265 vorbis_info_floor0 *info=look->vi;
266 double *work=alloca((look->ln+look->n)*sizeof(double));
276 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
277 of=fopen(buffer,"a");
280 sprintf(buffer,"lsp0ent_%d.vqd",vb->mode);
281 ef=fopen(buffer,"a");
284 /* our floor comes in on a linear scale; go to a [-Inf...0] dB
285 scale. The curve has to be positive, so we offset it. */
287 for(j=0;j<look->n;j++){
288 double val=todB(in[j])+info->ampdB;
295 /* use 'out' as temp storage */
296 /* Convert our floor to a set of lpc coefficients */
297 amp=sqrt(_curve_to_lpc(work,out,look,seq));
299 /* amp is in the range (0. to ampdB]. Encode that range using
303 long maxval=(1L<<info->ampbits)-1;
305 long val=rint(amp/info->ampdB*maxval);
307 if(val<0)val=0; /* likely */
308 if(val>maxval)val=maxval; /* not bloody likely */
310 _oggpack_write(&vb->opb,val,info->ampbits);
312 amp=(float)val/maxval*info->ampdB;
319 /* the spec supports using one of a number of codebooks. Right
320 now, encode using this lib supports only one */
321 codebook *b=vb->vd->fullbooks+info->books[0];
322 _oggpack_write(&vb->opb,0,_ilog(info->numbooks));
324 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
325 vorbis_lpc_to_lsp(out,out,look->m);
331 for(j=0;j<look->m;j++){
332 fprintf(of,"%.12g, ",out[j]-last);
341 /* code the spectral envelope, and keep track of the actual
342 quantized values; we don't want creeping error as each block is
343 nailed to the last quantized value of the previous block. */
345 for(j=0;j<look->m;j+=b->dim){
346 int entry=_f0_fit(b,out,work,j);
347 bits+=vorbis_book_encode(b,entry,&vb->opb);
350 fprintf(ef,"%d,\n",entry);
358 for(j=0;j<look->m;j++){
363 _analysis_output("lsp",seq,out,look->m,0,0);
371 /* take the coefficients back to a spectral envelope curve */
372 _lsp_to_curve(out,work,amp,look,"Ffloor",seq++);
373 for(j=0;j<look->n;j++)out[j]= fromdB(out[j]-info->ampdB);
377 memset(out,0,sizeof(double)*look->n);
382 static int inverse(vorbis_block *vb,vorbis_look_floor *i,double *out){
383 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
384 vorbis_info_floor0 *info=look->vi;
387 int ampraw=_oggpack_read(&vb->opb,info->ampbits);
388 if(ampraw>0){ /* also handles the -1 out of data case */
389 long maxval=(1<<info->ampbits)-1;
390 double amp=(float)ampraw/maxval*info->ampdB;
391 int booknum=_oggpack_read(&vb->opb,_ilog(info->numbooks));
394 codebook *b=vb->vd->fullbooks+info->books[booknum];
397 memset(out,0,sizeof(double)*look->m);
399 for(j=0;j<look->m;j+=b->dim)
400 if(vorbis_book_decodevs(b,out+j,&vb->opb,1,-1)==-1)goto eop;
402 for(k=0;k<b->dim;k++,j++)out[j]+=last;
406 /* take the coefficients back to a spectral envelope curve */
407 _lsp_to_curve(out,out,amp,look,"",0);
409 for(j=0;j<look->n;j++)out[j]=fromdB(out[j]-info->ampdB);
415 memset(out,0,sizeof(double)*look->n);
420 vorbis_func_floor floor0_exportbundle={
421 &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse