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,64 @@
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-2007 *
9
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
10
+ * *
11
+ ********************************************************************
12
+
13
+ function: bark scale utility
14
+ last mod: $Id: barkmel.c 16037 2009-05-26 21:10:58Z xiphmont $
15
+
16
+ ********************************************************************/
17
+
18
+ #include <stdio.h>
19
+ #include "scales.h"
20
+ int main(){
21
+ int i;
22
+ double rate;
23
+ for(i=64;i<32000;i*=2){
24
+ rate=48000.f;
25
+ fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
26
+ rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
27
+
28
+ rate=44100.f;
29
+ fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
30
+ rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
31
+
32
+ rate=32000.f;
33
+ fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
34
+ rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
35
+
36
+ rate=22050.f;
37
+ fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
38
+ rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
39
+
40
+ rate=16000.f;
41
+ fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
42
+ rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
43
+
44
+ rate=11025.f;
45
+ fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
46
+ rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
47
+
48
+ rate=8000.f;
49
+ fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n\n",
50
+ rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
51
+
52
+
53
+ }
54
+ {
55
+ float i;
56
+ int j;
57
+ for(i=0.,j=0;i<28;i+=1,j++){
58
+ fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n",
59
+ j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.));
60
+ }
61
+ }
62
+ return(0);
63
+ }
64
+
@@ -0,0 +1,253 @@
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: bitrate tracking and management
14
+ last mod: $Id: bitrate.c 16227 2009-07-08 06:58:46Z xiphmont $
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 "os.h"
25
+ #include "misc.h"
26
+ #include "bitrate.h"
27
+
28
+ /* compute bitrate tracking setup */
29
+ void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){
30
+ codec_setup_info *ci=vi->codec_setup;
31
+ bitrate_manager_info *bi=&ci->bi;
32
+
33
+ memset(bm,0,sizeof(*bm));
34
+
35
+ if(bi && (bi->reservoir_bits>0)){
36
+ long ratesamples=vi->rate;
37
+ int halfsamples=ci->blocksizes[0]>>1;
38
+
39
+ bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0];
40
+ bm->managed=1;
41
+
42
+ bm->avg_bitsper= rint(1.*bi->avg_rate*halfsamples/ratesamples);
43
+ bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples);
44
+ bm->max_bitsper= rint(1.*bi->max_rate*halfsamples/ratesamples);
45
+
46
+ bm->avgfloat=PACKETBLOBS/2;
47
+
48
+ /* not a necessary fix, but one that leads to a more balanced
49
+ typical initialization */
50
+ {
51
+ long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
52
+ bm->minmax_reservoir=desired_fill;
53
+ bm->avg_reservoir=desired_fill;
54
+ }
55
+
56
+ }
57
+ }
58
+
59
+ void vorbis_bitrate_clear(bitrate_manager_state *bm){
60
+ memset(bm,0,sizeof(*bm));
61
+ return;
62
+ }
63
+
64
+ int vorbis_bitrate_managed(vorbis_block *vb){
65
+ vorbis_dsp_state *vd=vb->vd;
66
+ private_state *b=vd->backend_state;
67
+ bitrate_manager_state *bm=&b->bms;
68
+
69
+ if(bm && bm->managed)return(1);
70
+ return(0);
71
+ }
72
+
73
+ /* finish taking in the block we just processed */
74
+ int vorbis_bitrate_addblock(vorbis_block *vb){
75
+ vorbis_block_internal *vbi=vb->internal;
76
+ vorbis_dsp_state *vd=vb->vd;
77
+ private_state *b=vd->backend_state;
78
+ bitrate_manager_state *bm=&b->bms;
79
+ vorbis_info *vi=vd->vi;
80
+ codec_setup_info *ci=vi->codec_setup;
81
+ bitrate_manager_info *bi=&ci->bi;
82
+
83
+ int choice=rint(bm->avgfloat);
84
+ long this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
85
+ long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper);
86
+ long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper);
87
+ int samples=ci->blocksizes[vb->W]>>1;
88
+ long desired_fill=bi->reservoir_bits*bi->reservoir_bias;
89
+ if(!bm->managed){
90
+ /* not a bitrate managed stream, but for API simplicity, we'll
91
+ buffer the packet to keep the code path clean */
92
+
93
+ if(bm->vb)return(-1); /* one has been submitted without
94
+ being claimed */
95
+ bm->vb=vb;
96
+ return(0);
97
+ }
98
+
99
+ bm->vb=vb;
100
+
101
+ /* look ahead for avg floater */
102
+ if(bm->avg_bitsper>0){
103
+ double slew=0.;
104
+ long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
105
+ double slewlimit= 15./bi->slew_damp;
106
+
107
+ /* choosing a new floater:
108
+ if we're over target, we slew down
109
+ if we're under target, we slew up
110
+
111
+ choose slew as follows: look through packetblobs of this frame
112
+ and set slew as the first in the appropriate direction that
113
+ gives us the slew we want. This may mean no slew if delta is
114
+ already favorable.
115
+
116
+ Then limit slew to slew max */
117
+
118
+ if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
119
+ while(choice>0 && this_bits>avg_target_bits &&
120
+ bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){
121
+ choice--;
122
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
123
+ }
124
+ }else if(bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
125
+ while(choice+1<PACKETBLOBS && this_bits<avg_target_bits &&
126
+ bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){
127
+ choice++;
128
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
129
+ }
130
+ }
131
+
132
+ slew=rint(choice-bm->avgfloat)/samples*vi->rate;
133
+ if(slew<-slewlimit)slew=-slewlimit;
134
+ if(slew>slewlimit)slew=slewlimit;
135
+ choice=rint(bm->avgfloat+= slew/vi->rate*samples);
136
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
137
+ }
138
+
139
+
140
+
141
+ /* enforce min(if used) on the current floater (if used) */
142
+ if(bm->min_bitsper>0){
143
+ /* do we need to force the bitrate up? */
144
+ if(this_bits<min_target_bits){
145
+ while(bm->minmax_reservoir-(min_target_bits-this_bits)<0){
146
+ choice++;
147
+ if(choice>=PACKETBLOBS)break;
148
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
149
+ }
150
+ }
151
+ }
152
+
153
+ /* enforce max (if used) on the current floater (if used) */
154
+ if(bm->max_bitsper>0){
155
+ /* do we need to force the bitrate down? */
156
+ if(this_bits>max_target_bits){
157
+ while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){
158
+ choice--;
159
+ if(choice<0)break;
160
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
161
+ }
162
+ }
163
+ }
164
+
165
+ /* Choice of packetblobs now made based on floater, and min/max
166
+ requirements. Now boundary check extreme choices */
167
+
168
+ if(choice<0){
169
+ /* choosing a smaller packetblob is insufficient to trim bitrate.
170
+ frame will need to be truncated */
171
+ long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8;
172
+ bm->choice=choice=0;
173
+
174
+ if(oggpack_bytes(vbi->packetblob[choice])>maxsize){
175
+
176
+ oggpack_writetrunc(vbi->packetblob[choice],maxsize*8);
177
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
178
+ }
179
+ }else{
180
+ long minsize=(min_target_bits-bm->minmax_reservoir+7)/8;
181
+ if(choice>=PACKETBLOBS)
182
+ choice=PACKETBLOBS-1;
183
+
184
+ bm->choice=choice;
185
+
186
+ /* prop up bitrate according to demand. pad this frame out with zeroes */
187
+ minsize-=oggpack_bytes(vbi->packetblob[choice]);
188
+ while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8);
189
+ this_bits=oggpack_bytes(vbi->packetblob[choice])*8;
190
+
191
+ }
192
+
193
+ /* now we have the final packet and the final packet size. Update statistics */
194
+ /* min and max reservoir */
195
+ if(bm->min_bitsper>0 || bm->max_bitsper>0){
196
+
197
+ if(max_target_bits>0 && this_bits>max_target_bits){
198
+ bm->minmax_reservoir+=(this_bits-max_target_bits);
199
+ }else if(min_target_bits>0 && this_bits<min_target_bits){
200
+ bm->minmax_reservoir+=(this_bits-min_target_bits);
201
+ }else{
202
+ /* inbetween; we want to take reservoir toward but not past desired_fill */
203
+ if(bm->minmax_reservoir>desired_fill){
204
+ if(max_target_bits>0){ /* logical bulletproofing against initialization state */
205
+ bm->minmax_reservoir+=(this_bits-max_target_bits);
206
+ if(bm->minmax_reservoir<desired_fill)bm->minmax_reservoir=desired_fill;
207
+ }else{
208
+ bm->minmax_reservoir=desired_fill;
209
+ }
210
+ }else{
211
+ if(min_target_bits>0){ /* logical bulletproofing against initialization state */
212
+ bm->minmax_reservoir+=(this_bits-min_target_bits);
213
+ if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill;
214
+ }else{
215
+ bm->minmax_reservoir=desired_fill;
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ /* avg reservoir */
222
+ if(bm->avg_bitsper>0){
223
+ long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper);
224
+ bm->avg_reservoir+=this_bits-avg_target_bits;
225
+ }
226
+
227
+ return(0);
228
+ }
229
+
230
+ int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){
231
+ private_state *b=vd->backend_state;
232
+ bitrate_manager_state *bm=&b->bms;
233
+ vorbis_block *vb=bm->vb;
234
+ int choice=PACKETBLOBS/2;
235
+ if(!vb)return 0;
236
+
237
+ if(op){
238
+ vorbis_block_internal *vbi=vb->internal;
239
+
240
+ if(vorbis_bitrate_managed(vb))
241
+ choice=bm->choice;
242
+
243
+ op->packet=oggpack_get_buffer(vbi->packetblob[choice]);
244
+ op->bytes=oggpack_bytes(vbi->packetblob[choice]);
245
+ op->b_o_s=0;
246
+ op->e_o_s=vb->eofflag;
247
+ op->granulepos=vb->granulepos;
248
+ op->packetno=vb->sequence; /* for sake of completeness */
249
+ }
250
+
251
+ bm->vb=0;
252
+ return(1);
253
+ }
@@ -0,0 +1,59 @@
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-2007 *
9
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
10
+ * *
11
+ ********************************************************************
12
+
13
+ function: bitrate tracking and management
14
+ last mod: $Id: bitrate.h 13293 2007-07-24 00:09:47Z xiphmont $
15
+
16
+ ********************************************************************/
17
+
18
+ #ifndef _V_BITRATE_H_
19
+ #define _V_BITRATE_H_
20
+
21
+ #include "vorbis/codec.h"
22
+ #include "codec_internal.h"
23
+ #include "os.h"
24
+
25
+ /* encode side bitrate tracking */
26
+ typedef struct bitrate_manager_state {
27
+ int managed;
28
+
29
+ long avg_reservoir;
30
+ long minmax_reservoir;
31
+ long avg_bitsper;
32
+ long min_bitsper;
33
+ long max_bitsper;
34
+
35
+ long short_per_long;
36
+ double avgfloat;
37
+
38
+ vorbis_block *vb;
39
+ int choice;
40
+ } bitrate_manager_state;
41
+
42
+ typedef struct bitrate_manager_info{
43
+ long avg_rate;
44
+ long min_rate;
45
+ long max_rate;
46
+ long reservoir_bits;
47
+ double reservoir_bias;
48
+
49
+ double slew_damp;
50
+
51
+ } bitrate_manager_info;
52
+
53
+ extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs);
54
+ extern void vorbis_bitrate_clear(bitrate_manager_state *bs);
55
+ extern int vorbis_bitrate_managed(vorbis_block *vb);
56
+ extern int vorbis_bitrate_addblock(vorbis_block *vb);
57
+ extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op);
58
+
59
+ #endif
@@ -0,0 +1,1046 @@
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: PCM data vector blocking, windowing and dis/reassembly
14
+ last mod: $Id: block.c 17561 2010-10-23 10:34:24Z xiphmont $
15
+
16
+ Handle windowing, overlap-add, etc of the PCM vectors. This is made
17
+ more amusing by Vorbis' current two allowed block sizes.
18
+
19
+ ********************************************************************/
20
+
21
+ #include <stdio.h>
22
+ #include <stdlib.h>
23
+ #include <string.h>
24
+ #include <ogg/ogg.h>
25
+ #include "vorbis/codec.h"
26
+ #include "codec_internal.h"
27
+
28
+ #include "window.h"
29
+ #include "mdct.h"
30
+ #include "lpc.h"
31
+ #include "registry.h"
32
+ #include "misc.h"
33
+
34
+ static int ilog2(unsigned int v){
35
+ int ret=0;
36
+ if(v)--v;
37
+ while(v){
38
+ ret++;
39
+ v>>=1;
40
+ }
41
+ return(ret);
42
+ }
43
+
44
+ /* pcm accumulator examples (not exhaustive):
45
+
46
+ <-------------- lW ---------------->
47
+ <--------------- W ---------------->
48
+ : .....|..... _______________ |
49
+ : .''' | '''_--- | |\ |
50
+ :.....''' |_____--- '''......| | \_______|
51
+ :.................|__________________|_______|__|______|
52
+ |<------ Sl ------>| > Sr < |endW
53
+ |beginSl |endSl | |endSr
54
+ |beginW |endlW |beginSr
55
+
56
+
57
+ |< lW >|
58
+ <--------------- W ---------------->
59
+ | | .. ______________ |
60
+ | | ' `/ | ---_ |
61
+ |___.'___/`. | ---_____|
62
+ |_______|__|_______|_________________|
63
+ | >|Sl|< |<------ Sr ----->|endW
64
+ | | |endSl |beginSr |endSr
65
+ |beginW | |endlW
66
+ mult[0] |beginSl mult[n]
67
+
68
+ <-------------- lW ----------------->
69
+ |<--W-->|
70
+ : .............. ___ | |
71
+ : .''' |`/ \ | |
72
+ :.....''' |/`....\|...|
73
+ :.........................|___|___|___|
74
+ |Sl |Sr |endW
75
+ | | |endSr
76
+ | |beginSr
77
+ | |endSl
78
+ |beginSl
79
+ |beginW
80
+ */
81
+
82
+ /* block abstraction setup *********************************************/
83
+
84
+ #ifndef WORD_ALIGN
85
+ #define WORD_ALIGN 8
86
+ #endif
87
+
88
+ int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb){
89
+ int i;
90
+ memset(vb,0,sizeof(*vb));
91
+ vb->vd=v;
92
+ vb->localalloc=0;
93
+ vb->localstore=NULL;
94
+ if(v->analysisp){
95
+ vorbis_block_internal *vbi=
96
+ vb->internal=_ogg_calloc(1,sizeof(vorbis_block_internal));
97
+ vbi->ampmax=-9999;
98
+
99
+ for(i=0;i<PACKETBLOBS;i++){
100
+ if(i==PACKETBLOBS/2){
101
+ vbi->packetblob[i]=&vb->opb;
102
+ }else{
103
+ vbi->packetblob[i]=
104
+ _ogg_calloc(1,sizeof(oggpack_buffer));
105
+ }
106
+ oggpack_writeinit(vbi->packetblob[i]);
107
+ }
108
+ }
109
+
110
+ return(0);
111
+ }
112
+
113
+ void *_vorbis_block_alloc(vorbis_block *vb,long bytes){
114
+ bytes=(bytes+(WORD_ALIGN-1)) & ~(WORD_ALIGN-1);
115
+ if(bytes+vb->localtop>vb->localalloc){
116
+ /* can't just _ogg_realloc... there are outstanding pointers */
117
+ if(vb->localstore){
118
+ struct alloc_chain *link=_ogg_malloc(sizeof(*link));
119
+ vb->totaluse+=vb->localtop;
120
+ link->next=vb->reap;
121
+ link->ptr=vb->localstore;
122
+ vb->reap=link;
123
+ }
124
+ /* highly conservative */
125
+ vb->localalloc=bytes;
126
+ vb->localstore=_ogg_malloc(vb->localalloc);
127
+ vb->localtop=0;
128
+ }
129
+ {
130
+ void *ret=(void *)(((char *)vb->localstore)+vb->localtop);
131
+ vb->localtop+=bytes;
132
+ return ret;
133
+ }
134
+ }
135
+
136
+ /* reap the chain, pull the ripcord */
137
+ void _vorbis_block_ripcord(vorbis_block *vb){
138
+ /* reap the chain */
139
+ struct alloc_chain *reap=vb->reap;
140
+ while(reap){
141
+ struct alloc_chain *next=reap->next;
142
+ _ogg_free(reap->ptr);
143
+ memset(reap,0,sizeof(*reap));
144
+ _ogg_free(reap);
145
+ reap=next;
146
+ }
147
+ /* consolidate storage */
148
+ if(vb->totaluse){
149
+ vb->localstore=_ogg_realloc(vb->localstore,vb->totaluse+vb->localalloc);
150
+ vb->localalloc+=vb->totaluse;
151
+ vb->totaluse=0;
152
+ }
153
+
154
+ /* pull the ripcord */
155
+ vb->localtop=0;
156
+ vb->reap=NULL;
157
+ }
158
+
159
+ int vorbis_block_clear(vorbis_block *vb){
160
+ int i;
161
+ vorbis_block_internal *vbi=vb->internal;
162
+
163
+ _vorbis_block_ripcord(vb);
164
+ if(vb->localstore)_ogg_free(vb->localstore);
165
+
166
+ if(vbi){
167
+ for(i=0;i<PACKETBLOBS;i++){
168
+ oggpack_writeclear(vbi->packetblob[i]);
169
+ if(i!=PACKETBLOBS/2)_ogg_free(vbi->packetblob[i]);
170
+ }
171
+ _ogg_free(vbi);
172
+ }
173
+ memset(vb,0,sizeof(*vb));
174
+ return(0);
175
+ }
176
+
177
+ /* Analysis side code, but directly related to blocking. Thus it's
178
+ here and not in analysis.c (which is for analysis transforms only).
179
+ The init is here because some of it is shared */
180
+
181
+ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
182
+ int i;
183
+ codec_setup_info *ci=vi->codec_setup;
184
+ private_state *b=NULL;
185
+ int hs;
186
+
187
+ if(ci==NULL) return 1;
188
+ hs=ci->halfrate_flag;
189
+
190
+ memset(v,0,sizeof(*v));
191
+ b=v->backend_state=_ogg_calloc(1,sizeof(*b));
192
+
193
+ v->vi=vi;
194
+ b->modebits=ilog2(ci->modes);
195
+
196
+ b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
197
+ b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
198
+
199
+ /* MDCT is tranform 0 */
200
+
201
+ b->transform[0][0]=_ogg_calloc(1,sizeof(mdct_lookup));
202
+ b->transform[1][0]=_ogg_calloc(1,sizeof(mdct_lookup));
203
+ mdct_init(b->transform[0][0],ci->blocksizes[0]>>hs);
204
+ mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
205
+
206
+ /* Vorbis I uses only window type 0 */
207
+ b->window[0]=ilog2(ci->blocksizes[0])-6;
208
+ b->window[1]=ilog2(ci->blocksizes[1])-6;
209
+
210
+ if(encp){ /* encode/decode differ here */
211
+
212
+ /* analysis always needs an fft */
213
+ drft_init(&b->fft_look[0],ci->blocksizes[0]);
214
+ drft_init(&b->fft_look[1],ci->blocksizes[1]);
215
+
216
+ /* finish the codebooks */
217
+ if(!ci->fullbooks){
218
+ ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
219
+ for(i=0;i<ci->books;i++)
220
+ vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
221
+ }
222
+
223
+ b->psy=_ogg_calloc(ci->psys,sizeof(*b->psy));
224
+ for(i=0;i<ci->psys;i++){
225
+ _vp_psy_init(b->psy+i,
226
+ ci->psy_param[i],
227
+ &ci->psy_g_param,
228
+ ci->blocksizes[ci->psy_param[i]->blockflag]/2,
229
+ vi->rate);
230
+ }
231
+
232
+ v->analysisp=1;
233
+ }else{
234
+ /* finish the codebooks */
235
+ if(!ci->fullbooks){
236
+ ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
237
+ for(i=0;i<ci->books;i++){
238
+ if(ci->book_param[i]==NULL)
239
+ goto abort_books;
240
+ if(vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]))
241
+ goto abort_books;
242
+ /* decode codebooks are now standalone after init */
243
+ vorbis_staticbook_destroy(ci->book_param[i]);
244
+ ci->book_param[i]=NULL;
245
+ }
246
+ }
247
+ }
248
+
249
+ /* initialize the storage vectors. blocksize[1] is small for encode,
250
+ but the correct size for decode */
251
+ v->pcm_storage=ci->blocksizes[1];
252
+ v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
253
+ v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
254
+ {
255
+ int i;
256
+ for(i=0;i<vi->channels;i++)
257
+ v->pcm[i]=_ogg_calloc(v->pcm_storage,sizeof(*v->pcm[i]));
258
+ }
259
+
260
+ /* all 1 (large block) or 0 (small block) */
261
+ /* explicitly set for the sake of clarity */
262
+ v->lW=0; /* previous window size */
263
+ v->W=0; /* current window size */
264
+
265
+ /* all vector indexes */
266
+ v->centerW=ci->blocksizes[1]/2;
267
+
268
+ v->pcm_current=v->centerW;
269
+
270
+ /* initialize all the backend lookups */
271
+ b->flr=_ogg_calloc(ci->floors,sizeof(*b->flr));
272
+ b->residue=_ogg_calloc(ci->residues,sizeof(*b->residue));
273
+
274
+ for(i=0;i<ci->floors;i++)
275
+ b->flr[i]=_floor_P[ci->floor_type[i]]->
276
+ look(v,ci->floor_param[i]);
277
+
278
+ for(i=0;i<ci->residues;i++)
279
+ b->residue[i]=_residue_P[ci->residue_type[i]]->
280
+ look(v,ci->residue_param[i]);
281
+
282
+ return 0;
283
+ abort_books:
284
+ for(i=0;i<ci->books;i++){
285
+ if(ci->book_param[i]!=NULL){
286
+ vorbis_staticbook_destroy(ci->book_param[i]);
287
+ ci->book_param[i]=NULL;
288
+ }
289
+ }
290
+ vorbis_dsp_clear(v);
291
+ return -1;
292
+ }
293
+
294
+ /* arbitrary settings and spec-mandated numbers get filled in here */
295
+ int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi){
296
+ private_state *b=NULL;
297
+
298
+ if(_vds_shared_init(v,vi,1))return 1;
299
+ b=v->backend_state;
300
+ b->psy_g_look=_vp_global_look(vi);
301
+
302
+ /* Initialize the envelope state storage */
303
+ b->ve=_ogg_calloc(1,sizeof(*b->ve));
304
+ _ve_envelope_init(b->ve,vi);
305
+
306
+ vorbis_bitrate_init(vi,&b->bms);
307
+
308
+ /* compressed audio packets start after the headers
309
+ with sequence number 3 */
310
+ v->sequence=3;
311
+
312
+ return(0);
313
+ }
314
+
315
+ void vorbis_dsp_clear(vorbis_dsp_state *v){
316
+ int i;
317
+ if(v){
318
+ vorbis_info *vi=v->vi;
319
+ codec_setup_info *ci=(vi?vi->codec_setup:NULL);
320
+ private_state *b=v->backend_state;
321
+
322
+ if(b){
323
+
324
+ if(b->ve){
325
+ _ve_envelope_clear(b->ve);
326
+ _ogg_free(b->ve);
327
+ }
328
+
329
+ if(b->transform[0]){
330
+ mdct_clear(b->transform[0][0]);
331
+ _ogg_free(b->transform[0][0]);
332
+ _ogg_free(b->transform[0]);
333
+ }
334
+ if(b->transform[1]){
335
+ mdct_clear(b->transform[1][0]);
336
+ _ogg_free(b->transform[1][0]);
337
+ _ogg_free(b->transform[1]);
338
+ }
339
+
340
+ if(b->flr){
341
+ if(ci)
342
+ for(i=0;i<ci->floors;i++)
343
+ _floor_P[ci->floor_type[i]]->
344
+ free_look(b->flr[i]);
345
+ _ogg_free(b->flr);
346
+ }
347
+ if(b->residue){
348
+ if(ci)
349
+ for(i=0;i<ci->residues;i++)
350
+ _residue_P[ci->residue_type[i]]->
351
+ free_look(b->residue[i]);
352
+ _ogg_free(b->residue);
353
+ }
354
+ if(b->psy){
355
+ if(ci)
356
+ for(i=0;i<ci->psys;i++)
357
+ _vp_psy_clear(b->psy+i);
358
+ _ogg_free(b->psy);
359
+ }
360
+
361
+ if(b->psy_g_look)_vp_global_free(b->psy_g_look);
362
+ vorbis_bitrate_clear(&b->bms);
363
+
364
+ drft_clear(&b->fft_look[0]);
365
+ drft_clear(&b->fft_look[1]);
366
+
367
+ }
368
+
369
+ if(v->pcm){
370
+ if(vi)
371
+ for(i=0;i<vi->channels;i++)
372
+ if(v->pcm[i])_ogg_free(v->pcm[i]);
373
+ _ogg_free(v->pcm);
374
+ if(v->pcmret)_ogg_free(v->pcmret);
375
+ }
376
+
377
+ if(b){
378
+ /* free header, header1, header2 */
379
+ if(b->header)_ogg_free(b->header);
380
+ if(b->header1)_ogg_free(b->header1);
381
+ if(b->header2)_ogg_free(b->header2);
382
+ _ogg_free(b);
383
+ }
384
+
385
+ memset(v,0,sizeof(*v));
386
+ }
387
+ }
388
+
389
+ float **vorbis_analysis_buffer(vorbis_dsp_state *v, int vals){
390
+ int i;
391
+ vorbis_info *vi=v->vi;
392
+ private_state *b=v->backend_state;
393
+
394
+ /* free header, header1, header2 */
395
+ if(b->header)_ogg_free(b->header);b->header=NULL;
396
+ if(b->header1)_ogg_free(b->header1);b->header1=NULL;
397
+ if(b->header2)_ogg_free(b->header2);b->header2=NULL;
398
+
399
+ /* Do we have enough storage space for the requested buffer? If not,
400
+ expand the PCM (and envelope) storage */
401
+
402
+ if(v->pcm_current+vals>=v->pcm_storage){
403
+ v->pcm_storage=v->pcm_current+vals*2;
404
+
405
+ for(i=0;i<vi->channels;i++){
406
+ v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
407
+ }
408
+ }
409
+
410
+ for(i=0;i<vi->channels;i++)
411
+ v->pcmret[i]=v->pcm[i]+v->pcm_current;
412
+
413
+ return(v->pcmret);
414
+ }
415
+
416
+ static void _preextrapolate_helper(vorbis_dsp_state *v){
417
+ int i;
418
+ int order=16;
419
+ float *lpc=alloca(order*sizeof(*lpc));
420
+ float *work=alloca(v->pcm_current*sizeof(*work));
421
+ long j;
422
+ v->preextrapolate=1;
423
+
424
+ if(v->pcm_current-v->centerW>order*2){ /* safety */
425
+ for(i=0;i<v->vi->channels;i++){
426
+ /* need to run the extrapolation in reverse! */
427
+ for(j=0;j<v->pcm_current;j++)
428
+ work[j]=v->pcm[i][v->pcm_current-j-1];
429
+
430
+ /* prime as above */
431
+ vorbis_lpc_from_data(work,lpc,v->pcm_current-v->centerW,order);
432
+
433
+ #if 0
434
+ if(v->vi->channels==2){
435
+ if(i==0)
436
+ _analysis_output("predataL",0,work,v->pcm_current-v->centerW,0,0,0);
437
+ else
438
+ _analysis_output("predataR",0,work,v->pcm_current-v->centerW,0,0,0);
439
+ }else{
440
+ _analysis_output("predata",0,work,v->pcm_current-v->centerW,0,0,0);
441
+ }
442
+ #endif
443
+
444
+ /* run the predictor filter */
445
+ vorbis_lpc_predict(lpc,work+v->pcm_current-v->centerW-order,
446
+ order,
447
+ work+v->pcm_current-v->centerW,
448
+ v->centerW);
449
+
450
+ for(j=0;j<v->pcm_current;j++)
451
+ v->pcm[i][v->pcm_current-j-1]=work[j];
452
+
453
+ }
454
+ }
455
+ }
456
+
457
+
458
+ /* call with val<=0 to set eof */
459
+
460
+ int vorbis_analysis_wrote(vorbis_dsp_state *v, int vals){
461
+ vorbis_info *vi=v->vi;
462
+ codec_setup_info *ci=vi->codec_setup;
463
+
464
+ if(vals<=0){
465
+ int order=32;
466
+ int i;
467
+ float *lpc=alloca(order*sizeof(*lpc));
468
+
469
+ /* if it wasn't done earlier (very short sample) */
470
+ if(!v->preextrapolate)
471
+ _preextrapolate_helper(v);
472
+
473
+ /* We're encoding the end of the stream. Just make sure we have
474
+ [at least] a few full blocks of zeroes at the end. */
475
+ /* actually, we don't want zeroes; that could drop a large
476
+ amplitude off a cliff, creating spread spectrum noise that will
477
+ suck to encode. Extrapolate for the sake of cleanliness. */
478
+
479
+ vorbis_analysis_buffer(v,ci->blocksizes[1]*3);
480
+ v->eofflag=v->pcm_current;
481
+ v->pcm_current+=ci->blocksizes[1]*3;
482
+
483
+ for(i=0;i<vi->channels;i++){
484
+ if(v->eofflag>order*2){
485
+ /* extrapolate with LPC to fill in */
486
+ long n;
487
+
488
+ /* make a predictor filter */
489
+ n=v->eofflag;
490
+ if(n>ci->blocksizes[1])n=ci->blocksizes[1];
491
+ vorbis_lpc_from_data(v->pcm[i]+v->eofflag-n,lpc,n,order);
492
+
493
+ /* run the predictor filter */
494
+ vorbis_lpc_predict(lpc,v->pcm[i]+v->eofflag-order,order,
495
+ v->pcm[i]+v->eofflag,v->pcm_current-v->eofflag);
496
+ }else{
497
+ /* not enough data to extrapolate (unlikely to happen due to
498
+ guarding the overlap, but bulletproof in case that
499
+ assumtion goes away). zeroes will do. */
500
+ memset(v->pcm[i]+v->eofflag,0,
501
+ (v->pcm_current-v->eofflag)*sizeof(*v->pcm[i]));
502
+
503
+ }
504
+ }
505
+ }else{
506
+
507
+ if(v->pcm_current+vals>v->pcm_storage)
508
+ return(OV_EINVAL);
509
+
510
+ v->pcm_current+=vals;
511
+
512
+ /* we may want to reverse extrapolate the beginning of a stream
513
+ too... in case we're beginning on a cliff! */
514
+ /* clumsy, but simple. It only runs once, so simple is good. */
515
+ if(!v->preextrapolate && v->pcm_current-v->centerW>ci->blocksizes[1])
516
+ _preextrapolate_helper(v);
517
+
518
+ }
519
+ return(0);
520
+ }
521
+
522
+ /* do the deltas, envelope shaping, pre-echo and determine the size of
523
+ the next block on which to continue analysis */
524
+ int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb){
525
+ int i;
526
+ vorbis_info *vi=v->vi;
527
+ codec_setup_info *ci=vi->codec_setup;
528
+ private_state *b=v->backend_state;
529
+ vorbis_look_psy_global *g=b->psy_g_look;
530
+ long beginW=v->centerW-ci->blocksizes[v->W]/2,centerNext;
531
+ vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal;
532
+
533
+ /* check to see if we're started... */
534
+ if(!v->preextrapolate)return(0);
535
+
536
+ /* check to see if we're done... */
537
+ if(v->eofflag==-1)return(0);
538
+
539
+ /* By our invariant, we have lW, W and centerW set. Search for
540
+ the next boundary so we can determine nW (the next window size)
541
+ which lets us compute the shape of the current block's window */
542
+
543
+ /* we do an envelope search even on a single blocksize; we may still
544
+ be throwing more bits at impulses, and envelope search handles
545
+ marking impulses too. */
546
+ {
547
+ long bp=_ve_envelope_search(v);
548
+ if(bp==-1){
549
+
550
+ if(v->eofflag==0)return(0); /* not enough data currently to search for a
551
+ full long block */
552
+ v->nW=0;
553
+ }else{
554
+
555
+ if(ci->blocksizes[0]==ci->blocksizes[1])
556
+ v->nW=0;
557
+ else
558
+ v->nW=bp;
559
+ }
560
+ }
561
+
562
+ centerNext=v->centerW+ci->blocksizes[v->W]/4+ci->blocksizes[v->nW]/4;
563
+
564
+ {
565
+ /* center of next block + next block maximum right side. */
566
+
567
+ long blockbound=centerNext+ci->blocksizes[v->nW]/2;
568
+ if(v->pcm_current<blockbound)return(0); /* not enough data yet;
569
+ although this check is
570
+ less strict that the
571
+ _ve_envelope_search,
572
+ the search is not run
573
+ if we only use one
574
+ block size */
575
+
576
+
577
+ }
578
+
579
+ /* fill in the block. Note that for a short window, lW and nW are *short*
580
+ regardless of actual settings in the stream */
581
+
582
+ _vorbis_block_ripcord(vb);
583
+ vb->lW=v->lW;
584
+ vb->W=v->W;
585
+ vb->nW=v->nW;
586
+
587
+ if(v->W){
588
+ if(!v->lW || !v->nW){
589
+ vbi->blocktype=BLOCKTYPE_TRANSITION;
590
+ /*fprintf(stderr,"-");*/
591
+ }else{
592
+ vbi->blocktype=BLOCKTYPE_LONG;
593
+ /*fprintf(stderr,"_");*/
594
+ }
595
+ }else{
596
+ if(_ve_envelope_mark(v)){
597
+ vbi->blocktype=BLOCKTYPE_IMPULSE;
598
+ /*fprintf(stderr,"|");*/
599
+
600
+ }else{
601
+ vbi->blocktype=BLOCKTYPE_PADDING;
602
+ /*fprintf(stderr,".");*/
603
+
604
+ }
605
+ }
606
+
607
+ vb->vd=v;
608
+ vb->sequence=v->sequence++;
609
+ vb->granulepos=v->granulepos;
610
+ vb->pcmend=ci->blocksizes[v->W];
611
+
612
+ /* copy the vectors; this uses the local storage in vb */
613
+
614
+ /* this tracks 'strongest peak' for later psychoacoustics */
615
+ /* moved to the global psy state; clean this mess up */
616
+ if(vbi->ampmax>g->ampmax)g->ampmax=vbi->ampmax;
617
+ g->ampmax=_vp_ampmax_decay(g->ampmax,v);
618
+ vbi->ampmax=g->ampmax;
619
+
620
+ vb->pcm=_vorbis_block_alloc(vb,sizeof(*vb->pcm)*vi->channels);
621
+ vbi->pcmdelay=_vorbis_block_alloc(vb,sizeof(*vbi->pcmdelay)*vi->channels);
622
+ for(i=0;i<vi->channels;i++){
623
+ vbi->pcmdelay[i]=
624
+ _vorbis_block_alloc(vb,(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
625
+ memcpy(vbi->pcmdelay[i],v->pcm[i],(vb->pcmend+beginW)*sizeof(*vbi->pcmdelay[i]));
626
+ vb->pcm[i]=vbi->pcmdelay[i]+beginW;
627
+
628
+ /* before we added the delay
629
+ vb->pcm[i]=_vorbis_block_alloc(vb,vb->pcmend*sizeof(*vb->pcm[i]));
630
+ memcpy(vb->pcm[i],v->pcm[i]+beginW,ci->blocksizes[v->W]*sizeof(*vb->pcm[i]));
631
+ */
632
+
633
+ }
634
+
635
+ /* handle eof detection: eof==0 means that we've not yet received EOF
636
+ eof>0 marks the last 'real' sample in pcm[]
637
+ eof<0 'no more to do'; doesn't get here */
638
+
639
+ if(v->eofflag){
640
+ if(v->centerW>=v->eofflag){
641
+ v->eofflag=-1;
642
+ vb->eofflag=1;
643
+ return(1);
644
+ }
645
+ }
646
+
647
+ /* advance storage vectors and clean up */
648
+ {
649
+ int new_centerNext=ci->blocksizes[1]/2;
650
+ int movementW=centerNext-new_centerNext;
651
+
652
+ if(movementW>0){
653
+
654
+ _ve_envelope_shift(b->ve,movementW);
655
+ v->pcm_current-=movementW;
656
+
657
+ for(i=0;i<vi->channels;i++)
658
+ memmove(v->pcm[i],v->pcm[i]+movementW,
659
+ v->pcm_current*sizeof(*v->pcm[i]));
660
+
661
+
662
+ v->lW=v->W;
663
+ v->W=v->nW;
664
+ v->centerW=new_centerNext;
665
+
666
+ if(v->eofflag){
667
+ v->eofflag-=movementW;
668
+ if(v->eofflag<=0)v->eofflag=-1;
669
+ /* do not add padding to end of stream! */
670
+ if(v->centerW>=v->eofflag){
671
+ v->granulepos+=movementW-(v->centerW-v->eofflag);
672
+ }else{
673
+ v->granulepos+=movementW;
674
+ }
675
+ }else{
676
+ v->granulepos+=movementW;
677
+ }
678
+ }
679
+ }
680
+
681
+ /* done */
682
+ return(1);
683
+ }
684
+
685
+ int vorbis_synthesis_restart(vorbis_dsp_state *v){
686
+ vorbis_info *vi=v->vi;
687
+ codec_setup_info *ci;
688
+ int hs;
689
+
690
+ if(!v->backend_state)return -1;
691
+ if(!vi)return -1;
692
+ ci=vi->codec_setup;
693
+ if(!ci)return -1;
694
+ hs=ci->halfrate_flag;
695
+
696
+ v->centerW=ci->blocksizes[1]>>(hs+1);
697
+ v->pcm_current=v->centerW>>hs;
698
+
699
+ v->pcm_returned=-1;
700
+ v->granulepos=-1;
701
+ v->sequence=-1;
702
+ v->eofflag=0;
703
+ ((private_state *)(v->backend_state))->sample_count=-1;
704
+
705
+ return(0);
706
+ }
707
+
708
+ int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
709
+ if(_vds_shared_init(v,vi,0)){
710
+ vorbis_dsp_clear(v);
711
+ return 1;
712
+ }
713
+ vorbis_synthesis_restart(v);
714
+ return 0;
715
+ }
716
+
717
+ /* Unlike in analysis, the window is only partially applied for each
718
+ block. The time domain envelope is not yet handled at the point of
719
+ calling (as it relies on the previous block). */
720
+
721
+ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
722
+ vorbis_info *vi=v->vi;
723
+ codec_setup_info *ci=vi->codec_setup;
724
+ private_state *b=v->backend_state;
725
+ int hs=ci->halfrate_flag;
726
+ int i,j;
727
+
728
+ if(!vb)return(OV_EINVAL);
729
+ if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
730
+
731
+ v->lW=v->W;
732
+ v->W=vb->W;
733
+ v->nW=-1;
734
+
735
+ if((v->sequence==-1)||
736
+ (v->sequence+1 != vb->sequence)){
737
+ v->granulepos=-1; /* out of sequence; lose count */
738
+ b->sample_count=-1;
739
+ }
740
+
741
+ v->sequence=vb->sequence;
742
+
743
+ if(vb->pcm){ /* no pcm to process if vorbis_synthesis_trackonly
744
+ was called on block */
745
+ int n=ci->blocksizes[v->W]>>(hs+1);
746
+ int n0=ci->blocksizes[0]>>(hs+1);
747
+ int n1=ci->blocksizes[1]>>(hs+1);
748
+
749
+ int thisCenter;
750
+ int prevCenter;
751
+
752
+ v->glue_bits+=vb->glue_bits;
753
+ v->time_bits+=vb->time_bits;
754
+ v->floor_bits+=vb->floor_bits;
755
+ v->res_bits+=vb->res_bits;
756
+
757
+ if(v->centerW){
758
+ thisCenter=n1;
759
+ prevCenter=0;
760
+ }else{
761
+ thisCenter=0;
762
+ prevCenter=n1;
763
+ }
764
+
765
+ /* v->pcm is now used like a two-stage double buffer. We don't want
766
+ to have to constantly shift *or* adjust memory usage. Don't
767
+ accept a new block until the old is shifted out */
768
+
769
+ for(j=0;j<vi->channels;j++){
770
+ /* the overlap/add section */
771
+ if(v->lW){
772
+ if(v->W){
773
+ /* large/large */
774
+ float *w=_vorbis_window_get(b->window[1]-hs);
775
+ float *pcm=v->pcm[j]+prevCenter;
776
+ float *p=vb->pcm[j];
777
+ for(i=0;i<n1;i++)
778
+ pcm[i]=pcm[i]*w[n1-i-1] + p[i]*w[i];
779
+ }else{
780
+ /* large/small */
781
+ float *w=_vorbis_window_get(b->window[0]-hs);
782
+ float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
783
+ float *p=vb->pcm[j];
784
+ for(i=0;i<n0;i++)
785
+ pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
786
+ }
787
+ }else{
788
+ if(v->W){
789
+ /* small/large */
790
+ float *w=_vorbis_window_get(b->window[0]-hs);
791
+ float *pcm=v->pcm[j]+prevCenter;
792
+ float *p=vb->pcm[j]+n1/2-n0/2;
793
+ for(i=0;i<n0;i++)
794
+ pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
795
+ for(;i<n1/2+n0/2;i++)
796
+ pcm[i]=p[i];
797
+ }else{
798
+ /* small/small */
799
+ float *w=_vorbis_window_get(b->window[0]-hs);
800
+ float *pcm=v->pcm[j]+prevCenter;
801
+ float *p=vb->pcm[j];
802
+ for(i=0;i<n0;i++)
803
+ pcm[i]=pcm[i]*w[n0-i-1] +p[i]*w[i];
804
+ }
805
+ }
806
+
807
+ /* the copy section */
808
+ {
809
+ float *pcm=v->pcm[j]+thisCenter;
810
+ float *p=vb->pcm[j]+n;
811
+ for(i=0;i<n;i++)
812
+ pcm[i]=p[i];
813
+ }
814
+ }
815
+
816
+ if(v->centerW)
817
+ v->centerW=0;
818
+ else
819
+ v->centerW=n1;
820
+
821
+ /* deal with initial packet state; we do this using the explicit
822
+ pcm_returned==-1 flag otherwise we're sensitive to first block
823
+ being short or long */
824
+
825
+ if(v->pcm_returned==-1){
826
+ v->pcm_returned=thisCenter;
827
+ v->pcm_current=thisCenter;
828
+ }else{
829
+ v->pcm_returned=prevCenter;
830
+ v->pcm_current=prevCenter+
831
+ ((ci->blocksizes[v->lW]/4+
832
+ ci->blocksizes[v->W]/4)>>hs);
833
+ }
834
+
835
+ }
836
+
837
+ /* track the frame number... This is for convenience, but also
838
+ making sure our last packet doesn't end with added padding. If
839
+ the last packet is partial, the number of samples we'll have to
840
+ return will be past the vb->granulepos.
841
+
842
+ This is not foolproof! It will be confused if we begin
843
+ decoding at the last page after a seek or hole. In that case,
844
+ we don't have a starting point to judge where the last frame
845
+ is. For this reason, vorbisfile will always try to make sure
846
+ it reads the last two marked pages in proper sequence */
847
+
848
+ if(b->sample_count==-1){
849
+ b->sample_count=0;
850
+ }else{
851
+ b->sample_count+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
852
+ }
853
+
854
+ if(v->granulepos==-1){
855
+ if(vb->granulepos!=-1){ /* only set if we have a position to set to */
856
+
857
+ v->granulepos=vb->granulepos;
858
+
859
+ /* is this a short page? */
860
+ if(b->sample_count>v->granulepos){
861
+ /* corner case; if this is both the first and last audio page,
862
+ then spec says the end is cut, not beginning */
863
+ long extra=b->sample_count-vb->granulepos;
864
+
865
+ /* we use ogg_int64_t for granule positions because a
866
+ uint64 isn't universally available. Unfortunately,
867
+ that means granposes can be 'negative' and result in
868
+ extra being negative */
869
+ if(extra<0)
870
+ extra=0;
871
+
872
+ if(vb->eofflag){
873
+ /* trim the end */
874
+ /* no preceding granulepos; assume we started at zero (we'd
875
+ have to in a short single-page stream) */
876
+ /* granulepos could be -1 due to a seek, but that would result
877
+ in a long count, not short count */
878
+
879
+ /* Guard against corrupt/malicious frames that set EOP and
880
+ a backdated granpos; don't rewind more samples than we
881
+ actually have */
882
+ if(extra > (v->pcm_current - v->pcm_returned)<<hs)
883
+ extra = (v->pcm_current - v->pcm_returned)<<hs;
884
+
885
+ v->pcm_current-=extra>>hs;
886
+ }else{
887
+ /* trim the beginning */
888
+ v->pcm_returned+=extra>>hs;
889
+ if(v->pcm_returned>v->pcm_current)
890
+ v->pcm_returned=v->pcm_current;
891
+ }
892
+
893
+ }
894
+
895
+ }
896
+ }else{
897
+ v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
898
+ if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
899
+
900
+ if(v->granulepos>vb->granulepos){
901
+ long extra=v->granulepos-vb->granulepos;
902
+
903
+ if(extra)
904
+ if(vb->eofflag){
905
+ /* partial last frame. Strip the extra samples off */
906
+
907
+ /* Guard against corrupt/malicious frames that set EOP and
908
+ a backdated granpos; don't rewind more samples than we
909
+ actually have */
910
+ if(extra > (v->pcm_current - v->pcm_returned)<<hs)
911
+ extra = (v->pcm_current - v->pcm_returned)<<hs;
912
+
913
+ /* we use ogg_int64_t for granule positions because a
914
+ uint64 isn't universally available. Unfortunately,
915
+ that means granposes can be 'negative' and result in
916
+ extra being negative */
917
+ if(extra<0)
918
+ extra=0;
919
+
920
+ v->pcm_current-=extra>>hs;
921
+ } /* else {Shouldn't happen *unless* the bitstream is out of
922
+ spec. Either way, believe the bitstream } */
923
+ } /* else {Shouldn't happen *unless* the bitstream is out of
924
+ spec. Either way, believe the bitstream } */
925
+ v->granulepos=vb->granulepos;
926
+ }
927
+ }
928
+
929
+ /* Update, cleanup */
930
+
931
+ if(vb->eofflag)v->eofflag=1;
932
+ return(0);
933
+
934
+ }
935
+
936
+ /* pcm==NULL indicates we just want the pending samples, no more */
937
+ int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
938
+ vorbis_info *vi=v->vi;
939
+
940
+ if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
941
+ if(pcm){
942
+ int i;
943
+ for(i=0;i<vi->channels;i++)
944
+ v->pcmret[i]=v->pcm[i]+v->pcm_returned;
945
+ *pcm=v->pcmret;
946
+ }
947
+ return(v->pcm_current-v->pcm_returned);
948
+ }
949
+ return(0);
950
+ }
951
+
952
+ int vorbis_synthesis_read(vorbis_dsp_state *v,int n){
953
+ if(n && v->pcm_returned+n>v->pcm_current)return(OV_EINVAL);
954
+ v->pcm_returned+=n;
955
+ return(0);
956
+ }
957
+
958
+ /* intended for use with a specific vorbisfile feature; we want access
959
+ to the [usually synthetic/postextrapolated] buffer and lapping at
960
+ the end of a decode cycle, specifically, a half-short-block worth.
961
+ This funtion works like pcmout above, except it will also expose
962
+ this implicit buffer data not normally decoded. */
963
+ int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm){
964
+ vorbis_info *vi=v->vi;
965
+ codec_setup_info *ci=vi->codec_setup;
966
+ int hs=ci->halfrate_flag;
967
+
968
+ int n=ci->blocksizes[v->W]>>(hs+1);
969
+ int n0=ci->blocksizes[0]>>(hs+1);
970
+ int n1=ci->blocksizes[1]>>(hs+1);
971
+ int i,j;
972
+
973
+ if(v->pcm_returned<0)return 0;
974
+
975
+ /* our returned data ends at pcm_returned; because the synthesis pcm
976
+ buffer is a two-fragment ring, that means our data block may be
977
+ fragmented by buffering, wrapping or a short block not filling
978
+ out a buffer. To simplify things, we unfragment if it's at all
979
+ possibly needed. Otherwise, we'd need to call lapout more than
980
+ once as well as hold additional dsp state. Opt for
981
+ simplicity. */
982
+
983
+ /* centerW was advanced by blockin; it would be the center of the
984
+ *next* block */
985
+ if(v->centerW==n1){
986
+ /* the data buffer wraps; swap the halves */
987
+ /* slow, sure, small */
988
+ for(j=0;j<vi->channels;j++){
989
+ float *p=v->pcm[j];
990
+ for(i=0;i<n1;i++){
991
+ float temp=p[i];
992
+ p[i]=p[i+n1];
993
+ p[i+n1]=temp;
994
+ }
995
+ }
996
+
997
+ v->pcm_current-=n1;
998
+ v->pcm_returned-=n1;
999
+ v->centerW=0;
1000
+ }
1001
+
1002
+ /* solidify buffer into contiguous space */
1003
+ if((v->lW^v->W)==1){
1004
+ /* long/short or short/long */
1005
+ for(j=0;j<vi->channels;j++){
1006
+ float *s=v->pcm[j];
1007
+ float *d=v->pcm[j]+(n1-n0)/2;
1008
+ for(i=(n1+n0)/2-1;i>=0;--i)
1009
+ d[i]=s[i];
1010
+ }
1011
+ v->pcm_returned+=(n1-n0)/2;
1012
+ v->pcm_current+=(n1-n0)/2;
1013
+ }else{
1014
+ if(v->lW==0){
1015
+ /* short/short */
1016
+ for(j=0;j<vi->channels;j++){
1017
+ float *s=v->pcm[j];
1018
+ float *d=v->pcm[j]+n1-n0;
1019
+ for(i=n0-1;i>=0;--i)
1020
+ d[i]=s[i];
1021
+ }
1022
+ v->pcm_returned+=n1-n0;
1023
+ v->pcm_current+=n1-n0;
1024
+ }
1025
+ }
1026
+
1027
+ if(pcm){
1028
+ int i;
1029
+ for(i=0;i<vi->channels;i++)
1030
+ v->pcmret[i]=v->pcm[i]+v->pcm_returned;
1031
+ *pcm=v->pcmret;
1032
+ }
1033
+
1034
+ return(n1+n-v->pcm_returned);
1035
+
1036
+ }
1037
+
1038
+ float *vorbis_window(vorbis_dsp_state *v,int W){
1039
+ vorbis_info *vi=v->vi;
1040
+ codec_setup_info *ci=vi->codec_setup;
1041
+ int hs=ci->halfrate_flag;
1042
+ private_state *b=v->backend_state;
1043
+
1044
+ if(b->window[W]-1<0)return NULL;
1045
+ return _vorbis_window_get(b->window[W]-hs);
1046
+ }