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