Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Channel.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 79 - (hide annotations) (download)
Fri May 1 13:35:15 2009 UTC (14 years, 11 months ago) by hikarin
File size: 18742 byte(s)
[ocmml/slmml] * implemented the extension (@x)
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 79 Velocity = noteOn.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     m_osc2.Form = lfo.Main;
165     m_mod2 = m_osc2.ModulatorFromForm(lfo.Main);
166     m_osc2sign = lfo.Reverse ? -1.0 : 1.0;
167     if (lfo.Main >= OscillatorForm.Max)
168     m_osc2connect = false;
169     if (lfo.Main == OscillatorForm.GBWave)
170     {
171     GBWave gbWave = (GBWave)m_osc2.ModulatorFromForm(OscillatorForm.GBWave);
172     gbWave.WaveNo = (int)lfo.Sub;
173     }
174     m_lfoDepth = lfo.Depth;
175     m_osc2connect = m_lfoDepth == 0 ? false : true;
176     m_mod2.Frequency = frequency;
177     m_mod2.ResetPhase();
178     Noise noise = (Noise)m_osc2.ModulatorFromForm(OscillatorForm.Noise);
179     noise.NoiseFrequency = frequency / Sample.RATE;
180     m_lfoDelay = lfo.Delay;
181     int time = lfo.Time;
182     m_lfoEnd = time > 0 ? m_lfoDelay + time : 0;
183     }
184    
185     public void GetSamples(ref short[] samples, int start, int delta, int max)
186     {
187     int end = Math.Min(start + delta, max);
188     int frequencyIndex = 0;
189     if (!m_vco.Playing)
190     {
191     for (int i = start; i < end; i++)
192 hikarin 48 s_samples[i] = 0;
193 hikarin 37 }
194     else if (m_inSens < 0.000001)
195     {
196     if (!m_osc2connect)
197     {
198 hikarin 48 m_mod1.GetSamples(ref s_samples, start, end);
199 hikarin 37 if (VolumeMode == 0)
200 hikarin 79 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
201 hikarin 37 else
202 hikarin 79 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
203 hikarin 37 }
204     else
205     {
206     int s = start, e = 0;
207     do
208     {
209 hikarin 48 e = Math.Min(s + s_lfoDelta, end);
210 hikarin 42 frequencyIndex = m_frequencyIndex;
211 hikarin 37 if (m_onCounter >= m_lfoDelay &&
212     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
213     {
214     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
215     m_mod2.AddPhase(e - s - 1);
216     }
217     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
218 hikarin 48 m_mod1.GetSamples(ref s_samples, s, e);
219 hikarin 37 if (VolumeMode == 0)
220 hikarin 79 m_vco.GetAmplitudeSamplesLinear(ref s_samples, s, e, m_ampLevel);
221 hikarin 37 else
222 hikarin 79 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, s, e, m_ampLevel);
223 hikarin 37 m_onCounter += e - s;
224     s = e;
225     } while (s < end);
226     }
227     }
228     else
229     {
230     if (!m_osc2connect)
231     {
232 hikarin 42 m_mod1.Frequency = Channel.FrequencyFromIndex(m_frequencyIndex);
233 hikarin 37 for (int i = start; i < end; i++)
234 hikarin 48 s_samples[i] = m_mod1.NextSampleOfs((int)(s_pipeArray[m_inPipe][i] * m_inSens));
235 hikarin 37 if (m_volumeMode == 0)
236 hikarin 79 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
237 hikarin 37 else
238 hikarin 79 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
239 hikarin 37 }
240     else
241     {
242     for (int i = start; i < end; i++)
243     {
244 hikarin 42 frequencyIndex = m_frequencyIndex;
245 hikarin 37 if (m_onCounter >= m_lfoDelay &&
246     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
247     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
248     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
249 hikarin 48 s_samples[i] = m_mod1.NextSampleOfs((int)(s_pipeArray[m_inPipe][i] * m_inSens));
250 hikarin 37 m_onCounter++;
251     }
252     }
253     }
254     double key = m_mod1.Frequency;
255 hikarin 48 m_formant.GetSamples(ref s_samples, start, end);
256 hikarin 37 m_filter.Envelope = m_vcf;
257     m_filter.Frequency = m_lpfFrequency;
258     m_filter.Amount = m_lpfAmount;
259     m_filter.Resonance = m_lpfResonance;
260     m_filter.Key = key;
261 hikarin 48 m_filter.GetSample(ref s_samples, start, end);
262 hikarin 37 switch (m_outMode)
263     {
264     case ChannelOutputMode.Default:
265     for (int i = start; i < end; i++)
266     {
267     int n = i << 1;
268 hikarin 48 double amplitude = s_samples[i];
269 hikarin 37 samples[n] += (amplitude * m_panLeft).ToShort();
270     samples[n + 1] += (amplitude * m_panRight).ToShort();
271     }
272     break;
273     case ChannelOutputMode.Overwrite:
274     for (int i = start; i < end; i++)
275 hikarin 48 s_pipeArray[m_outPipe][i] = s_samples[i];
276 hikarin 37 break;
277     case ChannelOutputMode.Add:
278     for (int i = start; i < end; i++)
279 hikarin 48 s_pipeArray[m_outPipe][i] += s_samples[i];
280 hikarin 37 break;
281     }
282     }
283     #endregion
284    
285     #region ������������������������������
286     private void SetModulatorFrequency()
287     {
288     m_frequencyIndex = m_noteIndex * PITCH_RESOLUTION + m_detune;
289     double freq = FrequencyFromIndex(m_frequencyIndex);
290     m_mod1.Frequency = FrequencyFromIndex(m_frequencyIndex);
291     }
292     #endregion
293    
294     #region ������������������������������
295     public Events.VCO ADSRForVCO
296     {
297     set
298     {
299     m_vco.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
300     value.Decay * (1.0 / VELOCITY_MAX2),
301     value.Sustain * (1.0 / VELOCITY_MAX2),
302     value.Release * (1.0 / VELOCITY_MAX2));
303     }
304     }
305    
306     public Events.VCF ADSRForVCF
307     {
308     set
309     {
310     m_vcf.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
311     value.Decay * (1.0 / VELOCITY_MAX2),
312     value.Sustain * (1.0 / VELOCITY_MAX2),
313     value.Release * (1.0 / VELOCITY_MAX2));
314     }
315     }
316    
317     public Events.Form Form
318     {
319     set
320     {
321     m_osc1.Form = value.Main;
322     m_mod1 = m_osc1.ModulatorFromForm(value.Main);
323     if (value.Main == OscillatorForm.GBWave)
324     {
325     GBWave gbwave = (GBWave)m_osc1.ModulatorFromForm(OscillatorForm.GBWave);
326     gbwave.WaveNo = (int)value.Sub;
327     }
328     }
329     }
330    
331     public Events.LPF LPF
332     {
333     set
334     {
335     FilterType sw = value.Switch;
336     if (sw >= FilterType.HPFQuality &&
337     sw <= FilterType.LPFQuality &&
338     !m_enableFilter)
339     {
340     m_enableFilter = true;
341     m_filter.Switch = sw;
342     }
343     m_lpfAmount = Math.Min(Math.Max(value.Amount, -VELOCITY_MAX2), VELOCITY_MAX2);
344     m_lpfAmount *= PITCH_RESOLUTION;
345     int frequencyIndex = value.Frequency;
346     frequencyIndex = Math.Min(Math.Max(frequencyIndex, 0), VELOCITY_MAX2);
347     m_lpfFrequency = frequencyIndex * PITCH_RESOLUTION;
348     m_lpfResonance = value.Resonance * (1.0 / VELOCITY_MAX2);
349     m_lpfResonance = Math.Min(Math.Max(m_lpfResonance, 0.0), 1.0);
350     }
351     }
352    
353     public Events.Input Input
354     {
355     set
356     {
357     m_inSens = (1 << (value.Sens - 1)) * (1.0 / 8.0) * Modulator.PHASE_LENGTH;
358     m_inPipe = value.Pipe;
359     }
360     }
361    
362     public Events.Output Output
363     {
364     set
365     {
366     m_outMode = value.Mode;
367 hikarin 48 m_outPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
368 hikarin 37 }
369     }
370    
371    
372     public int NoteIndex
373     {
374     set
375     {
376     m_noteIndex = value;
377     SetModulatorFrequency();
378     }
379     }
380    
381     public int Detune
382     {
383     set
384     {
385     m_detune = value;
386     SetModulatorFrequency();
387     }
388     }
389    
390     public double NoiseFrequency
391     {
392     set
393     {
394     Noise noise = (Noise)m_osc1.ModulatorFromForm(OscillatorForm.Noise);
395     noise.NoiseFrequency = 1.0 - value * (1.0 / VELOCITY_MAX);
396     }
397     }
398    
399     public int PWM
400     {
401     set
402     {
403     Pulse pulse;
404     if (m_osc1.Form != OscillatorForm.FCPulse)
405     {
406     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.Pulse);
407     pulse.PWM = value * (1.0 / 100.0);
408     }
409     else
410     {
411     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.FCPulse);
412     pulse.PWM = 0.125 * value;
413     }
414     }
415     }
416    
417     public int Pan
418     {
419     set
420     {
421     m_panRight = Math.Max((value - 1) * (0.25 / 63.0), 0.0);
422     m_panLeft = (2.0 * 0.25) - m_panRight;
423     }
424     }
425    
426     public FormantVowel FormantVowel
427     {
428     set
429     {
430     m_formant.Vowel = value;
431     }
432     }
433    
434     public int VolumeMode
435     {
436     private get;
437     set;
438     }
439 hikarin 79
440     public int Velocity
441     {
442     set
443     {
444     int expression = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
445     m_velocity = VolumeMode > 0 ? s_volumeMap[expression] : (double)(expression / VELOCITY_MAX2);
446     m_ampLevel = m_velocity * m_expression;
447     }
448     }
449    
450     public int Expression
451     {
452     set
453     {
454     int velocity = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
455     m_velocity = VolumeMode > 0 ? s_volumeMap[velocity] : (double)(velocity / VELOCITY_MAX2);
456     m_ampLevel = m_velocity * m_expression;
457     }
458     }
459 hikarin 37 #endregion
460    
461     #region ���������������������������
462 hikarin 48 private static bool s_initialized = false;
463     private static double[] s_frequencyMap = new double[VELOCITY_MAX * PITCH_RESOLUTION];
464     private static int s_frequencyLength = 0;
465     private static double[] s_volumeMap = new double[VELOCITY_MAX];
466     private static int s_volumeLength = 0;
467     private static double[] s_samples;
468     private static int s_sampleLength = 0;
469     private static double[][] s_pipeArray;
470     private static int s_pipeArrayNum = 0;
471     private static int s_lfoDelta = VELOCITY_MAX;
472 hikarin 37 private Envelope m_vco;
473     private Envelope m_vcf;
474     private IModulator m_mod1;
475     private Oscillator m_osc1;
476     private IModulator m_mod2;
477     private Oscillator m_osc2;
478     private int m_noteIndex;
479     private int m_detune;
480 hikarin 42 private int m_frequencyIndex;
481 hikarin 37 private bool m_osc2connect;
482     private double m_osc2sign;
483     private Filter m_filter;
484     private bool m_enableFilter;
485     private Formant m_formant;
486 hikarin 79 private double m_expression;
487 hikarin 37 private double m_velocity;
488 hikarin 79 private double m_ampLevel;
489 hikarin 37 private double m_panLeft;
490     private double m_panRight;
491     private int m_onCounter;
492     private int m_lfoDelay;
493     private double m_lfoDepth;
494     private int m_lfoEnd;
495     private double m_lpfAmount;
496     private double m_lpfFrequency;
497     private double m_lpfResonance;
498     private int m_volumeMode;
499     private double m_inSens;
500     private int m_inPipe;
501     private ChannelOutputMode m_outMode;
502     private int m_outPipe;
503     #endregion
504     }
505     }

Properties

Name Value
svn:keywords Id

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