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.31 2000/12/07 07:26:20 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.);
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.)/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;
180 fprintf(stderr,"%ld:%ld ",val,j);
182 fprintf(stderr,"\n");
183 look->linearmap[j]=-1;
185 look->lsp_look=_ogg_malloc(look->ln*sizeof(float));
186 for(j=0;j<look->ln;j++)
187 look->lsp_look[j]=2*cos(M_PI/look->ln*j);
192 /* less efficient than the decode side (written for clarity). We're
193 not bottlenecked here anyway */
195 float _curve_to_lpc(float *curve,float *lpc,
196 vorbis_look_floor0 *l){
197 /* map the input curve to a bark-scale curve for encoding */
200 float *work=alloca(sizeof(float)*mapped);
204 memset(work,0,sizeof(float)*mapped);
206 /* Only the decode side is behavior-specced; for now in the encoder,
207 we select the maximum value of each band as representative (this
208 helps make sure peaks don't go out of range. In error terms,
209 selecting min would make more sense, but the codebook is trained
210 numerically, so we don't actually lose. We'd still want to
211 use the original curve for error and noise estimation */
214 bark=l->linearmap[i];
215 if(work[bark]<curve[i])work[bark]=curve[i];
217 /* If the bark scale is climbing rapidly, some bins may end up
218 going unused. This isn't a waste actually; it keeps the
219 scale resolution even so that the LPC generator has an easy
220 time. However, if we leave the bins empty we lose energy.
221 So, fill 'em in. The decoder does not do anything with he
222 unused bins, so we can fill them anyway we like to end up
223 with a better spectral curve */
225 /* we'll always have a bin zero, so we don't need to guard init */
228 float del=(float)j/span;
229 work[j+last]=work[bark]*del+work[last]*(1.-del);
235 /* If we're over-ranged to avoid edge effects, fill in the end of spectrum gap */
236 for(i=bark+1;i<mapped;i++)
239 return vorbis_lpc_from_curve(work,lpc,&(l->lpclook));
242 /* generate the whole freq response curve of an LSP IIR filter */
243 static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
244 float *in,float *out,vorbis_bitbuffer *vbb){
246 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
247 vorbis_info_floor0 *info=look->vi;
248 float *work=alloca((look->ln+look->n)*sizeof(float));
260 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
261 of=fopen(buffer,"a");
264 sprintf(buffer,"lsp0ent_%d.vqd",vb->mode);
265 ef=fopen(buffer,"a");
268 /* our floor comes in on a linear scale; go to a [-Inf...0] dB
269 scale. The curve has to be positive, so we offset it. */
271 for(j=0;j<look->n;j++)
272 work[j]=todB(in[j])+info->ampdB;
274 /* use 'out' as temp storage */
275 /* Convert our floor to a set of lpc coefficients */
276 amp=sqrt(_curve_to_lpc(work,out,look));
278 /* amp is in the range (0. to ampdB]. Encode that range using
282 long maxval=(1L<<info->ampbits)-1;
284 val=rint(amp/info->ampdB*maxval);
286 if(val<0)val=0; /* likely */
287 if(val>maxval)val=maxval; /* not bloody likely */
289 /*oggpack_write(&vb->opb,val,info->ampbits);*/
291 amp=(float)val/maxval*info->ampdB;
298 /* the spec supports using one of a number of codebooks. Right
299 now, encode using this lib supports only one */
300 backend_lookup_state *be=vb->vd->backend_state;
301 codebook *b=be->fullbooks+info->books[0];
302 bitbuf_write(vbb,0,_ilog(info->numbooks));
304 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
305 vorbis_lpc_to_lsp(out,out,look->m);
309 float *lspwork=alloca(look->m*sizeof(float));
310 memcpy(lspwork,out,look->m*sizeof(float));
311 vorbis_lsp_to_curve(work,look->linearmap,look->n,look->ln,
312 lspwork,look->m,amp,info->ampdB);
313 _analysis_output("prefit",seq,work,look->n,0,1);
324 for(j=0;j<look->m;j++){
325 fprintf(of,"%.12g, ",out[j]-last);
334 /* code the spectral envelope, and keep track of the actual
335 quantized values; we don't want creeping error as each block is
336 nailed to the last quantized value of the previous block. */
338 for(j=0;j<look->m;j+=b->dim){
339 int entry=_f0_fit(b,out,work,j);
340 bits+=vorbis_book_bufencode(b,entry,vbb);
343 fprintf(ef,"%d,\n",entry);
351 for(j=0;j<look->m;j++){
363 /* take the coefficients back to a spectral envelope curve */
364 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
365 work,look->m,amp,info->ampdB);
369 memset(out,0,sizeof(float)*look->n);
374 static float floor0_forward2(vorbis_block *vb,vorbis_look_floor *i,
375 long amp,float error,
376 vorbis_bitbuffer *vbb){
379 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
380 vorbis_info_floor0 *info=look->vi;
381 long maxval=(1L<<info->ampbits)-1;
382 long adj=rint(todB(error)/info->ampdB*maxval/2);
387 oggpack_write(&vb->opb,amp,info->ampbits);
388 bitbuf_pack(&vb->opb,vbb);
389 return(fromdB((float)adj/maxval*info->ampdB));
395 static int floor0_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
396 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
397 vorbis_info_floor0 *info=look->vi;
400 int ampraw=oggpack_read(&vb->opb,info->ampbits);
401 if(ampraw>0){ /* also handles the -1 out of data case */
402 long maxval=(1<<info->ampbits)-1;
403 float amp=(float)ampraw/maxval*info->ampdB;
404 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
405 float *lsp=alloca(sizeof(float)*look->m);
408 backend_lookup_state *be=vb->vd->backend_state;
409 codebook *b=be->fullbooks+info->books[booknum];
412 memset(out,0,sizeof(float)*look->m);
414 for(j=0;j<look->m;j+=b->dim)
415 if(vorbis_book_decodevs(b,lsp+j,&vb->opb,1,-1)==-1)goto eop;
417 for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
421 /* take the coefficients back to a spectral envelope curve */
422 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
423 lsp,look->m,amp,info->ampdB);
429 memset(out,0,sizeof(float)*look->n);
434 vorbis_func_floor floor0_exportbundle={
435 &floor0_pack,&floor0_unpack,&floor0_look,&floor0_copy_info,&floor0_free_info,
436 &floor0_free_look,&floor0_forward,&floor0_forward2,&floor0_inverse