Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/slmml/Channel.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 138 - (show annotations) (download)
Sat Aug 22 13:31:42 2009 UTC (14 years, 6 months ago) by hikarin
File size: 22071 byte(s)
[ocmml/slmml] * implemented Ring Modulator and Sync
1 /*
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 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 const int VELOCITY_MAX = 128;
49 public const int VELOCITY_MAX2 = VELOCITY_MAX - 1;
50 #endregion
51
52 #region ������������������������������������
53 public static void Initialize(int nbSamples)
54 {
55 if (!s_initialized)
56 {
57 int i = 0;
58 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 }
70 }
71
72 public static void Release()
73 {
74 s_pipeArray = null;
75 s_samples = null;
76 }
77
78 public static void CreatePipes(int number)
79 {
80 s_pipeArray = new double[number][];
81 s_pipeArrayNum = number;
82 for (int i = 0; i < number; i++)
83 {
84 s_pipeArray[i] = new double[s_sampleLength];
85 for (int j = 0; j < s_sampleLength; j++)
86 s_pipeArray[i][j] = 0;
87 }
88 }
89
90 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 public static double FrequencyFromIndex(int index)
103 {
104 index = Math.Min(Math.Max(index, 0), Math.Max(s_frequencyLength, 1) - 1);
105 return s_frequencyMap[index];
106 }
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 m_volumeMode = 0;
123 m_expression = 0;
124 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 m_frequencyIndex = 0;
134 Pan = 64;
135 Expression = 127;
136 Velocity = 100;
137 Input = new Events.Input() { Sens = 0, Pipe = 0 };
138 Output = new Events.Output() { Mode = ChannelOutputMode.Default, Pipe = 0 };
139 Ring = new Events.Ring() { Sens = 0, Pipe = 0 };
140 Sync = new Events.Sync() { Mode = ChannelOutputMode.Default, Pipe = 0 };
141 }
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 Velocity = velocity;
156 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 FCDPCM fcDPCM = (FCDPCM)m_osc1.ModulatorFromForm(OscillatorForm.FCDPCM);
163 fcDPCM.DPCMFrequency = index;
164 }
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 OscillatorForm mainForm = lfo.Main - 1;
181 m_osc2.Form = mainForm;
182 m_mod2 = m_osc2.ModulatorFromForm(mainForm);
183 m_osc2sign = lfo.Reverse ? -1.0 : 1.0;
184 if (mainForm >= OscillatorForm.Max)
185 m_osc2connect = false;
186 if (mainForm == OscillatorForm.GBWave)
187 {
188 GBWave gbWave = (GBWave)m_osc2.ModulatorFromForm(OscillatorForm.GBWave);
189 gbWave.WaveIndex = (int)lfo.Sub;
190 }
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 public void GetSamples(ref double[] samples, int start, int delta, int max)
203 {
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 s_samples[i] = 0;
210 }
211 else if (m_inSens < 0.000001)
212 {
213 if (!m_osc2connect)
214 {
215 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 if (VolumeMode == 0)
228 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
229 else
230 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
231 }
232 else
233 {
234 int s = start, e = 0;
235 do
236 {
237 e = Math.Min(s + s_lfoDelta, end);
238 frequencyIndex = m_frequencyIndex;
239 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 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 if (VolumeMode == 0)
259 m_vco.GetAmplitudeSamplesLinear(ref s_samples, s, e, m_ampLevel);
260 else
261 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, s, e, m_ampLevel);
262 m_onCounter += e - s;
263 s = e;
264 } while (s < end);
265 }
266 }
267 else
268 {
269 if (!m_osc2connect)
270 {
271 m_mod1.Frequency = Channel.FrequencyFromIndex(m_frequencyIndex);
272 for (int i = start; i < end; i++)
273 s_samples[i] = m_mod1.NextSampleFrom((int)(s_pipeArray[m_inPipe][i] * m_inSens));
274 if (m_volumeMode == 0)
275 m_vco.GetAmplitudeSamplesLinear(ref s_samples, start, end, m_ampLevel);
276 else
277 m_vco.GetAmplitudeSamplesNonLinear(ref s_samples, start, end, m_ampLevel);
278 }
279 else
280 {
281 for (int i = start; i < end; i++)
282 {
283 frequencyIndex = m_frequencyIndex;
284 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 s_samples[i] = m_mod1.NextSampleFrom((int)(s_pipeArray[m_inPipe][i] * m_inSens));
289 m_onCounter++;
290 }
291 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 }
296 }
297 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 double key = m_mod1.Frequency;
303 m_formant.GetSamples(ref s_samples, start, end);
304 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 m_filter.GetSample(ref s_samples, start, end);
310 switch (m_outMode)
311 {
312 case ChannelOutputMode.Default:
313 for (int i = start; i < end; i++)
314 {
315 int n = i << 1;
316 double amplitude = s_samples[i];
317 samples[n] += amplitude * m_panLeft;
318 samples[n + 1] += amplitude * m_panRight;
319 }
320 break;
321 case ChannelOutputMode.Overwrite:
322 for (int i = start; i < end; i++)
323 s_pipeArray[m_outPipe][i] = s_samples[i];
324 break;
325 case ChannelOutputMode.Add:
326 for (int i = start; i < end; i++)
327 s_pipeArray[m_outPipe][i] += s_samples[i];
328 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 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 }
352 }
353
354 public Events.VCF ADSRForVCF
355 {
356 set
357 {
358 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 }
364 }
365
366 public Events.Form Form
367 {
368 set
369 {
370 OscillatorForm main = value.Main;
371 m_osc1.Form = main;
372 m_mod1 = m_osc1.ModulatorFromForm(main);
373 if (main == OscillatorForm.GBWave)
374 {
375 GBWave gbWave = (GBWave)m_osc1.ModulatorFromForm(OscillatorForm.GBWave);
376 gbWave.WaveIndex = (int)value.Sub;
377 }
378 if (main == OscillatorForm.FCDPCM)
379 {
380 FCDPCM fcDCPM = (FCDPCM)m_osc1.ModulatorFromForm(OscillatorForm.FCDPCM);
381 fcDCPM.WaveIndex = (int)value.Sub;
382 }
383 }
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 m_inPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
414 }
415 }
416
417 public Events.Output Output
418 {
419 set
420 {
421 m_outMode = value.Mode;
422 m_outPipe = Math.Min(Math.Max(value.Pipe, 0), s_pipeArrayNum);
423 }
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
494 public int Velocity
495 {
496 set
497 {
498 int velocity = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
499 m_velocity = VolumeMode > 0 ? s_volumeMap[velocity] : (double)velocity / VELOCITY_MAX2;
500 m_ampLevel = m_velocity * m_expression;
501 }
502 }
503
504 public int Expression
505 {
506 set
507 {
508 int expression = Math.Min(Math.Max(value, 0), VELOCITY_MAX2);
509 m_expression = VolumeMode > 0 ? s_volumeMap[expression] : (double)expression / VELOCITY_MAX2;
510 m_ampLevel = m_velocity * m_expression;
511 }
512 }
513
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 #endregion
532
533 #region ���������������������������
534 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 private static double[] s_samples = null;
540 private static int s_sampleLength = 0;
541 private static double[][] s_pipeArray = null;
542 private static int s_syncSourceLength = 0;
543 private static bool[][] s_syncSource;
544 private static int s_pipeArrayNum = 0;
545 private static int s_lfoDelta = VELOCITY_MAX;
546 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 private int m_frequencyIndex;
555 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 private double m_expression;
561 private double m_velocity;
562 private double m_ampLevel;
563 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 private double m_ringSens;
578 private int m_ringPipe;
579 private ChannelOutputMode m_syncMode;
580 private int m_syncPipe;
581 #endregion
582 }
583 }

Properties

Name Value
svn:keywords Id

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