Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Channel.cs

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:keywords Id

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