Added os.h to res0.c and floor0.c in order to give _alloca/rint to MSVC
[platform/upstream/libvorbis.git] / lib / floor0.c
1 /********************************************************************
2  *                                                                  *
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.                            *
7  *                                                                  *
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/                                             *
11  *                                                                  *
12  ********************************************************************
13
14  function: floor backend 0 implementation
15  last mod: $Id: floor0.c,v 1.13 2000/04/06 15:47:55 xiphmont Exp $
16
17  ********************************************************************/
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <math.h>
22 #include "vorbis/codec.h"
23 #include "bitwise.h"
24 #include "registry.h"
25 #include "lpc.h"
26 #include "lsp.h"
27 #include "bookinternal.h"
28 #include "scales.h"
29 #include "misc.h"
30 #include "os.h"
31
32 typedef struct {
33   long n;
34   long m;
35   
36   double ampscale;
37   double ampvals;
38
39   vorbis_info_floor0 *vi;
40   lpc_lookup lpclook;
41 } vorbis_look_floor0;
42
43 static void free_info(vorbis_info_floor *i){
44   if(i){
45     memset(i,0,sizeof(vorbis_info_floor0));
46     free(i);
47   }
48 }
49
50 static void free_look(vorbis_look_floor *i){
51   vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
52   if(i){
53     lpc_clear(&look->lpclook);
54     memset(look,0,sizeof(vorbis_look_floor0));
55     free(look);
56   }
57 }
58
59 static void pack (vorbis_info_floor *i,oggpack_buffer *opb){
60   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
61   int j;
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);
70 }
71
72 static vorbis_info_floor *unpack (vorbis_info *vi,oggpack_buffer *opb){
73   int j;
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;
81   
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;
86
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;
90   }
91   return(info);  
92  err_out:
93   free_info(info);
94   return(NULL);
95 }
96
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));
102   look->m=info->order;
103   look->n=vi->blocksizes[mi->blockflag]/2;
104   look->vi=info;
105   lpc_init(&look->lpclook,look->n,info->barkmap,info->rate,look->m);
106
107   return look;
108 }
109
110 #include <stdio.h>
111
112 static int forward(vorbis_block *vb,vorbis_look_floor *i,
113                     double *in,double *out){
114   long j,k,stage;
115   vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
116   vorbis_info_floor0 *info=look->vi;
117   double amp;
118   long bits=0;
119
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));
123
124   /* amp is in the range 0. to 1. (well, more like .7). Log scale it */
125   
126   /* 0              == 0 dB
127      (1<<ampbits)-1 == amp dB   = 1. amp */
128   {
129     long ampscale=fromdB(info->ampdB);
130     long maxval=(1<<info->ampbits)-1;
131
132     long val=todB(amp*ampscale)/info->ampdB*maxval+1;
133
134     if(val<0)val=0;           /* likely */
135     if(val>maxval)val=maxval; /* not bloody likely */
136
137     _oggpack_write(&vb->opb,val,info->ampbits);
138     if(val>0)
139       amp=fromdB((val-.5)/maxval*info->ampdB)/ampscale;
140     else
141       amp=0;
142   }
143
144   if(amp>0){
145     double *work=alloca(sizeof(double)*look->m);
146     
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);
150
151 #ifdef TRAIN
152     {
153       int j;
154       FILE *of;
155       char buffer[80];
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]);
160       fprintf(of,"\n");
161       fclose(of);
162     }
163 #endif
164
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. */
168     
169     /* first stage is a bit different because quantization error must be
170        handled carefully */
171     for(stage=0;stage<info->stages;stage++){
172       codebook *b=vb->vd->fullbooks+info->books[stage];
173       
174       if(stage==0){
175         double last=0.;
176         for(j=0;j<look->m;){
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++){
180             out[j]+=last;
181             work[j]-=out[j];
182           }
183           last=out[j-1];
184         }
185       }else{
186         memcpy(out,work,sizeof(double)*look->m);
187         for(j=0;j<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];
190         }
191       }
192     }
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);
197     return(1);
198   }
199
200   fprintf(stderr,"Encoded %ld LSP coefficients in %ld bits\n",look->m,bits);
201
202   memset(out,0,sizeof(double)*look->n);
203   return(0);
204 }
205
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;
209   int j,k,stage;
210   
211   long ampraw=_oggpack_read(&vb->opb,info->ampbits);
212   if(ampraw>0){
213     long ampscale=fromdB(info->ampdB);
214     long maxval=(1<<info->ampbits)-1;
215     double amp=fromdB((ampraw-.5)/maxval*info->ampdB)/ampscale;
216
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);
222       if(stage==0){
223         double last=0.;
224         for(j=0;j<look->m;){
225           for(k=0;k<b->dim;k++,j++)out[j]+=last;
226           last=out[j-1];
227         }
228       }
229     }
230   
231
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);
235     return(1);
236   }else
237     memset(out,0,sizeof(double)*look->n);
238   return(0);
239 }
240
241 /* export hooks */
242 vorbis_func_floor floor0_exportbundle={
243   &pack,&unpack,&look,&free_info,&free_look,&forward,&inverse
244 };
245
246