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.46 2001/10/02 00:14:30 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;
279 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
280 of=fopen(buffer,"a");
287 /* our floor comes in on a [-Inf...0] dB scale. The curve has to be
288 positive, so we offset it. */
290 for(j=0;j<look->n;j++)
291 codedflr[j]=logmask[j]+info->ampdB;
293 /* use 'out' as temp storage */
294 /* Convert our floor to a set of lpc coefficients */
295 amp=sqrt(_curve_to_lpc(codedflr,codedflr,look));
297 /* amp is in the range (0. to ampdB]. Encode that range using
301 long maxval=(1L<<info->ampbits)-1;
303 val=rint(amp/info->ampdB*maxval);
305 if(val<0)val=0; /* likely */
306 if(val>maxval)val=maxval; /* not bloody likely */
309 amp=(float)val/maxval*info->ampdB;
315 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
316 _analysis_output("lpc",seq-1,codedflr,look->m,0,0);
317 if(vorbis_lpc_to_lsp(codedflr,codedflr,look->m))
322 oggpack_write(&vb->opb,val,info->ampbits);
323 look->bits+=info->ampbits+1;
327 float *lspwork=alloca(look->m*sizeof(*lspwork));
329 /* the spec supports using one of a number of codebooks. Right
330 now, encode using this lib supports only one */
331 backend_lookup_state *be=vb->vd->backend_state;
335 _analysis_output("lsp",seq-1,codedflr,look->m,0,0);
337 /* which codebook to use? We do it only by range right now. */
338 if(info->numbooks>1){
340 for(j=0;j<look->m;j++){
341 float val=codedflr[j]-last;
342 if(val<info->lessthan || val>info->greaterthan)break;
352 b=be->fullbooks+info->books[booknum];
353 oggpack_write(&vb->opb,booknum,_ilog(info->numbooks));
354 look->bits+=_ilog(info->numbooks);
359 for(j=0;j<look->m;j++){
360 fprintf(of,"%.12g, ",codedflr[j]-last);
367 sprintf(buffer,"lsp0ent_m%d_b%d.vqd",vb->mode,booknum);
368 ef=fopen(buffer,"a");
372 /* code the spectral envelope, and keep track of the actual
373 quantized values; we don't want creeping error as each block is
374 nailed to the last quantized value of the previous block. */
376 for(j=0;j<look->m;j+=b->dim){
377 int entry=_f0_fit(b,codedflr,lspwork,j);
378 look->bits+=vorbis_book_encode(b,entry,&vb->opb);
381 fprintf(ef,"%d,\n",entry);
390 _analysis_output("lsp2",seq-1,lspwork,look->m,0,0);
392 /* take the coefficients back to a spectral envelope curve */
393 for(j=0;j<look->n;j++)
395 vorbis_lsp_to_curve(codedflr,look->linearmap,look->n,look->ln,
396 lspwork,look->m,amp,info->ampdB);
398 _analysis_output("barklsp",seq-1,codedflr,look->n,1,1);
399 _analysis_output("lsp3",seq-1,codedflr,look->n,0,1);
408 memset(codedflr,0,sizeof(*codedflr)*look->n);
409 memset(mdct,0,sizeof(*mdct)*look->n);
413 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
414 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
415 vorbis_info_floor0 *info=look->vi;
418 int ampraw=oggpack_read(&vb->opb,info->ampbits);
419 if(ampraw>0){ /* also handles the -1 out of data case */
420 long maxval=(1<<info->ampbits)-1;
421 float amp=(float)ampraw/maxval*info->ampdB;
422 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
424 if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
425 backend_lookup_state *be=vb->vd->backend_state;
426 codebook *b=be->fullbooks+info->books[booknum];
428 float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+1));
430 for(j=0;j<look->m;j+=b->dim)
431 if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop;
433 for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
445 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
446 void *memo,float *out){
447 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
448 vorbis_info_floor0 *info=look->vi;
451 float *lsp=(float *)memo;
452 float amp=lsp[look->m];
454 /* take the coefficients back to a spectral envelope curve */
455 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
456 lsp,look->m,amp,info->ampdB);
459 memset(out,0,sizeof(*out)*look->n);
464 vorbis_func_floor floor0_exportbundle={
465 &floor0_pack,&floor0_unpack,&floor0_look,&floor0_copy_info,&floor0_free_info,
466 &floor0_free_look,&floor0_forward,&floor0_inverse1,&floor0_inverse2