Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/slmml/Channel.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 138 - (hide annotations) (download)
Sat Aug 22 13:31:42 2009 UTC (14 years, 7 months ago) by hikarin
File size: 22071 byte(s)
[ocmml/slmml] * implemented Ring Modulator and Sync
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 hikarin 107 public const int VELOCITY_MAX = 128;
49     public const int VELOCITY_MAX2 = VELOCITY_MAX - 1;
50 hikarin 37 #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 hikarin 138 public static void CreateSyncSources(int number)
91     {
92     s_syncSource = new bool[number][];
93     s_syncSourceLength = number;
94     for (int i = 0; i < number; i++)
95     {
96     s_syncSource[i] = new bool[s_sampleLength];
97     for (int j = 0; j < s_sampleLength; j++)
98     s_syncSource[i][j] = false;
99     }
100     }
101    
102 hikarin 37 public static double FrequencyFromIndex(int index)
103     {
104 hikarin 48 index = Math.Min(Math.Max(index, 0), Math.Max(s_frequencyLength, 1) - 1);
105     return s_frequencyMap[index];
106 hikarin 37 }
107     #endregion
108    
109     #region ���������������������������������������������������������
110     public Channel()
111     {
112     m_vco = new Envelope(0.0, 60.0 / VELOCITY_MAX2, 30.0 / VELOCITY_MAX2, 1.0 / VELOCITY_MAX2);
113     m_vcf = new Envelope(0.0, 30.0 / VELOCITY_MAX2, 0.0, 1.0);
114     m_osc1 = new Oscillator();
115     m_mod1 = m_osc1.CurrentModulator;
116     m_osc2 = new Oscillator() { Form = OscillatorForm.Sine };
117     m_osc2.MakeAsLFO();
118     m_mod2 = m_osc2.CurrentModulator;
119     m_filter = new Filter();
120     m_osc2connect = m_enableFilter = false;
121     m_formant = new Formant();
122 hikarin 79 m_volumeMode = 0;
123     m_expression = 0;
124 hikarin 37 m_onCounter = 0;
125     m_lfoDelay = 0;
126     m_lfoDepth = 0;
127     m_lfoEnd = 0;
128     m_lpfAmount = 0;
129     m_lpfFrequency = 0;
130     m_lpfResonance = 0;
131     NoteIndex = 0;
132     Detune = 0;
133 hikarin 42 m_frequencyIndex = 0;
134 hikarin 37 Pan = 64;
135 hikarin 79 Expression = 127;
136     Velocity = 100;
137 hikarin 37 Input = new Events.Input() { Sens = 0, Pipe = 0 };
138     Output = new Events.Output() { Mode = ChannelOutputMode.Default, Pipe = 0 };
139 hikarin 138 Ring = new Events.Ring() { Sens = 0, Pipe = 0 };
140     Sync = new Events.Sync() { Mode = ChannelOutputMode.Default, Pipe = 0 };
141 hikarin 37 }
142     #endregion
143    
144     #region ���������������������������
145     public void EnableNote(Events.NoteOn noteOn)
146     {
147     int index = noteOn.Index, velocity = noteOn.Velocity;
148     NoteIndex = index;
149     m_vco.Trigger(false);
150     m_vcf.Trigger(true);
151     m_mod1.ResetPhase();
152     m_mod2.ResetPhase();
153     m_filter.Reset();
154     m_onCounter = 0;
155 hikarin 100 Velocity = velocity;
156 hikarin 37 FCNoise fcNoise = (FCNoise)m_osc1.ModulatorFromForm(OscillatorForm.FCNoise);
157     fcNoise.NoiseFrequencyIndex = index;
158     GBLongNoise longNoise = (GBLongNoise)m_osc1.ModulatorFromForm(OscillatorForm.GBLongNoise);
159     longNoise.NoiseFrequencyIndex = index;
160     GBShortNoise shortNoise = (GBShortNoise)m_osc1.ModulatorFromForm(OscillatorForm.GBShortNoise);
161     shortNoise.NoiseFrequencyIndex = index;
162 hikarin 107 FCDPCM fcDPCM = (FCDPCM)m_osc1.ModulatorFromForm(OscillatorForm.FCDPCM);
163     fcDPCM.DPCMFrequency = index;
164 hikarin 37 }
165    
166     public void DisableNote()
167     {
168     m_vco.Release();
169     m_vcf.Release();
170     }
171    
172     public void Close()
173     {
174     DisableNote();
175     m_filter.Switch = FilterType.None;
176     }
177    
178     public void SetLFO(Events.LFO lfo, double frequency)
179     {
180 hikarin 95 OscillatorForm mainForm = lfo.Main - 1;
181     m_osc2.Form = mainForm;
182     m_mod2 = m_osc2.ModulatorFromForm(mainForm);
183 hikarin 37 m_osc2sign = lfo.Reverse ? -1.0 : 1.0;
184 hikarin 95 if (mainForm >= OscillatorForm.Max)
185 hikarin 37 m_osc2connect = false;
186 hikarin 95 if (mainForm == OscillatorForm.GBWave)
187 hikarin 37 {
188     GBWave gbWave = (GBWave)m_osc2.ModulatorFromForm(OscillatorForm.GBWave);
189 hikarin 107 gbWave.WaveIndex = (int)lfo.Sub;
190 hikarin 37 }
191     m_lfoDepth = lfo.Depth;
192     m_osc2connect = m_lfoDepth == 0 ? false : true;
193     m_mod2.Frequency = frequency;
194     m_mod2.ResetPhase();
195     Noise noise = (Noise)m_osc2.ModulatorFromForm(OscillatorForm.Noise);
196     noise.NoiseFrequency = frequency / Sample.RATE;
197     m_lfoDelay = lfo.Delay;
198     int time = lfo.Time;
199     m_lfoEnd = time > 0 ? m_lfoDelay + time : 0;
200     }
201    
202 hikarin 80 public void GetSamples(ref double[] samples, int start, int delta, int max)
203 hikarin 37 {
204     int end = Math.Min(start + delta, max);
205     int frequencyIndex = 0;
206     if (!m_vco.Playing)
207     {
208     for (int i = start; i < end; i++)
209 hikarin 48 s_samples[i] = 0;
210 hikarin 37 }
211     else if (m_inSens < 0.000001)
212     {
213     if (!m_osc2connect)
214     {
215 hikarin 138 switch (m_syncMode)
216     {
217     case ChannelOutputMode.Overwrite:
218     m_mod1.GetSamplesSyncOut(ref s_samples, ref s_syncSource[m_syncPipe], start, end);
219     break;
220     case ChannelOutputMode.Add:
221     m_mod1.GetSamplesSyncIn(ref s_samples, s_syncSource[m_syncPipe], start, end);
222     break;
223     default:
224     m_mod1.GetSamples(ref s_samples, start, end);
225     break;
226     }
227 hikarin 37 if (VolumeMode == 0)
228 hikarin 79 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
229 hikarin 37 else
230 hikarin 79 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
231 hikarin 37 }
232     else
233     {
234     int s = start, e = 0;
235     do
236     {
237 hikarin 48 e = Math.Min(s + s_lfoDelta, end);
238 hikarin 42 frequencyIndex = m_frequencyIndex;
239 hikarin 37 if (m_onCounter >= m_lfoDelay &&
240     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
241     {
242     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
243     m_mod2.AddPhase(e - s - 1);
244     }
245     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
246 hikarin 138 switch (m_syncMode)
247     {
248     case ChannelOutputMode.Overwrite:
249     m_mod1.GetSamplesSyncOut(ref s_samples, ref s_syncSource[m_syncPipe], s, e);
250     break;
251     case ChannelOutputMode.Add:
252     m_mod1.GetSamplesSyncIn(ref s_samples, s_syncSource[m_syncPipe], s, e);
253     break;
254     default:
255     m_mod1.GetSamples(ref s_samples, s, e);
256     break;
257     }
258 hikarin 37 if (VolumeMode == 0)
259 hikarin 79 m_vco.GetAmplitudeSamplesLinear(ref s_samples, s, e, m_ampLevel);
260 hikarin 37 else
261 hikarin 79 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, s, e, m_ampLevel);
262 hikarin 37 m_onCounter += e - s;
263     s = e;
264     } while (s < end);
265     }
266     }
267     else
268     {
269     if (!m_osc2connect)
270     {
271 hikarin 42 m_mod1.Frequency = Channel.FrequencyFromIndex(m_frequencyIndex);
272 hikarin 37 for (int i = start; i < end; i++)
273 hikarin 107 s_samples[i] = m_mod1.NextSampleFrom((int)(s_pipeArray[m_inPipe][i] * m_inSens));
274 hikarin 37 if (m_volumeMode == 0)
275 hikarin 79 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
276 hikarin 37 else
277 hikarin 79 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
278 hikarin 37 }
279     else
280     {
281     for (int i = start; i < end; i++)
282     {
283 hikarin 42 frequencyIndex = m_frequencyIndex;
284 hikarin 37 if (m_onCounter >= m_lfoDelay &&
285     (m_lfoEnd == 0 || m_onCounter < m_lfoEnd))
286     frequencyIndex += (int)(m_mod2.NextSample * m_osc2sign * m_lfoDepth);
287     m_mod1.Frequency = Channel.FrequencyFromIndex(frequencyIndex);
288 hikarin 107 s_samples[i] = m_mod1.NextSampleFrom((int)(s_pipeArray[m_inPipe][i] * m_inSens));
289 hikarin 37 m_onCounter++;
290     }
291 hikarin 85 if (m_volumeMode == 0)
292     m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
293     else
294     m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
295 hikarin 37 }
296     }
297 hikarin 138 if (m_ringSens >= 0.000001)
298     {
299     for (int i = start; i < end; i++)
300     s_samples[i] *= s_pipeArray[m_ringPipe][i] * m_ringSens;
301     }
302 hikarin 37 double key = m_mod1.Frequency;
303 hikarin 48 m_formant.GetSamples(ref s_samples, start, end);
304 hikarin 37 m_filter.Envelope = m_vcf;
305     m_filter.Frequency = m_lpfFrequency;
306     m_filter.Amount = m_lpfAmount;
307     m_filter.Resonance = m_lpfResonance;
308     m_filter.Key = key;
309 hikarin 48 m_filter.GetSample(ref s_samples, start, end);
310 hikarin 37 switch (m_outMode)
311     {
312     case ChannelOutputMode.Default:
313     for (int i = start; i < end; i++)
314     {
315     int n = i << 1;
316 hikarin 48 double amplitude = s_samples[i];
317 hikarin 80 samples[n] += amplitude * m_panLeft;
318     samples[n + 1] += amplitude * m_panRight;
319 hikarin 37 }
320     break;
321     case ChannelOutputMode.Overwrite:
322     for (int i = start; i < end; i++)
323 hikarin 48 s_pipeArray[m_outPipe][i] = s_samples[i];
324 hikarin 37 break;
325     case ChannelOutputMode.Add:
326     for (int i = start; i < end; i++)
327 hikarin 48 s_pipeArray[m_outPipe][i] += s_samples[i];
328 hikarin 37 break;
329     }
330     }
331     #endregion
332    
333     #region ������������������������������
334     private void SetModulatorFrequency()
335     {
336     m_frequencyIndex = m_noteIndex * PITCH_RESOLUTION + m_detune;
337     m_mod1.Frequency = FrequencyFromIndex(m_frequencyIndex);
338     }
339     #endregion
340    
341     #region ������������������������������
342     public Events.VCO ADSRForVCO
343     {
344     set
345     {
346 hikarin 100 double multiply = (1.0 / VELOCITY_MAX2);
347     m_vco.SetASDR(value.Attack * multiply,
348     value.Decay * multiply,
349     value.Sustain * multiply,
350     value.Release * multiply);
351 hikarin 37 }
352     }
353    
354     public Events.VCF ADSRForVCF
355     {
356     set
357     {
358 hikarin 100 double multiply = (1.0 / VELOCITY_MAX2);
359     m_vcf.SetASDR(value.Attack * multiply,
360     value.Decay * multiply,
361     value.Sustain * multiply,
362     value.Release * multiply);
363 hikarin 37 }
364     }
365    
366     public Events.Form Form
367     {
368     set
369     {
370 hikarin 107 OscillatorForm main = value.Main;
371     m_osc1.Form = main;
372     m_mod1 = m_osc1.ModulatorFromForm(main);
373     if (main == OscillatorForm.GBWave)
374 hikarin 37 {
375 hikarin 107 GBWave gbWave = (GBWave)m_osc1.ModulatorFromForm(OscillatorForm.GBWave);
376     gbWave.WaveIndex = (int)value.Sub;
377 hikarin 37 }
378 hikarin 107 if (main == OscillatorForm.FCDPCM)
379     {
380     FCDPCM fcDCPM = (FCDPCM)m_osc1.ModulatorFromForm(OscillatorForm.FCDPCM);
381     fcDCPM.WaveIndex = (int)value.Sub;
382     }
383 hikarin 37 }
384     }
385    
386     public Events.LPF LPF
387     {
388     set
389     {
390     FilterType sw = value.Switch;
391     if (sw >= FilterType.HPFQuality &&
392     sw <= FilterType.LPFQuality &&
393     !m_enableFilter)
394     {
395     m_enableFilter = true;
396     m_filter.Switch = sw;
397     }
398     m_lpfAmount = Math.Min(Math.Max(value.Amount, -VELOCITY_MAX2), VELOCITY_MAX2);
399     m_lpfAmount *= PITCH_RESOLUTION;
400     int frequencyIndex = value.Frequency;
401     frequencyIndex = Math.Min(Math.Max(frequencyIndex, 0), VELOCITY_MAX2);
402     m_lpfFrequency = frequencyIndex * PITCH_RESOLUTION;
403     m_lpfResonance = value.Resonance * (1.0 / VELOCITY_MAX2);
404     m_lpfResonance = Math.Min(Math.Max(m_lpfResonance, 0.0), 1.0);
405     }
406     }
407    
408     public Events.Input Input
409     {
410     set
411     {
412     m_inSens = (1 << (value.Sens - 1)) * (1.0 / 8.0) * Modulator.PHASE_LENGTH;
413 hikarin 138 m_inPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
414 hikarin 37 }
415     }
416    
417     public Events.Output Output
418     {
419     set
420     {
421     m_outMode = value.Mode;
422 hikarin 48 m_outPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
423 hikarin 37 }
424     }
425    
426     public int NoteIndex
427     {
428     set
429     {
430     m_noteIndex = value;
431     SetModulatorFrequency();
432     }
433     }
434    
435     public int Detune
436     {
437     set
438     {
439     m_detune = value;
440     SetModulatorFrequency();
441     }
442     }
443    
444     public double NoiseFrequency
445     {
446     set
447     {
448     Noise noise = (Noise)m_osc1.ModulatorFromForm(OscillatorForm.Noise);
449     noise.NoiseFrequency = 1.0 - value * (1.0 / VELOCITY_MAX);
450     }
451     }
452    
453     public int PWM
454     {
455     set
456     {
457     Pulse pulse;
458     if (m_osc1.Form != OscillatorForm.FCPulse)
459     {
460     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.Pulse);
461     pulse.PWM = value * (1.0 / 100.0);
462     }
463     else
464     {
465     pulse = (Pulse)m_osc1.ModulatorFromForm(OscillatorForm.FCPulse);
466     pulse.PWM = 0.125 * value;
467     }
468     }
469     }
470    
471     public int Pan
472     {
473     set
474     {
475     m_panRight = Math.Max((value - 1) * (0.25 / 63.0), 0.0);
476     m_panLeft = (2.0 * 0.25) - m_panRight;
477     }
478     }
479    
480     public FormantVowel FormantVowel
481     {
482     set
483     {
484     m_formant.Vowel = value;
485     }
486     }
487    
488     public int VolumeMode
489     {
490     private get;
491     set;
492     }
493 hikarin 79
494     public int Velocity
495     {
496     set
497     {
498 hikarin 81 int velocity = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
499     m_velocity = VolumeMode > 0 ? s_volumeMap[velocity] : (double)velocity / VELOCITY_MAX2;
500 hikarin 79 m_ampLevel = m_velocity * m_expression;
501     }
502     }
503    
504     public int Expression
505     {
506     set
507     {
508 hikarin 81 int expression = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
509     m_expression = VolumeMode > 0 ? s_volumeMap[expression] : (double)expression / VELOCITY_MAX2;
510 hikarin 79 m_ampLevel = m_velocity * m_expression;
511     }
512     }
513 hikarin 138
514     public Events.Ring Ring
515     {
516     set
517     {
518     m_ringSens = (1 << (value.Sens - 1)) / 8.0;
519     m_ringPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
520     }
521     }
522    
523     public Events.Sync Sync
524     {
525     set
526     {
527     m_syncMode = value.Mode;
528     m_syncPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
529     }
530     }
531 hikarin 37 #endregion
532    
533     #region ���������������������������
534 hikarin 48 private static bool s_initialized = false;
535     private static double[] s_frequencyMap = new double[VELOCITY_MAX * PITCH_RESOLUTION];
536     private static int s_frequencyLength = 0;
537     private static double[] s_volumeMap = new double[VELOCITY_MAX];
538     private static int s_volumeLength = 0;
539 hikarin 138 private static double[] s_samples = null;
540 hikarin 48 private static int s_sampleLength = 0;
541 hikarin 138 private static double[][] s_pipeArray = null;
542     private static int s_syncSourceLength = 0;
543     private static bool[][] s_syncSource;
544 hikarin 48 private static int s_pipeArrayNum = 0;
545     private static int s_lfoDelta = VELOCITY_MAX;
546 hikarin 37 private Envelope m_vco;
547     private Envelope m_vcf;
548     private IModulator m_mod1;
549     private Oscillator m_osc1;
550     private IModulator m_mod2;
551     private Oscillator m_osc2;
552     private int m_noteIndex;
553     private int m_detune;
554 hikarin 42 private int m_frequencyIndex;
555 hikarin 37 private bool m_osc2connect;
556     private double m_osc2sign;
557     private Filter m_filter;
558     private bool m_enableFilter;
559     private Formant m_formant;
560 hikarin 79 private double m_expression;
561 hikarin 37 private double m_velocity;
562 hikarin 79 private double m_ampLevel;
563 hikarin 37 private double m_panLeft;
564     private double m_panRight;
565     private int m_onCounter;
566     private int m_lfoDelay;
567     private double m_lfoDepth;
568     private int m_lfoEnd;
569     private double m_lpfAmount;
570     private double m_lpfFrequency;
571     private double m_lpfResonance;
572     private int m_volumeMode;
573     private double m_inSens;
574     private int m_inPipe;
575     private ChannelOutputMode m_outMode;
576     private int m_outPipe;
577 hikarin 138 private double m_ringSens;
578     private int m_ringPipe;
579     private ChannelOutputMode m_syncMode;
580     private int m_syncPipe;
581 hikarin 37 #endregion
582     }
583     }

Properties

Name Value
svn:keywords Id

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