media/libvorbis/lib/vorbis_floor0.c

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:7670d0e61294
1 /********************************************************************
2 * *
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************
12
13 function: floor backend 0 implementation
14 last mod: $Id: floor0.c 19031 2013-12-03 19:20:50Z tterribe $
15
16 ********************************************************************/
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21 #include <ogg/ogg.h>
22 #include "vorbis/codec.h"
23 #include "codec_internal.h"
24 #include "registry.h"
25 #include "lpc.h"
26 #include "lsp.h"
27 #include "codebook.h"
28 #include "scales.h"
29 #include "misc.h"
30 #include "os.h"
31
32 #include "misc.h"
33 #include <stdio.h>
34
35 typedef struct {
36 int ln;
37 int m;
38 int **linearmap;
39 int n[2];
40
41 vorbis_info_floor0 *vi;
42
43 long bits;
44 long frames;
45 } vorbis_look_floor0;
46
47
48 /***********************************************/
49
50 static void floor0_free_info(vorbis_info_floor *i){
51 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
52 if(info){
53 memset(info,0,sizeof(*info));
54 _ogg_free(info);
55 }
56 }
57
58 static void floor0_free_look(vorbis_look_floor *i){
59 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
60 if(look){
61
62 if(look->linearmap){
63
64 if(look->linearmap[0])_ogg_free(look->linearmap[0]);
65 if(look->linearmap[1])_ogg_free(look->linearmap[1]);
66
67 _ogg_free(look->linearmap);
68 }
69 memset(look,0,sizeof(*look));
70 _ogg_free(look);
71 }
72 }
73
74 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
75 codec_setup_info *ci=vi->codec_setup;
76 int j;
77
78 vorbis_info_floor0 *info=_ogg_malloc(sizeof(*info));
79 info->order=oggpack_read(opb,8);
80 info->rate=oggpack_read(opb,16);
81 info->barkmap=oggpack_read(opb,16);
82 info->ampbits=oggpack_read(opb,6);
83 info->ampdB=oggpack_read(opb,8);
84 info->numbooks=oggpack_read(opb,4)+1;
85
86 if(info->order<1)goto err_out;
87 if(info->rate<1)goto err_out;
88 if(info->barkmap<1)goto err_out;
89 if(info->numbooks<1)goto err_out;
90
91 for(j=0;j<info->numbooks;j++){
92 info->books[j]=oggpack_read(opb,8);
93 if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
94 if(ci->book_param[info->books[j]]->maptype==0)goto err_out;
95 if(ci->book_param[info->books[j]]->dim<1)goto err_out;
96 }
97 return(info);
98
99 err_out:
100 floor0_free_info(info);
101 return(NULL);
102 }
103
104 /* initialize Bark scale and normalization lookups. We could do this
105 with static tables, but Vorbis allows a number of possible
106 combinations, so it's best to do it computationally.
107
108 The below is authoritative in terms of defining scale mapping.
109 Note that the scale depends on the sampling rate as well as the
110 linear block and mapping sizes */
111
112 static void floor0_map_lazy_init(vorbis_block *vb,
113 vorbis_info_floor *infoX,
114 vorbis_look_floor0 *look){
115 if(!look->linearmap[vb->W]){
116 vorbis_dsp_state *vd=vb->vd;
117 vorbis_info *vi=vd->vi;
118 codec_setup_info *ci=vi->codec_setup;
119 vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX;
120 int W=vb->W;
121 int n=ci->blocksizes[W]/2,j;
122
123 /* we choose a scaling constant so that:
124 floor(bark(rate/2-1)*C)=mapped-1
125 floor(bark(rate/2)*C)=mapped */
126 float scale=look->ln/toBARK(info->rate/2.f);
127
128 /* the mapping from a linear scale to a smaller bark scale is
129 straightforward. We do *not* make sure that the linear mapping
130 does not skip bark-scale bins; the decoder simply skips them and
131 the encoder may do what it wishes in filling them. They're
132 necessary in some mapping combinations to keep the scale spacing
133 accurate */
134 look->linearmap[W]=_ogg_malloc((n+1)*sizeof(**look->linearmap));
135 for(j=0;j<n;j++){
136 int val=floor( toBARK((info->rate/2.f)/n*j)
137 *scale); /* bark numbers represent band edges */
138 if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
139 look->linearmap[W][j]=val;
140 }
141 look->linearmap[W][j]=-1;
142 look->n[W]=n;
143 }
144 }
145
146 static vorbis_look_floor *floor0_look(vorbis_dsp_state *vd,
147 vorbis_info_floor *i){
148 vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
149 vorbis_look_floor0 *look=_ogg_calloc(1,sizeof(*look));
150
151 (void)vd;
152
153 look->m=info->order;
154 look->ln=info->barkmap;
155 look->vi=info;
156
157 look->linearmap=_ogg_calloc(2,sizeof(*look->linearmap));
158
159 return look;
160 }
161
162 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
163 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
164 vorbis_info_floor0 *info=look->vi;
165 int j,k;
166
167 int ampraw=oggpack_read(&vb->opb,info->ampbits);
168 if(ampraw>0){ /* also handles the -1 out of data case */
169 long maxval=(1<<info->ampbits)-1;
170 float amp=(float)ampraw/maxval*info->ampdB;
171 int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
172
173 if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
174 codec_setup_info *ci=vb->vd->vi->codec_setup;
175 codebook *b=ci->fullbooks+info->books[booknum];
176 float last=0.f;
177
178 /* the additional b->dim is a guard against any possible stack
179 smash; b->dim is provably more than we can overflow the
180 vector */
181 float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1));
182
183 if(vorbis_book_decodev_set(b,lsp,&vb->opb,look->m)==-1)goto eop;
184 for(j=0;j<look->m;){
185 for(k=0;j<look->m && k<b->dim;k++,j++)lsp[j]+=last;
186 last=lsp[j-1];
187 }
188
189 lsp[look->m]=amp;
190 return(lsp);
191 }
192 }
193 eop:
194 return(NULL);
195 }
196
197 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
198 void *memo,float *out){
199 vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
200 vorbis_info_floor0 *info=look->vi;
201
202 floor0_map_lazy_init(vb,info,look);
203
204 if(memo){
205 float *lsp=(float *)memo;
206 float amp=lsp[look->m];
207
208 /* take the coefficients back to a spectral envelope curve */
209 vorbis_lsp_to_curve(out,
210 look->linearmap[vb->W],
211 look->n[vb->W],
212 look->ln,
213 lsp,look->m,amp,(float)info->ampdB);
214 return(1);
215 }
216 memset(out,0,sizeof(*out)*look->n[vb->W]);
217 return(0);
218 }
219
220 /* export hooks */
221 const vorbis_func_floor floor0_exportbundle={
222 NULL,&floor0_unpack,&floor0_look,&floor0_free_info,
223 &floor0_free_look,&floor0_inverse1,&floor0_inverse2
224 };

mercurial