Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Filter.cs

Parent Directory Parent Directory | Revision Log Revision Log


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

1 hikarin 58 /*
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 hikarin 37
28 hikarin 58 //
29     // $Id$
30     //
31    
32     using System;
33    
34 hikarin 37 namespace SlMML
35     {
36     public enum FilterType
37     {
38 hikarin 52 LPFQuality = 1,
39 hikarin 37 LPFFast = 2,
40     None = 0,
41 hikarin 52 HPFFast = -2,
42     HPFQuality = -1
43 hikarin 37 };
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 hikarin 52 UpdateValueForFastFilter(ref cut, out input, samples[i]);
70 hikarin 37 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 hikarin 52 UpdateSamplesForHPFQuality(ref samples, i, cut, fb);
82 hikarin 37 }
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 hikarin 52 UpdateSamplesForHPFQuality(ref samples, i, cut, fb);
90 hikarin 37 }
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 hikarin 52 UpdateSamplesForLPFQuality(ref samples, i, cut, fb);
101 hikarin 37 }
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 hikarin 52 UpdateSamplesForLPFQuality(ref samples, i, cut, fb);
109 hikarin 37 }
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 hikarin 52 UpdateValueForFastFilter(ref cut, out input, samples[i]);
117 hikarin 37 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 hikarin 52 private void UpdateSamplesForHPFQuality(ref double[] samples, int index, double cut, double fb)
144 hikarin 37 {
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 hikarin 52 private void UpdateSamplesForLPFQuality(ref double[] samples, int index, double cut, double fb)
152 hikarin 37 {
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 hikarin 52 private void UpdateValueForFastFilter(ref double cut, out double input, double sample)
158 hikarin 37 {
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