Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Envelope.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: 6473 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 class Envelope
37     {
38     #region ���������������������������������������
39     private static void Initialize()
40     {
41 hikarin 48 if (!s_initialized)
42 hikarin 37 {
43 hikarin 48 s_volumeMap[0] = 0.0;
44     for (int i = 0; i < s_volumeLength; i++)
45     s_volumeMap[i] = Math.Pow(10.0, (i - 255.0) * (48.0 / (255.0 * 20.0)));
46     s_initialized = true;
47 hikarin 37 }
48     }
49     #endregion
50    
51     #region ���������������������������������������������������������
52     public Envelope(double attack, double decay, double sustain, double release)
53     {
54     Initialize();
55     SetASDR(attack, decay, sustain, release);
56     Playing = false;
57     m_releasing = true;
58     m_currentValue = 0;
59     m_releaseStep = 0;
60     }
61     #endregion
62    
63     #region ���������������������������
64     public void SetASDR(double attack, double decay, double sustain, double release)
65     {
66     if (attack != 0.0)
67     {
68     m_attackTime = (int)(attack * Sample.RATE);
69     m_attackRcpr = 1.0 / m_attackTime;
70     }
71     if (decay != 0.0)
72     {
73     m_decayTime = (int)(decay * Sample.RATE);
74     m_decayRcpr = 1.0 / m_decayTime;
75     }
76     m_sustainLevel = sustain;
77     m_releaseTime = (release > 0.0 ? release : (1.0 / Channel.VELOCITY_MAX2)) * Sample.RATE;
78     }
79    
80     public void Trigger(bool zeroStart)
81     {
82     Playing = true;
83     m_releasing = false;
84     m_startAmplitude = zeroStart ? 0 : m_currentValue;
85     m_timeInSamples = 1;
86     }
87    
88     public void Release()
89     {
90     m_releasing = true;
91     m_releaseStep = m_currentValue / m_releaseTime;
92     }
93    
94     public void GetAmplitudeSamplesLinear(ref double[] samples, int start, int end, double velocity)
95     {
96     for (int i = start; i < end; i++)
97     {
98     if (!Playing)
99     {
100     samples[i] = 0.0;
101     continue;
102     }
103     double n = samples[i];
104     UpdateCurrentValue();
105     samples[i] = n * m_currentValue * velocity;
106     }
107     }
108    
109     public void GetAmplitudeSamplesNonLinear(ref double[] samples, int start, int end, double velocity)
110     {
111     for (int i = start; i < end; i++)
112     {
113     if (!Playing)
114     {
115     samples[i] = (0.0).ToShort();
116     continue;
117     }
118     double n = samples[i];
119     UpdateCurrentValue();
120 hikarin 48 samples[i] = n * s_volumeMap[(int)(Math.Min(m_currentValue, 1.0) * 255)] * velocity;
121 hikarin 37 }
122     }
123     #endregion
124    
125     #region ������������������������������
126     private void UpdateCurrentValue()
127     {
128     if (!m_releasing)
129     {
130     if (m_timeInSamples < m_attackTime)
131     m_currentValue = m_startAmplitude + (1 - m_startAmplitude) * m_timeInSamples * m_attackRcpr;
132     else if (m_timeInSamples < m_attackTime + m_decayTime)
133     m_currentValue = 1.0 - ((m_timeInSamples - m_attackTime) * m_decayRcpr) * (1.0 - m_sustainLevel);
134     else
135     m_currentValue = m_sustainLevel;
136     }
137     else
138     m_currentValue -= m_releaseStep;
139     if (m_currentValue <= 0)
140     {
141     Playing = false;
142     m_currentValue = 0;
143     }
144     ++m_timeInSamples;
145     }
146     #endregion
147    
148     #region ������������������������������
149     public double NextAmplitudeLinear
150     {
151     get
152     {
153     if (!Playing)
154     return 0;
155     UpdateCurrentValue();
156     return m_currentValue;
157     }
158     }
159    
160     public bool Playing
161     {
162     private set;
163     get;
164     }
165     #endregion
166    
167     #region ���������������������������
168 hikarin 48 private static int s_volumeLength = 256;
169     private static double[] s_volumeMap = new double[s_volumeLength];
170     private static bool s_initialized = false;
171 hikarin 37 private int m_attackTime;
172     private double m_attackRcpr;
173     private int m_decayTime;
174     private double m_decayRcpr;
175     private double m_sustainLevel;
176     private double m_releaseTime;
177     private double m_currentValue;
178     private double m_releaseStep;
179     private bool m_releasing;
180     private int m_timeInSamples;
181     private double m_startAmplitude;
182     #endregion
183     }
184     }

Properties

Name Value
svn:keywords Id

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