Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Channel.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 42 - (hide annotations) (download)
Mon Mar 30 14:15:57 2009 UTC (15 years ago) by hikarin
File size: 16556 byte(s)
[ocmml/slmml] * fixed a bug that causes noise with LFO event
1 hikarin 37 using System;
2     using SlMML.Modulators;
3    
4     namespace SlMML
5     {
6     public enum ChannelOutputMode
7     {
8     Default = 0,
9     Overwrite = 1,
10     Add = 2
11     }
12    
13     public class Channel
14     {
15     #region 定数の定義
16     public const int PITCH_RESOLUTION = 100;
17     public static readonly int VELOCITY_MAX = 128;
18     public static readonly int VELOCITY_MAX2 = VELOCITY_MAX - 1;
19     #endregion
20    
21     #region 公開クラスメソッドの定義
22     public static void Initialize(int nbSamples)
23     {
24     if (!m_initialized)
25     {
26     int i = 0;
27     m_sampleLength = nbSamples;
28     m_samples = new double[nbSamples];
29     m_frequencyLength = m_frequencyMap.Length;
30     for (i = 0; i < m_frequencyLength; i++)
31     m_frequencyMap[i] = Sample.FREQUENCY_BASE * Math.Pow(2.0, (i - 69.0 * PITCH_RESOLUTION) / (12.0 * PITCH_RESOLUTION));
32     m_volumeLength = VELOCITY_MAX;
33     m_volumeMap[0] = 0.0;
34     for (i = 1; i < m_volumeLength; i++)
35     m_volumeMap[i] = Math.Pow(10.0, (i - VELOCITY_MAX2) * (48.0 / (VELOCITY_MAX2 * 20.0)));
36     m_pipeArray = null;
37     m_initialized = true;
38     }
39     }
40    
41     public static void Release()
42     {
43     m_pipeArray = null;
44     m_samples = null;
45     }
46    
47     public static void CreatePipes(int number)
48     {
49     m_pipeArray = new double[number][];
50     m_pipeArrayNum = number;
51     for (int i = 0; i < number; i++)
52     {
53     m_pipeArray[i] = new double[m_sampleLength];
54     for (int j = 0; j < m_sampleLength; j++)
55     m_pipeArray[i][j] = 0;
56     }
57     }
58    
59     public static double FrequencyFromIndex(int index)
60     {
61     index = Math.Min(Math.Max(index, 0), Math.Max(m_frequencyLength, 1) - 1);
62     return m_frequencyMap[index];
63     }
64     #endregion
65    
66     #region コンストラクタおよびデストラクタの定義
67     public Channel()
68     {
69     m_vco = new Envelope(0.0, 60.0 / VELOCITY_MAX2, 30.0 / VELOCITY_MAX2, 1.0 / VELOCITY_MAX2);
70     m_vcf = new Envelope(0.0, 30.0 / VELOCITY_MAX2, 0.0, 1.0);
71     m_osc1 = new Oscillator();
72     m_mod1 = m_osc1.CurrentModulator;
73     m_osc2 = new Oscillator() { Form = OscillatorForm.Sine };
74     m_osc2.MakeAsLFO();
75     m_mod2 = m_osc2.CurrentModulator;
76     m_filter = new Filter();
77     m_osc2connect = m_enableFilter = false;
78     m_formant = new Formant();
79     m_velocity = 100.0 / (VELOCITY_MAX - 1.0);
80     m_onCounter = 0;
81     m_lfoDelay = 0;
82     m_lfoDepth = 0;
83     m_lfoEnd = 0;
84     m_lpfAmount = 0;
85     m_lpfFrequency = 0;
86     m_lpfResonance = 0;
87     m_volumeMode = 0;
88     NoteIndex = 0;
89     Detune = 0;
90 hikarin 42 m_frequencyIndex = 0;
91 hikarin 37 Pan = 64;
92     Input = new Events.Input() { Sens = 0, Pipe = 0 };
93     Output = new Events.Output() { Mode = ChannelOutputMode.Default, Pipe = 0 };
94     }
95     #endregion
96    
97     #region 公開メソッドの定義
98     public void EnableNote(Events.NoteOn noteOn)
99     {
100     int index = noteOn.Index, velocity = noteOn.Velocity;
101     NoteIndex = index;
102     m_vco.Trigger(false);
103     m_vcf.Trigger(true);
104     m_mod1.ResetPhase();
105     m_mod2.ResetPhase();
106     m_filter.Reset();
107     velocity = Math.Min(Math.Max(velocity, 0), VELOCITY_MAX2);
108     m_velocity = VolumeMode > 0 ? m_volumeMap[velocity] : (double)velocity / VELOCITY_MAX2;
109     m_onCounter = 0;
110     FCNoise fcNoise = (FCNoise)m_osc1.ModulatorFromForm(OscillatorForm.FCNoise);
111     fcNoise.NoiseFrequencyIndex = index;
112     GBLongNoise longNoise = (GBLongNoise)m_osc1.ModulatorFromForm(OscillatorForm.GBLongNoise);
113     longNoise.NoiseFrequencyIndex = index;
114     GBShortNoise shortNoise = (GBShortNoise)m_osc1.ModulatorFromForm(OscillatorForm.GBShortNoise);
115     shortNoise.NoiseFrequencyIndex = index;
116     }
117    
118     public void DisableNote()
119     {
120     m_vco.Release();
121     m_vcf.Release();
122     }
123    
124     public void Close()
125     {
126     DisableNote();
127     m_filter.Switch = FilterType.None;
128     }
129    
130     public void SetLFO(Events.LFO lfo, double frequency)
131     {
132     m_osc2.Form = lfo.Main;
133     m_mod2 = m_osc2.ModulatorFromForm(lfo.Main);
134     m_osc2sign = lfo.Reverse ? -1.0 : 1.0;
135     if (lfo.Main >= OscillatorForm.Max)
136     m_osc2connect = false;
137     if (lfo.Main == OscillatorForm.GBWave)
138     {
139     GBWave gbWave = (GBWave)m_osc2.ModulatorFromForm(OscillatorForm.GBWave);
140     gbWave.WaveNo = (int)lfo.Sub;
141     }
142     m_lfoDepth = lfo.Depth;
143     m_osc2connect = m_lfoDepth == 0 ? false : true;
144     m_mod2.Frequency = frequency;
145     m_mod2.ResetPhase();
146     Noise noise = (Noise)m_osc2.ModulatorFromForm(OscillatorForm.Noise);
147     noise.NoiseFrequency = frequency / Sample.RATE;
148     m_lfoDelay = lfo.Delay;
149     int time = lfo.Time;
150     m_lfoEnd = time > 0 ? m_lfoDelay + time : 0;
151     }
152    
153     public void GetSamples(ref short[] samples, int start, int delta, int max)
154     {
155     int end = Math.Min(start + delta, max);
156     int frequencyIndex = 0;
157     if (!m_vco.Playing)
158     {
159     for (int i = start; i < end; i++)
160     m_samples[i] = 0;
161     }
162     else if (m_inSens < 0.000001)
163     {
164     if (!m_osc2connect)
165     {
166     m_mod1.GetSamples(ref m_samples, start, end);
167     if (VolumeMode == 0)
168     m_vco.GetAmplitudeSamplesLinear(ref m_samples, start, end, m_velocity);
169     else
170     m_vco.GetAmplitudeSamplesNonLinear(ref m_samples, start, end, m_velocity);
171     }
172     else
173     {
174     int s = start, e = 0;
175     do
176     {
177     e = Math.Min(s + m_lfoDelta, end);
178 hikarin 42 frequencyIndex = m_frequencyIndex;
179 hikarin 37 if (m_onCounter >= m_lfoDelay &&
180     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
181     {
182     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
183     m_mod2.AddPhase(e - s - 1);
184     }
185     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
186     m_mod1.GetSamples(ref m_samples, s, e);
187     if (VolumeMode == 0)
188     m_vco.GetAmplitudeSamplesLinear(ref m_samples, s, e, m_velocity);
189     else
190     m_vco.GetAmplitudeSamplesNonLinear(ref m_samples, s, e, m_velocity);
191     m_onCounter += e - s;
192     s = e;
193     } while (s < end);
194     }
195     }
196     else
197     {
198     if (!m_osc2connect)
199     {
200 hikarin 42 m_mod1.Frequency = Channel.FrequencyFromIndex(m_frequencyIndex);
201 hikarin 37 for (int i = start; i < end; i++)
202 hikarin 42 m_samples[i] = m_mod1.NextSampleOfs((int)(m_pipeArray[m_inPipe][i] * m_inSens));
203 hikarin 37 if (m_volumeMode == 0)
204     m_vco.GetAmplitudeSamplesLinear(ref m_samples, start, end, m_velocity);
205     else
206     m_vco.GetAmplitudeSamplesNonLinear(ref m_samples, start, end, m_velocity);
207     }
208     else
209     {
210     for (int i = start; i < end; i++)
211     {
212 hikarin 42 frequencyIndex = m_frequencyIndex;
213 hikarin 37 if (m_onCounter >= m_lfoDelay &&
214     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
215     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
216     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
217 hikarin 42 m_samples[i] = m_mod1.NextSampleOfs((int)(m_pipeArray[m_inPipe][i] * m_inSens));
218 hikarin 37 m_onCounter++;
219     }
220     }
221     }
222     double key = m_mod1.Frequency;
223     m_formant.GetSamples(ref m_samples, start, end);
224     m_filter.Envelope = m_vcf;
225     m_filter.Frequency = m_lpfFrequency;
226     m_filter.Amount = m_lpfAmount;
227     m_filter.Resonance = m_lpfResonance;
228     m_filter.Key = key;
229     m_filter.GetSample(ref m_samples, start, end);
230     switch (m_outMode)
231     {
232     case ChannelOutputMode.Default:
233     for (int i = start; i < end; i++)
234     {
235     int n = i << 1;
236     double amplitude = m_samples[i];
237     samples[n] += (amplitude * m_panLeft).ToShort();
238     samples[n + 1] += (amplitude * m_panRight).ToShort();
239     }
240     break;
241     case ChannelOutputMode.Overwrite:
242     for (int i = start; i < end; i++)
243     m_pipeArray[m_outPipe][i] = m_samples[i];
244     break;
245     case ChannelOutputMode.Add:
246     for (int i = start; i < end; i++)
247     m_pipeArray[m_outPipe][i] += m_samples[i];
248     break;
249     }
250     }
251     #endregion
252    
253     #region 非公開メソッドの定義
254     private void SetModulatorFrequency()
255     {
256     m_frequencyIndex = m_noteIndex * PITCH_RESOLUTION + m_detune;
257     double freq = FrequencyFromIndex(m_frequencyIndex);
258     m_mod1.Frequency = FrequencyFromIndex(m_frequencyIndex);
259     }
260     #endregion
261    
262     #region 公開プロパティの定義
263     public Events.VCO ADSRForVCO
264     {
265     set
266     {
267     m_vco.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
268     value.Decay * (1.0 / VELOCITY_MAX2),
269     value.Sustain * (1.0 / VELOCITY_MAX2),
270     value.Release * (1.0 / VELOCITY_MAX2));
271     }
272     }
273    
274     public Events.VCF ADSRForVCF
275     {
276     set
277     {
278     m_vcf.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
279     value.Decay * (1.0 / VELOCITY_MAX2),
280     value.Sustain * (1.0 / VELOCITY_MAX2),
281     value.Release * (1.0 / VELOCITY_MAX2));
282     }
283     }
284    
285     public Events.Form Form
286     {
287     set
288     {
289     m_osc1.Form = value.Main;
290     m_mod1 = m_osc1.ModulatorFromForm(value.Main);
291     if (value.Main == OscillatorForm.GBWave)
292     {
293     GBWave gbwave = (GBWave)m_osc1.ModulatorFromForm(OscillatorForm.GBWave);
294     gbwave.WaveNo = (int)value.Sub;
295     }
296     }
297     }
298    
299     public Events.LPF LPF
300     {
301     set
302     {
303     FilterType sw = value.Switch;
304     if (sw >= FilterType.HPFQuality &&
305     sw <= FilterType.LPFQuality &&
306     !m_enableFilter)
307     {
308     m_enableFilter = true;
309     m_filter.Switch = sw;
310     }
311     m_lpfAmount = Math.Min(Math.Max(value.Amount, -VELOCITY_MAX2), VELOCITY_MAX2);
312     m_lpfAmount *= PITCH_RESOLUTION;
313     int frequencyIndex = value.Frequency;
314     frequencyIndex = Math.Min(Math.Max(frequencyIndex, 0), VELOCITY_MAX2);
315     m_lpfFrequency = frequencyIndex * PITCH_RESOLUTION;
316     m_lpfResonance = value.Resonance * (1.0 / VELOCITY_MAX2);
317     m_lpfResonance = Math.Min(Math.Max(m_lpfResonance, 0.0), 1.0);
318     }
319     }
320    
321     public Events.Input Input
322     {
323     set
324     {
325     m_inSens = (1 << (value.Sens - 1)) * (1.0 / 8.0) * Modulator.PHASE_LENGTH;
326     m_inPipe = value.Pipe;
327     }
328     }
329    
330     public Events.Output Output
331     {
332     set
333     {
334     m_outMode = value.Mode;
335     m_outPipe = Math.Min(Math.Max(value.Pipe, 0), m_pipeArrayNum);
336     }
337     }
338    
339    
340     public int NoteIndex
341     {
342     set
343     {
344     m_noteIndex = value;
345     SetModulatorFrequency();
346     }
347     }
348    
349     public int Detune
350     {
351     set
352     {
353     m_detune = value;
354     SetModulatorFrequency();
355     }
356     }
357    
358     public double NoiseFrequency
359     {
360     set
361     {
362     Noise noise = (Noise)m_osc1.ModulatorFromForm(OscillatorForm.Noise);
363     noise.NoiseFrequency = 1.0 - value * (1.0 / VELOCITY_MAX);
364     }
365     }
366    
367     public int PWM
368     {
369     set
370     {
371     Pulse pulse;
372     if (m_osc1.Form != OscillatorForm.FCPulse)
373     {
374     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.Pulse);
375     pulse.PWM = value * (1.0 / 100.0);
376     }
377     else
378     {
379     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.FCPulse);
380     pulse.PWM = 0.125 * value;
381     }
382     }
383     }
384    
385     public int Pan
386     {
387     set
388     {
389     m_panRight = Math.Max((value - 1) * (0.25 / 63.0), 0.0);
390     m_panLeft = (2.0 * 0.25) - m_panRight;
391     }
392     }
393    
394     public FormantVowel FormantVowel
395     {
396     set
397     {
398     m_formant.Vowel = value;
399     }
400     }
401    
402     public int VolumeMode
403     {
404     private get;
405     set;
406     }
407     #endregion
408    
409     #region メンバー変数の定義
410     private static bool m_initialized = false;
411     private static double[] m_frequencyMap = new double[VELOCITY_MAX * PITCH_RESOLUTION];
412     private static int m_frequencyLength = 0;
413     private static double[] m_volumeMap = new double[VELOCITY_MAX];
414     private static int m_volumeLength = 0;
415     private static double[] m_samples;
416     private static int m_sampleLength = 0;
417     private static double[][] m_pipeArray;
418     private static int m_pipeArrayNum = 0;
419     private static int m_lfoDelta = VELOCITY_MAX;
420     private Envelope m_vco;
421     private Envelope m_vcf;
422     private IModulator m_mod1;
423     private Oscillator m_osc1;
424     private IModulator m_mod2;
425     private Oscillator m_osc2;
426     private int m_noteIndex;
427     private int m_detune;
428 hikarin 42 private int m_frequencyIndex;
429 hikarin 37 private bool m_osc2connect;
430     private double m_osc2sign;
431     private Filter m_filter;
432     private bool m_enableFilter;
433     private Formant m_formant;
434     private double m_velocity;
435     private double m_panLeft;
436     private double m_panRight;
437     private int m_onCounter;
438     private int m_lfoDelay;
439     private double m_lfoDepth;
440     private int m_lfoEnd;
441     private double m_lpfAmount;
442     private double m_lpfFrequency;
443     private double m_lpfResonance;
444     private int m_volumeMode;
445     private double m_inSens;
446     private int m_inPipe;
447     private ChannelOutputMode m_outMode;
448     private int m_outPipe;
449     #endregion
450     }
451     }

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