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,225 @@
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: catch-all toplevel settings for q modes only
14
+ last mod: $Id: setup_X.h 16894 2010-02-12 20:32:12Z xiphmont $
15
+
16
+ ********************************************************************/
17
+
18
+ static const double rate_mapping_X[12]={
19
+ -1.,-1.,-1.,-1.,-1.,-1.,
20
+ -1.,-1.,-1.,-1.,-1.,-1.
21
+ };
22
+
23
+ static const ve_setup_data_template ve_setup_X_stereo={
24
+ 11,
25
+ rate_mapping_X,
26
+ quality_mapping_44,
27
+ 2,
28
+ 50000,
29
+ 200000,
30
+
31
+ blocksize_short_44,
32
+ blocksize_long_44,
33
+
34
+ _psy_tone_masteratt_44,
35
+ _psy_tone_0dB,
36
+ _psy_tone_suppress,
37
+
38
+ _vp_tonemask_adj_otherblock,
39
+ _vp_tonemask_adj_longblock,
40
+ _vp_tonemask_adj_otherblock,
41
+
42
+ _psy_noiseguards_44,
43
+ _psy_noisebias_impulse,
44
+ _psy_noisebias_padding,
45
+ _psy_noisebias_trans,
46
+ _psy_noisebias_long,
47
+ _psy_noise_suppress,
48
+
49
+ _psy_compand_44,
50
+ _psy_compand_short_mapping,
51
+ _psy_compand_long_mapping,
52
+
53
+ {_noise_start_short_44,_noise_start_long_44},
54
+ {_noise_part_short_44,_noise_part_long_44},
55
+ _noise_thresh_44,
56
+
57
+ _psy_ath_floater,
58
+ _psy_ath_abs,
59
+
60
+ _psy_lowpass_44,
61
+
62
+ _psy_global_44,
63
+ _global_mapping_44,
64
+ _psy_stereo_modes_44,
65
+
66
+ _floor_books,
67
+ _floor,
68
+ 2,
69
+ _floor_mapping_44,
70
+
71
+ _mapres_template_44_stereo
72
+ };
73
+
74
+ static const ve_setup_data_template ve_setup_X_uncoupled={
75
+ 11,
76
+ rate_mapping_X,
77
+ quality_mapping_44,
78
+ -1,
79
+ 50000,
80
+ 200000,
81
+
82
+ blocksize_short_44,
83
+ blocksize_long_44,
84
+
85
+ _psy_tone_masteratt_44,
86
+ _psy_tone_0dB,
87
+ _psy_tone_suppress,
88
+
89
+ _vp_tonemask_adj_otherblock,
90
+ _vp_tonemask_adj_longblock,
91
+ _vp_tonemask_adj_otherblock,
92
+
93
+ _psy_noiseguards_44,
94
+ _psy_noisebias_impulse,
95
+ _psy_noisebias_padding,
96
+ _psy_noisebias_trans,
97
+ _psy_noisebias_long,
98
+ _psy_noise_suppress,
99
+
100
+ _psy_compand_44,
101
+ _psy_compand_short_mapping,
102
+ _psy_compand_long_mapping,
103
+
104
+ {_noise_start_short_44,_noise_start_long_44},
105
+ {_noise_part_short_44,_noise_part_long_44},
106
+ _noise_thresh_44,
107
+
108
+ _psy_ath_floater,
109
+ _psy_ath_abs,
110
+
111
+ _psy_lowpass_44,
112
+
113
+ _psy_global_44,
114
+ _global_mapping_44,
115
+ NULL,
116
+
117
+ _floor_books,
118
+ _floor,
119
+ 2,
120
+ _floor_mapping_44,
121
+
122
+ _mapres_template_44_uncoupled
123
+ };
124
+
125
+ static const ve_setup_data_template ve_setup_XX_stereo={
126
+ 2,
127
+ rate_mapping_X,
128
+ quality_mapping_8,
129
+ 2,
130
+ 0,
131
+ 8000,
132
+
133
+ blocksize_8,
134
+ blocksize_8,
135
+
136
+ _psy_tone_masteratt_8,
137
+ _psy_tone_0dB,
138
+ _psy_tone_suppress,
139
+
140
+ _vp_tonemask_adj_8,
141
+ NULL,
142
+ _vp_tonemask_adj_8,
143
+
144
+ _psy_noiseguards_8,
145
+ _psy_noisebias_8,
146
+ _psy_noisebias_8,
147
+ NULL,
148
+ NULL,
149
+ _psy_noise_suppress,
150
+
151
+ _psy_compand_8,
152
+ _psy_compand_8_mapping,
153
+ NULL,
154
+
155
+ {_noise_start_8,_noise_start_8},
156
+ {_noise_part_8,_noise_part_8},
157
+ _noise_thresh_5only,
158
+
159
+ _psy_ath_floater_8,
160
+ _psy_ath_abs_8,
161
+
162
+ _psy_lowpass_8,
163
+
164
+ _psy_global_44,
165
+ _global_mapping_8,
166
+ _psy_stereo_modes_8,
167
+
168
+ _floor_books,
169
+ _floor,
170
+ 1,
171
+ _floor_mapping_8,
172
+
173
+ _mapres_template_8_stereo
174
+ };
175
+
176
+ static const ve_setup_data_template ve_setup_XX_uncoupled={
177
+ 2,
178
+ rate_mapping_X,
179
+ quality_mapping_8,
180
+ -1,
181
+ 0,
182
+ 8000,
183
+
184
+ blocksize_8,
185
+ blocksize_8,
186
+
187
+ _psy_tone_masteratt_8,
188
+ _psy_tone_0dB,
189
+ _psy_tone_suppress,
190
+
191
+ _vp_tonemask_adj_8,
192
+ NULL,
193
+ _vp_tonemask_adj_8,
194
+
195
+ _psy_noiseguards_8,
196
+ _psy_noisebias_8,
197
+ _psy_noisebias_8,
198
+ NULL,
199
+ NULL,
200
+ _psy_noise_suppress,
201
+
202
+ _psy_compand_8,
203
+ _psy_compand_8_mapping,
204
+ NULL,
205
+
206
+ {_noise_start_8,_noise_start_8},
207
+ {_noise_part_8,_noise_part_8},
208
+ _noise_thresh_5only,
209
+
210
+ _psy_ath_floater_8,
211
+ _psy_ath_abs_8,
212
+
213
+ _psy_lowpass_8,
214
+
215
+ _psy_global_44,
216
+ _global_mapping_8,
217
+ _psy_stereo_modes_8,
218
+
219
+ _floor_books,
220
+ _floor,
221
+ 1,
222
+ _floor_mapping_8,
223
+
224
+ _mapres_template_8_uncoupled
225
+ };
@@ -0,0 +1,186 @@
1
+ #ifndef _OS_H
2
+ #define _OS_H
3
+ /********************************************************************
4
+ * *
5
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
6
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
7
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
8
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
9
+ * *
10
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
11
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
12
+ * *
13
+ ********************************************************************
14
+
15
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
16
+ last mod: $Id: os.h 16227 2009-07-08 06:58:46Z xiphmont $
17
+
18
+ ********************************************************************/
19
+
20
+ #ifdef HAVE_CONFIG_H
21
+ #include "config.h"
22
+ #endif
23
+
24
+ #include <math.h>
25
+ #include <ogg/os_types.h>
26
+
27
+ #include "misc.h"
28
+
29
+ #ifndef _V_IFDEFJAIL_H_
30
+ # define _V_IFDEFJAIL_H_
31
+
32
+ # ifdef __GNUC__
33
+ # define STIN static __inline__
34
+ # elif _WIN32
35
+ # define STIN static __inline
36
+ # else
37
+ # define STIN static
38
+ # endif
39
+
40
+ #ifdef DJGPP
41
+ # define rint(x) (floor((x)+0.5f))
42
+ #endif
43
+
44
+ #ifndef M_PI
45
+ # define M_PI (3.1415926536f)
46
+ #endif
47
+
48
+ #if defined(_WIN32) && !defined(__SYMBIAN32__)
49
+ # include <malloc.h>
50
+ # define rint(x) (floor((x)+0.5f))
51
+ # define NO_FLOAT_MATH_LIB
52
+ # define FAST_HYPOT(a, b) sqrt((a)*(a) + (b)*(b))
53
+ #endif
54
+
55
+ #if defined(__SYMBIAN32__) && defined(__WINS__)
56
+ void *_alloca(size_t size);
57
+ # define alloca _alloca
58
+ #endif
59
+
60
+ #ifndef FAST_HYPOT
61
+ # define FAST_HYPOT hypot
62
+ #endif
63
+
64
+ #endif
65
+
66
+ #ifdef HAVE_ALLOCA_H
67
+ # include <alloca.h>
68
+ #endif
69
+
70
+ #ifdef USE_MEMORY_H
71
+ # include <memory.h>
72
+ #endif
73
+
74
+ #ifndef min
75
+ # define min(x,y) ((x)>(y)?(y):(x))
76
+ #endif
77
+
78
+ #ifndef max
79
+ # define max(x,y) ((x)<(y)?(y):(x))
80
+ #endif
81
+
82
+
83
+ /* Special i386 GCC implementation */
84
+ #if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
85
+ # define VORBIS_FPU_CONTROL
86
+ /* both GCC and MSVC are kinda stupid about rounding/casting to int.
87
+ Because of encapsulation constraints (GCC can't see inside the asm
88
+ block and so we end up doing stupid things like a store/load that
89
+ is collectively a noop), we do it this way */
90
+
91
+ /* we must set up the fpu before this works!! */
92
+
93
+ typedef ogg_int16_t vorbis_fpu_control;
94
+
95
+ static inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
96
+ ogg_int16_t ret;
97
+ ogg_int16_t temp;
98
+ __asm__ __volatile__("fnstcw %0\n\t"
99
+ "movw %0,%%dx\n\t"
100
+ "andw $62463,%%dx\n\t"
101
+ "movw %%dx,%1\n\t"
102
+ "fldcw %1\n\t":"=m"(ret):"m"(temp): "dx");
103
+ *fpu=ret;
104
+ }
105
+
106
+ static inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
107
+ __asm__ __volatile__("fldcw %0":: "m"(fpu));
108
+ }
109
+
110
+ /* assumes the FPU is in round mode! */
111
+ static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
112
+ we get extra fst/fld to
113
+ truncate precision */
114
+ int i;
115
+ __asm__("fistl %0": "=m"(i) : "t"(f));
116
+ return(i);
117
+ }
118
+ #endif /* Special i386 GCC implementation */
119
+
120
+
121
+ /* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
122
+ * 64 bit compiler */
123
+ #if defined(_MSC_VER) && !defined(_WIN64) && !defined(_WIN32_WCE)
124
+ # define VORBIS_FPU_CONTROL
125
+
126
+ typedef ogg_int16_t vorbis_fpu_control;
127
+
128
+ static __inline int vorbis_ftoi(double f){
129
+ int i;
130
+ __asm{
131
+ fld f
132
+ fistp i
133
+ }
134
+ return i;
135
+ }
136
+
137
+ static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
138
+ }
139
+
140
+ static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
141
+ }
142
+
143
+ #endif /* Special MSVC 32 bit implementation */
144
+
145
+
146
+ /* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be
147
+ done safely because all x86_64 CPUs supports SSE2. */
148
+ #if (defined(_MSC_VER) && defined(_WIN64)) || (defined(__GNUC__) && defined (__x86_64__))
149
+ # define VORBIS_FPU_CONTROL
150
+
151
+ typedef ogg_int16_t vorbis_fpu_control;
152
+
153
+ #include <emmintrin.h>
154
+ static __inline int vorbis_ftoi(double f){
155
+ return _mm_cvtsd_si32(_mm_load_sd(&f));
156
+ }
157
+
158
+ static __inline void vorbis_fpu_setround(vorbis_fpu_control *fpu){
159
+ }
160
+
161
+ static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
162
+ }
163
+
164
+ #endif /* Special MSVC x64 implementation */
165
+
166
+
167
+ /* If no special implementation was found for the current compiler / platform,
168
+ use the default implementation here: */
169
+ #ifndef VORBIS_FPU_CONTROL
170
+
171
+ typedef int vorbis_fpu_control;
172
+
173
+ static int vorbis_ftoi(double f){
174
+ /* Note: MSVC and GCC (at least on some systems) round towards zero, thus,
175
+ the floor() call is required to ensure correct roudning of
176
+ negative numbers */
177
+ return (int)floor(f+.5);
178
+ }
179
+
180
+ /* We don't have special code for this compiler/arch, so do it the slow way */
181
+ # define vorbis_fpu_setround(vorbis_fpu_control) {}
182
+ # define vorbis_fpu_restore(vorbis_fpu_control) {}
183
+
184
+ #endif /* default implementation */
185
+
186
+ #endif /* _OS_H */
@@ -0,0 +1,1203 @@
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-2010 *
9
+ * by the Xiph.Org Foundation http://www.xiph.org/ *
10
+ * *
11
+ ********************************************************************
12
+
13
+ function: psychoacoustics not including preecho
14
+ last mod: $Id: psy.c 17569 2010-10-26 17:09:47Z xiphmont $
15
+
16
+ ********************************************************************/
17
+
18
+ #include <stdlib.h>
19
+ #include <math.h>
20
+ #include <string.h>
21
+ #include "vorbis/codec.h"
22
+ #include "codec_internal.h"
23
+
24
+ #include "masking.h"
25
+ #include "psy.h"
26
+ #include "os.h"
27
+ #include "lpc.h"
28
+ #include "smallft.h"
29
+ #include "scales.h"
30
+ #include "misc.h"
31
+
32
+ #define NEGINF -9999.f
33
+ static const double stereo_threshholds[]={0.0, .5, 1.0, 1.5, 2.5, 4.5, 8.5, 16.5, 9e10};
34
+ static const double stereo_threshholds_limited[]={0.0, .5, 1.0, 1.5, 2.0, 2.5, 4.5, 8.5, 9e10};
35
+
36
+ vorbis_look_psy_global *_vp_global_look(vorbis_info *vi){
37
+ codec_setup_info *ci=vi->codec_setup;
38
+ vorbis_info_psy_global *gi=&ci->psy_g_param;
39
+ vorbis_look_psy_global *look=_ogg_calloc(1,sizeof(*look));
40
+
41
+ look->channels=vi->channels;
42
+
43
+ look->ampmax=-9999.;
44
+ look->gi=gi;
45
+ return(look);
46
+ }
47
+
48
+ void _vp_global_free(vorbis_look_psy_global *look){
49
+ if(look){
50
+ memset(look,0,sizeof(*look));
51
+ _ogg_free(look);
52
+ }
53
+ }
54
+
55
+ void _vi_gpsy_free(vorbis_info_psy_global *i){
56
+ if(i){
57
+ memset(i,0,sizeof(*i));
58
+ _ogg_free(i);
59
+ }
60
+ }
61
+
62
+ void _vi_psy_free(vorbis_info_psy *i){
63
+ if(i){
64
+ memset(i,0,sizeof(*i));
65
+ _ogg_free(i);
66
+ }
67
+ }
68
+
69
+ static void min_curve(float *c,
70
+ float *c2){
71
+ int i;
72
+ for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
73
+ }
74
+ static void max_curve(float *c,
75
+ float *c2){
76
+ int i;
77
+ for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
78
+ }
79
+
80
+ static void attenuate_curve(float *c,float att){
81
+ int i;
82
+ for(i=0;i<EHMER_MAX;i++)
83
+ c[i]+=att;
84
+ }
85
+
86
+ static float ***setup_tone_curves(float curveatt_dB[P_BANDS],float binHz,int n,
87
+ float center_boost, float center_decay_rate){
88
+ int i,j,k,m;
89
+ float ath[EHMER_MAX];
90
+ float workc[P_BANDS][P_LEVELS][EHMER_MAX];
91
+ float athc[P_LEVELS][EHMER_MAX];
92
+ float *brute_buffer=alloca(n*sizeof(*brute_buffer));
93
+
94
+ float ***ret=_ogg_malloc(sizeof(*ret)*P_BANDS);
95
+
96
+ memset(workc,0,sizeof(workc));
97
+
98
+ for(i=0;i<P_BANDS;i++){
99
+ /* we add back in the ATH to avoid low level curves falling off to
100
+ -infinity and unnecessarily cutting off high level curves in the
101
+ curve limiting (last step). */
102
+
103
+ /* A half-band's settings must be valid over the whole band, and
104
+ it's better to mask too little than too much */
105
+ int ath_offset=i*4;
106
+ for(j=0;j<EHMER_MAX;j++){
107
+ float min=999.;
108
+ for(k=0;k<4;k++)
109
+ if(j+k+ath_offset<MAX_ATH){
110
+ if(min>ATH[j+k+ath_offset])min=ATH[j+k+ath_offset];
111
+ }else{
112
+ if(min>ATH[MAX_ATH-1])min=ATH[MAX_ATH-1];
113
+ }
114
+ ath[j]=min;
115
+ }
116
+
117
+ /* copy curves into working space, replicate the 50dB curve to 30
118
+ and 40, replicate the 100dB curve to 110 */
119
+ for(j=0;j<6;j++)
120
+ memcpy(workc[i][j+2],tonemasks[i][j],EHMER_MAX*sizeof(*tonemasks[i][j]));
121
+ memcpy(workc[i][0],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
122
+ memcpy(workc[i][1],tonemasks[i][0],EHMER_MAX*sizeof(*tonemasks[i][0]));
123
+
124
+ /* apply centered curve boost/decay */
125
+ for(j=0;j<P_LEVELS;j++){
126
+ for(k=0;k<EHMER_MAX;k++){
127
+ float adj=center_boost+abs(EHMER_OFFSET-k)*center_decay_rate;
128
+ if(adj<0. && center_boost>0)adj=0.;
129
+ if(adj>0. && center_boost<0)adj=0.;
130
+ workc[i][j][k]+=adj;
131
+ }
132
+ }
133
+
134
+ /* normalize curves so the driving amplitude is 0dB */
135
+ /* make temp curves with the ATH overlayed */
136
+ for(j=0;j<P_LEVELS;j++){
137
+ attenuate_curve(workc[i][j],curveatt_dB[i]+100.-(j<2?2:j)*10.-P_LEVEL_0);
138
+ memcpy(athc[j],ath,EHMER_MAX*sizeof(**athc));
139
+ attenuate_curve(athc[j],+100.-j*10.f-P_LEVEL_0);
140
+ max_curve(athc[j],workc[i][j]);
141
+ }
142
+
143
+ /* Now limit the louder curves.
144
+
145
+ the idea is this: We don't know what the playback attenuation
146
+ will be; 0dB SL moves every time the user twiddles the volume
147
+ knob. So that means we have to use a single 'most pessimal' curve
148
+ for all masking amplitudes, right? Wrong. The *loudest* sound
149
+ can be in (we assume) a range of ...+100dB] SL. However, sounds
150
+ 20dB down will be in a range ...+80], 40dB down is from ...+60],
151
+ etc... */
152
+
153
+ for(j=1;j<P_LEVELS;j++){
154
+ min_curve(athc[j],athc[j-1]);
155
+ min_curve(workc[i][j],athc[j]);
156
+ }
157
+ }
158
+
159
+ for(i=0;i<P_BANDS;i++){
160
+ int hi_curve,lo_curve,bin;
161
+ ret[i]=_ogg_malloc(sizeof(**ret)*P_LEVELS);
162
+
163
+ /* low frequency curves are measured with greater resolution than
164
+ the MDCT/FFT will actually give us; we want the curve applied
165
+ to the tone data to be pessimistic and thus apply the minimum
166
+ masking possible for a given bin. That means that a single bin
167
+ could span more than one octave and that the curve will be a
168
+ composite of multiple octaves. It also may mean that a single
169
+ bin may span > an eighth of an octave and that the eighth
170
+ octave values may also be composited. */
171
+
172
+ /* which octave curves will we be compositing? */
173
+ bin=floor(fromOC(i*.5)/binHz);
174
+ lo_curve= ceil(toOC(bin*binHz+1)*2);
175
+ hi_curve= floor(toOC((bin+1)*binHz)*2);
176
+ if(lo_curve>i)lo_curve=i;
177
+ if(lo_curve<0)lo_curve=0;
178
+ if(hi_curve>=P_BANDS)hi_curve=P_BANDS-1;
179
+
180
+ for(m=0;m<P_LEVELS;m++){
181
+ ret[i][m]=_ogg_malloc(sizeof(***ret)*(EHMER_MAX+2));
182
+
183
+ for(j=0;j<n;j++)brute_buffer[j]=999.;
184
+
185
+ /* render the curve into bins, then pull values back into curve.
186
+ The point is that any inherent subsampling aliasing results in
187
+ a safe minimum */
188
+ for(k=lo_curve;k<=hi_curve;k++){
189
+ int l=0;
190
+
191
+ for(j=0;j<EHMER_MAX;j++){
192
+ int lo_bin= fromOC(j*.125+k*.5-2.0625)/binHz;
193
+ int hi_bin= fromOC(j*.125+k*.5-1.9375)/binHz+1;
194
+
195
+ if(lo_bin<0)lo_bin=0;
196
+ if(lo_bin>n)lo_bin=n;
197
+ if(lo_bin<l)l=lo_bin;
198
+ if(hi_bin<0)hi_bin=0;
199
+ if(hi_bin>n)hi_bin=n;
200
+
201
+ for(;l<hi_bin && l<n;l++)
202
+ if(brute_buffer[l]>workc[k][m][j])
203
+ brute_buffer[l]=workc[k][m][j];
204
+ }
205
+
206
+ for(;l<n;l++)
207
+ if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
208
+ brute_buffer[l]=workc[k][m][EHMER_MAX-1];
209
+
210
+ }
211
+
212
+ /* be equally paranoid about being valid up to next half ocatve */
213
+ if(i+1<P_BANDS){
214
+ int l=0;
215
+ k=i+1;
216
+ for(j=0;j<EHMER_MAX;j++){
217
+ int lo_bin= fromOC(j*.125+i*.5-2.0625)/binHz;
218
+ int hi_bin= fromOC(j*.125+i*.5-1.9375)/binHz+1;
219
+
220
+ if(lo_bin<0)lo_bin=0;
221
+ if(lo_bin>n)lo_bin=n;
222
+ if(lo_bin<l)l=lo_bin;
223
+ if(hi_bin<0)hi_bin=0;
224
+ if(hi_bin>n)hi_bin=n;
225
+
226
+ for(;l<hi_bin && l<n;l++)
227
+ if(brute_buffer[l]>workc[k][m][j])
228
+ brute_buffer[l]=workc[k][m][j];
229
+ }
230
+
231
+ for(;l<n;l++)
232
+ if(brute_buffer[l]>workc[k][m][EHMER_MAX-1])
233
+ brute_buffer[l]=workc[k][m][EHMER_MAX-1];
234
+
235
+ }
236
+
237
+
238
+ for(j=0;j<EHMER_MAX;j++){
239
+ int bin=fromOC(j*.125+i*.5-2.)/binHz;
240
+ if(bin<0){
241
+ ret[i][m][j+2]=-999.;
242
+ }else{
243
+ if(bin>=n){
244
+ ret[i][m][j+2]=-999.;
245
+ }else{
246
+ ret[i][m][j+2]=brute_buffer[bin];
247
+ }
248
+ }
249
+ }
250
+
251
+ /* add fenceposts */
252
+ for(j=0;j<EHMER_OFFSET;j++)
253
+ if(ret[i][m][j+2]>-200.f)break;
254
+ ret[i][m][0]=j;
255
+
256
+ for(j=EHMER_MAX-1;j>EHMER_OFFSET+1;j--)
257
+ if(ret[i][m][j+2]>-200.f)
258
+ break;
259
+ ret[i][m][1]=j;
260
+
261
+ }
262
+ }
263
+
264
+ return(ret);
265
+ }
266
+
267
+ void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,
268
+ vorbis_info_psy_global *gi,int n,long rate){
269
+ long i,j,lo=-99,hi=1;
270
+ long maxoc;
271
+ memset(p,0,sizeof(*p));
272
+
273
+ p->eighth_octave_lines=gi->eighth_octave_lines;
274
+ p->shiftoc=rint(log(gi->eighth_octave_lines*8.f)/log(2.f))-1;
275
+
276
+ p->firstoc=toOC(.25f*rate*.5/n)*(1<<(p->shiftoc+1))-gi->eighth_octave_lines;
277
+ maxoc=toOC((n+.25f)*rate*.5/n)*(1<<(p->shiftoc+1))+.5f;
278
+ p->total_octave_lines=maxoc-p->firstoc+1;
279
+ p->ath=_ogg_malloc(n*sizeof(*p->ath));
280
+
281
+ p->octave=_ogg_malloc(n*sizeof(*p->octave));
282
+ p->bark=_ogg_malloc(n*sizeof(*p->bark));
283
+ p->vi=vi;
284
+ p->n=n;
285
+ p->rate=rate;
286
+
287
+ /* AoTuV HF weighting */
288
+ p->m_val = 1.;
289
+ if(rate < 26000) p->m_val = 0;
290
+ else if(rate < 38000) p->m_val = .94; /* 32kHz */
291
+ else if(rate > 46000) p->m_val = 1.275; /* 48kHz */
292
+
293
+ /* set up the lookups for a given blocksize and sample rate */
294
+
295
+ for(i=0,j=0;i<MAX_ATH-1;i++){
296
+ int endpos=rint(fromOC((i+1)*.125-2.)*2*n/rate);
297
+ float base=ATH[i];
298
+ if(j<endpos){
299
+ float delta=(ATH[i+1]-base)/(endpos-j);
300
+ for(;j<endpos && j<n;j++){
301
+ p->ath[j]=base+100.;
302
+ base+=delta;
303
+ }
304
+ }
305
+ }
306
+
307
+ for(;j<n;j++){
308
+ p->ath[j]=p->ath[j-1];
309
+ }
310
+
311
+ for(i=0;i<n;i++){
312
+ float bark=toBARK(rate/(2*n)*i);
313
+
314
+ for(;lo+vi->noisewindowlomin<i &&
315
+ toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++);
316
+
317
+ for(;hi<=n && (hi<i+vi->noisewindowhimin ||
318
+ toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++);
319
+
320
+ p->bark[i]=((lo-1)<<16)+(hi-1);
321
+
322
+ }
323
+
324
+ for(i=0;i<n;i++)
325
+ p->octave[i]=toOC((i+.25f)*.5*rate/n)*(1<<(p->shiftoc+1))+.5f;
326
+
327
+ p->tonecurves=setup_tone_curves(vi->toneatt,rate*.5/n,n,
328
+ vi->tone_centerboost,vi->tone_decay);
329
+
330
+ /* set up rolling noise median */
331
+ p->noiseoffset=_ogg_malloc(P_NOISECURVES*sizeof(*p->noiseoffset));
332
+ for(i=0;i<P_NOISECURVES;i++)
333
+ p->noiseoffset[i]=_ogg_malloc(n*sizeof(**p->noiseoffset));
334
+
335
+ for(i=0;i<n;i++){
336
+ float halfoc=toOC((i+.5)*rate/(2.*n))*2.;
337
+ int inthalfoc;
338
+ float del;
339
+
340
+ if(halfoc<0)halfoc=0;
341
+ if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
342
+ inthalfoc=(int)halfoc;
343
+ del=halfoc-inthalfoc;
344
+
345
+ for(j=0;j<P_NOISECURVES;j++)
346
+ p->noiseoffset[j][i]=
347
+ p->vi->noiseoff[j][inthalfoc]*(1.-del) +
348
+ p->vi->noiseoff[j][inthalfoc+1]*del;
349
+
350
+ }
351
+ #if 0
352
+ {
353
+ static int ls=0;
354
+ _analysis_output_always("noiseoff0",ls,p->noiseoffset[0],n,1,0,0);
355
+ _analysis_output_always("noiseoff1",ls,p->noiseoffset[1],n,1,0,0);
356
+ _analysis_output_always("noiseoff2",ls++,p->noiseoffset[2],n,1,0,0);
357
+ }
358
+ #endif
359
+ }
360
+
361
+ void _vp_psy_clear(vorbis_look_psy *p){
362
+ int i,j;
363
+ if(p){
364
+ if(p->ath)_ogg_free(p->ath);
365
+ if(p->octave)_ogg_free(p->octave);
366
+ if(p->bark)_ogg_free(p->bark);
367
+ if(p->tonecurves){
368
+ for(i=0;i<P_BANDS;i++){
369
+ for(j=0;j<P_LEVELS;j++){
370
+ _ogg_free(p->tonecurves[i][j]);
371
+ }
372
+ _ogg_free(p->tonecurves[i]);
373
+ }
374
+ _ogg_free(p->tonecurves);
375
+ }
376
+ if(p->noiseoffset){
377
+ for(i=0;i<P_NOISECURVES;i++){
378
+ _ogg_free(p->noiseoffset[i]);
379
+ }
380
+ _ogg_free(p->noiseoffset);
381
+ }
382
+ memset(p,0,sizeof(*p));
383
+ }
384
+ }
385
+
386
+ /* octave/(8*eighth_octave_lines) x scale and dB y scale */
387
+ static void seed_curve(float *seed,
388
+ const float **curves,
389
+ float amp,
390
+ int oc, int n,
391
+ int linesper,float dBoffset){
392
+ int i,post1;
393
+ int seedptr;
394
+ const float *posts,*curve;
395
+
396
+ int choice=(int)((amp+dBoffset-P_LEVEL_0)*.1f);
397
+ choice=max(choice,0);
398
+ choice=min(choice,P_LEVELS-1);
399
+ posts=curves[choice];
400
+ curve=posts+2;
401
+ post1=(int)posts[1];
402
+ seedptr=oc+(posts[0]-EHMER_OFFSET)*linesper-(linesper>>1);
403
+
404
+ for(i=posts[0];i<post1;i++){
405
+ if(seedptr>0){
406
+ float lin=amp+curve[i];
407
+ if(seed[seedptr]<lin)seed[seedptr]=lin;
408
+ }
409
+ seedptr+=linesper;
410
+ if(seedptr>=n)break;
411
+ }
412
+ }
413
+
414
+ static void seed_loop(vorbis_look_psy *p,
415
+ const float ***curves,
416
+ const float *f,
417
+ const float *flr,
418
+ float *seed,
419
+ float specmax){
420
+ vorbis_info_psy *vi=p->vi;
421
+ long n=p->n,i;
422
+ float dBoffset=vi->max_curve_dB-specmax;
423
+
424
+ /* prime the working vector with peak values */
425
+
426
+ for(i=0;i<n;i++){
427
+ float max=f[i];
428
+ long oc=p->octave[i];
429
+ while(i+1<n && p->octave[i+1]==oc){
430
+ i++;
431
+ if(f[i]>max)max=f[i];
432
+ }
433
+
434
+ if(max+6.f>flr[i]){
435
+ oc=oc>>p->shiftoc;
436
+
437
+ if(oc>=P_BANDS)oc=P_BANDS-1;
438
+ if(oc<0)oc=0;
439
+
440
+ seed_curve(seed,
441
+ curves[oc],
442
+ max,
443
+ p->octave[i]-p->firstoc,
444
+ p->total_octave_lines,
445
+ p->eighth_octave_lines,
446
+ dBoffset);
447
+ }
448
+ }
449
+ }
450
+
451
+ static void seed_chase(float *seeds, int linesper, long n){
452
+ long *posstack=alloca(n*sizeof(*posstack));
453
+ float *ampstack=alloca(n*sizeof(*ampstack));
454
+ long stack=0;
455
+ long pos=0;
456
+ long i;
457
+
458
+ for(i=0;i<n;i++){
459
+ if(stack<2){
460
+ posstack[stack]=i;
461
+ ampstack[stack++]=seeds[i];
462
+ }else{
463
+ while(1){
464
+ if(seeds[i]<ampstack[stack-1]){
465
+ posstack[stack]=i;
466
+ ampstack[stack++]=seeds[i];
467
+ break;
468
+ }else{
469
+ if(i<posstack[stack-1]+linesper){
470
+ if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
471
+ i<posstack[stack-2]+linesper){
472
+ /* we completely overlap, making stack-1 irrelevant. pop it */
473
+ stack--;
474
+ continue;
475
+ }
476
+ }
477
+ posstack[stack]=i;
478
+ ampstack[stack++]=seeds[i];
479
+ break;
480
+
481
+ }
482
+ }
483
+ }
484
+ }
485
+
486
+ /* the stack now contains only the positions that are relevant. Scan
487
+ 'em straight through */
488
+
489
+ for(i=0;i<stack;i++){
490
+ long endpos;
491
+ if(i<stack-1 && ampstack[i+1]>ampstack[i]){
492
+ endpos=posstack[i+1];
493
+ }else{
494
+ endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
495
+ discarded in short frames */
496
+ }
497
+ if(endpos>n)endpos=n;
498
+ for(;pos<endpos;pos++)
499
+ seeds[pos]=ampstack[i];
500
+ }
501
+
502
+ /* there. Linear time. I now remember this was on a problem set I
503
+ had in Grad Skool... I didn't solve it at the time ;-) */
504
+
505
+ }
506
+
507
+ /* bleaugh, this is more complicated than it needs to be */
508
+ #include<stdio.h>
509
+ static void max_seeds(vorbis_look_psy *p,
510
+ float *seed,
511
+ float *flr){
512
+ long n=p->total_octave_lines;
513
+ int linesper=p->eighth_octave_lines;
514
+ long linpos=0;
515
+ long pos;
516
+
517
+ seed_chase(seed,linesper,n); /* for masking */
518
+
519
+ pos=p->octave[0]-p->firstoc-(linesper>>1);
520
+
521
+ while(linpos+1<p->n){
522
+ float minV=seed[pos];
523
+ long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
524
+ if(minV>p->vi->tone_abs_limit)minV=p->vi->tone_abs_limit;
525
+ while(pos+1<=end){
526
+ pos++;
527
+ if((seed[pos]>NEGINF && seed[pos]<minV) || minV==NEGINF)
528
+ minV=seed[pos];
529
+ }
530
+
531
+ end=pos+p->firstoc;
532
+ for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
533
+ if(flr[linpos]<minV)flr[linpos]=minV;
534
+ }
535
+
536
+ {
537
+ float minV=seed[p->total_octave_lines-1];
538
+ for(;linpos<p->n;linpos++)
539
+ if(flr[linpos]<minV)flr[linpos]=minV;
540
+ }
541
+
542
+ }
543
+
544
+ static void bark_noise_hybridmp(int n,const long *b,
545
+ const float *f,
546
+ float *noise,
547
+ const float offset,
548
+ const int fixed){
549
+
550
+ float *N=alloca(n*sizeof(*N));
551
+ float *X=alloca(n*sizeof(*N));
552
+ float *XX=alloca(n*sizeof(*N));
553
+ float *Y=alloca(n*sizeof(*N));
554
+ float *XY=alloca(n*sizeof(*N));
555
+
556
+ float tN, tX, tXX, tY, tXY;
557
+ int i;
558
+
559
+ int lo, hi;
560
+ float R=0.f;
561
+ float A=0.f;
562
+ float B=0.f;
563
+ float D=1.f;
564
+ float w, x, y;
565
+
566
+ tN = tX = tXX = tY = tXY = 0.f;
567
+
568
+ y = f[0] + offset;
569
+ if (y < 1.f) y = 1.f;
570
+
571
+ w = y * y * .5;
572
+
573
+ tN += w;
574
+ tX += w;
575
+ tY += w * y;
576
+
577
+ N[0] = tN;
578
+ X[0] = tX;
579
+ XX[0] = tXX;
580
+ Y[0] = tY;
581
+ XY[0] = tXY;
582
+
583
+ for (i = 1, x = 1.f; i < n; i++, x += 1.f) {
584
+
585
+ y = f[i] + offset;
586
+ if (y < 1.f) y = 1.f;
587
+
588
+ w = y * y;
589
+
590
+ tN += w;
591
+ tX += w * x;
592
+ tXX += w * x * x;
593
+ tY += w * y;
594
+ tXY += w * x * y;
595
+
596
+ N[i] = tN;
597
+ X[i] = tX;
598
+ XX[i] = tXX;
599
+ Y[i] = tY;
600
+ XY[i] = tXY;
601
+ }
602
+
603
+ for (i = 0, x = 0.f;; i++, x += 1.f) {
604
+
605
+ lo = b[i] >> 16;
606
+ if( lo>=0 ) break;
607
+ hi = b[i] & 0xffff;
608
+
609
+ tN = N[hi] + N[-lo];
610
+ tX = X[hi] - X[-lo];
611
+ tXX = XX[hi] + XX[-lo];
612
+ tY = Y[hi] + Y[-lo];
613
+ tXY = XY[hi] - XY[-lo];
614
+
615
+ A = tY * tXX - tX * tXY;
616
+ B = tN * tXY - tX * tY;
617
+ D = tN * tXX - tX * tX;
618
+ R = (A + x * B) / D;
619
+ if (R < 0.f)
620
+ R = 0.f;
621
+
622
+ noise[i] = R - offset;
623
+ }
624
+
625
+ for ( ;; i++, x += 1.f) {
626
+
627
+ lo = b[i] >> 16;
628
+ hi = b[i] & 0xffff;
629
+ if(hi>=n)break;
630
+
631
+ tN = N[hi] - N[lo];
632
+ tX = X[hi] - X[lo];
633
+ tXX = XX[hi] - XX[lo];
634
+ tY = Y[hi] - Y[lo];
635
+ tXY = XY[hi] - XY[lo];
636
+
637
+ A = tY * tXX - tX * tXY;
638
+ B = tN * tXY - tX * tY;
639
+ D = tN * tXX - tX * tX;
640
+ R = (A + x * B) / D;
641
+ if (R < 0.f) R = 0.f;
642
+
643
+ noise[i] = R - offset;
644
+ }
645
+ for ( ; i < n; i++, x += 1.f) {
646
+
647
+ R = (A + x * B) / D;
648
+ if (R < 0.f) R = 0.f;
649
+
650
+ noise[i] = R - offset;
651
+ }
652
+
653
+ if (fixed <= 0) return;
654
+
655
+ for (i = 0, x = 0.f;; i++, x += 1.f) {
656
+ hi = i + fixed / 2;
657
+ lo = hi - fixed;
658
+ if(lo>=0)break;
659
+
660
+ tN = N[hi] + N[-lo];
661
+ tX = X[hi] - X[-lo];
662
+ tXX = XX[hi] + XX[-lo];
663
+ tY = Y[hi] + Y[-lo];
664
+ tXY = XY[hi] - XY[-lo];
665
+
666
+
667
+ A = tY * tXX - tX * tXY;
668
+ B = tN * tXY - tX * tY;
669
+ D = tN * tXX - tX * tX;
670
+ R = (A + x * B) / D;
671
+
672
+ if (R - offset < noise[i]) noise[i] = R - offset;
673
+ }
674
+ for ( ;; i++, x += 1.f) {
675
+
676
+ hi = i + fixed / 2;
677
+ lo = hi - fixed;
678
+ if(hi>=n)break;
679
+
680
+ tN = N[hi] - N[lo];
681
+ tX = X[hi] - X[lo];
682
+ tXX = XX[hi] - XX[lo];
683
+ tY = Y[hi] - Y[lo];
684
+ tXY = XY[hi] - XY[lo];
685
+
686
+ A = tY * tXX - tX * tXY;
687
+ B = tN * tXY - tX * tY;
688
+ D = tN * tXX - tX * tX;
689
+ R = (A + x * B) / D;
690
+
691
+ if (R - offset < noise[i]) noise[i] = R - offset;
692
+ }
693
+ for ( ; i < n; i++, x += 1.f) {
694
+ R = (A + x * B) / D;
695
+ if (R - offset < noise[i]) noise[i] = R - offset;
696
+ }
697
+ }
698
+
699
+ void _vp_noisemask(vorbis_look_psy *p,
700
+ float *logmdct,
701
+ float *logmask){
702
+
703
+ int i,n=p->n;
704
+ float *work=alloca(n*sizeof(*work));
705
+
706
+ bark_noise_hybridmp(n,p->bark,logmdct,logmask,
707
+ 140.,-1);
708
+
709
+ for(i=0;i<n;i++)work[i]=logmdct[i]-logmask[i];
710
+
711
+ bark_noise_hybridmp(n,p->bark,work,logmask,0.,
712
+ p->vi->noisewindowfixed);
713
+
714
+ for(i=0;i<n;i++)work[i]=logmdct[i]-work[i];
715
+
716
+ #if 0
717
+ {
718
+ static int seq=0;
719
+
720
+ float work2[n];
721
+ for(i=0;i<n;i++){
722
+ work2[i]=logmask[i]+work[i];
723
+ }
724
+
725
+ if(seq&1)
726
+ _analysis_output("median2R",seq/2,work,n,1,0,0);
727
+ else
728
+ _analysis_output("median2L",seq/2,work,n,1,0,0);
729
+
730
+ if(seq&1)
731
+ _analysis_output("envelope2R",seq/2,work2,n,1,0,0);
732
+ else
733
+ _analysis_output("envelope2L",seq/2,work2,n,1,0,0);
734
+ seq++;
735
+ }
736
+ #endif
737
+
738
+ for(i=0;i<n;i++){
739
+ int dB=logmask[i]+.5;
740
+ if(dB>=NOISE_COMPAND_LEVELS)dB=NOISE_COMPAND_LEVELS-1;
741
+ if(dB<0)dB=0;
742
+ logmask[i]= work[i]+p->vi->noisecompand[dB];
743
+ }
744
+
745
+ }
746
+
747
+ void _vp_tonemask(vorbis_look_psy *p,
748
+ float *logfft,
749
+ float *logmask,
750
+ float global_specmax,
751
+ float local_specmax){
752
+
753
+ int i,n=p->n;
754
+
755
+ float *seed=alloca(sizeof(*seed)*p->total_octave_lines);
756
+ float att=local_specmax+p->vi->ath_adjatt;
757
+ for(i=0;i<p->total_octave_lines;i++)seed[i]=NEGINF;
758
+
759
+ /* set the ATH (floating below localmax, not global max by a
760
+ specified att) */
761
+ if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
762
+
763
+ for(i=0;i<n;i++)
764
+ logmask[i]=p->ath[i]+att;
765
+
766
+ /* tone masking */
767
+ seed_loop(p,(const float ***)p->tonecurves,logfft,logmask,seed,global_specmax);
768
+ max_seeds(p,seed,logmask);
769
+
770
+ }
771
+
772
+ void _vp_offset_and_mix(vorbis_look_psy *p,
773
+ float *noise,
774
+ float *tone,
775
+ int offset_select,
776
+ float *logmask,
777
+ float *mdct,
778
+ float *logmdct){
779
+ int i,n=p->n;
780
+ float de, coeffi, cx;/* AoTuV */
781
+ float toneatt=p->vi->tone_masteratt[offset_select];
782
+
783
+ cx = p->m_val;
784
+
785
+ for(i=0;i<n;i++){
786
+ float val= noise[i]+p->noiseoffset[offset_select][i];
787
+ if(val>p->vi->noisemaxsupp)val=p->vi->noisemaxsupp;
788
+ logmask[i]=max(val,tone[i]+toneatt);
789
+
790
+
791
+ /* AoTuV */
792
+ /** @ M1 **
793
+ The following codes improve a noise problem.
794
+ A fundamental idea uses the value of masking and carries out
795
+ the relative compensation of the MDCT.
796
+ However, this code is not perfect and all noise problems cannot be solved.
797
+ by Aoyumi @ 2004/04/18
798
+ */
799
+
800
+ if(offset_select == 1) {
801
+ coeffi = -17.2; /* coeffi is a -17.2dB threshold */
802
+ val = val - logmdct[i]; /* val == mdct line value relative to floor in dB */
803
+
804
+ if(val > coeffi){
805
+ /* mdct value is > -17.2 dB below floor */
806
+
807
+ de = 1.0-((val-coeffi)*0.005*cx);
808
+ /* pro-rated attenuation:
809
+ -0.00 dB boost if mdct value is -17.2dB (relative to floor)
810
+ -0.77 dB boost if mdct value is 0dB (relative to floor)
811
+ -1.64 dB boost if mdct value is +17.2dB (relative to floor)
812
+ etc... */
813
+
814
+ if(de < 0) de = 0.0001;
815
+ }else
816
+ /* mdct value is <= -17.2 dB below floor */
817
+
818
+ de = 1.0-((val-coeffi)*0.0003*cx);
819
+ /* pro-rated attenuation:
820
+ +0.00 dB atten if mdct value is -17.2dB (relative to floor)
821
+ +0.45 dB atten if mdct value is -34.4dB (relative to floor)
822
+ etc... */
823
+
824
+ mdct[i] *= de;
825
+
826
+ }
827
+ }
828
+ }
829
+
830
+ float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
831
+ vorbis_info *vi=vd->vi;
832
+ codec_setup_info *ci=vi->codec_setup;
833
+ vorbis_info_psy_global *gi=&ci->psy_g_param;
834
+
835
+ int n=ci->blocksizes[vd->W]/2;
836
+ float secs=(float)n/vi->rate;
837
+
838
+ amp+=secs*gi->ampmax_att_per_sec;
839
+ if(amp<-9999)amp=-9999;
840
+ return(amp);
841
+ }
842
+
843
+ static float FLOOR1_fromdB_LOOKUP[256]={
844
+ 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
845
+ 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
846
+ 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
847
+ 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
848
+ 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
849
+ 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
850
+ 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
851
+ 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
852
+ 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
853
+ 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
854
+ 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
855
+ 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
856
+ 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
857
+ 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
858
+ 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
859
+ 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
860
+ 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
861
+ 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
862
+ 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
863
+ 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
864
+ 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
865
+ 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
866
+ 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
867
+ 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
868
+ 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
869
+ 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
870
+ 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
871
+ 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
872
+ 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
873
+ 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
874
+ 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
875
+ 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
876
+ 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
877
+ 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
878
+ 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
879
+ 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
880
+ 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
881
+ 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
882
+ 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
883
+ 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
884
+ 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
885
+ 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
886
+ 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
887
+ 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
888
+ 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
889
+ 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
890
+ 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
891
+ 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
892
+ 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
893
+ 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
894
+ 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
895
+ 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
896
+ 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
897
+ 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
898
+ 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
899
+ 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
900
+ 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
901
+ 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
902
+ 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
903
+ 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
904
+ 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
905
+ 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
906
+ 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
907
+ 0.82788260F, 0.88168307F, 0.9389798F, 1.F,
908
+ };
909
+
910
+ /* this is for per-channel noise normalization */
911
+ static int apsort(const void *a, const void *b){
912
+ float f1=**(float**)a;
913
+ float f2=**(float**)b;
914
+ return (f1<f2)-(f1>f2);
915
+ }
916
+
917
+ static void flag_lossless(int limit, float prepoint, float postpoint, float *mdct,
918
+ float *floor, int *flag, int i, int jn){
919
+ int j;
920
+ for(j=0;j<jn;j++){
921
+ float point = j>=limit-i ? postpoint : prepoint;
922
+ float r = fabs(mdct[j])/floor[j];
923
+ if(r<point)
924
+ flag[j]=0;
925
+ else
926
+ flag[j]=1;
927
+ }
928
+ }
929
+
930
+ /* Overload/Side effect: On input, the *q vector holds either the
931
+ quantized energy (for elements with the flag set) or the absolute
932
+ values of the *r vector (for elements with flag unset). On output,
933
+ *q holds the quantized energy for all elements */
934
+ static float noise_normalize(vorbis_look_psy *p, int limit, float *r, float *q, float *f, int *flags, float acc, int i, int n, int *out){
935
+
936
+ vorbis_info_psy *vi=p->vi;
937
+ float **sort = alloca(n*sizeof(*sort));
938
+ int j,count=0;
939
+ int start = (vi->normal_p ? vi->normal_start-i : n);
940
+ if(start>n)start=n;
941
+
942
+ /* force classic behavior where only energy in the current band is considered */
943
+ acc=0.f;
944
+
945
+ /* still responsible for populating *out where noise norm not in
946
+ effect. There's no need to [re]populate *q in these areas */
947
+ for(j=0;j<start;j++){
948
+ if(!flags || !flags[j]){ /* lossless coupling already quantized.
949
+ Don't touch; requantizing based on
950
+ energy would be incorrect. */
951
+ float ve = q[j]/f[j];
952
+ if(r[j]<0)
953
+ out[j] = -rint(sqrt(ve));
954
+ else
955
+ out[j] = rint(sqrt(ve));
956
+ }
957
+ }
958
+
959
+ /* sort magnitudes for noise norm portion of partition */
960
+ for(;j<n;j++){
961
+ if(!flags || !flags[j]){ /* can't noise norm elements that have
962
+ already been loslessly coupled; we can
963
+ only account for their energy error */
964
+ float ve = q[j]/f[j];
965
+ /* Despite all the new, more capable coupling code, for now we
966
+ implement noise norm as it has been up to this point. Only
967
+ consider promotions to unit magnitude from 0. In addition
968
+ the only energy error counted is quantizations to zero. */
969
+ /* also-- the original point code only applied noise norm at > pointlimit */
970
+ if(ve<.25f && (!flags || j>=limit-i)){
971
+ acc += ve;
972
+ sort[count++]=q+j; /* q is fabs(r) for unflagged element */
973
+ }else{
974
+ /* For now: no acc adjustment for nonzero quantization. populate *out and q as this value is final. */
975
+ if(r[j]<0)
976
+ out[j] = -rint(sqrt(ve));
977
+ else
978
+ out[j] = rint(sqrt(ve));
979
+ q[j] = out[j]*out[j]*f[j];
980
+ }
981
+ }/* else{
982
+ again, no energy adjustment for error in nonzero quant-- for now
983
+ }*/
984
+ }
985
+
986
+ if(count){
987
+ /* noise norm to do */
988
+ qsort(sort,count,sizeof(*sort),apsort);
989
+ for(j=0;j<count;j++){
990
+ int k=sort[j]-q;
991
+ if(acc>=vi->normal_thresh){
992
+ out[k]=unitnorm(r[k]);
993
+ acc-=1.f;
994
+ q[k]=f[k];
995
+ }else{
996
+ out[k]=0;
997
+ q[k]=0.f;
998
+ }
999
+ }
1000
+ }
1001
+
1002
+ return acc;
1003
+ }
1004
+
1005
+ /* Noise normalization, quantization and coupling are not wholly
1006
+ seperable processes in depth>1 coupling. */
1007
+ void _vp_couple_quantize_normalize(int blobno,
1008
+ vorbis_info_psy_global *g,
1009
+ vorbis_look_psy *p,
1010
+ vorbis_info_mapping0 *vi,
1011
+ float **mdct,
1012
+ int **iwork,
1013
+ int *nonzero,
1014
+ int sliding_lowpass,
1015
+ int ch){
1016
+
1017
+ int i;
1018
+ int n = p->n;
1019
+ int partition=(p->vi->normal_p ? p->vi->normal_partition : 16);
1020
+ int limit = g->coupling_pointlimit[p->vi->blockflag][blobno];
1021
+ float prepoint=stereo_threshholds[g->coupling_prepointamp[blobno]];
1022
+ float postpoint=stereo_threshholds[g->coupling_postpointamp[blobno]];
1023
+ float de=0.1*p->m_val; /* a blend of the AoTuV M2 and M3 code here and below */
1024
+
1025
+ /* mdct is our raw mdct output, floor not removed. */
1026
+ /* inout passes in the ifloor, passes back quantized result */
1027
+
1028
+ /* unquantized energy (negative indicates amplitude has negative sign) */
1029
+ float **raw = alloca(ch*sizeof(*raw));
1030
+
1031
+ /* dual pupose; quantized energy (if flag set), othersize fabs(raw) */
1032
+ float **quant = alloca(ch*sizeof(*quant));
1033
+
1034
+ /* floor energy */
1035
+ float **floor = alloca(ch*sizeof(*floor));
1036
+
1037
+ /* flags indicating raw/quantized status of elements in raw vector */
1038
+ int **flag = alloca(ch*sizeof(*flag));
1039
+
1040
+ /* non-zero flag working vector */
1041
+ int *nz = alloca(ch*sizeof(*nz));
1042
+
1043
+ /* energy surplus/defecit tracking */
1044
+ float *acc = alloca((ch+vi->coupling_steps)*sizeof(*acc));
1045
+
1046
+ /* The threshold of a stereo is changed with the size of n */
1047
+ if(n > 1000)
1048
+ postpoint=stereo_threshholds_limited[g->coupling_postpointamp[blobno]];
1049
+
1050
+ raw[0] = alloca(ch*partition*sizeof(**raw));
1051
+ quant[0] = alloca(ch*partition*sizeof(**quant));
1052
+ floor[0] = alloca(ch*partition*sizeof(**floor));
1053
+ flag[0] = alloca(ch*partition*sizeof(**flag));
1054
+
1055
+ for(i=1;i<ch;i++){
1056
+ raw[i] = &raw[0][partition*i];
1057
+ quant[i] = &quant[0][partition*i];
1058
+ floor[i] = &floor[0][partition*i];
1059
+ flag[i] = &flag[0][partition*i];
1060
+ }
1061
+ for(i=0;i<ch+vi->coupling_steps;i++)
1062
+ acc[i]=0.f;
1063
+
1064
+ for(i=0;i<n;i+=partition){
1065
+ int k,j,jn = partition > n-i ? n-i : partition;
1066
+ int step,track = 0;
1067
+
1068
+ memcpy(nz,nonzero,sizeof(*nz)*ch);
1069
+
1070
+ /* prefill */
1071
+ memset(flag[0],0,ch*partition*sizeof(**flag));
1072
+ for(k=0;k<ch;k++){
1073
+ int *iout = &iwork[k][i];
1074
+ if(nz[k]){
1075
+
1076
+ for(j=0;j<jn;j++)
1077
+ floor[k][j] = FLOOR1_fromdB_LOOKUP[iout[j]];
1078
+
1079
+ flag_lossless(limit,prepoint,postpoint,&mdct[k][i],floor[k],flag[k],i,jn);
1080
+
1081
+ for(j=0;j<jn;j++){
1082
+ quant[k][j] = raw[k][j] = mdct[k][i+j]*mdct[k][i+j];
1083
+ if(mdct[k][i+j]<0.f) raw[k][j]*=-1.f;
1084
+ floor[k][j]*=floor[k][j];
1085
+ }
1086
+
1087
+ acc[track]=noise_normalize(p,limit,raw[k],quant[k],floor[k],NULL,acc[track],i,jn,iout);
1088
+
1089
+ }else{
1090
+ for(j=0;j<jn;j++){
1091
+ floor[k][j] = 1e-10f;
1092
+ raw[k][j] = 0.f;
1093
+ quant[k][j] = 0.f;
1094
+ flag[k][j] = 0;
1095
+ iout[j]=0;
1096
+ }
1097
+ acc[track]=0.f;
1098
+ }
1099
+ track++;
1100
+ }
1101
+
1102
+ /* coupling */
1103
+ for(step=0;step<vi->coupling_steps;step++){
1104
+ int Mi = vi->coupling_mag[step];
1105
+ int Ai = vi->coupling_ang[step];
1106
+ int *iM = &iwork[Mi][i];
1107
+ int *iA = &iwork[Ai][i];
1108
+ float *reM = raw[Mi];
1109
+ float *reA = raw[Ai];
1110
+ float *qeM = quant[Mi];
1111
+ float *qeA = quant[Ai];
1112
+ float *floorM = floor[Mi];
1113
+ float *floorA = floor[Ai];
1114
+ int *fM = flag[Mi];
1115
+ int *fA = flag[Ai];
1116
+
1117
+ if(nz[Mi] || nz[Ai]){
1118
+ nz[Mi] = nz[Ai] = 1;
1119
+
1120
+ for(j=0;j<jn;j++){
1121
+
1122
+ if(j<sliding_lowpass-i){
1123
+ if(fM[j] || fA[j]){
1124
+ /* lossless coupling */
1125
+
1126
+ reM[j] = fabs(reM[j])+fabs(reA[j]);
1127
+ qeM[j] = qeM[j]+qeA[j];
1128
+ fM[j]=fA[j]=1;
1129
+
1130
+ /* couple iM/iA */
1131
+ {
1132
+ int A = iM[j];
1133
+ int B = iA[j];
1134
+
1135
+ if(abs(A)>abs(B)){
1136
+ iA[j]=(A>0?A-B:B-A);
1137
+ }else{
1138
+ iA[j]=(B>0?A-B:B-A);
1139
+ iM[j]=B;
1140
+ }
1141
+
1142
+ /* collapse two equivalent tuples to one */
1143
+ if(iA[j]>=abs(iM[j])*2){
1144
+ iA[j]= -iA[j];
1145
+ iM[j]= -iM[j];
1146
+ }
1147
+
1148
+ }
1149
+
1150
+ }else{
1151
+ /* lossy (point) coupling */
1152
+ if(j<limit-i){
1153
+ /* dipole */
1154
+ reM[j] += reA[j];
1155
+ qeM[j] = fabs(reM[j]);
1156
+ }else{
1157
+ /* AoTuV */
1158
+ /** @ M2 **
1159
+ The boost problem by the combination of noise normalization and point stereo is eased.
1160
+ However, this is a temporary patch.
1161
+ by Aoyumi @ 2004/04/18
1162
+ */
1163
+ /*float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit)));
1164
+ /* elliptical
1165
+ if(reM[j]+reA[j]<0){
1166
+ reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
1167
+ }else{
1168
+ reM[j] = (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);
1169
+ }*/
1170
+
1171
+ /* elliptical */
1172
+ if(reM[j]+reA[j]<0){
1173
+ reM[j] = - (qeM[j] = fabs(reM[j])+fabs(reA[j]));
1174
+ }else{
1175
+ reM[j] = (qeM[j] = fabs(reM[j])+fabs(reA[j]));
1176
+ }
1177
+
1178
+
1179
+ }
1180
+ reA[j]=qeA[j]=0.f;
1181
+ fA[j]=1;
1182
+ iA[j]=0;
1183
+ }
1184
+ }
1185
+ floorM[j]=floorA[j]=floorM[j]+floorA[j];
1186
+ }
1187
+ /* normalize the resulting mag vector */
1188
+ acc[track]=noise_normalize(p,limit,raw[Mi],quant[Mi],floor[Mi],flag[Mi],acc[track],i,jn,iM);
1189
+ track++;
1190
+ }
1191
+ }
1192
+ }
1193
+
1194
+ for(i=0;i<vi->coupling_steps;i++){
1195
+ /* make sure coupling a zero and a nonzero channel results in two
1196
+ nonzero channels. */
1197
+ if(nonzero[vi->coupling_mag[i]] ||
1198
+ nonzero[vi->coupling_ang[i]]){
1199
+ nonzero[vi->coupling_mag[i]]=1;
1200
+ nonzero[vi->coupling_ang[i]]=1;
1201
+ }
1202
+ }
1203
+ }