diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llaudio/windgen.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/linden/indra/llaudio/windgen.h b/linden/indra/llaudio/windgen.h new file mode 100644 index 0000000..39ce568 --- /dev/null +++ b/linden/indra/llaudio/windgen.h | |||
@@ -0,0 +1,138 @@ | |||
1 | /** | ||
2 | * @file windgen.h | ||
3 | * @brief Templated wind noise generation | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2002&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2002-2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlife.com/developers/opensource/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | #ifndef WINDGEN_H | ||
32 | #define WINDGEN_H | ||
33 | |||
34 | #include "llcommon.h" | ||
35 | #include "llrand.h" | ||
36 | |||
37 | template <class MIXBUFFERFORMAT_T> | ||
38 | class LLWindGen | ||
39 | { | ||
40 | public: | ||
41 | LLWindGen() : | ||
42 | mTargetGain(0.f), | ||
43 | mTargetFreq(100.f), | ||
44 | mTargetPanGainR(0.5f), | ||
45 | mbuf0(0.0), | ||
46 | mbuf1(0.0), | ||
47 | mbuf2(0.0), | ||
48 | mbuf3(0.0), | ||
49 | mbuf4(0.0), | ||
50 | mbuf5(0.0), | ||
51 | mY0(0.0), | ||
52 | mY1(0.0), | ||
53 | mCurrentGain(0.f), | ||
54 | mCurrentFreq(100.f), | ||
55 | mCurrentPanGainR(0.5f) {}; | ||
56 | |||
57 | static const U32 getInputSamplingRate() {return mInputSamplingRate;} | ||
58 | |||
59 | // newbuffer = the buffer passed from the previous DSP unit. | ||
60 | // numsamples = length in samples-per-channel at this mix time. | ||
61 | // stride = number of bytes between start of each sample. | ||
62 | // NOTE: generates L/R interleaved stereo | ||
63 | MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples, int stride) | ||
64 | { | ||
65 | U8 *cursamplep = (U8*)newbuffer; | ||
66 | |||
67 | double bandwidth = 50.0F; | ||
68 | double a0,b1,b2; | ||
69 | |||
70 | // calculate resonant filter coeffs | ||
71 | b2 = exp(-(F_TWO_PI) * (bandwidth / mInputSamplingRate)); | ||
72 | |||
73 | while (numsamples--) | ||
74 | { | ||
75 | mCurrentFreq = (float)((0.999 * mCurrentFreq) + (0.001 * mTargetFreq)); | ||
76 | mCurrentGain = (float)((0.999 * mCurrentGain) + (0.001 * mTargetGain)); | ||
77 | mCurrentPanGainR = (float)((0.999 * mCurrentPanGainR) + (0.001 * mTargetPanGainR)); | ||
78 | b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (mCurrentFreq / mInputSamplingRate)); | ||
79 | a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2)); | ||
80 | double nextSample; | ||
81 | |||
82 | // start with white noise | ||
83 | nextSample = ll_frand(2.0f) - 1.0f; | ||
84 | |||
85 | #if 1 // LLAE_WIND_PINK apply pinking filter | ||
86 | mbuf0 = 0.997f * mbuf0 + 0.0126502f * nextSample; | ||
87 | mbuf1 = 0.985f * mbuf1 + 0.0139083f * nextSample; | ||
88 | mbuf2 = 0.950f * mbuf2 + 0.0205439f * nextSample; | ||
89 | mbuf3 = 0.850f * mbuf3 + 0.0387225f * nextSample; | ||
90 | mbuf4 = 0.620f * mbuf4 + 0.0465932f * nextSample; | ||
91 | mbuf5 = 0.250f * mbuf5 + 0.1093477f * nextSample; | ||
92 | |||
93 | nextSample = mbuf0 + mbuf1 + mbuf2 + mbuf3 + mbuf4 + mbuf5; | ||
94 | #endif | ||
95 | |||
96 | #if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise | ||
97 | nextSample = (double)( a0 * nextSample - b1 * mY0 - b2 * mY1 ); | ||
98 | |||
99 | mY1 = mY0; | ||
100 | mY0 = nextSample; | ||
101 | #endif | ||
102 | |||
103 | nextSample *= mCurrentGain; | ||
104 | |||
105 | MIXBUFFERFORMAT_T sample; | ||
106 | |||
107 | sample = llfloor(((F32)nextSample*32768.f*(1.0f - mCurrentPanGainR))+0.5f); | ||
108 | *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); | ||
109 | cursamplep += stride; | ||
110 | |||
111 | sample = llfloor(((F32)nextSample*32768.f*mCurrentPanGainR)+0.5f); | ||
112 | *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); | ||
113 | cursamplep += stride; | ||
114 | } | ||
115 | |||
116 | return newbuffer; | ||
117 | } | ||
118 | |||
119 | F32 mTargetGain; | ||
120 | F32 mTargetFreq; | ||
121 | F32 mTargetPanGainR; | ||
122 | |||
123 | private: | ||
124 | static const U32 mInputSamplingRate = 44100; | ||
125 | F64 mbuf0; | ||
126 | F64 mbuf1; | ||
127 | F64 mbuf2; | ||
128 | F64 mbuf3; | ||
129 | F64 mbuf4; | ||
130 | F64 mbuf5; | ||
131 | F64 mY0; | ||
132 | F64 mY1; | ||
133 | F32 mCurrentGain; | ||
134 | F32 mCurrentFreq; | ||
135 | F32 mCurrentPanGainR; | ||
136 | }; | ||
137 | |||
138 | #endif | ||