gosu 0.7.45 → 0.7.46

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/COPYING +6 -11
  2. data/Gosu/{ButtonsWin.hpp → Buttons.hpp} +91 -4
  3. data/Gosu/ButtonsMac.hpp +91 -4
  4. data/Gosu/Graphics.hpp +10 -0
  5. data/Gosu/ImageData.hpp +1 -0
  6. data/Gosu/Input.hpp +2 -3
  7. data/Gosu/Version.hpp +2 -2
  8. data/Gosu/Window.hpp +1 -1
  9. data/GosuImpl/Audio/AudioToolboxFile.hpp +4 -0
  10. data/GosuImpl/Graphics/BitmapApple.mm +5 -11
  11. data/GosuImpl/Graphics/ClipRectStack.hpp +2 -2
  12. data/GosuImpl/Graphics/Common.hpp +1 -1
  13. data/GosuImpl/Graphics/DrawOpQueue.hpp +30 -29
  14. data/GosuImpl/Graphics/Graphics.cpp +2 -3
  15. data/GosuImpl/Graphics/TextMac.cpp +9 -5
  16. data/GosuImpl/Graphics/TextTouch.mm +8 -4
  17. data/GosuImpl/Graphics/Texture.cpp +4 -1
  18. data/GosuImpl/InputMac.mm +24 -45
  19. data/GosuImpl/InputX.cpp +25 -39
  20. data/GosuImpl/RubyGosu.swg +11 -0
  21. data/GosuImpl/RubyGosu_wrap.cxx +109 -40
  22. data/GosuImpl/RubyGosu_wrap.h +1 -1
  23. data/GosuImpl/TextInputWin.cpp +1 -1
  24. data/GosuImpl/TextInputX.cpp +3 -1
  25. data/GosuImpl/WinMain.cpp +3 -4
  26. data/GosuImpl/WindowMac.mm +83 -73
  27. data/GosuImpl/WindowWin.cpp +65 -58
  28. data/dependencies/libogg/AUTHORS +4 -0
  29. data/dependencies/libogg/CHANGES +70 -0
  30. data/dependencies/libogg/COPYING +28 -0
  31. data/dependencies/libogg/include/ogg/ogg.h +209 -0
  32. data/dependencies/libogg/include/ogg/os_types.h +147 -0
  33. data/dependencies/libogg/src/bitwise.c +857 -0
  34. data/dependencies/libogg/src/framing.c +2089 -0
  35. data/dependencies/libvorbis/AUTHORS +3 -0
  36. data/dependencies/libvorbis/CHANGES +126 -0
  37. data/dependencies/libvorbis/COPYING +28 -0
  38. data/dependencies/libvorbis/include/vorbis/codec.h +243 -0
  39. data/dependencies/libvorbis/include/vorbis/vorbisenc.h +436 -0
  40. data/dependencies/libvorbis/include/vorbis/vorbisfile.h +206 -0
  41. data/dependencies/libvorbis/lib/analysis.c +120 -0
  42. data/dependencies/libvorbis/lib/backends.h +144 -0
  43. data/dependencies/libvorbis/lib/barkmel.c +64 -0
  44. data/dependencies/libvorbis/lib/bitrate.c +253 -0
  45. data/dependencies/libvorbis/lib/bitrate.h +59 -0
  46. data/dependencies/libvorbis/lib/block.c +1046 -0
  47. data/dependencies/libvorbis/lib/books/coupled/res_books_51.h +12257 -0
  48. data/dependencies/libvorbis/lib/books/coupled/res_books_stereo.h +15783 -0
  49. data/dependencies/libvorbis/lib/books/floor/floor_books.h +1547 -0
  50. data/dependencies/libvorbis/lib/books/uncoupled/res_books_uncoupled.h +7758 -0
  51. data/dependencies/libvorbis/lib/codebook.c +479 -0
  52. data/dependencies/libvorbis/lib/codebook.h +119 -0
  53. data/dependencies/libvorbis/lib/codec_internal.h +167 -0
  54. data/dependencies/libvorbis/lib/envelope.c +375 -0
  55. data/dependencies/libvorbis/lib/envelope.h +80 -0
  56. data/dependencies/libvorbis/lib/floor0.c +222 -0
  57. data/dependencies/libvorbis/lib/floor1.c +1099 -0
  58. data/dependencies/libvorbis/lib/highlevel.h +58 -0
  59. data/dependencies/libvorbis/lib/info.c +664 -0
  60. data/dependencies/libvorbis/lib/lookup.c +94 -0
  61. data/dependencies/libvorbis/lib/lookup.h +32 -0
  62. data/dependencies/libvorbis/lib/lookup_data.h +192 -0
  63. data/dependencies/libvorbis/lib/lpc.c +160 -0
  64. data/dependencies/libvorbis/lib/lpc.h +29 -0
  65. data/dependencies/libvorbis/lib/lsp.c +456 -0
  66. data/dependencies/libvorbis/lib/lsp.h +28 -0
  67. data/dependencies/libvorbis/lib/mapping0.c +816 -0
  68. data/dependencies/libvorbis/lib/masking.h +785 -0
  69. data/dependencies/libvorbis/lib/mdct.c +563 -0
  70. data/dependencies/libvorbis/lib/mdct.h +71 -0
  71. data/dependencies/libvorbis/lib/misc.h +57 -0
  72. data/dependencies/libvorbis/lib/modes/floor_all.h +260 -0
  73. data/dependencies/libvorbis/lib/modes/psych_11.h +51 -0
  74. data/dependencies/libvorbis/lib/modes/psych_16.h +133 -0
  75. data/dependencies/libvorbis/lib/modes/psych_44.h +642 -0
  76. data/dependencies/libvorbis/lib/modes/psych_8.h +101 -0
  77. data/dependencies/libvorbis/lib/modes/residue_16.h +163 -0
  78. data/dependencies/libvorbis/lib/modes/residue_44.h +292 -0
  79. data/dependencies/libvorbis/lib/modes/residue_44p51.h +451 -0
  80. data/dependencies/libvorbis/lib/modes/residue_44u.h +318 -0
  81. data/dependencies/libvorbis/lib/modes/residue_8.h +109 -0
  82. data/dependencies/libvorbis/lib/modes/setup_11.h +143 -0
  83. data/dependencies/libvorbis/lib/modes/setup_16.h +153 -0
  84. data/dependencies/libvorbis/lib/modes/setup_22.h +128 -0
  85. data/dependencies/libvorbis/lib/modes/setup_32.h +132 -0
  86. data/dependencies/libvorbis/lib/modes/setup_44.h +117 -0
  87. data/dependencies/libvorbis/lib/modes/setup_44p51.h +74 -0
  88. data/dependencies/libvorbis/lib/modes/setup_44u.h +74 -0
  89. data/dependencies/libvorbis/lib/modes/setup_8.h +149 -0
  90. data/dependencies/libvorbis/lib/modes/setup_X.h +225 -0
  91. data/dependencies/libvorbis/lib/os.h +186 -0
  92. data/dependencies/libvorbis/lib/psy.c +1203 -0
  93. data/dependencies/libvorbis/lib/psy.h +154 -0
  94. data/dependencies/libvorbis/lib/psytune.c +524 -0
  95. data/dependencies/libvorbis/lib/registry.c +45 -0
  96. data/dependencies/libvorbis/lib/registry.h +32 -0
  97. data/dependencies/libvorbis/lib/res0.c +889 -0
  98. data/dependencies/libvorbis/lib/scales.h +90 -0
  99. data/dependencies/libvorbis/lib/sharedbook.c +579 -0
  100. data/dependencies/libvorbis/lib/smallft.c +1255 -0
  101. data/dependencies/libvorbis/lib/smallft.h +34 -0
  102. data/dependencies/libvorbis/lib/synthesis.c +184 -0
  103. data/dependencies/libvorbis/lib/tone.c +54 -0
  104. data/dependencies/libvorbis/lib/vorbisenc.c +1215 -0
  105. data/dependencies/libvorbis/lib/vorbisfile.c +2337 -0
  106. data/dependencies/libvorbis/lib/window.c +2135 -0
  107. data/dependencies/libvorbis/lib/window.h +26 -0
  108. data/dependencies/ogg_vorbis.license +28 -0
  109. data/lib/gosu/swig_patches.rb +2 -2
  110. data/linux/extconf.rb +17 -3
  111. metadata +96 -17
  112. data/Gosu/ButtonsX.hpp +0 -141
  113. data/GosuImpl/Audio/AudioSDL.cpp +0 -315
