Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/slmml/Filter.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 58 - (show annotations) (download)
Sat Apr 4 12:56:58 2009 UTC (14 years, 11 months ago) by hikarin
File size: 8175 byte(s)
[ocmml/slmml] * added a license and an $Id$ header

1 /*
2 Copyright (c) 2009, hkrn All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6
7 Redistributions of source code must retain the above copyright notice, this
8 list of conditions and the following disclaimer. Redistributions in binary
9 form must reproduce the above copyright notice, this list of conditions and
10 the following disclaimer in the documentation and/or other materials
11 provided with the distribution. Neither the name of the hkrn nor
12 the names of its contributors may be used to endorse or promote products
13 derived from this software without specific prior written permission.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
19 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
25 DAMAGE.
26 */
27
28 //
29 // $Id$
30 //
31
32 using System;
33
34 namespace SlMML
35 {
36 public enum FilterType
37 {
38 LPFQuality = 1,
39 LPFFast = 2,
40 None = 0,
41 HPFFast = -2,
42 HPFQuality = -1
43 };
44
45 public class Filter
46 {
47 #region ���������������������������
48 public void Reset()
49 {
50 m_t1 = 0;
51 m_t2 = 0;
52 m_b0 = 0;
53 m_b1 = 0;
54 m_b2 = 0;
55 m_b3 = 0;
56 m_b4 = 0;
57 }
58
59 public void GetSample(ref double[] samples, int start, int end)
60 {
61 double cut = 0, k = GetKeyValue(Key), fb = 0;
62 switch (Switch)
63 {
64 case FilterType.HPFFast:
65 for (int i = start; i < end; i++)
66 {
67 double input = 0;
68 cut = Channel.FrequencyFromIndex((int)(Frequency + Amount * Envelope.NextAmplitudeLinear)) * k;
69 UpdateValueForFastFilter(ref cut, out input, samples[i]);
70 samples[i] = input - m_b4;
71 }
72 break;
73 case FilterType.HPFQuality:
74 fb = 0;
75 if (Amount > 0.0001 || Amount < -0.0001)
76 {
77 for (int i = start; i < end; i++)
78 {
79 cut = Channel.FrequencyFromIndex((int)(Frequency + Amount * Envelope.NextAmplitudeLinear)) * k;
80 UpdateCutAndFb(ref cut, ref fb);
81 UpdateSamplesForHPFQuality(ref samples, i, cut, fb);
82 }
83 }
84 else
85 {
86 cut = Channel.FrequencyFromIndex((int)(Frequency)) * k;
87 UpdateCutAndFb(ref cut, ref fb);
88 for (int i = start; i < end; i++)
89 UpdateSamplesForHPFQuality(ref samples, i, cut, fb);
90 }
91 break;
92 case FilterType.LPFQuality:
93 fb = 0;
94 if (Amount > 0.0001 || Amount < -0.0001)
95 {
96 for (int i = start; i < end; i++)
97 {
98 cut = Channel.FrequencyFromIndex((int)(Frequency + Amount * Envelope.NextAmplitudeLinear)) * k;
99 UpdateCutAndFb(ref cut, ref fb);
100 UpdateSamplesForLPFQuality(ref samples, i, cut, fb);
101 }
102 }
103 else
104 {
105 cut = Channel.FrequencyFromIndex((int)(Frequency)) * k;
106 UpdateCutAndFb(ref cut, ref fb);
107 for (int i = start; i < end; i++)
108 UpdateSamplesForLPFQuality(ref samples, i, cut, fb);
109 }
110 break;
111 case FilterType.LPFFast:
112 for (int i = start; i < end; i++)
113 {
114 double input = 0;
115 cut = Channel.FrequencyFromIndex((int)(Frequency + Amount * Envelope.NextAmplitudeLinear)) * k;
116 UpdateValueForFastFilter(ref cut, out input, samples[i]);
117 samples[i] = m_b4;
118 }
119 break;
120 }
121 }
122 #endregion
123
124 #region ������������������������������
125 private void UpdateCutValue(ref double cut)
126 {
127 if (cut < 1.0 / 127.0)
128 cut = 0;
129 cut = Math.Min(cut, 1.0 - 0.0001);
130 }
131
132 private void UpdateCutAndFb(ref double cut, ref double fb)
133 {
134 UpdateCutValue(ref cut);
135 fb = Resonance + Resonance / (1.0 - cut);
136 }
137
138 private double GetKeyValue(double key)
139 {
140 return key * (2.0 * Math.PI / (Sample.RATE * Sample.FREQUENCY_BASE));
141 }
142
143 private void UpdateSamplesForHPFQuality(ref double[] samples, int index, double cut, double fb)
144 {
145 double input = samples[index];
146 m_b0 = m_b0 + cut * (input - m_b0 + fb * (m_b0 - m_b1));
147 m_b1 = m_b1 + cut * (m_b0 - m_b1);
148 samples[index] = input - m_b0;
149 }
150
151 private void UpdateSamplesForLPFQuality(ref double[] samples, int index, double cut, double fb)
152 {
153 m_b0 = m_b0 + cut * (samples[index] - m_b0 + fb * (m_b0 - m_b1));
154 samples[index] = m_b1 = m_b1 + cut * (m_b0 - m_b1);
155 }
156
157 private void UpdateValueForFastFilter(ref double cut, out double input, double sample)
158 {
159 UpdateCutValue(ref cut);
160 double q = 1.0 - cut;
161 double p = cut + 0.8 * cut * q;
162 double f = p + p - 1.0;
163 q = Resonance * (1.0 + 0.5 * q * (1.0 - q + 5.6 * q * q));
164 input = sample;
165 input -= q * m_b4;
166 m_t1 = m_b1;
167 m_b1 = (input + m_b0) * p - m_b1 * f;
168 m_t2 = m_b2;
169 m_b2 = (m_b1 + m_t1) * p - m_b2 * f;
170 m_t1 = m_b3;
171 m_b3 = (m_b2 + m_t2) * p - m_b3 * f;
172 m_b4 = (m_b3 + m_t1) * p - m_b4 * f;
173 m_b4 = m_b4 - m_b4 * m_b4 * m_b4 * 0.16667;
174 m_b0 = input;
175 }
176 #endregion
177
178 #region ������������������������������
179 public FilterType Switch
180 {
181 private get
182 {
183 return m_type;
184 }
185 set
186 {
187 Reset();
188 m_type = value;
189 }
190 }
191
192 public Envelope Envelope
193 {
194 private get;
195 set;
196 }
197
198 public double Frequency
199 {
200 private get;
201 set;
202 }
203
204 public double Amount
205 {
206 private get;
207 set;
208 }
209
210 public double Resonance
211 {
212 private get;
213 set;
214 }
215
216 public double Key
217 {
218 private get;
219 set;
220 }
221 #endregion
222
223 #region ���������������������������
224 private FilterType m_type;
225 private double m_t1;
226 private double m_t2;
227 private double m_b0;
228 private double m_b1;
229 private double m_b2;
230 private double m_b3;
231 private double m_b4;
232 #endregion
233 }
234 }

Properties

Name Value
svn:keywords Id

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26