Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Channel.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: 18075 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    
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     m_velocity = 100.0 / (VELOCITY_MAX - 1.0);
111     m_onCounter = 0;
112     m_lfoDelay = 0;
113     m_lfoDepth = 0;
114     m_lfoEnd = 0;
115     m_lpfAmount = 0;
116     m_lpfFrequency = 0;
117     m_lpfResonance = 0;
118     m_volumeMode = 0;
119     NoteIndex = 0;
120     Detune = 0;
121 hikarin 42 m_frequencyIndex = 0;
122 hikarin 37 Pan = 64;
123     Input = new Events.Input() { Sens = 0, Pipe = 0 };
124     Output = new Events.Output() { Mode = ChannelOutputMode.Default, Pipe = 0 };
125     }
126     #endregion
127    
128     #region ���������������������������
129     public void EnableNote(Events.NoteOn noteOn)
130     {
131     int index = noteOn.Index, velocity = noteOn.Velocity;
132     NoteIndex = index;
133     m_vco.Trigger(false);
134     m_vcf.Trigger(true);
135     m_mod1.ResetPhase();
136     m_mod2.ResetPhase();
137     m_filter.Reset();
138     velocity = Math.Min(Math.Max(velocity, 0), VELOCITY_MAX2);
139 hikarin 48 m_velocity = VolumeMode > 0 ? s_volumeMap[velocity] : (double)velocity / VELOCITY_MAX2;
140 hikarin 37 m_onCounter = 0;
141     FCNoise fcNoise = (FCNoise)m_osc1.ModulatorFromForm(OscillatorForm.FCNoise);
142     fcNoise.NoiseFrequencyIndex = index;
143     GBLongNoise longNoise = (GBLongNoise)m_osc1.ModulatorFromForm(OscillatorForm.GBLongNoise);
144     longNoise.NoiseFrequencyIndex = index;
145     GBShortNoise shortNoise = (GBShortNoise)m_osc1.ModulatorFromForm(OscillatorForm.GBShortNoise);
146     shortNoise.NoiseFrequencyIndex = index;
147     }
148    
149     public void DisableNote()
150     {
151     m_vco.Release();
152     m_vcf.Release();
153     }
154    
155     public void Close()
156     {
157     DisableNote();
158     m_filter.Switch = FilterType.None;
159     }
160    
161     public void SetLFO(Events.LFO lfo, double frequency)
162     {
163     m_osc2.Form = lfo.Main;
164     m_mod2 = m_osc2.ModulatorFromForm(lfo.Main);
165     m_osc2sign = lfo.Reverse ? -1.0 : 1.0;
166     if (lfo.Main >= OscillatorForm.Max)
167     m_osc2connect = false;
168     if (lfo.Main == OscillatorForm.GBWave)
169     {
170     GBWave gbWave = (GBWave)m_osc2.ModulatorFromForm(OscillatorForm.GBWave);
171     gbWave.WaveNo = (int)lfo.Sub;
172     }
173     m_lfoDepth = lfo.Depth;
174     m_osc2connect = m_lfoDepth == 0 ? false : true;
175     m_mod2.Frequency = frequency;
176     m_mod2.ResetPhase();
177     Noise noise = (Noise)m_osc2.ModulatorFromForm(OscillatorForm.Noise);
178     noise.NoiseFrequency = frequency / Sample.RATE;
179     m_lfoDelay = lfo.Delay;
180     int time = lfo.Time;
181     m_lfoEnd = time > 0 ? m_lfoDelay + time : 0;
182     }
183    
184     public void GetSamples(ref short[] samples, int start, int delta, int max)
185     {
186     int end = Math.Min(start + delta, max);
187     int frequencyIndex = 0;
188     if (!m_vco.Playing)
189     {
190     for (int i = start; i < end; i++)
191 hikarin 48 s_samples[i] = 0;
192 hikarin 37 }
193     else if (m_inSens < 0.000001)
194     {
195     if (!m_osc2connect)
196     {
197 hikarin 48 m_mod1.GetSamples(ref s_samples, start, end);
198 hikarin 37 if (VolumeMode == 0)
199 hikarin 48 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_velocity);
200 hikarin 37 else
201 hikarin 48 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_velocity);
202 hikarin 37 }
203     else
204     {
205     int s = start, e = 0;
206     do
207     {
208 hikarin 48 e = Math.Min(s + s_lfoDelta, end);
209 hikarin 42 frequencyIndex = m_frequencyIndex;
210 hikarin 37 if (m_onCounter >= m_lfoDelay &&
211     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
212     {
213     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
214     m_mod2.AddPhase(e - s - 1);
215     }
216     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
217 hikarin 48 m_mod1.GetSamples(ref s_samples, s, e);
218 hikarin 37 if (VolumeMode == 0)
219 hikarin 48 m_vco.GetAmplitudeSamplesLinear(ref s_samples, s, e, m_velocity);
220 hikarin 37 else
221 hikarin 48 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, s, e, m_velocity);
222 hikarin 37 m_onCounter += e - s;
223     s = e;
224     } while (s < end);
225     }
226     }
227     else
228     {
229     if (!m_osc2connect)
230     {
231 hikarin 42 m_mod1.Frequency = Channel.FrequencyFromIndex(m_frequencyIndex);
232 hikarin 37 for (int i = start; i < end; i++)
233 hikarin 48 s_samples[i] = m_mod1.NextSampleOfs((int)(s_pipeArray[m_inPipe][i] * m_inSens));
234 hikarin 37 if (m_volumeMode == 0)
235 hikarin 48 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_velocity);
236 hikarin 37 else
237 hikarin 48 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_velocity);
238 hikarin 37 }
239     else
240     {
241     for (int i = start; i < end; i++)
242     {
243 hikarin 42 frequencyIndex = m_frequencyIndex;
244 hikarin 37 if (m_onCounter >= m_lfoDelay &&
245     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
246     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
247     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
248 hikarin 48 s_samples[i] = m_mod1.NextSampleOfs((int)(s_pipeArray[m_inPipe][i] * m_inSens));
249 hikarin 37 m_onCounter++;
250     }
251     }
252     }
253     double key = m_mod1.Frequency;
254 hikarin 48 m_formant.GetSamples(ref s_samples, start, end);
255 hikarin 37 m_filter.Envelope = m_vcf;
256     m_filter.Frequency = m_lpfFrequency;
257     m_filter.Amount = m_lpfAmount;
258     m_filter.Resonance = m_lpfResonance;
259     m_filter.Key = key;
260 hikarin 48 m_filter.GetSample(ref s_samples, start, end);
261 hikarin 37 switch (m_outMode)
262     {
263     case ChannelOutputMode.Default:
264     for (int i = start; i < end; i++)
265     {
266     int n = i << 1;
267 hikarin 48 double amplitude = s_samples[i];
268 hikarin 37 samples[n] += (amplitude * m_panLeft).ToShort();
269     samples[n + 1] += (amplitude * m_panRight).ToShort();
270     }
271     break;
272     case ChannelOutputMode.Overwrite:
273     for (int i = start; i < end; i++)
274 hikarin 48 s_pipeArray[m_outPipe][i] = s_samples[i];
275 hikarin 37 break;
276     case ChannelOutputMode.Add:
277     for (int i = start; i < end; i++)
278 hikarin 48 s_pipeArray[m_outPipe][i] += s_samples[i];
279 hikarin 37 break;
280     }
281     }
282     #endregion
283    
284     #region ������������������������������
285     private void SetModulatorFrequency()
286     {
287     m_frequencyIndex = m_noteIndex * PITCH_RESOLUTION + m_detune;
288     double freq = FrequencyFromIndex(m_frequencyIndex);
289     m_mod1.Frequency = FrequencyFromIndex(m_frequencyIndex);
290     }
291     #endregion
292    
293     #region ������������������������������
294     public Events.VCO ADSRForVCO
295     {
296     set
297     {
298     m_vco.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
299     value.Decay * (1.0 / VELOCITY_MAX2),
300     value.Sustain * (1.0 / VELOCITY_MAX2),
301     value.Release * (1.0 / VELOCITY_MAX2));
302     }
303     }
304    
305     public Events.VCF ADSRForVCF
306     {
307     set
308     {
309     m_vcf.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
310     value.Decay * (1.0 / VELOCITY_MAX2),
311     value.Sustain * (1.0 / VELOCITY_MAX2),
312     value.Release * (1.0 / VELOCITY_MAX2));
313     }
314     }
315    
316     public Events.Form Form
317     {
318     set
319     {
320     m_osc1.Form = value.Main;
321     m_mod1 = m_osc1.ModulatorFromForm(value.Main);
322     if (value.Main == OscillatorForm.GBWave)
323     {
324     GBWave gbwave = (GBWave)m_osc1.ModulatorFromForm(OscillatorForm.GBWave);
325     gbwave.WaveNo = (int)value.Sub;
326     }
327     }
328     }
329    
330     public Events.LPF LPF
331     {
332     set
333     {
334     FilterType sw = value.Switch;
335     if (sw >= FilterType.HPFQuality &&
336     sw <= FilterType.LPFQuality &&
337     !m_enableFilter)
338     {
339     m_enableFilter = true;
340     m_filter.Switch = sw;
341     }
342     m_lpfAmount = Math.Min(Math.Max(value.Amount, -VELOCITY_MAX2), VELOCITY_MAX2);
343     m_lpfAmount *= PITCH_RESOLUTION;
344     int frequencyIndex = value.Frequency;
345     frequencyIndex = Math.Min(Math.Max(frequencyIndex, 0), VELOCITY_MAX2);
346     m_lpfFrequency = frequencyIndex * PITCH_RESOLUTION;
347     m_lpfResonance = value.Resonance * (1.0 / VELOCITY_MAX2);
348     m_lpfResonance = Math.Min(Math.Max(m_lpfResonance, 0.0), 1.0);
349     }
350     }
351    
352     public Events.Input Input
353     {
354     set
355     {
356     m_inSens = (1 << (value.Sens - 1)) * (1.0 / 8.0) * Modulator.PHASE_LENGTH;
357     m_inPipe = value.Pipe;
358     }
359     }
360    
361     public Events.Output Output
362     {
363     set
364     {
365     m_outMode = value.Mode;
366 hikarin 48 m_outPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
367 hikarin 37 }
368     }
369    
370    
371     public int NoteIndex
372     {
373     set
374     {
375     m_noteIndex = value;
376     SetModulatorFrequency();
377     }
378     }
379    
380     public int Detune
381     {
382     set
383     {
384     m_detune = value;
385     SetModulatorFrequency();
386     }
387     }
388    
389     public double NoiseFrequency
390     {
391     set
392     {
393     Noise noise = (Noise)m_osc1.ModulatorFromForm(OscillatorForm.Noise);
394     noise.NoiseFrequency = 1.0 - value * (1.0 / VELOCITY_MAX);
395     }
396     }
397    
398     public int PWM
399     {
400     set
401     {
402     Pulse pulse;
403     if (m_osc1.Form != OscillatorForm.FCPulse)
404     {
405     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.Pulse);
406     pulse.PWM = value * (1.0 / 100.0);
407     }
408     else
409     {
410     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.FCPulse);
411     pulse.PWM = 0.125 * value;
412     }
413     }
414     }
415    
416     public int Pan
417     {
418     set
419     {
420     m_panRight = Math.Max((value - 1) * (0.25 / 63.0), 0.0);
421     m_panLeft = (2.0 * 0.25) - m_panRight;
422     }
423     }
424    
425     public FormantVowel FormantVowel
426     {
427     set
428     {
429     m_formant.Vowel = value;
430     }
431     }
432    
433     public int VolumeMode
434     {
435     private get;
436     set;
437     }
438     #endregion
439    
440     #region ���������������������������
441 hikarin 48 private static bool s_initialized = false;
442     private static double[] s_frequencyMap = new double[VELOCITY_MAX * PITCH_RESOLUTION];
443     private static int s_frequencyLength = 0;
444     private static double[] s_volumeMap = new double[VELOCITY_MAX];
445     private static int s_volumeLength = 0;
446     private static double[] s_samples;
447     private static int s_sampleLength = 0;
448     private static double[][] s_pipeArray;
449     private static int s_pipeArrayNum = 0;
450     private static int s_lfoDelta = VELOCITY_MAX;
451 hikarin 37 private Envelope m_vco;
452     private Envelope m_vcf;
453     private IModulator m_mod1;
454     private Oscillator m_osc1;
455     private IModulator m_mod2;
456     private Oscillator m_osc2;
457     private int m_noteIndex;
458     private int m_detune;
459 hikarin 42 private int m_frequencyIndex;
460 hikarin 37 private bool m_osc2connect;
461     private double m_osc2sign;
462     private Filter m_filter;
463     private bool m_enableFilter;
464     private Formant m_formant;
465     private double m_velocity;
466     private double m_panLeft;
467     private double m_panRight;
468     private int m_onCounter;
469     private int m_lfoDelay;
470     private double m_lfoDepth;
471     private int m_lfoEnd;
472     private double m_lpfAmount;
473     private double m_lpfFrequency;
474     private double m_lpfResonance;
475     private int m_volumeMode;
476     private double m_inSens;
477     private int m_inPipe;
478     private ChannelOutputMode m_outMode;
479     private int m_outPipe;
480     #endregion
481     }
482     }

Properties

Name Value
svn:keywords Id

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