1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH 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.13 2000/04/06 15:47:55 xiphmont Exp $
17 ********************************************************************/
22 #include "vorbis/codec.h"
27 #include "bookinternal.h"
39 vorbis_info_floor0 *vi;
43 static void free_info(vorbis_info_floor *i){
45 memset(i,0,sizeof(vorbis_info_floor0));
50 static void free_look(vorbis_look_floor *i){
51 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
53 lpc_clear(&look->lpclook);
54 memset(look,0,sizeof(vorbis_look_floor0));
59 static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
60 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
62 _oggpack_write(opb,info->order,8);
63 _oggpack_write(opb,info->rate,16);
64 _oggpack_write(opb,info->barkmap,16);
65 _oggpack_write(opb,info->ampbits,6);
66 _oggpack_write(opb,info->ampdB,8);
67 _oggpack_write(opb,info->stages-1,4);
68 for(j=0;j<info->stages;j++)
69 _oggpack_write(opb,info->books[j],8);
72 static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){
74 vorbis_info_floor0 *info=malloc(sizeof(vorbis_info_floor0));
75 info->order=_oggpack_read(opb,8);
76 info->rate=_oggpack_read(opb,16);
77 info->barkmap=_oggpack_read(opb,16);
78 info->ampbits=_oggpack_read(opb,6);
79 info->ampdB=_oggpack_read(opb,8);
80 info->stages=_oggpack_read(opb,4)+1;
82 if(info->order<1)goto err_out;
83 if(info->rate<1)goto err_out;
84 if(info->barkmap<1)goto err_out;
85 if(info->stages<1)goto err_out;
87 for(j=0;j<info->stages;j++){
88 info->books[j]=_oggpack_read(opb,8);
89 if(info->books[j]<0 || info->books[j]>=vi->books)goto err_out;
97 static vorbis_look_floor *look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
98 vorbis_info_floor *i){
99 vorbis_info *vi=vd->vi;
100 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
101 vorbis_look_floor0 *look=malloc(sizeof(vorbis_look_floor0));
103 look->n=vi->blocksizes[mi->blockflag]/2;
105 lpc_init(&look->lpclook,look->n,info->barkmap,info->rate,look->m);
112 static int forward(vorbis_block *vb,vorbis_look_floor *i,
113 double *in,double *out){
115 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
116 vorbis_info_floor0 *info=look->vi;
120 /* use 'out' as temp storage */
121 /* Convert our floor to a set of lpc coefficients */
122 amp=sqrt(vorbis_curve_to_lpc(in,out,&look->lpclook));
124 /* amp is in the range 0. to 1. (well, more like .7). Log scale it */
127 (1<<ampbits)-1 == amp dB = 1. amp */
129 long ampscale=fromdB(info->ampdB);
130 long maxval=(1<<info->ampbits)-1;
132 long val=todB(amp*ampscale)/info->ampdB*maxval+1;
134 if(val<0)val=0; /* likely */
135 if(val>maxval)val=maxval; /* not bloody likely */
137 _oggpack_write(&vb->opb,val,info->ampbits);
139 amp=fromdB((val-.5)/maxval*info->ampdB)/ampscale;
145 double *work=alloca(sizeof(double)*look->m);
147 /* LSP <-> LPC is orthogonal and LSP quantizes more stably */
148 vorbis_lpc_to_lsp(out,out,look->m);
149 memcpy(work,out,sizeof(double)*look->m);
156 sprintf(buffer,"lsp0coeff_%d.vqd",vb->mode);
157 of=fopen(buffer,"a");
158 for(j=0;j<look->m;j++)
159 fprintf(of,"%g, ",out[j]);
165 /* code the spectral envelope, and keep track of the actual
166 quantized values; we don't want creeping error as each block is
167 nailed to the last quantized value of the previous block. */
169 /* first stage is a bit different because quantization error must be
171 for(stage=0;stage<info->stages;stage++){
172 codebook *b=vb->vd->fullbooks+info->books[stage];
177 for(k=0;k<b->dim;k++)out[j+k]-=last;
178 bits+=vorbis_book_encodev(b,out+j,&vb->opb);
179 for(k=0;k<b->dim;k++,j++){
186 memcpy(out,work,sizeof(double)*look->m);
188 bits+=vorbis_book_encodev(b,out+j,&vb->opb);
189 for(k=0;k<b->dim;k++,j++)work[j]-=out[j];
193 /* take the coefficients back to a spectral envelope curve */
194 vorbis_lsp_to_lpc(out,out,look->m);
195 vorbis_lpc_to_curve(out,out,amp,&look->lpclook);
196 fprintf(stderr,"Encoded %ld LSP coefficients in %ld bits\n",look->m,bits);
200 fprintf(stderr,"Encoded %ld LSP coefficients in %ld bits\n",look->m,bits);
202 memset(out,0,sizeof(double)*look->n);
206 static int inverse(vorbis_block *vb,vorbis_look_floor *i,double *out){
207 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
208 vorbis_info_floor0 *info=look->vi;
211 long ampraw=_oggpack_read(&vb->opb,info->ampbits);
213 long ampscale=fromdB(info->ampdB);
214 long maxval=(1<<info->ampbits)-1;
215 double amp=fromdB((ampraw-.5)/maxval*info->ampdB)/ampscale;
217 memset(out,0,sizeof(double)*look->m);
218 for(stage=0;stage<info->stages;stage++){
219 codebook *b=vb->vd->fullbooks+info->books[stage];
220 for(j=0;j<look->m;j+=b->dim)
221 vorbis_book_decodev(b,out+j,&vb->opb);
225 for(k=0;k<b->dim;k++,j++)out[j]+=last;
232 /* take the coefficients back to a spectral envelope curve */
233 vorbis_lsp_to_lpc(out,out,look->m);
234 vorbis_lpc_to_curve(out,out,amp,&look->lpclook);
237 memset(out,0,sizeof(double)*look->n);
242 vorbis_func_floor floor0_exportbundle={
243 &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse