Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/slmml/Track.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: 29308 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 System.Collections.Generic;
34 using System.Windows;
35
36 namespace SlMML
37 {
38 public class Track
39 {
40 #region ���������������
41 public const int TEMPO_TRACK = 0;
42 public const int FIRST_TRACK = 1;
43 #endregion
44
45 #region ���������������������������������������������������������
46 /// <summary>
47 /// ������������������������������������������������
48 /// </summary>
49 public Track()
50 {
51 End = false;
52 m_channel = new Channel();
53 m_events = new List<Events.Event>(32);
54 m_index = 0;
55 m_delta = 0;
56 GlobalTick = 0;
57 m_needle = 0.0;
58 Duration = new Duration(TimeSpan.FromMilliseconds(0));
59 BPM = DEFAULT_BPM;
60 RecordGate(15.0 / 16.0);
61 RecordGate(0);
62 }
63 #endregion
64
65 #region ���������������������������
66 /// <summary>
67 /// ������������������������������������������������������
68 /// </summary>
69 /// <param name="samples">������������������������</param>
70 /// <param name="start">���������������������������������</param>
71 /// <param name="end">���������������������������������</param>
72 /// <param name="update">������������������������������������������������</param>
73 public void GetSamples(ref double[] samples, int start, int end, bool update)
74 {
75 if (End)
76 return;
77 int eventCount = m_events.Count, i = start;
78 while (i < end)
79 {
80 bool loop = false;
81 double delta = 0;
82 do
83 {
84 loop = false;
85 if (m_index < eventCount)
86 {
87 Events.Event e = m_events[m_index];
88 delta = e.Delta * m_spt;
89 if (m_needle >= delta)
90 {
91 loop = true;
92 if (e is Events.NoteOn)
93 m_channel.EnableNote((Events.NoteOn)e);
94 else if (e is Events.NoteOff)
95 m_channel.DisableNote();
96 else if (e is Events.Note)
97 m_channel.NoteIndex = ((Events.Note)(e)).Index;
98 else if (e is Events.Tempo)
99 BPM = ((Events.Tempo)e).Value;
100 else if (e is Events.Form)
101 m_channel.Form = (Events.Form)e;
102 else if (e is Events.VCO)
103 m_channel.ADSRForVCO = (Events.VCO)e;
104 else if (e is Events.VCF)
105 m_channel.ADSRForVCF = (Events.VCF)e;
106 else if (e is Events.NoiseFrequency)
107 m_channel.NoiseFrequency = ((Events.NoiseFrequency)e).Value;
108 else if (e is Events.PWM)
109 m_channel.PWM = ((Events.PWM)e).Value;
110 else if (e is Events.Pan)
111 m_channel.Pan = ((Events.Pan)e).Value;
112 else if (e is Events.Vowel)
113 m_channel.FormantVowel = ((Events.Vowel)e).Value;
114 else if (e is Events.Detune)
115 m_channel.Detune = ((Events.Detune)e).Value;
116 else if (e is Events.LFO)
117 {
118 Events.LFO lfo = (Events.LFO)e;
119 double width = lfo.Width * m_spt;
120 lfo.Delay = (int)(lfo.Delay * m_spt);
121 lfo.Time = (int)(lfo.Time * width);
122 m_channel.SetLFO(lfo, Sample.RATE / width);
123 }
124 else if (e is Events.LPF)
125 m_channel.LPF = (Events.LPF)e;
126 else if (e is Events.VolumeMode)
127 m_channel.VolumeMode = ((Events.VolumeMode)e).Value;
128 else if (e is Events.Input)
129 m_channel.Input = (Events.Input)e;
130 else if (e is Events.Output)
131 m_channel.Output = (Events.Output)e;
132 else if (e is Events.Expression)
133 m_channel.Expression = ((Events.Expression)e).Value;
134 else if (e is Events.Ring)
135 m_channel.Ring = (Events.Ring)e;
136 else if (e is Events.Sync)
137 m_channel.Sync = (Events.Sync)e;
138 else if (e is Events.Close)
139 m_channel.Close();
140 else if (e is Events.Eot)
141 End = true;
142 m_needle -= delta;
143 m_index++;
144 }
145 }
146 }
147 while (loop);
148 int di = 0;
149 if (m_index < eventCount)
150 {
151 Events.Event e = m_events[m_index];
152 delta = e.Delta * m_spt;
153 di = (int)Math.Ceiling(delta - m_needle);
154 if (i + di >= end)
155 di = end - i;
156 m_needle += di;
157 if (update)
158 m_channel.GetSamples(ref samples, i, di, end);
159 i += di;
160 }
161 else
162 break;
163 }
164 }
165
166 public void Seek()
167 {
168 GlobalTick = 0;
169 }
170
171 public void Seek(int delta)
172 {
173 m_delta += delta;
174 GlobalTick += (uint)delta;
175 }
176
177 /// <summary>
178 /// ������������������������
179 /// </summary>
180 /// <param name="index">���������������</param>
181 /// <param name="length">������������������</param>
182 /// <param name="velocity">������������������������</param>
183 /// <param name="keyOn">���������������������������</param>
184 /// <param name="keyOff">���������������������������</param>
185 public void RecordNote(int index, int length, int velocity, bool keyOn, bool keyOff)
186 {
187 Events.Event e;
188 if (keyOn)
189 e = new Events.NoteOn() { Index = index, Velocity = velocity };
190 else
191 e = new Events.Note() { Index = index };
192 SetDeltaAndAddEvent(e);
193 if (keyOff)
194 {
195 int gate = Math.Max((int)(length * m_gate - m_gate2), 0);
196 Seek(gate);
197 e = new Events.NoteOff() { Index = index, Velocity = velocity };
198 SetDeltaAndAddEvent(e);
199 Seek(length - gate);
200 }
201 else
202 Seek(length);
203 }
204
205 /// <summary>
206 /// ������������������������
207 /// </summary>
208 /// <param name="length">������</param>
209 public void RecordRest(int length)
210 {
211 Seek(length);
212 }
213
214 /// <summary>
215 /// ������������������������
216 /// </summary>
217 /// <param name="msec">������(���������������)</param>
218 public void RecordRest(uint msec)
219 {
220 int length = (int)(msec * Sample.RATE / (m_spt * 1000));
221 Seek(length);
222 }
223
224 /// <summary>
225 /// ���������������������������������
226 /// </summary>
227 /// <param name="volume">������������������</param>
228 public void RecordVolume(int volume)
229 {
230 Events.Volume e = new Events.Volume() { Value = volume };
231 SetDeltaAndAddEvent(e);
232 }
233
234 /// <summary>
235 /// BPM������������������
236 /// </summary>
237 /// <param name="tempo">BPM���</param>
238 /// <param name="globalTick">������������������</param>
239 public void RecordTempo(int tempo, uint globalTick)
240 {
241 Events.Tempo e = new Events.Tempo() { Value = tempo };
242 SetDelta(e);
243 RecordGlobalTick(globalTick, e);
244 }
245
246 /// <summary>
247 /// ������������������������������������
248 /// </summary>
249 public void RecordEOT()
250 {
251 Events.Eot e = new Events.Eot() { Delta = m_delta };
252 SetDeltaAndAddEvent(e);
253 }
254
255 public void RecordGate(double gate)
256 {
257 m_gate = gate;
258 }
259
260 public void RecordGate(int gate)
261 {
262 m_gate2 = Math.Max(gate, 0);
263 }
264
265 /// <summary>
266 /// ������������������������������������
267 /// </summary>
268 /// <param name="form">���������������������������</param>
269 /// <param name="subform">���������������������������������</param>
270 public void RecordForm(OscillatorForm form, OscillatorForm subform)
271 {
272 Events.Form e = new Events.Form() { Main = form, Sub = subform };
273 SetDeltaAndAddEvent(e);
274 }
275
276 public void RecordNoiseFrequency(int frequency)
277 {
278 Events.NoiseFrequency e = new Events.NoiseFrequency() { Value = frequency };
279 SetDeltaAndAddEvent(e);
280 }
281
282 /// <summary>
283 /// PWM (Pulse Width Modulation)������������������
284 /// </summary>
285 /// <param name="pwm">PWM������</param>
286 public void RecordPWM(int pwm)
287 {
288 Events.PWM e = new Events.PWM() { Value = pwm };
289 SetDeltaAndAddEvent(e);
290 }
291
292 /// <summary>
293 /// ������������������������
294 /// </summary>
295 /// <param name="pan">������������</param>
296 public void RecordPan(int pan)
297 {
298 Events.Pan e = new Events.Pan() { Value = pan };
299 SetDeltaAndAddEvent(e);
300 }
301
302 /// <summary>
303 /// ���������������������
304 /// </summary>
305 /// <param name="vowel">������������</param>
306 public void RecordFormantVowel(FormantVowel vowel)
307 {
308 Events.Vowel e = new Events.Vowel() { Value = vowel };
309 SetDeltaAndAddEvent(e);
310 }
311
312 /// <summary>
313 /// ���������������������������������
314 /// </summary>
315 /// <param name="detune">���������������������</param>
316 public void RecordDetune(int detune)
317 {
318 Events.Detune e = new Events.Detune() { Value = detune };
319 SetDeltaAndAddEvent(e);
320 }
321
322 /// <summary>
323 /// LFO (Low Frequency Oscillator)������������������
324 /// </summary>
325 /// <param name="form">���������������������������</param>
326 /// <param name="subform">���������������������������������</param>
327 /// <param name="depth">������</param>
328 /// <param name="width">������</param>
329 /// <param name="delay">���������</param>
330 /// <param name="time">������</param>
331 /// <param name="reverse">���������������������������������������������������������</param>
332 public void RecordLFO(OscillatorForm form, OscillatorForm subform, int depth, int width, int delay, int time, bool reverse)
333 {
334 Events.LFO e = new Events.LFO()
335 {
336 Main = form,
337 Sub = subform,
338 Depth = depth,
339 Width = width,
340 Delay = delay,
341 Time = time,
342 Reverse = reverse
343 };
344 SetDeltaAndAddEvent(e);
345 }
346
347 /// <summary>
348 /// LPF (Low Pass Filter)������������������
349 /// </summary>
350 /// <param name="sw">������������</param>
351 /// <param name="amount">���</param>
352 /// <param name="frequency">���������</param>
353 /// <param name="resonance">���������</param>
354 public void RecordLPF(FilterType sw, int amount, int frequency, int resonance)
355 {
356 Events.LPF e = new Events.LPF()
357 {
358 Switch = sw,
359 Amount = amount,
360 Frequency = frequency,
361 Resonance = resonance
362 };
363 SetDeltaAndAddEvent(e);
364 }
365
366 /// <summary>
367 /// ������������������������������������������
368 /// </summary>
369 /// <param name="mode">������������������������</param>
370 public void RecordVolumeMode(int mode)
371 {
372 Events.VolumeMode e = new Events.VolumeMode() { Value = mode };
373 SetDeltaAndAddEvent(e);
374 }
375
376 /// <summary>
377 /// ������������������������
378 /// </summary>
379 /// <param name="inSens"></param>
380 /// <param name="pipe"></param>
381 public void RecordInput(int inSens, int pipe)
382 {
383 Events.Input e = new Events.Input() { Sens = inSens, Pipe = pipe };
384 SetDeltaAndAddEvent(e);
385 }
386
387 /// <summary>
388 /// ������������������������
389 /// </summary>
390 /// <param name="mode"></param>
391 /// <param name="pipe"></param>
392 public void RecordOutput(ChannelOutputMode mode, int pipe)
393 {
394 Events.Output e = new Events.Output() { Mode = mode, Pipe = pipe };
395 SetDeltaAndAddEvent(e);
396 }
397
398 /// <summary>
399 /// ���������������������������������������������
400 /// </summary>
401 /// <param name="expression">���������������������������������</param>
402 public void RecordExpression(int expression)
403 {
404 Events.Expression e = new Events.Expression() { Value = expression };
405 SetDeltaAndAddEvent(e);
406 }
407
408 /// <summary>
409 /// ���������������������������
410 /// </summary>
411 /// <param name="inSens"></param>
412 /// <param name="pipe"></param>
413 public void RecordRing(int inSens, int pipe)
414 {
415 Events.Ring e = new Events.Ring() { Sens = inSens, Pipe = pipe };
416 SetDeltaAndAddEvent(e);
417 }
418
419 /// <summary>
420 /// ������������������������
421 /// </summary>
422 /// <param name="mode"></param>
423 /// <param name="pipe"></param>
424 public void RecordSync(ChannelOutputMode mode, int pipe)
425 {
426 Events.Sync e = new Events.Sync() { Mode = mode, Pipe = pipe };
427 SetDeltaAndAddEvent(e);
428 }
429
430 /// <summary>
431 /// ���������������������������������
432 /// </summary>
433 public void RecordClose()
434 {
435 Events.Close e = new Events.Close();
436 SetDeltaAndAddEvent(e);
437 }
438
439 /// <summary>
440 /// ADSR (Attack, Decay, Sustain, Release)������������������
441 /// </summary>
442 /// <param name="attack">���������������������</param>
443 /// <param name="decay">������������</param>
444 /// <param name="sustain">���������������������������</param>
445 /// <param name="release">������������</param>
446 /// <param name="isVCO">VCO (Voltage Control Oscillator)���������������������</param>
447 public void RecordEnvelopeADSR(int attack, int decay, int sustain, int release, bool isVCO)
448 {
449 Events.Event e;
450 if (isVCO)
451 e = new Events.VCO()
452 {
453 Delta = m_delta,
454 Attack = attack,
455 Decay = decay,
456 Sustain = sustain,
457 Release = release
458 };
459 else
460 e = new Events.VCF()
461 {
462 Delta = m_delta,
463 Attack = attack,
464 Decay = decay,
465 Sustain = sustain,
466 Release = release
467 };
468 SetDeltaAndAddEvent(e);
469 }
470
471 /// <summary>
472 /// ������������������������������������������������������������
473 /// </summary>
474 /// <remarks>
475 /// ���������������������������������������������������������������3���������������������
476 /// </remarks>
477 /// <param name="tracks">���������������������</param>
478 public void ConductTracks(IList<Track> tracks)
479 {
480 int ni = m_events.Count;
481 int nj = tracks.Count;
482 uint globalSample = 0, globalTick = 0;
483 double spt = CalculateSPT(DEFAULT_BPM);
484 for (int i = 0; i < ni; i++)
485 {
486 Events.Event e = m_events[i];
487 uint delta = (uint)e.Delta;
488 globalTick += delta;
489 globalSample += (uint)(delta * spt);
490 Events.Tempo tempo = e as Events.Tempo;
491 if (tempo != null)
492 {
493 int tempoValue = tempo.Value;
494 for (int j = FIRST_TRACK; j < nj; j++)
495 {
496 Track track = tracks[j];
497 track.RecordTempo(tempoValue, globalTick);
498 spt = CalculateSPT(tempoValue);
499 }
500 }
501 }
502 uint maxGlobalTick = 0;
503 for (int j = FIRST_TRACK; j < nj; j++)
504 {
505 Track track = tracks[j];
506 uint trackGlobalTick = track.GlobalTick;
507 if (maxGlobalTick < trackGlobalTick)
508 maxGlobalTick = trackGlobalTick;
509 }
510 Events.Close close = new Events.Close();
511 RecordGlobalTick(maxGlobalTick, close);
512 globalSample += (uint)((maxGlobalTick - globalTick) * spt);
513 RecordRest((uint)3000);
514 RecordEOT();
515 globalSample += (uint)(3 * Sample.RATE);
516 Duration = new Duration(TimeSpan.FromMilliseconds(globalSample * (1000.0 / Sample.RATE)));
517 }
518 #endregion
519
520 #region ������������������������������
521 private void RecordGlobalTick(uint globalTick, Events.Event e)
522 {
523 int eventCount = m_events.Count;
524 uint preGlobalTick = 0;
525 for (int i = 0; i < eventCount; i++)
526 {
527 Events.Event ev = m_events[i];
528 uint nextTick = (uint)(preGlobalTick + ev.Delta);
529 if (nextTick >= globalTick)
530 {
531 ev.Delta = (int)(nextTick - globalTick);
532 e.Delta = (int)(globalTick - preGlobalTick);
533 m_events.Insert(i, e);
534 return;
535 }
536 preGlobalTick = nextTick;
537 }
538 e.Delta = (int)(globalTick - preGlobalTick);
539 AddEvent(e);
540 }
541
542 private void SetDeltaAndAddEvent(Events.Event e)
543 {
544 SetDelta(e);
545 AddEvent(e);
546 }
547
548 private void SetDelta(Events.Event e)
549 {
550 e.Delta = m_delta;
551 m_delta = 0;
552 }
553
554 private void AddEvent(Events.Event e)
555 {
556 m_events.Add(e);
557 }
558
559 private double CalculateSPT(double bpm)
560 {
561 return Sample.RATE / (bpm * 96.0 / 60.0);
562 }
563 #if DEBUG
564 internal List<Dictionary<string, string>> Dump()
565 {
566 List<Dictionary<string, string>> r = new List<Dictionary<string, string>>();
567 foreach (Events.Event e in m_events)
568 {
569 Dictionary<string, string> data = new Dictionary<string, string>();
570 data["status"] = e.GetType().Name;
571 if (e is Events.NoteOn)
572 {
573 Events.NoteOn noteOn = (Events.NoteOn)e;
574 data["index"] = noteOn.Index.ToString();
575 data["velocity"] = noteOn.Velocity.ToString();
576 }
577 else if (e is Events.Note)
578 data["index"] = ((Events.Note)(e)).Index.ToString();
579 else if (e is Events.Tempo)
580 data["bpm"] = ((Events.Tempo)e).Value.ToString();
581 else if (e is Events.Form)
582 {
583 Events.Form form = (Events.Form)e;
584 data["form"] = ((int)form.Main).ToString();
585 data["subform"] = ((int)form.Sub).ToString();
586 }
587 else if (e is Events.VCO)
588 {
589 Events.VCO vco = (Events.VCO)e;
590 data["attack"] = vco.Attack.ToString();
591 data["decay"] = vco.Decay.ToString();
592 r.Add(data);
593 data = new Dictionary<string, string>();
594 data["status"] = "VCO";
595 data["sustain"] = vco.Sustain.ToString();
596 data["release"] = vco.Release.ToString();
597 }
598 else if (e is Events.VCF)
599 {
600 Events.VCF vcf = (Events.VCF)e;
601 data["attack"] = vcf.Attack.ToString();
602 data["decay"] = vcf.Decay.ToString();
603 r.Add(data);
604 data = new Dictionary<string, string>();
605 data["status"] = "VCF";
606 data["sustain"] = vcf.Sustain.ToString();
607 data["release"] = vcf.Release.ToString();
608 }
609 else if (e is Events.NoiseFrequency)
610 data["frequency"] = ((Events.NoiseFrequency)e).Value.ToString();
611 else if (e is Events.PWM)
612 data["pwm"] = ((Events.PWM)e).Value.ToString();
613 else if (e is Events.Pan)
614 data["pan"] = ((Events.Pan)e).Value.ToString();
615 else if (e is Events.Vowel)
616 data["formant"] = ((int)((Events.Vowel)e).Value).ToString();
617 else if (e is Events.Detune)
618 data["detune"] = ((Events.Detune)e).Value.ToString();
619 else if (e is Events.LFO)
620 {
621 Events.LFO lfo = (Events.LFO)e;
622 int rv = lfo.Reverse ? -1 : 1;
623 data["form"] = ((int)lfo.Main * rv).ToString();
624 data["subform"] = ((int)lfo.Sub).ToString();
625 r.Add(data);
626 double width = lfo.Width * m_spt;
627 data = new Dictionary<string, string>();
628 data["status"] = "LFO";
629 data["depth"] = lfo.Depth.ToString();
630 //data["width"] = (Sample.RATE / width).ToString();
631 r.Add(data);
632 data = new Dictionary<string, string>();
633 data["status"] = "LFO";
634 data["delay"] = ((lfo.Delay * m_spt)).ToString();
635 //data["time"] = ((lfo.Time * lfo.Width)).ToString();
636 }
637 else if (e is Events.LPF)
638 {
639 Events.LPF lpf = (Events.LPF)e;
640 data["switch"] = ((int)lpf.Switch).ToString();
641 data["amount"] = lpf.Amount.ToString();
642 r.Add(data);
643 data = new Dictionary<string, string>();
644 data["status"] = "LPF";
645 data["frequency"] = lpf.Frequency.ToString();
646 data["resonance"] = lpf.Resonance.ToString();
647 }
648 else if (e is Events.VolumeMode)
649 data["volumeMode"] = ((Events.VolumeMode)e).Value.ToString();
650 else if (e is Events.Input)
651 {
652 Events.Input input = (Events.Input)e;
653 data["sens"] = input.Sens.ToString();
654 data["pipe"] = input.Pipe.ToString();
655 }
656 else if (e is Events.Output)
657 {
658 Events.Output output = (Events.Output)e;
659 data["mode"] = ((int)output.Mode).ToString();
660 data["pipe"] = output.Pipe.ToString();
661 }
662 else if (e is Events.Expression)
663 data["expression"] = ((Events.Expression)e).Value.ToString();
664 else if (e is Events.Ring)
665 {
666 Events.Ring ring = (Events.Ring)e;
667 data["sens"] = ring.Sens.ToString();
668 data["pipe"] = ring.Pipe.ToString();
669 }
670 else if (e is Events.Output)
671 {
672 Events.Sync sync = (Events.Sync)e;
673 data["mode"] = ((int)sync.Mode).ToString();
674 data["pipe"] = sync.Pipe.ToString();
675 }
676 r.Add(data);
677 }
678 return r;
679 }
680 #endif
681 #endregion
682
683 #region ������������������������������
684 /// <summary>
685 /// ������������������������������������������������������������������������
686 /// </summary>
687 public bool End
688 {
689 get;
690 private set;
691 }
692
693 public uint GlobalTick
694 {
695 get;
696 private set;
697 }
698
699 /// <summary>
700 /// ���������������������������������������������
701 /// </summary>
702 public Duration Duration
703 {
704 get;
705 private set;
706 }
707
708 /// <summary>
709 /// BPM (Beats Per Minute) ������������������
710 /// </summary>
711 public double BPM
712 {
713 get
714 {
715 return m_bpm;
716 }
717 set
718 {
719 m_bpm = value;
720 m_spt = CalculateSPT(value);
721 }
722 }
723
724 /// <summary>
725 /// ���������������������������������������������������
726 /// </summary>
727 public int EventCount
728 {
729 get
730 {
731 return m_events.Count;
732 }
733 }
734
735 public Dictionary<int,int> DeltasToSeek
736 {
737 get
738 {
739 Dictionary<int, int> r = new Dictionary<int, int>();
740 int delta = 0, i = 0;
741 foreach (Events.Event e in m_events)
742 {
743 r[delta] = i;
744 delta += e.Delta;
745 i++;
746 }
747 return r;
748 }
749 }
750 #endregion
751
752 #region ���������������������������
753 public static readonly int DEFAULT_BPM = 120;
754 private Channel m_channel;
755 private List<Events.Event> m_events;
756 private int m_index;
757 private int m_delta;
758 private double m_bpm;
759 private double m_spt;
760 private double m_needle;
761 private double m_gate;
762 private double m_gate2;
763 #endregion
764 }
765 }

Properties

Name Value
svn:keywords Id

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