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.27 2000/11/07 09:51:42 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)free(look->linearmap);
91 if(look->lsp_look)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;
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.-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 static int floor0_forward(vorbis_block *vb,vorbis_look_floor *i,
242 float *in,float *out){
244 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
245 vorbis_info_floor0 *info=look->vi;
246 float *work=alloca((look->ln+look->n)*sizeof(float));
257 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
258 of=fopen(buffer,"a");
261 sprintf(buffer,"lsp0ent_%d.vqd",vb->mode);
262 ef=fopen(buffer,"a");
265 /* our floor comes in on a linear scale; go to a [-Inf...0] dB
266 scale. The curve has to be positive, so we offset it. */
268 for(j=0;j<look->n;j++)
269 work[j]=todB(in[j])+info->ampdB;
271 /* use 'out' as temp storage */
272 /* Convert our floor to a set of lpc coefficients */
273 amp=sqrt(_curve_to_lpc(work,out,look));
275 /* amp is in the range (0. to ampdB]. Encode that range using
279 long maxval=(1L<<info->ampbits)-1;
281 long val=rint(amp/info->ampdB*maxval);
283 if(val<0)val=0; /* likely */
284 if(val>maxval)val=maxval; /* not bloody likely */
286 oggpack_write(&vb->opb,val,info->ampbits);
288 amp=(float)val/maxval*info->ampdB;
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;
298 codebook *b=be->fullbooks+info->books[0];
299 oggpack_write(&vb->opb,0,_ilog(info->numbooks));
301 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
302 vorbis_lpc_to_lsp(out,out,look->m);
306 float *lspwork=alloca(look->m*sizeof(float));
307 memcpy(lspwork,out,look->m*sizeof(float));
308 vorbis_lsp_to_curve(lspwork,look->linearmap,look->n,look->ln,
309 work,look->m,amp,info->ampdB);
310 _analysis_output("prefit",seq,work,look->n,0,1);
321 for(j=0;j<look->m;j++){
322 fprintf(of,"%.12g, ",out[j]-last);
331 /* code the spectral envelope, and keep track of the actual
332 quantized values; we don't want creeping error as each block is
333 nailed to the last quantized value of the previous block. */
335 for(j=0;j<look->m;j+=b->dim){
336 int entry=_f0_fit(b,out,work,j);
337 bits+=vorbis_book_encode(b,entry,&vb->opb);
340 fprintf(ef,"%d,\n",entry);
348 for(j=0;j<look->m;j++){
360 /* take the coefficients back to a spectral envelope curve */
361 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
362 work,look->m,amp,info->ampdB);
366 memset(out,0,sizeof(float)*look->n);
371 static int floor0_inverse(vorbis_block *vb,vorbis_look_floor *i,float *out){
372 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
373 vorbis_info_floor0 *info=look->vi;
376 int ampraw=oggpack_read(&vb->opb,info->ampbits);
377 if(ampraw>0){ /* also handles the -1 out of data case */
378 long maxval=(1<<info->ampbits)-1;
379 float amp=(float)ampraw/maxval*info->ampdB;
380 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
381 float *lsp=alloca(sizeof(float)*look->m);
384 backend_lookup_state *be=vb->vd->backend_state;
385 codebook *b=be->fullbooks+info->books[booknum];
388 memset(out,0,sizeof(double)*look->m);
390 for(j=0;j<look->m;j+=b->dim)
391 if(vorbis_book_decodevs(b,lsp+j,&vb->opb,1,-1)==-1)goto eop;
393 for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
397 /* take the coefficients back to a spectral envelope curve */
398 vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
399 lsp,look->m,amp,info->ampdB);
405 memset(out,0,sizeof(float)*look->n);
410 vorbis_func_floor floor0_exportbundle={
411 &floor0_pack,&floor0_unpack,&floor0_look,&floor0_copy_info,&floor0_free_info,
412 &floor0_free_look,&floor0_forward,&floor0_inverse