@@ -0,0 +1,90 @@
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: linear scale -> dB, Bark and Mel scales
14
+ last mod: $Id: scales.h 16227 2009-07-08 06:58:46Z xiphmont $
15
+
16
+ ********************************************************************/
17
+
18
+ #ifndef _V_SCALES_H_
19
+ #define _V_SCALES_H_
20
+
21
+ #include <math.h>
22
+ #include "os.h"
23
+
24
+ #ifdef _MSC_VER
25
+ /* MS Visual Studio doesn't have C99 inline keyword. */
26
+ #define inline __inline
27
+ #endif
28
+
29
+ /* 20log10(x) */
30
+ #define VORBIS_IEEE_FLOAT32 1
31
+ #ifdef VORBIS_IEEE_FLOAT32
32
+
33
+ static inline float unitnorm(float x){
34
+ union {
35
+ ogg_uint32_t i;
36
+ float f;
37
+ } ix;
38
+ ix.f = x;
39
+ ix.i = (ix.i & 0x80000000U) | (0x3f800000U);
40
+ return ix.f;
41
+ }
42
+
43
+ /* Segher was off (too high) by ~ .3 decibel. Center the conversion correctly. */
44
+ static inline float todB(const float *x){
45
+ union {
46
+ ogg_uint32_t i;
47
+ float f;
48
+ } ix;
49
+ ix.f = *x;
50
+ ix.i = ix.i&0x7fffffff;
51
+ return (float)(ix.i * 7.17711438e-7f -764.6161886f);
52
+ }
53
+
54
+ #define todB_nn(x) todB(x)
55
+
56
+ #else
57
+
58
+ static float unitnorm(float x){
59
+ if(x<0)return(-1.f);
60
+ return(1.f);
61
+ }
62
+
63
+ #define todB(x) (*(x)==0?-400.f:log(*(x)**(x))*4.34294480f)
64
+ #define todB_nn(x) (*(x)==0.f?-400.f:log(*(x))*8.6858896f)
65
+
66
+ #endif
67
+
68
+ #define fromdB(x) (exp((x)*.11512925f))
69
+
70
+ /* The bark scale equations are approximations, since the original
71
+ table was somewhat hand rolled. The below are chosen to have the
72
+ best possible fit to the rolled tables, thus their somewhat odd
73
+ appearance (these are more accurate and over a longer range than
74
+ the oft-quoted bark equations found in the texts I have). The
75
+ approximations are valid from 0 - 30kHz (nyquist) or so.
76
+
77
+ all f in Hz, z in Bark */
78
+
79
+ #define toBARK(n) (13.1f*atan(.00074f*(n))+2.24f*atan((n)*(n)*1.85e-8f)+1e-4f*(n))
80
+ #define fromBARK(z) (102.f*(z)-2.f*pow(z,2.f)+.4f*pow(z,3.f)+pow(1.46f,z)-1.f)
81
+ #define toMEL(n) (log(1.f+(n)*.001f)*1442.695f)
82
+ #define fromMEL(m) (1000.f*exp((m)/1442.695f)-1000.f)
83
+
84
+ /* Frequency to octave. We arbitrarily declare 63.5 Hz to be octave
85
+ 0.0 */
86
+
87
+ #define toOC(n) (log(n)*1.442695f-5.965784f)
88
+ #define fromOC(o) (exp(((o)+5.965784f)*.693147f))
89
+
90
+ #endif
@@ -0,0 +1,579 @@
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: basic shared codebook operations
14
+ last mod: $Id: sharedbook.c 17030 2010-03-25 06:52:55Z xiphmont $
15
+
16
+ ********************************************************************/
17
+
18
+ #include <stdlib.h>
19
+ #include <math.h>
20
+ #include <string.h>
21
+ #include <ogg/ogg.h>
22
+ #include "os.h"
23
+ #include "misc.h"
24
+ #include "vorbis/codec.h"
25
+ #include "codebook.h"
26
+ #include "scales.h"
27
+
28
+ /**** pack/unpack helpers ******************************************/
29
+ int _ilog(unsigned int v){
30
+ int ret=0;
31
+ while(v){
32
+ ret++;
33
+ v>>=1;
34
+ }
35
+ return(ret);
36
+ }
37
+
38
+ /* 32 bit float (not IEEE; nonnormalized mantissa +
39
+ biased exponent) : neeeeeee eeemmmmm mmmmmmmm mmmmmmmm
40
+ Why not IEEE? It's just not that important here. */
41
+
42
+ #define VQ_FEXP 10
43
+ #define VQ_FMAN 21
44
+ #define VQ_FEXP_BIAS 768 /* bias toward values smaller than 1. */
45
+
46
+ /* doesn't currently guard under/overflow */
47
+ long _float32_pack(float val){
48
+ int sign=0;
49
+ long exp;
50
+ long mant;
51
+ if(val<0){
52
+ sign=0x80000000;
53
+ val= -val;
54
+ }
55
+ exp= floor(log(val)/log(2.f)+.001); //+epsilon
56
+ mant=rint(ldexp(val,(VQ_FMAN-1)-exp));
57
+ exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
58
+
59
+ return(sign|exp|mant);
60
+ }
61
+
62
+ float _float32_unpack(long val){
63
+ double mant=val&0x1fffff;
64
+ int sign=val&0x80000000;
65
+ long exp =(val&0x7fe00000L)>>VQ_FMAN;
66
+ if(sign)mant= -mant;
67
+ return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS));
68
+ }
69
+
70
+ /* given a list of word lengths, generate a list of codewords. Works
71
+ for length ordered or unordered, always assigns the lowest valued
72
+ codewords first. Extended to handle unused entries (length 0) */
73
+ ogg_uint32_t *_make_words(long *l,long n,long sparsecount){
74
+ long i,j,count=0;
75
+ ogg_uint32_t marker[33];
76
+ ogg_uint32_t *r=_ogg_malloc((sparsecount?sparsecount:n)*sizeof(*r));
77
+ memset(marker,0,sizeof(marker));
78
+
79
+ for(i=0;i<n;i++){
80
+ long length=l[i];
81
+ if(length>0){
82
+ ogg_uint32_t entry=marker[length];
83
+
84
+ /* when we claim a node for an entry, we also claim the nodes
85
+ below it (pruning off the imagined tree that may have dangled
86
+ from it) as well as blocking the use of any nodes directly
87
+ above for leaves */
88
+
89
+ /* update ourself */
90
+ if(length<32 && (entry>>length)){
91
+ /* error condition; the lengths must specify an overpopulated tree */
92
+ _ogg_free(r);
93
+ return(NULL);
94
+ }
95
+ r[count++]=entry;
96
+
97
+ /* Look to see if the next shorter marker points to the node
98
+ above. if so, update it and repeat. */
99
+ {
100
+ for(j=length;j>0;j--){
101
+
102
+ if(marker[j]&1){
103
+ /* have to jump branches */
104
+ if(j==1)
105
+ marker[1]++;
106
+ else
107
+ marker[j]=marker[j-1]<<1;
108
+ break; /* invariant says next upper marker would already
109
+ have been moved if it was on the same path */
110
+ }
111
+ marker[j]++;
112
+ }
113
+ }
114
+
115
+ /* prune the tree; the implicit invariant says all the longer
116
+ markers were dangling from our just-taken node. Dangle them
117
+ from our *new* node. */
118
+ for(j=length+1;j<33;j++)
119
+ if((marker[j]>>1) == entry){
120
+ entry=marker[j];
121
+ marker[j]=marker[j-1]<<1;
122
+ }else
123
+ break;
124
+ }else
125
+ if(sparsecount==0)count++;
126
+ }
127
+
128
+ /* sanity check the huffman tree; an underpopulated tree must be
129
+ rejected. The only exception is the one-node pseudo-nil tree,
130
+ which appears to be underpopulated because the tree doesn't
131
+ really exist; there's only one possible 'codeword' or zero bits,
132
+ but the above tree-gen code doesn't mark that. */
133
+ if(sparsecount != 1){
134
+ for(i=1;i<33;i++)
135
+ if(marker[i] & (0xffffffffUL>>(32-i))){
136
+ _ogg_free(r);
137
+ return(NULL);
138
+ }
139
+ }
140
+
141
+ /* bitreverse the words because our bitwise packer/unpacker is LSb
142
+ endian */
143
+ for(i=0,count=0;i<n;i++){
144
+ ogg_uint32_t temp=0;
145
+ for(j=0;j<l[i];j++){
146
+ temp<<=1;
147
+ temp|=(r[count]>>j)&1;
148
+ }
149
+
150
+ if(sparsecount){
151
+ if(l[i])
152
+ r[count++]=temp;
153
+ }else
154
+ r[count++]=temp;
155
+ }
156
+
157
+ return(r);
158
+ }
159
+
160
+ /* there might be a straightforward one-line way to do the below
161
+ that's portable and totally safe against roundoff, but I haven't
162
+ thought of it. Therefore, we opt on the side of caution */
163
+ long _book_maptype1_quantvals(const static_codebook *b){
164
+ long vals=floor(pow((float)b->entries,1.f/b->dim));
165
+
166
+ /* the above *should* be reliable, but we'll not assume that FP is
167
+ ever reliable when bitstream sync is at stake; verify via integer
168
+ means that vals really is the greatest value of dim for which
169
+ vals^b->bim <= b->entries */
170
+ /* treat the above as an initial guess */
171
+ while(1){
172
+ long acc=1;
173
+ long acc1=1;
174
+ int i;
175
+ for(i=0;i<b->dim;i++){
176
+ acc*=vals;
177
+ acc1*=vals+1;
178
+ }
179
+ if(acc<=b->entries && acc1>b->entries){
180
+ return(vals);
181
+ }else{
182
+ if(acc>b->entries){
183
+ vals--;
184
+ }else{
185
+ vals++;
186
+ }
187
+ }
188
+ }
189
+ }
190
+
191
+ /* unpack the quantized list of values for encode/decode ***********/
192
+ /* we need to deal with two map types: in map type 1, the values are
193
+ generated algorithmically (each column of the vector counts through
194
+ the values in the quant vector). in map type 2, all the values came
195
+ in in an explicit list. Both value lists must be unpacked */
196
+ float *_book_unquantize(const static_codebook *b,int n,int *sparsemap){
197
+ long j,k,count=0;
198
+ if(b->maptype==1 || b->maptype==2){
199
+ int quantvals;
200
+ float mindel=_float32_unpack(b->q_min);
201
+ float delta=_float32_unpack(b->q_delta);
202
+ float *r=_ogg_calloc(n*b->dim,sizeof(*r));
203
+
204
+ /* maptype 1 and 2 both use a quantized value vector, but
205
+ different sizes */
206
+ switch(b->maptype){
207
+ case 1:
208
+ /* most of the time, entries%dimensions == 0, but we need to be
209
+ well defined. We define that the possible vales at each
210
+ scalar is values == entries/dim. If entries%dim != 0, we'll
211
+ have 'too few' values (values*dim<entries), which means that
212
+ we'll have 'left over' entries; left over entries use zeroed
213
+ values (and are wasted). So don't generate codebooks like
214
+ that */
215
+ quantvals=_book_maptype1_quantvals(b);
216
+ for(j=0;j<b->entries;j++){
217
+ if((sparsemap && b->lengthlist[j]) || !sparsemap){
218
+ float last=0.f;
219
+ int indexdiv=1;
220
+ for(k=0;k<b->dim;k++){
221
+ int index= (j/indexdiv)%quantvals;
222
+ float val=b->quantlist[index];
223
+ val=fabs(val)*delta+mindel+last;
224
+ if(b->q_sequencep)last=val;
225
+ if(sparsemap)
226
+ r[sparsemap[count]*b->dim+k]=val;
227
+ else
228
+ r[count*b->dim+k]=val;
229
+ indexdiv*=quantvals;
230
+ }
231
+ count++;
232
+ }
233
+
234
+ }
235
+ break;
236
+ case 2:
237
+ for(j=0;j<b->entries;j++){
238
+ if((sparsemap && b->lengthlist[j]) || !sparsemap){
239
+ float last=0.f;
240
+
241
+ for(k=0;k<b->dim;k++){
242
+ float val=b->quantlist[j*b->dim+k];
243
+ val=fabs(val)*delta+mindel+last;
244
+ if(b->q_sequencep)last=val;
245
+ if(sparsemap)
246
+ r[sparsemap[count]*b->dim+k]=val;
247
+ else
248
+ r[count*b->dim+k]=val;
249
+ }
250
+ count++;
251
+ }
252
+ }
253
+ break;
254
+ }
255
+
256
+ return(r);
257
+ }
258
+ return(NULL);
259
+ }
260
+
261
+ void vorbis_staticbook_destroy(static_codebook *b){
262
+ if(b->allocedp){
263
+ if(b->quantlist)_ogg_free(b->quantlist);
264
+ if(b->lengthlist)_ogg_free(b->lengthlist);
265
+ memset(b,0,sizeof(*b));
266
+ _ogg_free(b);
267
+ } /* otherwise, it is in static memory */
268
+ }
269
+
270
+ void vorbis_book_clear(codebook *b){
271
+ /* static book is not cleared; we're likely called on the lookup and
272
+ the static codebook belongs to the info struct */
273
+ if(b->valuelist)_ogg_free(b->valuelist);
274
+ if(b->codelist)_ogg_free(b->codelist);
275
+
276
+ if(b->dec_index)_ogg_free(b->dec_index);
277
+ if(b->dec_codelengths)_ogg_free(b->dec_codelengths);
278
+ if(b->dec_firsttable)_ogg_free(b->dec_firsttable);
279
+
280
+ memset(b,0,sizeof(*b));
281
+ }
282
+
283
+ int vorbis_book_init_encode(codebook *c,const static_codebook *s){
284
+
285
+ memset(c,0,sizeof(*c));
286
+ c->c=s;
287
+ c->entries=s->entries;
288
+ c->used_entries=s->entries;
289
+ c->dim=s->dim;
290
+ c->codelist=_make_words(s->lengthlist,s->entries,0);
291
+ //c->valuelist=_book_unquantize(s,s->entries,NULL);
292
+ c->quantvals=_book_maptype1_quantvals(s);
293
+ c->minval=(int)rint(_float32_unpack(s->q_min));
294
+ c->delta=(int)rint(_float32_unpack(s->q_delta));
295
+
296
+ return(0);
297
+ }
298
+
299
+ static ogg_uint32_t bitreverse(ogg_uint32_t x){
300
+ x= ((x>>16)&0x0000ffffUL) | ((x<<16)&0xffff0000UL);
301
+ x= ((x>> 8)&0x00ff00ffUL) | ((x<< 8)&0xff00ff00UL);
302
+ x= ((x>> 4)&0x0f0f0f0fUL) | ((x<< 4)&0xf0f0f0f0UL);
303
+ x= ((x>> 2)&0x33333333UL) | ((x<< 2)&0xccccccccUL);
304
+ return((x>> 1)&0x55555555UL) | ((x<< 1)&0xaaaaaaaaUL);
305
+ }
306
+
307
+ static int sort32a(const void *a,const void *b){
308
+ return ( **(ogg_uint32_t **)a>**(ogg_uint32_t **)b)-
309
+ ( **(ogg_uint32_t **)a<**(ogg_uint32_t **)b);
310
+ }
311
+
312
+ /* decode codebook arrangement is more heavily optimized than encode */
313
+ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
314
+ int i,j,n=0,tabn;
315
+ int *sortindex;
316
+ memset(c,0,sizeof(*c));
317
+
318
+ /* count actually used entries */
319
+ for(i=0;i<s->entries;i++)
320
+ if(s->lengthlist[i]>0)
321
+ n++;
322
+
323
+ c->entries=s->entries;
324
+ c->used_entries=n;
325
+ c->dim=s->dim;
326
+
327
+ if(n>0){
328
+
329
+ /* two different remappings go on here.
330
+
331
+ First, we collapse the likely sparse codebook down only to
332
+ actually represented values/words. This collapsing needs to be
333
+ indexed as map-valueless books are used to encode original entry
334
+ positions as integers.
335
+
336
+ Second, we reorder all vectors, including the entry index above,
337
+ by sorted bitreversed codeword to allow treeless decode. */
338
+
339
+ /* perform sort */
340
+ ogg_uint32_t *codes=_make_words(s->lengthlist,s->entries,c->used_entries);
341
+ ogg_uint32_t **codep=alloca(sizeof(*codep)*n);
342
+
343
+ if(codes==NULL)goto err_out;
344
+
345
+ for(i=0;i<n;i++){
346
+ codes[i]=bitreverse(codes[i]);
347
+ codep[i]=codes+i;
348
+ }
349
+
350
+ qsort(codep,n,sizeof(*codep),sort32a);
351
+
352
+ sortindex=alloca(n*sizeof(*sortindex));
353
+ c->codelist=_ogg_malloc(n*sizeof(*c->codelist));
354
+ /* the index is a reverse index */
355
+ for(i=0;i<n;i++){
356
+ int position=codep[i]-codes;
357
+ sortindex[position]=i;
358
+ }
359
+
360
+ for(i=0;i<n;i++)
361
+ c->codelist[sortindex[i]]=codes[i];
362
+ _ogg_free(codes);
363
+
364
+
365
+ c->valuelist=_book_unquantize(s,n,sortindex);
366
+ c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index));
367
+
368
+ for(n=0,i=0;i<s->entries;i++)
369
+ if(s->lengthlist[i]>0)
370
+ c->dec_index[sortindex[n++]]=i;
371
+
372
+ c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths));
373
+ for(n=0,i=0;i<s->entries;i++)
374
+ if(s->lengthlist[i]>0)
375
+ c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
376
+
377
+ c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
378
+ if(c->dec_firsttablen<5)c->dec_firsttablen=5;
379
+ if(c->dec_firsttablen>8)c->dec_firsttablen=8;
380
+
381
+ tabn=1<<c->dec_firsttablen;
382
+ c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
383
+ c->dec_maxlength=0;
384
+
385
+ for(i=0;i<n;i++){
386
+ if(c->dec_maxlength<c->dec_codelengths[i])
387
+ c->dec_maxlength=c->dec_codelengths[i];
388
+ if(c->dec_codelengths[i]<=c->dec_firsttablen){
389
+ ogg_uint32_t orig=bitreverse(c->codelist[i]);
390
+ for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
391
+ c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
392
+ }
393
+ }
394
+
395
+ /* now fill in 'unused' entries in the firsttable with hi/lo search
396
+ hints for the non-direct-hits */
397
+ {
398
+ ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
399
+ long lo=0,hi=0;
400
+
401
+ for(i=0;i<tabn;i++){
402
+ ogg_uint32_t word=i<<(32-c->dec_firsttablen);
403
+ if(c->dec_firsttable[bitreverse(word)]==0){
404
+ while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
405
+ while( hi<n && word>=(c->codelist[hi]&mask))hi++;
406
+
407
+ /* we only actually have 15 bits per hint to play with here.
408
+ In order to overflow gracefully (nothing breaks, efficiency
409
+ just drops), encode as the difference from the extremes. */
410
+ {
411
+ unsigned long loval=lo;
412
+ unsigned long hival=n-hi;
413
+
414
+ if(loval>0x7fff)loval=0x7fff;
415
+ if(hival>0x7fff)hival=0x7fff;
416
+ c->dec_firsttable[bitreverse(word)]=
417
+ 0x80000000UL | (loval<<15) | hival;
418
+ }
419
+ }
420
+ }
421
+ }
422
+ }
423
+
424
+ return(0);
425
+ err_out:
426
+ vorbis_book_clear(c);
427
+ return(-1);
428
+ }
429
+
430
+ long vorbis_book_codeword(codebook *book,int entry){
431
+ if(book->c) /* only use with encode; decode optimizations are
432
+ allowed to break this */
433
+ return book->codelist[entry];
434
+ return -1;
435
+ }
436
+
437
+ long vorbis_book_codelen(codebook *book,int entry){
438
+ if(book->c) /* only use with encode; decode optimizations are
439
+ allowed to break this */
440
+ return book->c->lengthlist[entry];
441
+ return -1;
442
+ }
443
+
444
+ #ifdef _V_SELFTEST
445
+
446
+ /* Unit tests of the dequantizer; this stuff will be OK
447
+ cross-platform, I simply want to be sure that special mapping cases
448
+ actually work properly; a bug could go unnoticed for a while */
449
+
450
+ #include <stdio.h>
451
+
452
+ /* cases:
453
+
454
+ no mapping
455
+ full, explicit mapping
456
+ algorithmic mapping
457
+
458
+ nonsequential
459
+ sequential
460
+ */
461
+
462
+ static long full_quantlist1[]={0,1,2,3, 4,5,6,7, 8,3,6,1};
463
+ static long partial_quantlist1[]={0,7,2};
464
+
465
+ /* no mapping */
466
+ static_codebook test1={
467
+ 4,16,
468
+ NULL,
469
+ 0,
470
+ 0,0,0,0,
471
+ NULL,
472
+ 0
473
+ };
474
+ static float *test1_result=NULL;
475
+
476
+ /* linear, full mapping, nonsequential */
477
+ static_codebook test2={
478
+ 4,3,
479
+ NULL,
480
+ 2,
481
+ -533200896,1611661312,4,0,
482
+ full_quantlist1,
483
+ 0
484
+ };
485
+ static float test2_result[]={-3,-2,-1,0, 1,2,3,4, 5,0,3,-2};
486
+
487
+ /* linear, full mapping, sequential */
488
+ static_codebook test3={
489
+ 4,3,
490
+ NULL,
491
+ 2,
492
+ -533200896,1611661312,4,1,
493
+ full_quantlist1,
494
+ 0
495
+ };
496
+ static float test3_result[]={-3,-5,-6,-6, 1,3,6,10, 5,5,8,6};
497
+
498
+ /* linear, algorithmic mapping, nonsequential */
499
+ static_codebook test4={
500
+ 3,27,
501
+ NULL,
502
+ 1,
503
+ -533200896,1611661312,4,0,
504
+ partial_quantlist1,
505
+ 0
506
+ };
507
+ static float test4_result[]={-3,-3,-3, 4,-3,-3, -1,-3,-3,
508
+ -3, 4,-3, 4, 4,-3, -1, 4,-3,
509
+ -3,-1,-3, 4,-1,-3, -1,-1,-3,
510
+ -3,-3, 4, 4,-3, 4, -1,-3, 4,
511
+ -3, 4, 4, 4, 4, 4, -1, 4, 4,
512
+ -3,-1, 4, 4,-1, 4, -1,-1, 4,
513
+ -3,-3,-1, 4,-3,-1, -1,-3,-1,
514
+ -3, 4,-1, 4, 4,-1, -1, 4,-1,
515
+ -3,-1,-1, 4,-1,-1, -1,-1,-1};
516
+
517
+ /* linear, algorithmic mapping, sequential */
518
+ static_codebook test5={
519
+ 3,27,
520
+ NULL,
521
+ 1,
522
+ -533200896,1611661312,4,1,
523
+ partial_quantlist1,
524
+ 0
525
+ };
526
+ static float test5_result[]={-3,-6,-9, 4, 1,-2, -1,-4,-7,
527
+ -3, 1,-2, 4, 8, 5, -1, 3, 0,
528
+ -3,-4,-7, 4, 3, 0, -1,-2,-5,
529
+ -3,-6,-2, 4, 1, 5, -1,-4, 0,
530
+ -3, 1, 5, 4, 8,12, -1, 3, 7,
531
+ -3,-4, 0, 4, 3, 7, -1,-2, 2,
532
+ -3,-6,-7, 4, 1, 0, -1,-4,-5,
533
+ -3, 1, 0, 4, 8, 7, -1, 3, 2,
534
+ -3,-4,-5, 4, 3, 2, -1,-2,-3};
535
+
536
+ void run_test(static_codebook *b,float *comp){
537
+ float *out=_book_unquantize(b,b->entries,NULL);
538
+ int i;
539
+
540
+ if(comp){
541
+ if(!out){
542
+ fprintf(stderr,"_book_unquantize incorrectly returned NULL\n");
543
+ exit(1);
544
+ }
545
+
546
+ for(i=0;i<b->entries*b->dim;i++)
547
+ if(fabs(out[i]-comp[i])>.0001){
548
+ fprintf(stderr,"disagreement in unquantized and reference data:\n"
549
+ "position %d, %g != %g\n",i,out[i],comp[i]);
550
+ exit(1);
551
+ }
552
+
553
+ }else{
554
+ if(out){
555
+ fprintf(stderr,"_book_unquantize returned a value array: \n"
556
+ " correct result should have been NULL\n");
557
+ exit(1);
558
+ }
559
+ }
560
+ }
561
+
562
+ int main(){
563
+ /* run the nine dequant tests, and compare to the hand-rolled results */
564
+ fprintf(stderr,"Dequant test 1... ");
565
+ run_test(&test1,test1_result);
566
+ fprintf(stderr,"OK\nDequant test 2... ");
567
+ run_test(&test2,test2_result);
568
+ fprintf(stderr,"OK\nDequant test 3... ");
569
+ run_test(&test3,test3_result);
570
+ fprintf(stderr,"OK\nDequant test 4... ");
571
+ run_test(&test4,test4_result);
572
+ fprintf(stderr,"OK\nDequant test 5... ");
573
+ run_test(&test5,test5_result);
574
+ fprintf(stderr,"OK\n\n");
575
+
576
+ return(0);
577
+ }
578
+
579
+ #endif