Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Channel.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 85 - (hide annotations) (download)
Sat May 2 13:22:59 2009 UTC (14 years, 11 months ago) by hikarin
File size: 18984 byte(s)
[ocmml/slmml] * forgot to implement GetAmplitudeSamples* when with input, LFO
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 hikarin 80 public void GetSamples(ref double[] samples, int start, int delta, int max)
186 hikarin 37 {
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 hikarin 85 if (m_volumeMode == 0)
253     m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
254     else
255     m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
256 hikarin 37 }
257     }
258     double key = m_mod1.Frequency;
259 hikarin 48 m_formant.GetSamples(ref s_samples, start, end);
260 hikarin 37 m_filter.Envelope = m_vcf;
261     m_filter.Frequency = m_lpfFrequency;
262     m_filter.Amount = m_lpfAmount;
263     m_filter.Resonance = m_lpfResonance;
264     m_filter.Key = key;
265 hikarin 48 m_filter.GetSample(ref s_samples, start, end);
266 hikarin 37 switch (m_outMode)
267     {
268     case ChannelOutputMode.Default:
269     for (int i = start; i < end; i++)
270     {
271     int n = i << 1;
272 hikarin 48 double amplitude = s_samples[i];
273 hikarin 80 samples[n] += amplitude * m_panLeft;
274     samples[n + 1] += amplitude * m_panRight;
275 hikarin 37 }
276     break;
277     case ChannelOutputMode.Overwrite:
278     for (int i = start; i < end; i++)
279 hikarin 48 s_pipeArray[m_outPipe][i] = s_samples[i];
280 hikarin 37 break;
281     case ChannelOutputMode.Add:
282     for (int i = start; i < end; i++)
283 hikarin 48 s_pipeArray[m_outPipe][i] += s_samples[i];
284 hikarin 37 break;
285     }
286     }
287     #endregion
288    
289     #region ������������������������������
290     private void SetModulatorFrequency()
291     {
292     m_frequencyIndex = m_noteIndex * PITCH_RESOLUTION + m_detune;
293     double freq = FrequencyFromIndex(m_frequencyIndex);
294     m_mod1.Frequency = FrequencyFromIndex(m_frequencyIndex);
295     }
296     #endregion
297    
298     #region ������������������������������
299     public Events.VCO ADSRForVCO
300     {
301     set
302     {
303     m_vco.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
304     value.Decay * (1.0 / VELOCITY_MAX2),
305     value.Sustain * (1.0 / VELOCITY_MAX2),
306     value.Release * (1.0 / VELOCITY_MAX2));
307     }
308     }
309    
310     public Events.VCF ADSRForVCF
311     {
312     set
313     {
314     m_vcf.SetASDR(value.Attack * (1.0 / VELOCITY_MAX2),
315     value.Decay * (1.0 / VELOCITY_MAX2),
316     value.Sustain * (1.0 / VELOCITY_MAX2),
317     value.Release * (1.0 / VELOCITY_MAX2));
318     }
319     }
320    
321     public Events.Form Form
322     {
323     set
324     {
325     m_osc1.Form = value.Main;
326     m_mod1 = m_osc1.ModulatorFromForm(value.Main);
327     if (value.Main == OscillatorForm.GBWave)
328     {
329     GBWave gbwave = (GBWave)m_osc1.ModulatorFromForm(OscillatorForm.GBWave);
330     gbwave.WaveNo = (int)value.Sub;
331     }
332     }
333     }
334    
335     public Events.LPF LPF
336     {
337     set
338     {
339     FilterType sw = value.Switch;
340     if (sw >= FilterType.HPFQuality &&
341     sw <= FilterType.LPFQuality &&
342     !m_enableFilter)
343     {
344     m_enableFilter = true;
345     m_filter.Switch = sw;
346     }
347     m_lpfAmount = Math.Min(Math.Max(value.Amount, -VELOCITY_MAX2), VELOCITY_MAX2);
348     m_lpfAmount *= PITCH_RESOLUTION;
349     int frequencyIndex = value.Frequency;
350     frequencyIndex = Math.Min(Math.Max(frequencyIndex, 0), VELOCITY_MAX2);
351     m_lpfFrequency = frequencyIndex * PITCH_RESOLUTION;
352     m_lpfResonance = value.Resonance * (1.0 / VELOCITY_MAX2);
353     m_lpfResonance = Math.Min(Math.Max(m_lpfResonance, 0.0), 1.0);
354     }
355     }
356    
357     public Events.Input Input
358     {
359     set
360     {
361     m_inSens = (1 << (value.Sens - 1)) * (1.0 / 8.0) * Modulator.PHASE_LENGTH;
362     m_inPipe = value.Pipe;
363     }
364     }
365    
366     public Events.Output Output
367     {
368     set
369     {
370     m_outMode = value.Mode;
371 hikarin 48 m_outPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
372 hikarin 37 }
373     }
374    
375    
376     public int NoteIndex
377     {
378     set
379     {
380     m_noteIndex = value;
381     SetModulatorFrequency();
382     }
383     }
384    
385     public int Detune
386     {
387     set
388     {
389     m_detune = value;
390     SetModulatorFrequency();
391     }
392     }
393    
394     public double NoiseFrequency
395     {
396     set
397     {
398     Noise noise = (Noise)m_osc1.ModulatorFromForm(OscillatorForm.Noise);
399     noise.NoiseFrequency = 1.0 - value * (1.0 / VELOCITY_MAX);
400     }
401     }
402    
403     public int PWM
404     {
405     set
406     {
407     Pulse pulse;
408     if (m_osc1.Form != OscillatorForm.FCPulse)
409     {
410     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.Pulse);
411     pulse.PWM = value * (1.0 / 100.0);
412     }
413     else
414     {
415     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.FCPulse);
416     pulse.PWM = 0.125 * value;
417     }
418     }
419     }
420    
421     public int Pan
422     {
423     set
424     {
425     m_panRight = Math.Max((value - 1) * (0.25 / 63.0), 0.0);
426     m_panLeft = (2.0 * 0.25) - m_panRight;
427     }
428     }
429    
430     public FormantVowel FormantVowel
431     {
432     set
433     {
434     m_formant.Vowel = value;
435     }
436     }
437    
438     public int VolumeMode
439     {
440     private get;
441     set;
442     }
443 hikarin 79
444     public int Velocity
445     {
446     set
447     {
448 hikarin 81 int velocity = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
449     m_velocity = VolumeMode > 0 ? s_volumeMap[velocity] : (double)velocity / VELOCITY_MAX2;
450 hikarin 79 m_ampLevel = m_velocity * m_expression;
451     }
452     }
453    
454     public int Expression
455     {
456     set
457     {
458 hikarin 81 int expression = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
459     m_expression = VolumeMode > 0 ? s_volumeMap[expression] : (double)expression / VELOCITY_MAX2;
460 hikarin 79 m_ampLevel = m_velocity * m_expression;
461     }
462     }
463 hikarin 37 #endregion
464    
465     #region ���������������������������
466 hikarin 48 private static bool s_initialized = false;
467     private static double[] s_frequencyMap = new double[VELOCITY_MAX * PITCH_RESOLUTION];
468     private static int s_frequencyLength = 0;
469     private static double[] s_volumeMap = new double[VELOCITY_MAX];
470     private static int s_volumeLength = 0;
471     private static double[] s_samples;
472     private static int s_sampleLength = 0;
473     private static double[][] s_pipeArray;
474     private static int s_pipeArrayNum = 0;
475     private static int s_lfoDelta = VELOCITY_MAX;
476 hikarin 37 private Envelope m_vco;
477     private Envelope m_vcf;
478     private IModulator m_mod1;
479     private Oscillator m_osc1;
480     private IModulator m_mod2;
481     private Oscillator m_osc2;
482     private int m_noteIndex;
483     private int m_detune;
484 hikarin 42 private int m_frequencyIndex;
485 hikarin 37 private bool m_osc2connect;
486     private double m_osc2sign;
487     private Filter m_filter;
488     private bool m_enableFilter;
489     private Formant m_formant;
490 hikarin 79 private double m_expression;
491 hikarin 37 private double m_velocity;
492 hikarin 79 private double m_ampLevel;
493 hikarin 37 private double m_panLeft;
494     private double m_panRight;
495     private int m_onCounter;
496     private int m_lfoDelay;
497     private double m_lfoDepth;
498     private int m_lfoEnd;
499     private double m_lpfAmount;
500     private double m_lpfFrequency;
501     private double m_lpfResonance;
502     private int m_volumeMode;
503     private double m_inSens;
504     private int m_inPipe;
505     private ChannelOutputMode m_outMode;
506     private int m_outPipe;
507     #endregion
508     }
509     }

Properties

Name Value
svn:keywords Id

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