1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU LESSER/LIBRARY PUBLIC LICENSE, WHICH IS INCLUDED WITH *
6 * THIS SOURCE. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the XIPHOPHORUS Company http://www.xiph.org/ *
11 ********************************************************************
13 function: floor backend 0 implementation
14 last mod: $Id: floor0.c,v 1.38 2001/02/17 10:13:47 xiphmont Exp $
16 ********************************************************************/
22 #include "vorbis/codec.h"
23 #include "codec_internal.h"
41 vorbis_info_floor0 *vi;
47 /* infrastructure for finding fit */
48 static long _f0_fit(codebook *book,
55 float *lsp=workfit+cursor;
57 if(cursor)base=workfit[cursor-1];
58 norm=orig[cursor+dim-1]-base;
61 lsp[i]=(orig[i+cursor]-base);
62 best=_best(book,lsp,1);
64 memcpy(lsp,book->valuelist+best*dim,dim*sizeof(float));
70 /***********************************************/
72 static vorbis_info_floor *floor0_copy_info (vorbis_info_floor *i){
73 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
74 vorbis_info_floor0 *ret=_ogg_malloc(sizeof(vorbis_info_floor0));
75 memcpy(ret,info,sizeof(vorbis_info_floor0));
79 static void floor0_free_info(vorbis_info_floor *i){
81 memset(i,0,sizeof(vorbis_info_floor0));
86 static void floor0_free_look(vorbis_look_floor *i){
87 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
89 if(look->linearmap)_ogg_free(look->linearmap);
90 if(look->lsp_look)_ogg_free(look->lsp_look);
91 lpc_clear(&look->lpclook);
92 memset(look,0,sizeof(vorbis_look_floor0));
97 static void floor0_pack (vorbis_info_floor *i,oggpack_buffer *opb){
98 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
100 oggpack_write(opb,info->order,8);
101 oggpack_write(opb,info->rate,16);
102 oggpack_write(opb,info->barkmap,16);
103 oggpack_write(opb,info->ampbits,6);
104 oggpack_write(opb,info->ampdB,8);
105 oggpack_write(opb,info->numbooks-1,4);
106 for(j=0;j<info->numbooks;j++)
107 oggpack_write(opb,info->books[j],8);
110 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
111 codec_setup_info *ci=vi->codec_setup;
114 vorbis_info_floor0 *info=_ogg_malloc(sizeof(vorbis_info_floor0));
115 info->order=oggpack_read(opb,8);
116 info->rate=oggpack_read(opb,16);
117 info->barkmap=oggpack_read(opb,16);
118 info->ampbits=oggpack_read(opb,6);
119 info->ampdB=oggpack_read(opb,8);
120 info->numbooks=oggpack_read(opb,4)+1;
122 if(info->order<1)goto err_out;
123 if(info->rate<1)goto err_out;
124 if(info->barkmap<1)goto err_out;
125 if(info->numbooks<1)goto err_out;
127 for(j=0;j<info->numbooks;j++){
128 info->books[j]=oggpack_read(opb,8);
129 if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
134 floor0_free_info(info);
138 /* initialize Bark scale and normalization lookups. We could do this
139 with static tables, but Vorbis allows a number of possible
140 combinations, so it's best to do it computationally.
142 The below is authoritative in terms of defining scale mapping.
143 Note that the scale depends on the sampling rate as well as the
144 linear block and mapping sizes */
146 static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
147 vorbis_info_floor *i){
150 vorbis_info *vi=vd->vi;
151 codec_setup_info *ci=vi->codec_setup;
152 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
153 vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(vorbis_look_floor0));
155 look->n=ci->blocksizes[mi->blockflag]/2;
156 look->ln=info->barkmap;
160 lpc_init(&look->lpclook,look->ln,look->m);
162 /* we choose a scaling constant so that:
163 floor(bark(rate/2-1)*C)=mapped-1
164 floor(bark(rate/2)*C)=mapped */
165 scale=look->ln/toBARK(info->rate/2.f);
167 /* the mapping from a linear scale to a smaller bark scale is
168 straightforward. We do *not* make sure that the linear mapping
169 does not skip bark-scale bins; the decoder simply skips them and
170 the encoder may do what it wishes in filling them. They're
171 necessary in some mapping combinations to keep the scale spacing
173 look->linearmap=_ogg_malloc((look->n+1)*sizeof(int));
174 for(j=0;j<look->n;j++){
175 int val=floor( toBARK((info->rate/2.f)/look->n*j)
176 *scale); /* bark numbers represent band edges */
177 if(val>=look->ln)val=look->ln; /* guard against the approximation */
178 look->linearmap[j]=val;
180 look->linearmap[j]=-1;
182 look->lsp_look=_ogg_malloc(look->ln*sizeof(float));
183 for(j=0;j<look->ln;j++)
184 look->lsp_look[j]=2*cos(M_PI/look->ln*j);
189 /* less efficient than the decode side (written for clarity). We're
190 not bottlenecked here anyway */
192 float _curve_to_lpc(float *curve,float *lpc,
193 vorbis_look_floor0 *l){
194 /* map the input curve to a bark-scale curve for encoding */
197 float *work=alloca(sizeof(float)*mapped);
201 memset(work,0,sizeof(float)*mapped);
203 /* Only the decode side is behavior-specced; for now in the encoder,
204 we select the maximum value of each band as representative (this
205 helps make sure peaks don't go out of range. In error terms,
206 selecting min would make more sense, but the codebook is trained
207 numerically, so we don't actually lose. We'd still want to
208 use the original curve for error and noise estimation */
211 bark=l->linearmap[i];
212 if(work[bark]<curve[i])work[bark]=curve[i];
214 /* If the bark scale is climbing rapidly, some bins may end up
215 going unused. This isn't a waste actually; it keeps the
216 scale resolution even so that the LPC generator has an easy
217 time. However, if we leave the bins empty we lose energy.
218 So, fill 'em in. The decoder does not do anything with he
219 unused bins, so we can fill them anyway we like to end up
220 with a better spectral curve */
222 /* we'll always have a bin zero, so we don't need to guard init */
225 float del=(float)j/span;
226 work[j+last]=work[bark]*del+work[last]*(1.f-del);
232 /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
233 for(i=bark+1;i<mapped;i++)
236 return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
239 /* generate the whole freq response curve of an LSP IIR filter */
240 /* didn't need in->out seperation, modifies the flr[] vector; takes in
241 a dB scale floor, puts out linear */
242 static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
245 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
246 vorbis_info_floor0 *info=look->vi;
258 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
259 of=fopen(buffer,"a");
266 /* our floor comes in on a [-Inf...0] dB scale. The curve has to be
267 positive, so we offset it. */
269 for(j=0;j<look->n;j++)
272 /* use 'out' as temp storage */
273 /* Convert our floor to a set of lpc coefficients */
274 amp=sqrt(_curve_to_lpc(flr,flr,look));
276 /* amp is in the range (0. to ampdB]. Encode that range using
280 long maxval=(1L<<info->ampbits)-1;
282 val=rint(amp/info->ampdB*maxval);
284 if(val<0)val=0; /* likely */
285 if(val>maxval)val=maxval; /* not bloody likely */
288 amp=(float)val/maxval*info->ampdB;
294 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
295 _analysis_output("lpc",seq-1,flr,look->m,0,0);
296 if(vorbis_lpc_to_lsp(flr,flr,look->m))
301 oggpack_write(&vb->opb,val,info->ampbits);
304 float *lspwork=alloca(look->m*sizeof(float));
306 /* the spec supports using one of a number of codebooks. Right
307 now, encode using this lib supports only one */
308 backend_lookup_state *be=vb->vd->backend_state;
312 _analysis_output("lsp",seq-1,flr,look->m,0,0);
314 /* which codebook to use? We do it only by range right now. */
315 if(info->numbooks>1){
317 for(j=0;j<look->m;j++){
318 float val=flr[j]-last;
319 if(val<info->lessthan || val>info->greaterthan)break;
329 b=be->fullbooks+info->books[booknum];
330 oggpack_write(&vb->opb,booknum,_ilog(info->numbooks));
336 for(j=0;j<look->m;j++){
337 fprintf(of,"%.12g, ",flr[j]-last);
344 sprintf(buffer,"lsp0ent_m%d_b%d.vqd",vb->mode,booknum);
345 ef=fopen(buffer,"a");
349 /* code the spectral envelope, and keep track of the actual
350 quantized values; we don't want creeping error as each block is
351 nailed to the last quantized value of the previous block. */
353 for(j=0;j<look->m;j+=b->dim){
354 int entry=_f0_fit(b,flr,lspwork,j);
355 bits+=vorbis_book_encode(b,entry,&vb->opb);
358 fprintf(ef,"%d,\n",entry);
367 _analysis_output("lsp2",seq-1,lspwork,look->m,0,0);
369 /* take the coefficients back to a spectral envelope curve */
370 vorbis_lsp_to_curve(flr,look->linearmap,look->n,look->ln,
371 lspwork,look->m,amp,info->ampdB);
372 _analysis_output("lsp3",seq-1,flr,look->n,0,1);
380 memset(flr,0,sizeof(float)*look->n);
384 static int floor0_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
385 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
386 vorbis_info_floor0 *info=look->vi;
389 int ampraw=oggpack_read(&vb->opb,info->ampbits);
390 if(ampraw>0){ /* also handles the -1 out of data case */
391 long maxval=(1<<info->ampbits)-1;
392 float amp=(float)ampraw/maxval*info->ampdB;
393 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
394 float *lsp=alloca(sizeof(float)*look->m);
396 if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
397 backend_lookup_state *be=vb->vd->backend_state;
398 codebook *b=be->fullbooks+info->books[booknum];
401 memset(out,0,sizeof(float)*look->m);
403 for(j=0;j<look->m;j+=b->dim)
404 if(vorbis_book_decodevs(b,lsp+j,&vb->opb,1,-1)==-1)goto eop;
406 for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
410 /* take the coefficients back to a spectral envelope curve */
411 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
412 lsp,look->m,amp,info->ampdB);
418 memset(out,0,sizeof(float)*look->n);
423 vorbis_func_floor floor0_exportbundle={
424 &floor0_pack,&floor0_unpack,&floor0_look,&floor0_copy_info,&floor0_free_info,
425 &floor0_free_look,&floor0_forward,&floor0_inverse