1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_Util.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 23894 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 #include <nw/snd/snd_Util.h>
18 
19 #include <nw/ut/ut_Inlines.h>
20 #include <nw/snd/snd_SoundArchive.h>
21 #include <nw/snd/snd_SoundArchivePlayer.h>
22 #include <nw/snd/snd_WaveArchiveFileReader.h>
23 
24 namespace nw {
25 namespace snd {
26 namespace internal {
27 
28 namespace {
29 
30 const int OCTAVE_DIVISION            = 12;
31 const int VOLUME_TABLE_SIZE          = Util::VOLUME_DB_MAX - Util::VOLUME_DB_MIN + 1;
32 
33 #if 0
34 const f32 PAN_CURVE_MIN = 0.71f;
35 f32 s_PanCurveMax = 1.0f; // PAN_CURVE_MIN;
36 #endif
37 
38 const f32 SURROUND_MODE_PAN_CURVE_MAX = 0.8f;
39 
40 //  ピッチスケールテーブル ( 半音単位 )
41 const f32 NoteTable[ OCTAVE_DIVISION ] =
42 {
43     1.00000000000000f,
44     1.05946309435930f,
45     1.12246204830937f,
46     1.18920711500272f,
47     1.25992104989487f,
48     1.33483985417003f,
49     1.41421356237310f,
50     1.49830707687668f,
51     1.58740105196820f,
52     1.68179283050743f,
53     1.78179743628068f,
54     1.88774862536339f
55 };
56 //  ピッチスケールテーブル ( 半音の 1/256 単位 )
57 
58 const f32 PitchTable[ Util::PITCH_DIVISION_RANGE ] =
59 {
60     1.00000000000000f, 1.00022565930507f, 1.00045136953226f, 1.00067713069307f,
61     1.00090294279898f, 1.00112880586149f, 1.00135471989211f, 1.00158068490233f,
62     1.00180670090365f, 1.00203276790759f, 1.00225888592566f, 1.00248505496936f,
63     1.00271127505020f, 1.00293754617972f, 1.00316386836942f, 1.00339024163082f,
64     1.00361666597546f, 1.00384314141486f, 1.00406966796055f, 1.00429624562407f,
65     1.00452287441694f, 1.00474955435071f, 1.00497628543691f, 1.00520306768709f,
66     1.00542990111280f, 1.00565678572558f, 1.00588372153699f, 1.00611070855857f,
67     1.00633774680189f, 1.00656483627850f, 1.00679197699996f, 1.00701916897784f,
68     1.00724641222370f, 1.00747370674912f, 1.00770105256566f, 1.00792844968490f,
69     1.00815589811842f, 1.00838339787779f, 1.00861094897460f, 1.00883855142043f,
70     1.00906620522687f, 1.00929391040551f, 1.00952166696794f, 1.00974947492577f,
71     1.00997733429057f, 1.01020524507396f, 1.01043320728755f, 1.01066122094292f,
72     1.01088928605170f, 1.01111740262549f, 1.01134557067591f, 1.01157379021458f,
73     1.01180206125310f, 1.01203038380312f, 1.01225875787623f, 1.01248718348409f,
74     1.01271566063830f, 1.01294418935052f, 1.01317276963236f, 1.01340140149547f,
75     1.01363008495149f, 1.01385882001206f, 1.01408760668882f, 1.01431644499343f,
76     1.01454533493752f, 1.01477427653277f, 1.01500326979081f, 1.01523231472332f,
77     1.01546141134194f, 1.01569055965835f, 1.01591975968421f, 1.01614901143119f,
78     1.01637831491095f, 1.01660767013518f, 1.01683707711556f, 1.01706653586375f,
79     1.01729604639144f, 1.01752560871032f, 1.01775522283207f, 1.01798488876839f,
80     1.01821460653096f, 1.01844437613148f, 1.01867419758165f, 1.01890407089317f,
81     1.01913399607774f, 1.01936397314707f, 1.01959400211286f, 1.01982408298683f,
82     1.02005421578069f, 1.02028440050616f, 1.02051463717495f, 1.02074492579879f,
83     1.02097526638940f, 1.02120565895850f, 1.02143610351784f, 1.02166660007913f,
84     1.02189714865412f, 1.02212774925453f, 1.02235840189212f, 1.02258910657863f,
85     1.02281986332579f, 1.02305067214536f, 1.02328153304909f, 1.02351244604873f,
86     1.02374341115603f, 1.02397442838276f, 1.02420549774068f, 1.02443661924155f,
87     1.02466779289714f, 1.02489901871921f, 1.02513029671954f, 1.02536162690990f,
88     1.02559300930208f, 1.02582444390784f, 1.02605593073898f, 1.02628746980727f,
89     1.02651906112451f, 1.02675070470248f, 1.02698240055299f, 1.02721414868781f,
90     1.02744594911876f, 1.02767780185764f, 1.02790970691624f, 1.02814166430638f,
91     1.02837367403986f, 1.02860573612850f, 1.02883785058410f, 1.02907001741849f,
92     1.02930223664349f, 1.02953450827092f, 1.02976683231260f, 1.02999920878037f,
93     1.03023163768604f, 1.03046411904146f, 1.03069665285846f, 1.03092923914889f,
94     1.03116187792457f, 1.03139456919736f, 1.03162731297909f, 1.03186010928163f,
95     1.03209295811682f, 1.03232585949652f, 1.03255881343258f, 1.03279181993686f,
96     1.03302487902123f, 1.03325799069755f, 1.03349115497769f, 1.03372437187351f,
97     1.03395764139691f, 1.03419096355973f, 1.03442433837388f, 1.03465776585123f,
98     1.03489124600365f, 1.03512477884305f, 1.03535836438130f, 1.03559200263031f,
99     1.03582569360196f, 1.03605943730815f, 1.03629323376078f, 1.03652708297176f,
100     1.03676098495299f, 1.03699493971638f, 1.03722894727384f, 1.03746300763728f,
101     1.03769712081862f, 1.03793128682977f, 1.03816550568267f, 1.03839977738923f,
102     1.03863410196138f, 1.03886847941105f, 1.03910290975017f, 1.03933739299068f,
103     1.03957192914452f, 1.03980651822362f, 1.04004116023993f, 1.04027585520539f,
104     1.04051060313196f, 1.04074540403158f, 1.04098025791621f, 1.04121516479780f,
105     1.04145012468832f, 1.04168513759972f, 1.04192020354397f, 1.04215532253304f,
106     1.04239049457890f, 1.04262571969352f, 1.04286099788887f, 1.04309632917694f,
107     1.04333171356970f, 1.04356715107914f, 1.04380264171725f, 1.04403818549601f,
108     1.04427378242741f, 1.04450943252346f, 1.04474513579614f, 1.04498089225746f,
109     1.04521670191942f, 1.04545256479402f, 1.04568848089328f, 1.04592445022919f,
110     1.04616047281379f, 1.04639654865907f, 1.04663267777707f, 1.04686886017980f,
111     1.04710509587929f, 1.04734138488756f, 1.04757772721665f, 1.04781412287858f,
112     1.04805057188539f, 1.04828707424912f, 1.04852362998181f, 1.04876023909550f,
113     1.04899690160224f, 1.04923361751407f, 1.04947038684306f, 1.04970720960124f,
114     1.04994408580069f, 1.05018101545345f, 1.05041799857160f, 1.05065503516719f,
115     1.05089212525229f, 1.05112926883898f, 1.05136646593932f, 1.05160371656540f,
116     1.05184102072929f, 1.05207837844307f, 1.05231578971883f, 1.05255325456865f,
117     1.05279077300463f, 1.05302834503885f, 1.05326597068341f, 1.05350364995040f,
118     1.05374138285194f, 1.05397916940012f, 1.05421700960704f, 1.05445490348482f,
119     1.05469285104557f, 1.05493085230140f, 1.05516890726443f, 1.05540701594677f,
120     1.05564517836056f, 1.05588339451791f, 1.05612166443095f, 1.05635998811181f,
121     1.05659836557263f, 1.05683679682555f, 1.05707528188269f, 1.05731382075621f,
122     1.05755241345824f, 1.05779106000093f, 1.05802976039644f, 1.05826851465692f,
123     1.05850732279451f, 1.05874618482139f, 1.05898510074970f, 1.05922407059161f
124 };
125 
126 const f32 Decibel2RatioTable[ VOLUME_TABLE_SIZE ] =
127 {
128                   0.000000000f, 3.05492E-05f, 3.09030E-05f, 3.12608E-05f, // -90.4dB = -infinity
129     3.16228E-05f, 3.19890E-05f, 3.23594E-05f, 3.27341E-05f, 3.31131E-05f, // -90.0dB
130     3.34965E-05f, 3.38844E-05f, 3.42768E-05f, 3.46737E-05f, 3.50752E-05f,
131     3.54813E-05f, 3.58922E-05f, 3.63078E-05f, 3.67282E-05f, 3.71535E-05f,
132     3.75837E-05f, 3.80189E-05f, 3.84592E-05f, 3.89045E-05f, 3.93550E-05f,
133     3.98107E-05f, 4.02717E-05f, 4.07380E-05f, 4.12098E-05f, 4.16869E-05f,
134     4.21697E-05f, 4.26580E-05f, 4.31519E-05f, 4.36516E-05f, 4.41570E-05f,
135     4.46684E-05f, 4.51856E-05f, 4.57088E-05f, 4.62381E-05f, 4.67735E-05f,
136     4.73151E-05f, 4.78630E-05f, 4.84172E-05f, 4.89779E-05f, 4.95450E-05f,
137     5.01187E-05f, 5.06991E-05f, 5.12861E-05f, 5.18800E-05f, 5.24807E-05f,
138     5.30884E-05f, 5.37032E-05f, 5.43250E-05f, 5.49541E-05f, 5.55904E-05f,
139     5.62341E-05f, 5.68853E-05f, 5.75440E-05f, 5.82103E-05f, 5.88844E-05f,
140     5.95662E-05f, 6.02560E-05f, 6.09537E-05f, 6.16595E-05f, 6.23735E-05f,
141     6.30957E-05f, 6.38263E-05f, 6.45654E-05f, 6.53131E-05f, 6.60693E-05f, // -84.0dB
142     6.68344E-05f, 6.76083E-05f, 6.83912E-05f, 6.91831E-05f, 6.99842E-05f,
143     7.07946E-05f, 7.16143E-05f, 7.24436E-05f, 7.32825E-05f, 7.41310E-05f,
144     7.49894E-05f, 7.58578E-05f, 7.67361E-05f, 7.76247E-05f, 7.85236E-05f,
145     7.94328E-05f, 8.03526E-05f, 8.12831E-05f, 8.22243E-05f, 8.31764E-05f,
146     8.41395E-05f, 8.51138E-05f, 8.60994E-05f, 8.70964E-05f, 8.81049E-05f,
147     8.91251E-05f, 9.01571E-05f, 9.12011E-05f, 9.22571E-05f, 9.33254E-05f,
148     9.44061E-05f, 9.54993E-05f, 9.66051E-05f, 9.77237E-05f, 9.88553E-05f,
149     0.000100000f, 0.000101158f, 0.000102329f, 0.000103514f, 0.000104713f, // -80.0dB
150     0.000105925f, 0.000107152f, 0.000108393f, 0.000109648f, 0.000110917f,
151     0.000112202f, 0.000113501f, 0.000114815f, 0.000116145f, 0.000117490f,
152     0.000118850f, 0.000120226f, 0.000121619f, 0.000123027f, 0.000124451f,
153     0.000125893f, 0.000127350f, 0.000128825f, 0.000130317f, 0.000131826f, // -78.0dB
154     0.000133352f, 0.000134896f, 0.000136458f, 0.000138038f, 0.000139637f,
155     0.000141254f, 0.000142889f, 0.000144544f, 0.000146218f, 0.000147911f,
156     0.000149624f, 0.000151356f, 0.000153109f, 0.000154882f, 0.000156675f,
157     0.000158489f, 0.000160325f, 0.000162181f, 0.000164059f, 0.000165959f,
158     0.000167880f, 0.000169824f, 0.000171791f, 0.000173780f, 0.000175792f,
159     0.000177828f, 0.000179887f, 0.000181970f, 0.000184077f, 0.000186209f,
160     0.000188365f, 0.000190546f, 0.000192752f, 0.000194984f, 0.000197242f,
161     0.000199526f, 0.000201837f, 0.000204174f, 0.000206538f, 0.000208930f,
162     0.000211349f, 0.000213796f, 0.000216272f, 0.000218776f, 0.000221309f,
163     0.000223872f, 0.000226464f, 0.000229087f, 0.000231739f, 0.000234423f,
164     0.000237137f, 0.000239883f, 0.000242661f, 0.000245471f, 0.000248313f,
165     0.000251189f, 0.000254097f, 0.000257040f, 0.000260016f, 0.000263027f, // -72.0dB
166     0.000266073f, 0.000269153f, 0.000272270f, 0.000275423f, 0.000278612f,
167     0.000281838f, 0.000285102f, 0.000288403f, 0.000291743f, 0.000295121f,
168     0.000298538f, 0.000301995f, 0.000305492f, 0.000309030f, 0.000312608f,
169     0.000316228f, 0.000319890f, 0.000323594f, 0.000327341f, 0.000331131f,
170     0.000334965f, 0.000338844f, 0.000342768f, 0.000346737f, 0.000350752f,
171     0.000354813f, 0.000358922f, 0.000363078f, 0.000367282f, 0.000371535f,
172     0.000375837f, 0.000380189f, 0.000384592f, 0.000389045f, 0.000393550f,
173     0.000398107f, 0.000402717f, 0.000407380f, 0.000412098f, 0.000416869f,
174     0.000421697f, 0.000426580f, 0.000431519f, 0.000436516f, 0.000441570f,
175     0.000446684f, 0.000451856f, 0.000457088f, 0.000462381f, 0.000467735f,
176     0.000473151f, 0.000478630f, 0.000484172f, 0.000489779f, 0.000495450f,
177     0.000501187f, 0.000506991f, 0.000512861f, 0.000518800f, 0.000524807f, // -66.0dB
178     0.000530884f, 0.000537032f, 0.000543250f, 0.000549541f, 0.000555904f,
179     0.000562341f, 0.000568853f, 0.000575440f, 0.000582103f, 0.000588844f,
180     0.000595662f, 0.000602560f, 0.000609537f, 0.000616595f, 0.000623735f,
181     0.000630957f, 0.000638263f, 0.000645654f, 0.000653131f, 0.000660693f,
182     0.000668344f, 0.000676083f, 0.000683912f, 0.000691831f, 0.000699842f,
183     0.000707946f, 0.000716143f, 0.000724436f, 0.000732825f, 0.000741310f,
184     0.000749894f, 0.000758578f, 0.000767361f, 0.000776247f, 0.000785236f,
185     0.000794328f, 0.000803526f, 0.000812831f, 0.000822243f, 0.000831764f,
186     0.000841395f, 0.000851138f, 0.000860994f, 0.000870964f, 0.000881049f,
187     0.000891251f, 0.000901571f, 0.000912011f, 0.000922571f, 0.000933254f,
188     0.000944061f, 0.000954993f, 0.000966051f, 0.000977237f, 0.000988553f,
189     0.001000000f, 0.001011579f, 0.001023293f, 0.001035142f, 0.001047129f, // -60.0dB ( 1/1000 )
190     0.001059254f, 0.001071519f, 0.001083927f, 0.001096478f, 0.001109175f,
191     0.001122018f, 0.001135011f, 0.001148154f, 0.001161449f, 0.001174898f,
192     0.001188502f, 0.001202264f, 0.001216186f, 0.001230269f, 0.001244515f,
193     0.001258925f, 0.001273503f, 0.001288250f, 0.001303167f, 0.001318257f,
194     0.001333521f, 0.001348963f, 0.001364583f, 0.001380384f, 0.001396368f,
195     0.001412538f, 0.001428894f, 0.001445440f, 0.001462177f, 0.001479108f,
196     0.001496236f, 0.001513561f, 0.001531087f, 0.001548817f, 0.001566751f,
197     0.001584893f, 0.001603245f, 0.001621810f, 0.001640590f, 0.001659587f,
198     0.001678804f, 0.001698244f, 0.001717908f, 0.001737801f, 0.001757924f,
199     0.001778279f, 0.001798871f, 0.001819701f, 0.001840772f, 0.001862087f,
200     0.001883649f, 0.001905461f, 0.001927525f, 0.001949845f, 0.001972423f,
201     0.001995262f, 0.002018366f, 0.002041738f, 0.002065380f, 0.002089296f, // -54.0dB
202     0.002113489f, 0.002137962f, 0.002162719f, 0.002187762f, 0.002213095f,
203     0.002238721f, 0.002264644f, 0.002290868f, 0.002317395f, 0.002344229f,
204     0.002371374f, 0.002398833f, 0.002426610f, 0.002454709f, 0.002483133f,
205     0.002511886f, 0.002540973f, 0.002570396f, 0.002600160f, 0.002630268f,
206     0.002660725f, 0.002691535f, 0.002722701f, 0.002754229f, 0.002786121f,
207     0.002818383f, 0.002851018f, 0.002884032f, 0.002917427f, 0.002951209f,
208     0.002985383f, 0.003019952f, 0.003054921f, 0.003090295f, 0.003126079f,
209     0.003162278f, 0.003198895f, 0.003235937f, 0.003273407f, 0.003311311f,
210     0.003349654f, 0.003388442f, 0.003427678f, 0.003467369f, 0.003507519f,
211     0.003548134f, 0.003589219f, 0.003630781f, 0.003672823f, 0.003715352f,
212     0.003758374f, 0.003801894f, 0.003845918f, 0.003890451f, 0.003935501f,
213     0.003981072f, 0.004027170f, 0.004073803f, 0.004120975f, 0.004168694f, // -48.0dB
214     0.004216965f, 0.004265795f, 0.004315191f, 0.004365158f, 0.004415704f,
215     0.004466836f, 0.004518559f, 0.004570882f, 0.004623810f, 0.004677351f,
216     0.004731513f, 0.004786301f, 0.004841724f, 0.004897788f, 0.004954502f,
217     0.005011872f, 0.005069907f, 0.005128614f, 0.005188000f, 0.005248075f,
218     0.005308844f, 0.005370318f, 0.005432503f, 0.005495409f, 0.005559043f,
219     0.005623413f, 0.005688529f, 0.005754399f, 0.005821032f, 0.005888437f,
220     0.005956621f, 0.006025596f, 0.006095369f, 0.006165950f, 0.006237348f,
221     0.006309573f, 0.006382635f, 0.006456542f, 0.006531306f, 0.006606934f,
222     0.006683439f, 0.006760830f, 0.006839116f, 0.006918310f, 0.006998420f,
223     0.007079458f, 0.007161434f, 0.007244360f, 0.007328245f, 0.007413102f,
224     0.007498942f, 0.007585776f, 0.007673615f, 0.007762471f, 0.007852356f,
225     0.007943282f, 0.008035261f, 0.008128305f, 0.008222426f, 0.008317638f, // -42.0dB
226     0.008413951f, 0.008511380f, 0.008609938f, 0.008709636f, 0.008810489f,
227     0.008912509f, 0.009015711f, 0.009120108f, 0.009225714f, 0.009332543f,
228     0.009440609f, 0.009549926f, 0.009660509f, 0.009772372f, 0.009885531f,
229     0.010000000f, 0.010115795f, 0.010232930f, 0.010351422f, 0.010471285f, // -40.0dB ( 1/100 )
230     0.010592537f, 0.010715193f, 0.010839269f, 0.010964782f, 0.011091748f,
231     0.011220185f, 0.011350108f, 0.011481536f, 0.011614486f, 0.011748976f,
232     0.011885022f, 0.012022644f, 0.012161860f, 0.012302688f, 0.012445146f,
233     0.012589254f, 0.012735031f, 0.012882496f, 0.013031668f, 0.013182567f,
234     0.013335214f, 0.013489629f, 0.013645831f, 0.013803843f, 0.013963684f,
235     0.014125375f, 0.014288940f, 0.014454398f, 0.014621772f, 0.014791084f,
236     0.014962357f, 0.015135612f, 0.015310875f, 0.015488166f, 0.015667511f,
237     0.015848932f, 0.016032454f, 0.016218101f, 0.016405898f, 0.016595869f, // -36.0dB
238     0.016788040f, 0.016982437f, 0.017179084f, 0.017378008f, 0.017579236f,
239     0.017782794f, 0.017988709f, 0.018197009f, 0.018407720f, 0.018620871f,
240     0.018836491f, 0.019054607f, 0.019275249f, 0.019498446f, 0.019724227f,
241     0.019952623f, 0.020183664f, 0.020417379f, 0.020653802f, 0.020892961f,
242     0.021134890f, 0.021379621f, 0.021627185f, 0.021877616f, 0.022130947f,
243     0.022387211f, 0.022646443f, 0.022908677f, 0.023173946f, 0.023442288f,
244     0.023713737f, 0.023988329f, 0.024266101f, 0.024547089f, 0.024831331f,
245     0.025118864f, 0.025409727f, 0.025703958f, 0.026001596f, 0.026302680f,
246     0.026607251f, 0.026915348f, 0.027227013f, 0.027542287f, 0.027861212f,
247     0.028183829f, 0.028510183f, 0.028840315f, 0.029174270f, 0.029512092f,
248     0.029853826f, 0.030199517f, 0.030549211f, 0.030902954f, 0.031260794f,
249     0.031622777f, 0.031988951f, 0.032359366f, 0.032734069f, 0.033113112f, // -30.0dB
250     0.033496544f, 0.033884416f, 0.034276779f, 0.034673685f, 0.035075187f,
251     0.035481339f, 0.035892193f, 0.036307805f, 0.036728230f, 0.037153523f,
252     0.037583740f, 0.038018940f, 0.038459178f, 0.038904514f, 0.039355008f,
253     0.039810717f, 0.040271703f, 0.040738028f, 0.041209752f, 0.041686938f,
254     0.042169650f, 0.042657952f, 0.043151908f, 0.043651583f, 0.044157045f,
255     0.044668359f, 0.045185594f, 0.045708819f, 0.046238102f, 0.046773514f,
256     0.047315126f, 0.047863009f, 0.048417237f, 0.048977882f, 0.049545019f,
257     0.050118723f, 0.050699071f, 0.051286138f, 0.051880004f, 0.052480746f,
258     0.053088444f, 0.053703180f, 0.054325033f, 0.054954087f, 0.055590426f,
259     0.056234133f, 0.056885293f, 0.057543994f, 0.058210322f, 0.058884366f,
260     0.059566214f, 0.060255959f, 0.060953690f, 0.061659500f, 0.062373484f,
261     0.063095734f, 0.063826349f, 0.064565423f, 0.065313055f, 0.066069345f, // -24.0dB
262     0.066834392f, 0.067608298f, 0.068391165f, 0.069183097f, 0.069984200f,
263     0.070794578f, 0.071614341f, 0.072443596f, 0.073282453f, 0.074131024f,
264     0.074989421f, 0.075857758f, 0.076736149f, 0.077624712f, 0.078523563f,
265     0.079432823f, 0.080352612f, 0.081283052f, 0.082224265f, 0.083176377f,
266     0.084139514f, 0.085113804f, 0.086099375f, 0.087096359f, 0.088104887f,
267     0.089125094f, 0.090157114f, 0.091201084f, 0.092257143f, 0.093325430f,
268     0.094406088f, 0.095499259f, 0.096605088f, 0.097723722f, 0.098855309f,
269     0.100000000f, 0.101157945f, 0.102329299f, 0.103514217f, 0.104712855f, // -20.0dB ( 1/10 )
270     0.105925373f, 0.107151931f, 0.108392691f, 0.109647820f, 0.110917482f,
271     0.112201845f, 0.113501082f, 0.114815362f, 0.116144861f, 0.117489755f,
272     0.118850223f, 0.120226443f, 0.121618600f, 0.123026877f, 0.124451461f,
273     0.125892541f, 0.127350308f, 0.128824955f, 0.130316678f, 0.131825674f, // -18.0dB
274     0.133352143f, 0.134896288f, 0.136458314f, 0.138038426f, 0.139636836f,
275     0.141253754f, 0.142889396f, 0.144543977f, 0.146217717f, 0.147910839f,
276     0.149623566f, 0.151356125f, 0.153108746f, 0.154881662f, 0.156675107f,
277     0.158489319f, 0.160324539f, 0.162181010f, 0.164058977f, 0.165958691f,
278     0.167880402f, 0.169824365f, 0.171790839f, 0.173780083f, 0.175792361f,
279     0.177827941f, 0.179887092f, 0.181970086f, 0.184077200f, 0.186208714f,
280     0.188364909f, 0.190546072f, 0.192752491f, 0.194984460f, 0.197242274f,
281     0.199526231f, 0.201836636f, 0.204173794f, 0.206538016f, 0.208929613f,
282     0.211348904f, 0.213796209f, 0.216271852f, 0.218776162f, 0.221309471f,
283     0.223872114f, 0.226464431f, 0.229086765f, 0.231739465f, 0.234422882f,
284     0.237137371f, 0.239883292f, 0.242661010f, 0.245470892f, 0.248313311f,
285     0.251188643f, 0.254097271f, 0.257039578f, 0.260015956f, 0.263026799f, // -12.0dB ( 1/4 )
286     0.266072506f, 0.269153480f, 0.272270131f, 0.275422870f, 0.278612117f,
287     0.281838293f, 0.285101827f, 0.288403150f, 0.291742701f, 0.295120923f,
288     0.298538262f, 0.301995172f, 0.305492111f, 0.309029543f, 0.312607937f,
289     0.316227766f, 0.319889511f, 0.323593657f, 0.327340695f, 0.331131121f,
290     0.334965439f, 0.338844156f, 0.342767787f, 0.346736850f, 0.350751874f,
291     0.354813389f, 0.358921935f, 0.363078055f, 0.367282300f, 0.371535229f,
292     0.375837404f, 0.380189396f, 0.384591782f, 0.389045145f, 0.393550075f,
293     0.398107171f, 0.402717034f, 0.407380278f, 0.412097519f, 0.416869383f,
294     0.421696503f, 0.426579519f, 0.431519077f, 0.436515832f, 0.441570447f,
295     0.446683592f, 0.451855944f, 0.457088190f, 0.462381021f, 0.467735141f,
296     0.473151259f, 0.478630092f, 0.484172368f, 0.489778819f, 0.495450191f,
297     0.501187234f, 0.506990708f, 0.512861384f, 0.518800039f, 0.524807460f, //  -6.0dB ( 1/2 )
298     0.530884444f, 0.537031796f, 0.543250331f, 0.549540874f, 0.555904257f,
299     0.562341325f, 0.568852931f, 0.575439937f, 0.582103218f, 0.588843655f,
300     0.595662144f, 0.602559586f, 0.609536897f, 0.616595002f, 0.623734835f,
301     0.630957344f, 0.638263486f, 0.645654229f, 0.653130553f, 0.660693448f,
302     0.668343918f, 0.676082975f, 0.683911647f, 0.691830971f, 0.699841996f,
303     0.707945784f, 0.716143410f, 0.724435960f, 0.732824533f, 0.741310241f,
304     0.749894209f, 0.758577575f, 0.767361489f, 0.776247117f, 0.785235635f,
305     0.794328235f, 0.803526122f, 0.812830516f, 0.822242650f, 0.831763771f, //  -2.0dB
306     0.841395142f, 0.851138038f, 0.860993752f, 0.870963590f, 0.881048873f,
307     0.891250938f, 0.901571138f, 0.912010839f, 0.922571427f, 0.933254301f, //  -1.0dB
308     0.944060876f, 0.954992586f, 0.966050879f, 0.977237221f, 0.988553095f,
309     1.000000000f, 1.011579454f, 1.023292992f, 1.035142167f, 1.047128548f, //   0.0dB
310     1.059253725f, 1.071519305f, 1.083926914f, 1.096478196f, 1.109174815f,
311     1.122018454f, 1.135010816f, 1.148153621f, 1.161448614f, 1.174897555f, //   1.0dB
312     1.188502227f, 1.202264435f, 1.216186001f, 1.230268771f, 1.244514612f,
313     1.258925412f, 1.273503081f, 1.288249552f, 1.303166778f, 1.318256739f, //   2.0dB
314     1.333521432f, 1.348962883f, 1.364583137f, 1.380384265f, 1.396368361f,
315     1.412537545f, 1.428893959f, 1.445439771f, 1.462177174f, 1.479108388f,
316     1.496235656f, 1.513561248f, 1.531087462f, 1.548816619f, 1.566751070f,
317     1.584893192f, 1.603245391f, 1.621810097f, 1.640589773f, 1.659586907f,
318     1.678804018f, 1.698243652f, 1.717908387f, 1.737800829f, 1.757923614f,
319     1.778279410f, 1.798870915f, 1.819700859f, 1.840772001f, 1.862087137f,
320     1.883649089f, 1.905460718f, 1.927524913f, 1.949844600f, 1.972422736f,
321     1.995262315f                                                          //   6.0dB ( *2 )
322 };
323 
324 const int PAN_TABLE_MAX              = 256;
325 const int PAN_TABLE_MIN              = 0;
326 const int PAN_TABLE_CENTER           = 128;
327 const int PAN_TABLE_SIZE             = PAN_TABLE_MAX - PAN_TABLE_MIN + 1;
328 
329 const f32 Pan2RatioTableSqrt[ PAN_TABLE_SIZE ] =
330 {
331     1.000000000f, 0.998044964f, 0.996086091f, 0.994123358f, 0.992156742f, 0.990186220f, 0.988211769f, 0.986233365f,
332     0.984250984f, 0.982264603f, 0.980274196f, 0.978279740f, 0.976281209f, 0.974278579f, 0.972271824f, 0.970260919f,
333     0.968245837f, 0.966226552f, 0.964203039f, 0.962175270f, 0.960143218f, 0.958106857f, 0.956066159f, 0.954021095f,
334     0.951971638f, 0.949917760f, 0.947859431f, 0.945796622f, 0.943729304f, 0.941657448f, 0.939581024f, 0.937500000f,
335     0.935414347f, 0.933324033f, 0.931229027f, 0.929129297f, 0.927024811f, 0.924915537f, 0.922801441f, 0.920682491f,
336     0.918558654f, 0.916429894f, 0.914296177f, 0.912157470f, 0.910013736f, 0.907864940f, 0.905711047f, 0.903552018f,
337     0.901387819f, 0.899218411f, 0.897043756f, 0.894863816f, 0.892678554f, 0.890487928f, 0.888291900f, 0.886090430f,
338     0.883883476f, 0.881670999f, 0.879452955f, 0.877229303f, 0.875000000f, 0.872765003f, 0.870524267f, 0.868277749f,
339     0.866025404f, 0.863767185f, 0.861503047f, 0.859232943f, 0.856956825f, 0.854674646f, 0.852386356f, 0.850091907f,
340     0.847791248f, 0.845484329f, 0.843171098f, 0.840851503f, 0.838525492f, 0.836193010f, 0.833854004f, 0.831508418f,
341     0.829156198f, 0.826797285f, 0.824431622f, 0.822059152f, 0.819679816f, 0.817293552f, 0.814900301f, 0.812500000f,
342     0.810092587f, 0.807677999f, 0.805256170f, 0.802827036f, 0.800390530f, 0.797946583f, 0.795495129f, 0.793036096f,
343     0.790569415f, 0.788095013f, 0.785612818f, 0.783122755f, 0.780624750f, 0.778118725f, 0.775604603f, 0.773082305f,
344     0.770551750f, 0.768012858f, 0.765465545f, 0.762909726f, 0.760345316f, 0.757772228f, 0.755190373f, 0.752599661f,
345     0.750000000f, 0.747391296f, 0.744773455f, 0.742146380f, 0.739509973f, 0.736864133f, 0.734208758f, 0.731543744f,
346     0.728868987f, 0.726184377f, 0.723489806f, 0.720785162f, 0.718070331f, 0.715345196f, 0.712609641f, 0.709863543f,
347     0.707106781f, 0.704339229f, 0.701560760f, 0.698771243f, 0.695970545f, 0.693158532f, 0.690335064f, 0.687500000f, // center(-3dB)
348     0.684653197f, 0.681794507f, 0.678923781f, 0.676040864f, 0.673145601f, 0.670237831f, 0.667317391f, 0.664384113f,
349     0.661437828f, 0.658478360f, 0.655505530f, 0.652519157f, 0.649519053f, 0.646505027f, 0.643476884f, 0.640434423f,
350     0.637377439f, 0.634305723f, 0.631219059f, 0.628117226f, 0.625000000f, 0.621867148f, 0.618718434f, 0.615553613f,
351     0.612372436f, 0.609174647f, 0.605959982f, 0.602728173f, 0.599478940f, 0.596212001f, 0.592927061f, 0.589623821f,
352     0.586301970f, 0.582961191f, 0.579601156f, 0.576221529f, 0.572821962f, 0.569402099f, 0.565961571f, 0.562500000f,
353     0.559016994f, 0.555512151f, 0.551985054f, 0.548435274f, 0.544862368f, 0.541265877f, 0.537645329f, 0.534000234f,
354     0.530330086f, 0.526634361f, 0.522912517f, 0.519163991f, 0.515388203f, 0.511584548f, 0.507752400f, 0.503891109f,
355     0.500000000f, 0.496078371f, 0.492125492f, 0.488140605f, 0.484122918f, 0.480071609f, 0.475985819f, 0.471864652f,
356     0.467707173f, 0.463512405f, 0.459279327f, 0.455006868f, 0.450693909f, 0.446339277f, 0.441941738f, 0.437500000f,
357     0.433012702f, 0.428478413f, 0.423895624f, 0.419262746f, 0.414578099f, 0.409839908f, 0.405046294f, 0.400195265f,
358     0.395284708f, 0.390312375f, 0.385275875f, 0.380172658f, 0.375000000f, 0.369754986f, 0.364434493f, 0.359035165f,
359     0.353553391f, 0.347985273f, 0.342326598f, 0.336572800f, 0.330718914f, 0.324759526f, 0.318688720f, 0.312500000f,
360     0.306186218f, 0.299739470f, 0.293150985f, 0.286410981f, 0.279508497f, 0.272431184f, 0.265165043f, 0.257694102f,
361     0.250000000f, 0.242061459f, 0.233853587f, 0.225346955f, 0.216506351f, 0.207289049f, 0.197642354f, 0.187500000f,
362     0.176776695f, 0.165359457f, 0.153093109f, 0.139754249f, 0.125000000f, 0.108253175f, 0.088388348f, 0.062500000f,
363     0.000000000f
364 };
365 const f32 Pan2RatioTableSqrtSurround[ PAN_TABLE_SIZE ] =
366 {
367     0.800000000f, 0.799274272f, 0.798548543f, 0.797822815f, 0.797097087f, 0.796371359f, 0.795645630f, 0.794919902f,
368     0.794194174f, 0.793468446f, 0.792742717f, 0.792016989f, 0.791291261f, 0.790565532f, 0.789839804f, 0.789114076f,
369     0.788388348f, 0.787662619f, 0.786936891f, 0.786211163f, 0.785485435f, 0.784759706f, 0.784033978f, 0.783308250f,
370     0.782582521f, 0.781856793f, 0.781131065f, 0.780405337f, 0.779679608f, 0.778953880f, 0.778228152f, 0.777502424f,
371     0.776776695f, 0.776050967f, 0.775325239f, 0.774599510f, 0.773873782f, 0.773148054f, 0.772422326f, 0.771696597f,
372     0.770970869f, 0.770245141f, 0.769519413f, 0.768793684f, 0.768067956f, 0.767342228f, 0.766616499f, 0.765890771f,
373     0.765165043f, 0.764439315f, 0.763713586f, 0.762987858f, 0.762262130f, 0.761536402f, 0.760810673f, 0.760084945f,
374     0.759359217f, 0.758633488f, 0.757907760f, 0.757182032f, 0.756456304f, 0.755730575f, 0.755004847f, 0.754279119f,
375     0.753553391f, 0.752827662f, 0.752101934f, 0.751376206f, 0.750650477f, 0.749924749f, 0.749199021f, 0.748473293f,
376     0.747747564f, 0.747021836f, 0.746296108f, 0.745570379f, 0.744844651f, 0.744118923f, 0.743393195f, 0.742667466f,
377     0.741941738f, 0.741216010f, 0.740490282f, 0.739764553f, 0.739038825f, 0.738313097f, 0.737587368f, 0.736861640f,
378     0.736135912f, 0.735410184f, 0.734684455f, 0.733958727f, 0.733232999f, 0.732507271f, 0.731781542f, 0.731055814f,
379     0.730330086f, 0.729604357f, 0.728878629f, 0.728152901f, 0.727427173f, 0.726701444f, 0.725975716f, 0.725249988f,
380     0.724524260f, 0.723798531f, 0.723072803f, 0.722347075f, 0.721621346f, 0.720895618f, 0.720169890f, 0.719444162f,
381     0.718718433f, 0.717992705f, 0.717266977f, 0.716541249f, 0.715815520f, 0.715089792f, 0.714364064f, 0.713638335f,
382     0.712912607f, 0.712186879f, 0.711461151f, 0.710735422f, 0.710009694f, 0.709283966f, 0.708558238f, 0.707832509f,
383     0.707106781f, 0.704339229f, 0.701560760f, 0.698771243f, 0.695970545f, 0.693158532f, 0.690335064f, 0.687500000f, // center(-3dB)
384     0.684653197f, 0.681794507f, 0.678923781f, 0.676040864f, 0.673145601f, 0.670237831f, 0.667317391f, 0.664384113f,
385     0.661437828f, 0.658478360f, 0.655505530f, 0.652519157f, 0.649519053f, 0.646505027f, 0.643476884f, 0.640434423f,
386     0.637377439f, 0.634305723f, 0.631219059f, 0.628117226f, 0.625000000f, 0.621867148f, 0.618718434f, 0.615553613f,
387     0.612372436f, 0.609174647f, 0.605959982f, 0.602728173f, 0.599478940f, 0.596212001f, 0.592927061f, 0.589623821f,
388     0.586301970f, 0.582961191f, 0.579601156f, 0.576221529f, 0.572821962f, 0.569402099f, 0.565961571f, 0.562500000f,
389     0.559016994f, 0.555512151f, 0.551985054f, 0.548435274f, 0.544862368f, 0.541265877f, 0.537645329f, 0.534000234f,
390     0.530330086f, 0.526634361f, 0.522912517f, 0.519163991f, 0.515388203f, 0.511584548f, 0.507752400f, 0.503891109f,
391     0.500000000f, 0.496078371f, 0.492125492f, 0.488140605f, 0.484122918f, 0.480071609f, 0.475985819f, 0.471864652f,
392     0.467707173f, 0.463512405f, 0.459279327f, 0.455006868f, 0.450693909f, 0.446339277f, 0.441941738f, 0.437500000f,
393     0.433012702f, 0.428478413f, 0.423895624f, 0.419262746f, 0.414578099f, 0.409839908f, 0.405046294f, 0.400195265f,
394     0.395284708f, 0.390312375f, 0.385275875f, 0.380172658f, 0.375000000f, 0.369754986f, 0.364434493f, 0.359035165f,
395     0.353553391f, 0.347985273f, 0.342326598f, 0.336572800f, 0.330718914f, 0.324759526f, 0.318688720f, 0.312500000f,
396     0.306186218f, 0.299739470f, 0.293150985f, 0.286410981f, 0.279508497f, 0.272431184f, 0.265165043f, 0.257694102f,
397     0.250000000f, 0.242061459f, 0.233853587f, 0.225346955f, 0.216506351f, 0.207289049f, 0.197642354f, 0.187500000f,
398     0.176776695f, 0.165359457f, 0.153093109f, 0.139754249f, 0.125000000f, 0.108253175f, 0.088388348f, 0.062500000f,
399     0.000000000f
400 };
401 
402 const f32 Pan2RatioTableSinCos[ PAN_TABLE_SIZE ] =
403 {
404     1.000000000f, 0.999981175f, 0.999924702f, 0.999830582f, 0.999698819f, 0.999529418f, 0.999322385f, 0.999077728f,
405     0.998795456f, 0.998475581f, 0.998118113f, 0.997723067f, 0.997290457f, 0.996820299f, 0.996312612f, 0.995767414f,
406     0.995184727f, 0.994564571f, 0.993906970f, 0.993211949f, 0.992479535f, 0.991709754f, 0.990902635f, 0.990058210f,
407     0.989176510f, 0.988257568f, 0.987301418f, 0.986308097f, 0.985277642f, 0.984210092f, 0.983105487f, 0.981963869f,
408     0.980785280f, 0.979569766f, 0.978317371f, 0.977028143f, 0.975702130f, 0.974339383f, 0.972939952f, 0.971503891f,
409     0.970031253f, 0.968522094f, 0.966976471f, 0.965394442f, 0.963776066f, 0.962121404f, 0.960430519f, 0.958703475f,
410     0.956940336f, 0.955141168f, 0.953306040f, 0.951435021f, 0.949528181f, 0.947585591f, 0.945607325f, 0.943593458f,
411     0.941544065f, 0.939459224f, 0.937339012f, 0.935183510f, 0.932992799f, 0.930766961f, 0.928506080f, 0.926210242f,
412     0.923879533f, 0.921514039f, 0.919113852f, 0.916679060f, 0.914209756f, 0.911706032f, 0.909167983f, 0.906595705f,
413     0.903989293f, 0.901348847f, 0.898674466f, 0.895966250f, 0.893224301f, 0.890448723f, 0.887639620f, 0.884797098f,
414     0.881921264f, 0.879012226f, 0.876070094f, 0.873094978f, 0.870086991f, 0.867046246f, 0.863972856f, 0.860866939f,
415     0.857728610f, 0.854557988f, 0.851355193f, 0.848120345f, 0.844853565f, 0.841554977f, 0.838224706f, 0.834862875f,
416     0.831469612f, 0.828045045f, 0.824589303f, 0.821102515f, 0.817584813f, 0.814036330f, 0.810457198f, 0.806847554f,
417     0.803207531f, 0.799537269f, 0.795836905f, 0.792106577f, 0.788346428f, 0.784556597f, 0.780737229f, 0.776888466f,
418     0.773010453f, 0.769103338f, 0.765167266f, 0.761202385f, 0.757208847f, 0.753186799f, 0.749136395f, 0.745057785f,
419     0.740951125f, 0.736816569f, 0.732654272f, 0.728464390f, 0.724247083f, 0.720002508f, 0.715730825f, 0.711432196f,
420     0.707106781f, 0.702754744f, 0.698376249f, 0.693971461f, 0.689540545f, 0.685083668f, 0.680600998f, 0.676092704f, // center(-3dB)
421     0.671558955f, 0.666999922f, 0.662415778f, 0.657806693f, 0.653172843f, 0.648514401f, 0.643831543f, 0.639124445f,
422     0.634393284f, 0.629638239f, 0.624859488f, 0.620057212f, 0.615231591f, 0.610382806f, 0.605511041f, 0.600616479f,
423     0.595699304f, 0.590759702f, 0.585797857f, 0.580813958f, 0.575808191f, 0.570780746f, 0.565731811f, 0.560661576f,
424     0.555570233f, 0.550457973f, 0.545324988f, 0.540171473f, 0.534997620f, 0.529803625f, 0.524589683f, 0.519355990f,
425     0.514102744f, 0.508830143f, 0.503538384f, 0.498227667f, 0.492898192f, 0.487550160f, 0.482183772f, 0.476799230f,
426     0.471396737f, 0.465976496f, 0.460538711f, 0.455083587f, 0.449611330f, 0.444122145f, 0.438616239f, 0.433093819f,
427     0.427555093f, 0.422000271f, 0.416429560f, 0.410843171f, 0.405241314f, 0.399624200f, 0.393992040f, 0.388345047f,
428     0.382683432f, 0.377007410f, 0.371317194f, 0.365612998f, 0.359895037f, 0.354163525f, 0.348418680f, 0.342660717f,
429     0.336889853f, 0.331106306f, 0.325310292f, 0.319502031f, 0.313681740f, 0.307849640f, 0.302005949f, 0.296150888f,
430     0.290284677f, 0.284407537f, 0.278519689f, 0.272621355f, 0.266712757f, 0.260794118f, 0.254865660f, 0.248927606f,
431     0.242980180f, 0.237023606f, 0.231058108f, 0.225083911f, 0.219101240f, 0.213110320f, 0.207111376f, 0.201104635f,
432     0.195090322f, 0.189068664f, 0.183039888f, 0.177004220f, 0.170961889f, 0.164913120f, 0.158858143f, 0.152797185f,
433     0.146730474f, 0.140658239f, 0.134580709f, 0.128498111f, 0.122410675f, 0.116318631f, 0.110222207f, 0.104121634f,
434     0.098017140f, 0.091908956f, 0.085797312f, 0.079682438f, 0.073564564f, 0.067443920f, 0.061320736f, 0.055195244f,
435     0.049067674f, 0.042938257f, 0.036807223f, 0.030674803f, 0.024541229f, 0.018406730f, 0.012271538f, 0.006135885f,
436     0.000000000f
437 };
438 const f32 Pan2RatioTableSinCosSurround[ PAN_TABLE_SIZE ] =
439 {
440     0.800000000f, 0.799274272f, 0.798548543f, 0.797822815f, 0.797097087f, 0.796371359f, 0.795645630f, 0.794919902f,
441     0.794194174f, 0.793468446f, 0.792742717f, 0.792016989f, 0.791291261f, 0.790565532f, 0.789839804f, 0.789114076f,
442     0.788388348f, 0.787662619f, 0.786936891f, 0.786211163f, 0.785485435f, 0.784759706f, 0.784033978f, 0.783308250f,
443     0.782582521f, 0.781856793f, 0.781131065f, 0.780405337f, 0.779679608f, 0.778953880f, 0.778228152f, 0.777502424f,
444     0.776776695f, 0.776050967f, 0.775325239f, 0.774599510f, 0.773873782f, 0.773148054f, 0.772422326f, 0.771696597f,
445     0.770970869f, 0.770245141f, 0.769519413f, 0.768793684f, 0.768067956f, 0.767342228f, 0.766616499f, 0.765890771f,
446     0.765165043f, 0.764439315f, 0.763713586f, 0.762987858f, 0.762262130f, 0.761536402f, 0.760810673f, 0.760084945f,
447     0.759359217f, 0.758633488f, 0.757907760f, 0.757182032f, 0.756456304f, 0.755730575f, 0.755004847f, 0.754279119f,
448     0.753553391f, 0.752827662f, 0.752101934f, 0.751376206f, 0.750650477f, 0.749924749f, 0.749199021f, 0.748473293f,
449     0.747747564f, 0.747021836f, 0.746296108f, 0.745570379f, 0.744844651f, 0.744118923f, 0.743393195f, 0.742667466f,
450     0.741941738f, 0.741216010f, 0.740490282f, 0.739764553f, 0.739038825f, 0.738313097f, 0.737587368f, 0.736861640f,
451     0.736135912f, 0.735410184f, 0.734684455f, 0.733958727f, 0.733232999f, 0.732507271f, 0.731781542f, 0.731055814f,
452     0.730330086f, 0.729604357f, 0.728878629f, 0.728152901f, 0.727427173f, 0.726701444f, 0.725975716f, 0.725249988f,
453     0.724524260f, 0.723798531f, 0.723072803f, 0.722347075f, 0.721621346f, 0.720895618f, 0.720169890f, 0.719444162f,
454     0.718718433f, 0.717992705f, 0.717266977f, 0.716541249f, 0.715815520f, 0.715089792f, 0.714364064f, 0.713638335f,
455     0.712912607f, 0.712186879f, 0.711461151f, 0.710735422f, 0.710009694f, 0.709283966f, 0.708558238f, 0.707832509f,
456     0.707106781f, 0.702754744f, 0.698376249f, 0.693971461f, 0.689540545f, 0.685083668f, 0.680600998f, 0.676092704f, // center(-3dB)
457     0.671558955f, 0.666999922f, 0.662415778f, 0.657806693f, 0.653172843f, 0.648514401f, 0.643831543f, 0.639124445f,
458     0.634393284f, 0.629638239f, 0.624859488f, 0.620057212f, 0.615231591f, 0.610382806f, 0.605511041f, 0.600616479f,
459     0.595699304f, 0.590759702f, 0.585797857f, 0.580813958f, 0.575808191f, 0.570780746f, 0.565731811f, 0.560661576f,
460     0.555570233f, 0.550457973f, 0.545324988f, 0.540171473f, 0.534997620f, 0.529803625f, 0.524589683f, 0.519355990f,
461     0.514102744f, 0.508830143f, 0.503538384f, 0.498227667f, 0.492898192f, 0.487550160f, 0.482183772f, 0.476799230f,
462     0.471396737f, 0.465976496f, 0.460538711f, 0.455083587f, 0.449611330f, 0.444122145f, 0.438616239f, 0.433093819f,
463     0.427555093f, 0.422000271f, 0.416429560f, 0.410843171f, 0.405241314f, 0.399624200f, 0.393992040f, 0.388345047f,
464     0.382683432f, 0.377007410f, 0.371317194f, 0.365612998f, 0.359895037f, 0.354163525f, 0.348418680f, 0.342660717f,
465     0.336889853f, 0.331106306f, 0.325310292f, 0.319502031f, 0.313681740f, 0.307849640f, 0.302005949f, 0.296150888f,
466     0.290284677f, 0.284407537f, 0.278519689f, 0.272621355f, 0.266712757f, 0.260794118f, 0.254865660f, 0.248927606f,
467     0.242980180f, 0.237023606f, 0.231058108f, 0.225083911f, 0.219101240f, 0.213110320f, 0.207111376f, 0.201104635f,
468     0.195090322f, 0.189068664f, 0.183039888f, 0.177004220f, 0.170961889f, 0.164913120f, 0.158858143f, 0.152797185f,
469     0.146730474f, 0.140658239f, 0.134580709f, 0.128498111f, 0.122410675f, 0.116318631f, 0.110222207f, 0.104121634f,
470     0.098017140f, 0.091908956f, 0.085797312f, 0.079682438f, 0.073564564f, 0.067443920f, 0.061320736f, 0.055195244f,
471     0.049067674f, 0.042938257f, 0.036807223f, 0.030674803f, 0.024541229f, 0.018406730f, 0.012271538f, 0.006135885f,
472     0.000000000f
473 };
474 
475 const f32 Pan2RatioTableLinear[ PAN_TABLE_SIZE ] =
476 {
477     1.000000000f, 0.996093750f, 0.992187500f, 0.988281250f, 0.984375000f, 0.980468750f, 0.976562500f, 0.972656250f,
478     0.968750000f, 0.964843750f, 0.960937500f, 0.957031250f, 0.953125000f, 0.949218750f, 0.945312500f, 0.941406250f,
479     0.937500000f, 0.933593750f, 0.929687500f, 0.925781250f, 0.921875000f, 0.917968750f, 0.914062500f, 0.910156250f,
480     0.906250000f, 0.902343750f, 0.898437500f, 0.894531250f, 0.890625000f, 0.886718750f, 0.882812500f, 0.878906250f,
481     0.875000000f, 0.871093750f, 0.867187500f, 0.863281250f, 0.859375000f, 0.855468750f, 0.851562500f, 0.847656250f,
482     0.843750000f, 0.839843750f, 0.835937500f, 0.832031250f, 0.828125000f, 0.824218750f, 0.820312500f, 0.816406250f,
483     0.812500000f, 0.808593750f, 0.804687500f, 0.800781250f, 0.796875000f, 0.792968750f, 0.789062500f, 0.785156250f,
484     0.781250000f, 0.777343750f, 0.773437500f, 0.769531250f, 0.765625000f, 0.761718750f, 0.757812500f, 0.753906250f,
485     0.750000000f, 0.746093750f, 0.742187500f, 0.738281250f, 0.734375000f, 0.730468750f, 0.726562500f, 0.722656250f,
486     0.718750000f, 0.714843750f, 0.710937500f, 0.707031250f, 0.703125000f, 0.699218750f, 0.695312500f, 0.691406250f,
487     0.687500000f, 0.683593750f, 0.679687500f, 0.675781250f, 0.671875000f, 0.667968750f, 0.664062500f, 0.660156250f,
488     0.656250000f, 0.652343750f, 0.648437500f, 0.644531250f, 0.640625000f, 0.636718750f, 0.632812500f, 0.628906250f,
489     0.625000000f, 0.621093750f, 0.617187500f, 0.613281250f, 0.609375000f, 0.605468750f, 0.601562500f, 0.597656250f,
490     0.593750000f, 0.589843750f, 0.585937500f, 0.582031250f, 0.578125000f, 0.574218750f, 0.570312500f, 0.566406250f,
491     0.562500000f, 0.558593750f, 0.554687500f, 0.550781250f, 0.546875000f, 0.542968750f, 0.539062500f, 0.535156250f,
492     0.531250000f, 0.527343750f, 0.523437500f, 0.519531250f, 0.515625000f, 0.511718750f, 0.507812500f, 0.503906250f,
493     0.500000000f, 0.496093750f, 0.492187500f, 0.488281250f, 0.484375000f, 0.480468750f, 0.476562500f, 0.472656250f, // center(-6dB)
494     0.468750000f, 0.464843750f, 0.460937500f, 0.457031250f, 0.453125000f, 0.449218750f, 0.445312500f, 0.441406250f,
495     0.437500000f, 0.433593750f, 0.429687500f, 0.425781250f, 0.421875000f, 0.417968750f, 0.414062500f, 0.410156250f,
496     0.406250000f, 0.402343750f, 0.398437500f, 0.394531250f, 0.390625000f, 0.386718750f, 0.382812500f, 0.378906250f,
497     0.375000000f, 0.371093750f, 0.367187500f, 0.363281250f, 0.359375000f, 0.355468750f, 0.351562500f, 0.347656250f,
498     0.343750000f, 0.339843750f, 0.335937500f, 0.332031250f, 0.328125000f, 0.324218750f, 0.320312500f, 0.316406250f,
499     0.312500000f, 0.308593750f, 0.304687500f, 0.300781250f, 0.296875000f, 0.292968750f, 0.289062500f, 0.285156250f,
500     0.281250000f, 0.277343750f, 0.273437500f, 0.269531250f, 0.265625000f, 0.261718750f, 0.257812500f, 0.253906250f,
501     0.250000000f, 0.246093750f, 0.242187500f, 0.238281250f, 0.234375000f, 0.230468750f, 0.226562500f, 0.222656250f,
502     0.218750000f, 0.214843750f, 0.210937500f, 0.207031250f, 0.203125000f, 0.199218750f, 0.195312500f, 0.191406250f,
503     0.187500000f, 0.183593750f, 0.179687500f, 0.175781250f, 0.171875000f, 0.167968750f, 0.164062500f, 0.160156250f,
504     0.156250000f, 0.152343750f, 0.148437500f, 0.144531250f, 0.140625000f, 0.136718750f, 0.132812500f, 0.128906250f,
505     0.125000000f, 0.121093750f, 0.117187500f, 0.113281250f, 0.109375000f, 0.105468750f, 0.101562500f, 0.097656250f,
506     0.093750000f, 0.089843750f, 0.085937500f, 0.082031250f, 0.078125000f, 0.074218750f, 0.070312500f, 0.066406250f,
507     0.062500000f, 0.058593750f, 0.054687500f, 0.050781250f, 0.046875000f, 0.042968750f, 0.039062500f, 0.035156250f,
508     0.031250000f, 0.027343750f, 0.023437500f, 0.019531250f, 0.015625000f, 0.011718750f, 0.007812500f, 0.003906250f,
509     0.000000000f
510 };
511 const f32 Pan2RatioTableLinearSurround[ PAN_TABLE_SIZE ] =
512 {
513     0.800000000f, 0.797656250f, 0.795312500f, 0.792968750f, 0.790625000f, 0.788281250f, 0.785937500f, 0.783593750f,
514     0.781250000f, 0.778906250f, 0.776562500f, 0.774218750f, 0.771875000f, 0.769531250f, 0.767187500f, 0.764843750f,
515     0.762500000f, 0.760156250f, 0.757812500f, 0.755468750f, 0.753125000f, 0.750781250f, 0.748437500f, 0.746093750f,
516     0.743750000f, 0.741406250f, 0.739062500f, 0.736718750f, 0.734375000f, 0.732031250f, 0.729687500f, 0.727343750f,
517     0.725000000f, 0.722656250f, 0.720312500f, 0.717968750f, 0.715625000f, 0.713281250f, 0.710937500f, 0.708593750f,
518     0.706250000f, 0.703906250f, 0.701562500f, 0.699218750f, 0.696875000f, 0.694531250f, 0.692187500f, 0.689843750f,
519     0.687500000f, 0.685156250f, 0.682812500f, 0.680468750f, 0.678125000f, 0.675781250f, 0.673437500f, 0.671093750f,
520     0.668750000f, 0.666406250f, 0.664062500f, 0.661718750f, 0.659375000f, 0.657031250f, 0.654687500f, 0.652343750f,
521     0.650000000f, 0.647656250f, 0.645312500f, 0.642968750f, 0.640625000f, 0.638281250f, 0.635937500f, 0.633593750f,
522     0.631250000f, 0.628906250f, 0.626562500f, 0.624218750f, 0.621875000f, 0.619531250f, 0.617187500f, 0.614843750f,
523     0.612500000f, 0.610156250f, 0.607812500f, 0.605468750f, 0.603125000f, 0.600781250f, 0.598437500f, 0.596093750f,
524     0.593750000f, 0.591406250f, 0.589062500f, 0.586718750f, 0.584375000f, 0.582031250f, 0.579687500f, 0.577343750f,
525     0.575000000f, 0.572656250f, 0.570312500f, 0.567968750f, 0.565625000f, 0.563281250f, 0.560937500f, 0.558593750f,
526     0.556250000f, 0.553906250f, 0.551562500f, 0.549218750f, 0.546875000f, 0.544531250f, 0.542187500f, 0.539843750f,
527     0.537500000f, 0.535156250f, 0.532812500f, 0.530468750f, 0.528125000f, 0.525781250f, 0.523437500f, 0.521093750f,
528     0.518750000f, 0.516406250f, 0.514062500f, 0.511718750f, 0.509375000f, 0.507031250f, 0.504687500f, 0.502343750f,
529     0.500000000f, 0.496093750f, 0.492187500f, 0.488281250f, 0.484375000f, 0.480468750f, 0.476562500f, 0.472656250f, // center(-6dB)
530     0.468750000f, 0.464843750f, 0.460937500f, 0.457031250f, 0.453125000f, 0.449218750f, 0.445312500f, 0.441406250f,
531     0.437500000f, 0.433593750f, 0.429687500f, 0.425781250f, 0.421875000f, 0.417968750f, 0.414062500f, 0.410156250f,
532     0.406250000f, 0.402343750f, 0.398437500f, 0.394531250f, 0.390625000f, 0.386718750f, 0.382812500f, 0.378906250f,
533     0.375000000f, 0.371093750f, 0.367187500f, 0.363281250f, 0.359375000f, 0.355468750f, 0.351562500f, 0.347656250f,
534     0.343750000f, 0.339843750f, 0.335937500f, 0.332031250f, 0.328125000f, 0.324218750f, 0.320312500f, 0.316406250f,
535     0.312500000f, 0.308593750f, 0.304687500f, 0.300781250f, 0.296875000f, 0.292968750f, 0.289062500f, 0.285156250f,
536     0.281250000f, 0.277343750f, 0.273437500f, 0.269531250f, 0.265625000f, 0.261718750f, 0.257812500f, 0.253906250f,
537     0.250000000f, 0.246093750f, 0.242187500f, 0.238281250f, 0.234375000f, 0.230468750f, 0.226562500f, 0.222656250f,
538     0.218750000f, 0.214843750f, 0.210937500f, 0.207031250f, 0.203125000f, 0.199218750f, 0.195312500f, 0.191406250f,
539     0.187500000f, 0.183593750f, 0.179687500f, 0.175781250f, 0.171875000f, 0.167968750f, 0.164062500f, 0.160156250f,
540     0.156250000f, 0.152343750f, 0.148437500f, 0.144531250f, 0.140625000f, 0.136718750f, 0.132812500f, 0.128906250f,
541     0.125000000f, 0.121093750f, 0.117187500f, 0.113281250f, 0.109375000f, 0.105468750f, 0.101562500f, 0.097656250f,
542     0.093750000f, 0.089843750f, 0.085937500f, 0.082031250f, 0.078125000f, 0.074218750f, 0.070312500f, 0.066406250f,
543     0.062500000f, 0.058593750f, 0.054687500f, 0.050781250f, 0.046875000f, 0.042968750f, 0.039062500f, 0.035156250f,
544     0.031250000f, 0.027343750f, 0.023437500f, 0.019531250f, 0.015625000f, 0.011718750f, 0.007812500f, 0.003906250f,
545     0.000000000f
546 };
547 
548 const int PAN_CURVE_NUM = 3;
549 const f32* PanTableTable[ PAN_CURVE_NUM ] =
550 {
551     Pan2RatioTableSqrt,
552     Pan2RatioTableSinCos,
553     Pan2RatioTableLinear
554 };
555 const f32* PanTableTableForSurround[ PAN_CURVE_NUM ] =
556 {
557     Pan2RatioTableSqrtSurround,
558     Pan2RatioTableSinCosSurround,
559     Pan2RatioTableLinearSurround
560 };
561 
562 // CalcTick 用
563 #ifdef NW_PLATFORM_CTR
564 class TickCalculator
565 {
566 private:
567     static const int LOG_BUF_SIZE = 20;
568 
569     nn::os::Tick m_Ticks[ LOG_BUF_SIZE ];
570     nn::os::Tick m_TmpTick;
571     int m_Counter;
572 
573 public:
TickCalculator()574     TickCalculator() : m_Counter( 0 ) {}
575 
Calc()576     void Calc()
577     {
578         nn::os::Tick tick2 = nn::os::Tick::GetSystemCurrent();
579         m_Ticks[ m_Counter ] = ( tick2 - m_TmpTick );
580         m_TmpTick = tick2;
581 
582         m_Counter += 1;
583         if ( m_Counter == LOG_BUF_SIZE )
584         {
585             char str[300]; str[0] = '\0';
586             for ( int i = 0; i < LOG_BUF_SIZE; i++ )
587             {
588                 std::snprintf( str, 300, "%s [%2lld]",
589                         str, m_Ticks[i].ToTimeSpan().GetMilliSeconds() );
590             }
591             NN_LOG("%s\n", str );
592             m_Counter = 0;
593         }
594     }
595 };
596 TickCalculator s_TickCalculator;
597 #endif
598 
599 } // anonymous namespace
600 
601 
602 
603 // CalcLpfFreq Table 80Hz - 16000Hz
604 //      - scale 値は scale = (0.1/3) * idx + 0.135614381 と見なす
605 //      - freq 値は RVL_SDK の axvpb.pb.lpf のカットオフ周波数を参考にした
606 const f32 Util::CALC_LPF_FREQ_INTERCEPT = 0.135614381f;
607 const u16 Util::CalcLpfFreqTable[ CALC_LPF_FREQ_TABLE_SIZE ] =
608 {
609     // freq(Hz),   scale
610        80,      // 0.135614381 == CALC_LPF_FREQ_INTERCEPT
611       100,      // 0.167807191
612       128,      // 0.203421572
613       160,      // 0.235614381
614       200,      // 0.267807191
615       256,      // 0.303421572
616       320,      // 0.335614381
617       400,      // 0.367807191
618       500,      // 0.400000000
619       640,      // 0.435614381
620       800,      // 0.467807191
621      1000,      // 0.500000000
622      1280,      // 0.535614381
623      1600,      // 0.567807191
624      2000,      // 0.600000000
625      2560,      // 0.635614381
626      3200,      // 0.667807191
627      4000,      // 0.700000000
628      5120,      // 0.735614381
629      6400,      // 0.767807191
630      8000,      // 0.800000000
631     10240,      // 0.835614381
632     12800,      // 0.867807191
633     16000       // 0.900000000
634 };
635 
CalcLpfFreq(f32 scale)636 u16 Util::CalcLpfFreq( f32 scale )
637 {
638     scale = ut::Clamp( scale, 0.0f, 1.0f );
639 
640     u16 freq = 0;
641 
642     // freq = static_cast<u16>( std::pow( 2.0, ( scale-1.0 ) * 10.0 ) * 32000.0 );
643     // のかわりにテーブルを使用する
644     if ( scale < CALC_LPF_FREQ_INTERCEPT )
645     {
646         freq = CalcLpfFreqTable[0];
647     }
648     else if ( scale >= 0.9f )
649     {
650         freq = CalcLpfFreqTable[CALC_LPF_FREQ_TABLE_SIZE-1];
651     }
652     else
653     {
654         int idx = static_cast<int>( (scale-CALC_LPF_FREQ_INTERCEPT) / (0.1f/3) );
655         freq = CalcLpfFreqTable[ idx ];
656     }
657 
658     return freq;
659 }
660 
661 #if 0
662 f32 Util::SetPanCurveMax( f32 max )
663 {
664     if ( max > PAN_CURVE_MIN )
665     {
666         s_PanCurveMax = max;
667     }
668     else
669     {
670         s_PanCurveMax = PAN_CURVE_MIN;
671     }
672     return s_PanCurveMax;
673 }
674 f32 Util::GetPanCurveMax()
675 {
676     return s_PanCurveMax;
677 }
678 f32 Util::GetPanCurveMin()
679 {
680     return PAN_CURVE_MIN;
681 }
682 #endif
683 
684 
CalcPanRatio(f32 pan,const PanInfo & info)685 f32 Util::CalcPanRatio( f32 pan, const PanInfo& info )
686 {
687     pan = ( ut::Clamp( pan, -1.0f, 1.0f ) + 1.0f ) / 2.0f; // 0.0 - 1.0 のスケールに
688 
689     const f32* table = NULL;
690     if ( nw::snd::SoundSystem::GetOutputMode() == nw::snd::OUTPUT_MODE_SURROUND )
691     {
692         table = PanTableTableForSurround[ info.curve ];
693     }
694     else
695     {
696         table = PanTableTable[ info.curve ];
697     }
698 
699     register f32 ratio = 0.0f;
700     ratio = table[ static_cast<int>( pan * PAN_TABLE_MAX + 0.5f ) ];
701 
702     if ( info.centerZeroFlag )
703     {
704         ratio /= table[ PAN_TABLE_CENTER ]; // 中央で1.0倍になるようにする
705     }
706 
707     if ( info.zeroClampFlag )
708     {
709         ratio = ut::Clamp( ratio, 0.0f, 1.0f );
710     }
711     else
712     {
713         ratio = ut::Clamp( ratio, 0.0f, 2.0f );
714     }
715 
716     return ratio;
717 }
718 
CalcSurroundPanRatio(f32 surroundPan,const PanInfo & info)719 f32 Util::CalcSurroundPanRatio( f32 surroundPan, const PanInfo& info )
720 {
721     surroundPan = ut::Clamp( surroundPan, 0.0f, 2.0f ) / 2.0f; // 0.0 - 1.0 のスケールに
722 
723     const f32* table = PanTableTable[ info.curve ];
724 
725     f32 ratio = table[ static_cast<int>( surroundPan * PAN_TABLE_MAX + 0.5f ) ];
726 
727     ratio = ut::Clamp( ratio, 0.0f, 2.0f );
728 
729     return ratio;
730 }
731 /*---------------------------------------------------------------------------*
732   Name:         CalcPitchRatio
733 
734   Description:  セント単位系から倍率を求める
735 
736   Arguments:    pitch : original key からのピッチのずれ(分解能:半音の1/256)
737 
738   Returns:      ピッチ倍率
739  *---------------------------------------------------------------------------*/
CalcPitchRatio(int pitch_)740 f32 Util::CalcPitchRatio( int pitch_ )
741 {
742     static const int RANGE = PITCH_DIVISION_RANGE * OCTAVE_DIVISION;
743 
744     register int pitch = pitch_;
745 
746     register int octave = 0;
747     while ( pitch < 0 )
748     {
749         octave--;
750         pitch += RANGE;
751     }
752     while ( pitch >= RANGE )
753     {
754         octave++;
755         pitch -= RANGE;
756     }
757 
758     register int note = pitch / PITCH_DIVISION_RANGE;
759     pitch -= note * PITCH_DIVISION_RANGE;
760 
761     register f32 ratio = 1.0f;
762     while ( octave > 0 )
763     {
764         ratio *= 2.0f;
765         octave--;
766     }
767     while ( octave < 0 )
768     {
769         ratio /= 2.0f;
770         octave++;
771     }
772 
773     if ( note  != 0 )
774     {
775         ratio *= NoteTable[note];
776     }
777     if ( pitch != 0 )
778     {
779         ratio *= PitchTable[pitch];
780     }
781 
782     return ratio;
783 }
784 
CalcVolumeRatio(f32 dB)785 f32 Util::CalcVolumeRatio( f32 dB )
786 {
787     dB = ut::Clamp( dB, -90.4f, 6.0f );
788     int index = static_cast<int>( dB * 10 ) - VOLUME_DB_MIN;
789     return Decibel2RatioTable[ index ];
790 }
791 
CalcRandom()792 u16 Util::CalcRandom()
793 {
794     static u32 u = 0x12345678;
795     u = u * 1664525 + 1013904223;
796     return static_cast<u16>( u >> 16 );
797 }
798 
799 // ID が waveArchiveId の波形アーカイブの waveIndex 番目の波形アドレスを返します。
800 // 未ロードの場合、NULL が返ります。
GetWaveFile(u32 waveArchiveId,u32 waveIndex,const SoundArchive & arc,const SoundArchivePlayer & player)801 const void* Util::GetWaveFile(
802     u32 waveArchiveId,
803     u32 waveIndex,
804     const SoundArchive& arc,
805     const SoundArchivePlayer& player )
806 {
807     // 波形アーカイブを取得
808     SoundArchive::WaveArchiveInfo info;
809     if ( ! arc.ReadWaveArchiveInfo( waveArchiveId, &info ) )
810     {
811         return NULL;    // ID == warcId の波形アーカイブ情報が見つからない
812     }
813 
814     const void* warcFile = player.detail_GetFileAddress( info.fileId );
815     NW_WARNING( warcFile, "warc(%d) is not loaded.", waveArchiveId );
816     if ( warcFile == NULL )
817     {
818         return NULL;    // 波形アーカイブが未ロードだった
819     }
820 
821     // 波形ファイルを取得
822     internal::WaveArchiveFileReader reader( warcFile, info.isLoadIndividual );
823     const void* waveFile = reader.GetWaveFile( waveIndex );
824     // TODO: この waveFile を差し替えることができれば、任意の波形で
825     //       ノートオンすることができる。
826     NW_WARNING( waveFile, "index(%d) in warc(%d) is not loaded.", waveIndex, waveArchiveId );
827     if ( waveFile == NULL )
828     {
829         return NULL;
830     }
831     return waveFile;
832 }
833 
CalcTick()834 void Util::CalcTick()
835 {
836 #ifdef NW_PLATFORM_CTR
837     s_TickCalculator.Calc();
838 #endif /* NW_PLATFORM_CTR */
839 }
840 
GetSampleByByte(unsigned long byte,SampleFormat format)841 unsigned long Util::GetSampleByByte( unsigned long byte, SampleFormat format )
842 {
843     unsigned long samples = 0;
844     unsigned long frac;
845 
846     switch ( format )
847     {
848     case SAMPLE_FORMAT_DSP_ADPCM:
849         samples = ( byte / 8 ) * 14;
850         frac = ( byte % 8 );
851         if ( frac != 0 )
852         {
853             samples += ( frac - 1 ) * 2 ;
854         }
855         break;
856 
857     case SAMPLE_FORMAT_PCM_S8:
858         samples = byte;
859         break;
860 
861     /*
862     case SAMPLE_FORMAT_PCM_S16_BE:
863     case SAMPLE_FORMAT_PCM_S16_LE:
864     */
865     case SAMPLE_FORMAT_PCM_S16:
866         samples = ( byte >> 1 );
867         break;
868 
869     default:
870         NW_ASSERTMSG( false, "Invalid format\n" );
871         break;
872     }
873 
874     return samples;
875 }
876 
GetByteBySample(unsigned long samples,SampleFormat format)877 unsigned long Util::GetByteBySample( unsigned long samples, SampleFormat format )
878 {
879     unsigned long byte = 0;
880     unsigned long frac;
881 
882     switch ( format )
883     {
884     case SAMPLE_FORMAT_DSP_ADPCM:
885         byte = ( samples / 14 ) * 8;
886         frac = ( samples % 14 );
887         if ( frac != 0 )
888         {
889             byte += ( ( frac + 1 ) >> 1 ) + 1;
890         }
891         break;
892 
893     case SAMPLE_FORMAT_PCM_S8:
894         byte = samples;
895         break;
896 
897     /*
898     case SAMPLE_FORMAT_PCM_S16_BE:
899     case SAMPLE_FORMAT_PCM_S16_LE:
900     */
901     case SAMPLE_FORMAT_PCM_S16:
902         byte = ( samples << 1 );
903         break;
904 
905     default:
906         NW_ASSERTMSG( false, "Invalid format\n" );
907         break;
908     }
909 
910     return byte;
911 }
912 
913 } // namespace nw::snd::internal
914 } // namespace nw::snd
915 } // namespace nw
916 
917