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-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.35 2001/01/22 01:38:24 xiphmont Exp $
17 ********************************************************************/
23 #include "vorbis/codec.h"
24 #include "codec_internal.h"
42 vorbis_info_floor0 *vi;
48 /* infrastructure for finding fit */
49 static long _f0_fit(codebook *book,
56 float *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(float));
71 /***********************************************/
73 static vorbis_info_floor *floor0_copy_info (vorbis_info_floor *i){
74 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
75 vorbis_info_floor0 *ret=_ogg_malloc(sizeof(vorbis_info_floor0));
76 memcpy(ret,info,sizeof(vorbis_info_floor0));
80 static void floor0_free_info(vorbis_info_floor *i){
82 memset(i,0,sizeof(vorbis_info_floor0));
87 static void floor0_free_look(vorbis_look_floor *i){
88 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
90 if(look->linearmap)_ogg_free(look->linearmap);
91 if(look->lsp_look)_ogg_free(look->lsp_look);
92 lpc_clear(&look->lpclook);
93 memset(look,0,sizeof(vorbis_look_floor0));
98 static void floor0_pack (vorbis_info_floor *i,oggpack_buffer *opb){
99 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
101 oggpack_write(opb,info->order,8);
102 oggpack_write(opb,info->rate,16);
103 oggpack_write(opb,info->barkmap,16);
104 oggpack_write(opb,info->ampbits,6);
105 oggpack_write(opb,info->ampdB,8);
106 oggpack_write(opb,info->numbooks-1,4);
107 for(j=0;j<info->numbooks;j++)
108 oggpack_write(opb,info->books[j],8);
111 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
112 codec_setup_info *ci=vi->codec_setup;
115 vorbis_info_floor0 *info=_ogg_malloc(sizeof(vorbis_info_floor0));
116 info->order=oggpack_read(opb,8);
117 info->rate=oggpack_read(opb,16);
118 info->barkmap=oggpack_read(opb,16);
119 info->ampbits=oggpack_read(opb,6);
120 info->ampdB=oggpack_read(opb,8);
121 info->numbooks=oggpack_read(opb,4)+1;
123 if(info->order<1)goto err_out;
124 if(info->rate<1)goto err_out;
125 if(info->barkmap<1)goto err_out;
126 if(info->numbooks<1)goto err_out;
128 for(j=0;j<info->numbooks;j++){
129 info->books[j]=oggpack_read(opb,8);
130 if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
135 floor0_free_info(info);
139 /* initialize Bark scale and normalization lookups. We could do this
140 with static tables, but Vorbis allows a number of possible
141 combinations, so it's best to do it computationally.
143 The below is authoritative in terms of defining scale mapping.
144 Note that the scale depends on the sampling rate as well as the
145 linear block and mapping sizes */
147 static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
148 vorbis_info_floor *i){
151 vorbis_info *vi=vd->vi;
152 codec_setup_info *ci=vi->codec_setup;
153 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
154 vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(vorbis_look_floor0));
156 look->n=ci->blocksizes[mi->blockflag]/2;
157 look->ln=info->barkmap;
161 lpc_init(&look->lpclook,look->ln,look->m);
163 /* we choose a scaling constant so that:
164 floor(bark(rate/2-1)*C)=mapped-1
165 floor(bark(rate/2)*C)=mapped */
166 scale=look->ln/toBARK(info->rate/2.f);
168 /* the mapping from a linear scale to a smaller bark scale is
169 straightforward. We do *not* make sure that the linear mapping
170 does not skip bark-scale bins; the decoder simply skips them and
171 the encoder may do what it wishes in filling them. They're
172 necessary in some mapping combinations to keep the scale spacing
174 look->linearmap=_ogg_malloc((look->n+1)*sizeof(int));
175 for(j=0;j<look->n;j++){
176 int val=floor( toBARK((info->rate/2.f)/look->n*j)
177 *scale); /* bark numbers represent band edges */
178 if(val>=look->ln)val=look->ln; /* guard against the approximation */
179 look->linearmap[j]=val;
181 look->linearmap[j]=-1;
183 look->lsp_look=_ogg_malloc(look->ln*sizeof(float));
184 for(j=0;j<look->ln;j++)
185 look->lsp_look[j]=2*cos(M_PI/look->ln*j);
190 /* less efficient than the decode side (written for clarity). We're
191 not bottlenecked here anyway */
193 float _curve_to_lpc(float *curve,float *lpc,
194 vorbis_look_floor0 *l){
195 /* map the input curve to a bark-scale curve for encoding */
198 float *work=alloca(sizeof(float)*mapped);
202 memset(work,0,sizeof(float)*mapped);
204 /* Only the decode side is behavior-specced; for now in the encoder,
205 we select the maximum value of each band as representative (this
206 helps make sure peaks don't go out of range. In error terms,
207 selecting min would make more sense, but the codebook is trained
208 numerically, so we don't actually lose. We'd still want to
209 use the original curve for error and noise estimation */
212 bark=l->linearmap[i];
213 if(work[bark]<curve[i])work[bark]=curve[i];
215 /* If the bark scale is climbing rapidly, some bins may end up
216 going unused. This isn't a waste actually; it keeps the
217 scale resolution even so that the LPC generator has an easy
218 time. However, if we leave the bins empty we lose energy.
219 So, fill 'em in. The decoder does not do anything with he
220 unused bins, so we can fill them anyway we like to end up
221 with a better spectral curve */
223 /* we'll always have a bin zero, so we don't need to guard init */
226 float del=(float)j/span;
227 work[j+last]=work[bark]*del+work[last]*(1.f-del);
233 /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
234 for(i=bark+1;i<mapped;i++)
237 return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
240 /* generate the whole freq response curve of an LSP IIR filter */
241 /* didn't need in->out seperation, modifies the flr[] vector; takes in
242 a dB scale floor, puts out linear */
243 static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
246 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
247 vorbis_info_floor0 *info=look->vi;
259 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
260 of=fopen(buffer,"a");
264 /* our floor comes in on a [-Inf...0] dB scale. The curve has to be
265 positive, so we offset it. */
267 for(j=0;j<look->n;j++)
270 /* use 'out' as temp storage */
271 /* Convert our floor to a set of lpc coefficients */
272 amp=sqrt(_curve_to_lpc(flr,flr,look));
274 /* amp is in the range (0. to ampdB]. Encode that range using
278 long maxval=(1L<<info->ampbits)-1;
280 val=rint(amp/info->ampdB*maxval);
282 if(val<0)val=0; /* likely */
283 if(val>maxval)val=maxval; /* not bloody likely */
285 oggpack_write(&vb->opb,val,info->ampbits);
287 amp=(float)val/maxval*info->ampdB;
293 float *lspwork=alloca(look->m*sizeof(float));
295 /* the spec supports using one of a number of codebooks. Right
296 now, encode using this lib supports only one */
297 backend_lookup_state *be=vb->vd->backend_state;
301 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
302 _analysis_output("lpc",seq,flr,look->m,0,0);
304 vorbis_lpc_to_lsp(flr,flr,look->m);
306 _analysis_output("lsp",seq,flr,look->m,0,0);
310 float *lspwork2=alloca(look->m*sizeof(float));
311 memcpy(lspwork2,flr,sizeof(float)*look->m);
312 memcpy(lspwork,flr,sizeof(float)*look->m);
313 vorbis_lsp_to_curve(flr,look->linearmap,look->n,look->ln,
314 lspwork2,look->m,amp,info->ampdB);
316 _analysis_output("prefit",seq++,flr,look->n,0,1);
317 memcpy(flr,lspwork,sizeof(float)*look->m);
322 /* which codebook to use? We do it only by range right now. */
323 if(info->numbooks>1){
325 for(j=0;j<look->m;j++){
326 float val=flr[j]-last;
327 if(val<info->lessthan || val>info->greaterthan)break;
337 b=be->fullbooks+info->books[booknum];
338 oggpack_write(&vb->opb,booknum,_ilog(info->numbooks));
344 for(j=0;j<look->m;j++){
345 fprintf(of,"%.12g, ",flr[j]-last);
352 sprintf(buffer,"lsp0ent_m%d_b%d.vqd",vb->mode,booknum);
353 ef=fopen(buffer,"a");
357 /* code the spectral envelope, and keep track of the actual
358 quantized values; we don't want creeping error as each block is
359 nailed to the last quantized value of the previous block. */
361 for(j=0;j<look->m;j+=b->dim){
362 int entry=_f0_fit(b,flr,lspwork,j);
363 bits+=vorbis_book_encode(b,entry,&vb->opb);
366 fprintf(ef,"%d,\n",entry);
375 /* take the coefficients back to a spectral envelope curve */
376 vorbis_lsp_to_curve(flr,look->linearmap,look->n,look->ln,
377 lspwork,look->m,amp,info->ampdB);
385 memset(flr,0,sizeof(float)*look->n);
390 static int floor0_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
391 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
392 vorbis_info_floor0 *info=look->vi;
395 int ampraw=oggpack_read(&vb->opb,info->ampbits);
396 if(ampraw>0){ /* also handles the -1 out of data case */
397 long maxval=(1<<info->ampbits)-1;
398 float amp=(float)ampraw/maxval*info->ampdB;
399 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
400 float *lsp=alloca(sizeof(float)*look->m);
403 backend_lookup_state *be=vb->vd->backend_state;
404 codebook *b=be->fullbooks+info->books[booknum];
407 memset(out,0,sizeof(float)*look->m);
409 for(j=0;j<look->m;j+=b->dim)
410 if(vorbis_book_decodevs(b,lsp+j,&vb->opb,1,-1)==-1)goto eop;
412 for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
416 /* take the coefficients back to a spectral envelope curve */
417 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
418 lsp,look->m,amp,info->ampdB);
424 memset(out,0,sizeof(float)*look->n);
429 vorbis_func_floor floor0_exportbundle={
430 &floor0_pack,&floor0_unpack,&floor0_look,&floor0_copy_info,&floor0_free_info,
431 &floor0_free_look,&floor0_forward,&floor0_inverse