Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Envelope.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 37 - (hide annotations) (download)
Sun Mar 29 15:10:03 2009 UTC (15 years ago) by hikarin
File size: 4948 byte(s)
[ocmml/slmml] * imported SlMML
1 hikarin 37 using System;
2    
3     namespace SlMML
4     {
5     public class Envelope
6     {
7     #region 非公開クラスメソッドの定義
8     private static void Initialize()
9     {
10     if (!m_initialized)
11     {
12     m_volumeMap[0] = 0.0;
13     for (int i = 0; i < volumeLength; i++)
14     m_volumeMap[i] = Math.Pow(10.0, (i - 255.0) * (48.0 / (255.0 * 20.0)));
15     m_initialized = true;
16     }
17     }
18     #endregion
19    
20     #region コンストラクタおよびデストラクタの定義
21     public Envelope(double attack, double decay, double sustain, double release)
22     {
23     Initialize();
24     SetASDR(attack, decay, sustain, release);
25     Playing = false;
26     m_releasing = true;
27     m_currentValue = 0;
28     m_releaseStep = 0;
29     }
30     #endregion
31    
32     #region 公開メソッドの定義
33     public void SetASDR(double attack, double decay, double sustain, double release)
34     {
35     if (attack != 0.0)
36     {
37     m_attackTime = (int)(attack * Sample.RATE);
38     m_attackRcpr = 1.0 / m_attackTime;
39     }
40     if (decay != 0.0)
41     {
42     m_decayTime = (int)(decay * Sample.RATE);
43     m_decayRcpr = 1.0 / m_decayTime;
44     }
45     m_sustainLevel = sustain;
46     m_releaseTime = (release > 0.0 ? release : (1.0 / Channel.VELOCITY_MAX2)) * Sample.RATE;
47     }
48    
49     public void Trigger(bool zeroStart)
50     {
51     Playing = true;
52     m_releasing = false;
53     m_startAmplitude = zeroStart ? 0 : m_currentValue;
54     m_timeInSamples = 1;
55     }
56    
57     public void Release()
58     {
59     m_releasing = true;
60     m_releaseStep = m_currentValue / m_releaseTime;
61     }
62    
63     public void GetAmplitudeSamplesLinear(ref double[] samples, int start, int end, double velocity)
64     {
65     for (int i = start; i < end; i++)
66     {
67     if (!Playing)
68     {
69     samples[i] = 0.0;
70     continue;
71     }
72     double n = samples[i];
73     UpdateCurrentValue();
74     samples[i] = n * m_currentValue * velocity;
75     }
76     }
77    
78     public void GetAmplitudeSamplesNonLinear(ref double[] samples, int start, int end, double velocity)
79     {
80     for (int i = start; i < end; i++)
81     {
82     if (!Playing)
83     {
84     samples[i] = (0.0).ToShort();
85     continue;
86     }
87     double n = samples[i];
88     UpdateCurrentValue();
89     samples[i] = n * m_volumeMap[(int)(Math.Min(m_currentValue, 1.0) * 255)] * velocity;
90     }
91     }
92     #endregion
93    
94     #region 非公開メソッドの定義
95     private void UpdateCurrentValue()
96     {
97     if (!m_releasing)
98     {
99     if (m_timeInSamples < m_attackTime)
100     m_currentValue = m_startAmplitude + (1 - m_startAmplitude) * m_timeInSamples * m_attackRcpr;
101     else if (m_timeInSamples < m_attackTime + m_decayTime)
102     m_currentValue = 1.0 - ((m_timeInSamples - m_attackTime) * m_decayRcpr) * (1.0 - m_sustainLevel);
103     else
104     m_currentValue = m_sustainLevel;
105     }
106     else
107     m_currentValue -= m_releaseStep;
108     if (m_currentValue <= 0)
109     {
110     Playing = false;
111     m_currentValue = 0;
112     }
113     ++m_timeInSamples;
114     }
115     #endregion
116    
117     #region 公開プロパティの定義
118     public double NextAmplitudeLinear
119     {
120     get
121     {
122     if (!Playing)
123     return 0;
124     UpdateCurrentValue();
125     return m_currentValue;
126     }
127     }
128    
129     public bool Playing
130     {
131     private set;
132     get;
133     }
134     #endregion
135    
136     #region メンバー変数の定義
137     private static int volumeLength = 256;
138     private static double[] m_volumeMap = new double[volumeLength];
139     private static bool m_initialized = false;
140     private int m_attackTime;
141     private double m_attackRcpr;
142     private int m_decayTime;
143     private double m_decayRcpr;
144     private double m_sustainLevel;
145     private double m_releaseTime;
146     private double m_currentValue;
147     private double m_releaseStep;
148     private bool m_releasing;
149     private int m_timeInSamples;
150     private double m_startAmplitude;
151     #endregion
152     }
153     }

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