1 /********************************************************************
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. *
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.48 2001/12/20 01:00:26 segher Exp $
16 ********************************************************************/
22 #include "vorbis/codec.h"
23 #include "codec_internal.h"
41 vorbis_info_floor0 *vi;
49 /* infrastructure for finding fit */
50 static long _f0_fit(codebook *book,
57 float *lsp=workfit+cursor;
59 if(cursor)base=workfit[cursor-1];
60 norm=orig[cursor+dim-1]-base;
63 lsp[i]=(orig[i+cursor]-base);
64 best=_best(book,lsp,1);
66 memcpy(lsp,book->valuelist+best*dim,dim*sizeof(*lsp));
72 /***********************************************/
74 static vorbis_info_floor *floor0_copy_info (vorbis_info_floor *i){
75 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
76 vorbis_info_floor0 *ret=_ogg_malloc(sizeof(*ret));
77 memcpy(ret,info,sizeof(*ret));
81 static void floor0_free_info(vorbis_info_floor *i){
82 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
84 memset(info,0,sizeof(*info));
89 static void floor0_free_look(vorbis_look_floor *i){
90 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
93 /*fprintf(stderr,"floor 0 bit usage %f\n",
94 (float)look->bits/look->frames);*/
96 if(look->linearmap)_ogg_free(look->linearmap);
97 if(look->lsp_look)_ogg_free(look->lsp_look);
98 lpc_clear(&look->lpclook);
99 memset(look,0,sizeof(*look));
104 static void floor0_pack (vorbis_info_floor *i,oggpack_buffer *opb){
105 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
107 oggpack_write(opb,info->order,8);
108 oggpack_write(opb,info->rate,16);
109 oggpack_write(opb,info->barkmap,16);
110 oggpack_write(opb,info->ampbits,6);
111 oggpack_write(opb,info->ampdB,8);
112 oggpack_write(opb,info->numbooks-1,4);
113 for(j=0;j<info->numbooks;j++)
114 oggpack_write(opb,info->books[j],8);
117 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
118 codec_setup_info *ci=vi->codec_setup;
121 vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
122 info->order=oggpack_read(opb,8);
123 info->rate=oggpack_read(opb,16);
124 info->barkmap=oggpack_read(opb,16);
125 info->ampbits=oggpack_read(opb,6);
126 info->ampdB=oggpack_read(opb,8);
127 info->numbooks=oggpack_read(opb,4)+1;
129 if(info->order<1)goto err_out;
130 if(info->rate<1)goto err_out;
131 if(info->barkmap<1)goto err_out;
132 if(info->numbooks<1)goto err_out;
134 for(j=0;j<info->numbooks;j++){
135 info->books[j]=oggpack_read(opb,8);
136 if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
141 floor0_free_info(info);
145 /* initialize Bark scale and normalization lookups. We could do this
146 with static tables, but Vorbis allows a number of possible
147 combinations, so it's best to do it computationally.
149 The below is authoritative in terms of defining scale mapping.
150 Note that the scale depends on the sampling rate as well as the
151 linear block and mapping sizes */
153 static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
154 vorbis_info_floor *i){
157 vorbis_info *vi=vd->vi;
158 codec_setup_info *ci=vi->codec_setup;
159 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
160 vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
162 look->n=ci->blocksizes[mi->blockflag]/2;
163 look->ln=info->barkmap;
167 lpc_init(&look->lpclook,look->ln,look->m);
169 /* we choose a scaling constant so that:
170 floor(bark(rate/2-1)*C)=mapped-1
171 floor(bark(rate/2)*C)=mapped */
172 scale=look->ln/toBARK(info->rate/2.f);
174 /* the mapping from a linear scale to a smaller bark scale is
175 straightforward. We do *not* make sure that the linear mapping
176 does not skip bark-scale bins; the decoder simply skips them and
177 the encoder may do what it wishes in filling them. They're
178 necessary in some mapping combinations to keep the scale spacing
180 look->linearmap=_ogg_malloc((look->n+1)*sizeof(*look->linearmap));
181 for(j=0;j<look->n;j++){
182 int val=floor( toBARK((info->rate/2.f)/look->n*j)
183 *scale); /* bark numbers represent band edges */
184 if(val>=look->ln)val=look->ln; /* guard against the approximation */
185 look->linearmap[j]=val;
187 look->linearmap[j]=-1;
189 look->lsp_look=_ogg_malloc(look->ln*sizeof(*look->lsp_look));
190 for(j=0;j<look->ln;j++)
191 look->lsp_look[j]=2*cos(M_PI/look->ln*j);
196 /* less efficient than the decode side (written for clarity). We're
197 not bottlenecked here anyway */
199 float _curve_to_lpc(float *curve,float *lpc,
200 vorbis_look_floor0 *l){
201 /* map the input curve to a bark-scale curve for encoding */
204 float *work=alloca(sizeof(*work)*mapped);
209 memset(work,0,sizeof(*work)*mapped);
211 /* Only the decode side is behavior-specced; for now in the encoder,
212 we select the maximum value of each band as representative (this
213 helps make sure peaks don't go out of range. In error terms,
214 selecting min would make more sense, but the codebook is trained
215 numerically, so we don't actually lose. We'd still want to
216 use the original curve for error and noise estimation */
219 bark=l->linearmap[i];
220 if(work[bark]<curve[i])work[bark]=curve[i];
222 /* If the bark scale is climbing rapidly, some bins may end up
223 going unused. This isn't a waste actually; it keeps the
224 scale resolution even so that the LPC generator has an easy
225 time. However, if we leave the bins empty we lose energy.
226 So, fill 'em in. The decoder does not do anything with he
227 unused bins, so we can fill them anyway we like to end up
228 with a better spectral curve */
230 /* we'll always have a bin zero, so we don't need to guard init */
233 float del=(float)j/span;
234 work[j+last]=work[bark]*del+work[last]*(1.f-del);
240 /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
241 for(i=bark+1;i<mapped;i++)
245 /**********************/
250 _analysis_output("barkfloor",seq,work,bark,0,0);
251 _analysis_output("barkcurve",seq++,curve,l->n,1,0);
256 /**********************/
258 return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
261 static int floor0_forward(vorbis_block *vb,vorbis_look_floor *in,
262 float *mdct, const float *logmdct, /* in */
263 const float *logmask, const float *logmax, /* in */
264 float *codedflr){ /* out */
266 vorbis_look_floor0 *look=(vorbis_look_floor0 *)in;
267 vorbis_info_floor0 *info=look->vi;
278 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
279 of=fopen(buffer,"a");
286 /* our floor comes in on a [-Inf...0] dB scale. The curve has to be
287 positive, so we offset it. */
289 for(j=0;j<look->n;j++)
290 codedflr[j]=logmask[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(codedflr,codedflr,look));
296 /* amp is in the range (0. to ampdB]. Encode that range using
300 long maxval=(1L<<info->ampbits)-1;
302 val=rint(amp/info->ampdB*maxval);
304 if(val<0)val=0; /* likely */
305 if(val>maxval)val=maxval; /* not bloody likely */
308 amp=(float)val/maxval*info->ampdB;
314 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
315 _analysis_output("lpc",seq-1,codedflr,look->m,0,0);
316 if(vorbis_lpc_to_lsp(codedflr,codedflr,look->m))
321 oggpack_write(&vb->opb,val,info->ampbits);
322 look->bits+=info->ampbits+1;
326 float *lspwork=alloca(look->m*sizeof(*lspwork));
328 /* the spec supports using one of a number of codebooks. Right
329 now, encode using this lib supports only one */
330 backend_lookup_state *be=vb->vd->backend_state;
334 _analysis_output("lsp",seq-1,codedflr,look->m,0,0);
336 /* which codebook to use? We do it only by range right now. */
337 if(info->numbooks>1){
339 for(j=0;j<look->m;j++){
340 float val=codedflr[j]-last;
341 if(val<info->lessthan || val>info->greaterthan)break;
351 b=be->fullbooks+info->books[booknum];
352 oggpack_write(&vb->opb,booknum,_ilog(info->numbooks));
353 look->bits+=_ilog(info->numbooks);
358 for(j=0;j<look->m;j++){
359 fprintf(of,"%.12g, ",codedflr[j]-last);
366 sprintf(buffer,"lsp0ent_m%d_b%d.vqd",vb->mode,booknum);
367 ef=fopen(buffer,"a");
371 /* code the spectral envelope, and keep track of the actual
372 quantized values; we don't want creeping error as each block is
373 nailed to the last quantized value of the previous block. */
375 for(j=0;j<look->m;j+=b->dim){
376 int entry=_f0_fit(b,codedflr,lspwork,j);
377 look->bits+=vorbis_book_encode(b,entry,&vb->opb);
380 fprintf(ef,"%d,\n",entry);
389 _analysis_output("lsp2",seq-1,lspwork,look->m,0,0);
391 /* take the coefficients back to a spectral envelope curve */
392 for(j=0;j<look->n;j++)
394 vorbis_lsp_to_curve(codedflr,look->linearmap,look->n,look->ln,
395 lspwork,look->m,amp,info->ampdB);
397 _analysis_output("barklsp",seq-1,codedflr,look->n,1,1);
398 _analysis_output("lsp3",seq-1,codedflr,look->n,0,1);
407 memset(codedflr,0,sizeof(*codedflr)*look->n);
408 memset(mdct,0,sizeof(*mdct)*look->n);
412 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
413 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
414 vorbis_info_floor0 *info=look->vi;
417 int ampraw=oggpack_read(&vb->opb,info->ampbits);
418 if(ampraw>0){ /* also handles the -1 out of data case */
419 long maxval=(1<<info->ampbits)-1;
420 float amp=(float)ampraw/maxval*info->ampdB;
421 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
423 if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
424 backend_lookup_state *be=vb->vd->backend_state;
425 codebook *b=be->fullbooks+info->books[booknum];
427 float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+1));
429 for(j=0;j<look->m;j+=b->dim)
430 if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop;
432 for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
444 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
445 void *memo,float *out){
446 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
447 vorbis_info_floor0 *info=look->vi;
450 float *lsp=(float *)memo;
451 float amp=lsp[look->m];
453 /* take the coefficients back to a spectral envelope curve */
454 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
455 lsp,look->m,amp,info->ampdB);
458 memset(out,0,sizeof(*out)*look->n);
463 vorbis_func_floor floor0_exportbundle={
464 &floor0_pack,&floor0_unpack,&floor0_look,&floor0_copy_info,&floor0_free_info,
465 &floor0_free_look,&floor0_forward,&floor0_inverse1,&floor0_inverse2