public void SendEvent(MidiEvent me, byte? channel, int miditick, ref MidiClock cmc) { if (channel == null) return; var m = _insts[Channels[channel.GetValueOrDefault()].Inst]; if ((m.Wave == null) && (channel.GetValueOrDefault() != 9)) return; //ノートオン if (miditick != -1) { var @event = me as NoteEvent; if (@event != null) { //Tone a; var ne = @event; if ((ne.Note < 120) && (ne.Note > 11) && (ne.Channel.Value != 9)) { if (ne.Velocity == 0) Tones[(int) channel][ne.Note].Stop(); if (Tones[(int) channel].ContainsKey(ne.Note)) { Tones[(int) channel][ne.Note].Abort(); Tones[(int) channel].Remove(ne.Note); } BTone[ne.Channel.Value] = NowTone; var t = new Tone(Pitchnames[ne.Note % 12], (ne.Note - 12) / 12, m.Wave, new Envelope(m.A, m.D, m.S, m.R), 255, 0, ne.Velocity, m.Noiseoption); LastTone[(byte) channel] = t; Tones[(int) channel].Add(ne.Note, t); Tones[(int) channel][ne.Note].StartPlay(miditick, ne.Gate); _tonequeue.Enqueue(t); NowTone = t; Portamenttick = 0; Bms = DX.GetNowCount(); } else { DX.PlaySoundMem(HPercs[ne.Note], DX.DX_PLAYTYPE_BACK); foreach (var handle in HPercs) { if (handle == 0) continue; DX.ChangePanSoundMem((Channels[9].Panpot - 64) * 4, HPercs[ne.Note]); DX.ChangeVolumeSoundMem( (int) (255 * (Channels[9].Volume / 127.0) * (Channels[9].Expression / 127.0) * (ne.Velocity / 127.0) * (Volume / 100f)), HPercs[ne.Note]); } } } } else { var onEvent = me as NoteOnEvent; if (onEvent != null) { //Tone a; var ne = onEvent; if ((ne.Note < 120) && (ne.Note > 11) && (ne.Channel.Value != 9)) { if (ne.Velocity == 0) Tones[(int) channel][ne.Note].Stop(); if (Tones[(int) channel].ContainsKey(ne.Note)) { Tones[(int) channel][ne.Note].Abort(); Tones[(int) channel].Remove(ne.Note); } var t = new Tone(Pitchnames[ne.Note % 12], (ne.Note - 12) / 12, m.Wave, new Envelope(m.A, m.D, m.S, m.R), 255, 0, ne.Velocity, m.Noiseoption); LastTone[(byte) channel] = t; Tones[(int) channel].Add(ne.Note, t); Tones[(int) channel][ne.Note].StartPlay(-1, -1); _tonequeue.Enqueue(t); } else { DX.PlaySoundMem(HPercs[ne.Note], DX.DX_PLAYTYPE_BACK); foreach (var handle in HPercs) { if (handle == 0) continue; DX.ChangePanSoundMem((Channels[9].Panpot - 64) * 4, HPercs[ne.Note]); DX.ChangeVolumeSoundMem( (int) (255 * (Channels[9].Volume / 127.0) * (Channels[9].Expression / 127.0) * (ne.Velocity / 127.0)), HPercs[ne.Note]); } } } //ノートオフ var @event = me as NoteOffEvent; if (@event != null) { var noe = @event; Tones[(int) channel][noe.Note].Stop(); } } var programEvent = me as ProgramEvent; if (programEvent != null) Channels[(int) channel].Inst = programEvent.Value; var controlEvent = me as ControlEvent; if (controlEvent != null) { var ce = controlEvent; switch (ce.Number) { case 10: Channels[(int) channel].Panpot = ce.Value; break; case 7: Channels[(int) channel].Volume = ce.Value; break; case 11: Channels[(int) channel].Expression = ce.Value; break; case 101: _rpns[0] = ce; break; case 100: _rpns[1] = ce; break; case 6: _rpns[2] = ce; if (_rpns[1] == null) break; switch (_rpns[1].Value) { case 0: Channels[(int) channel].BendRange = new Rpn(_rpns[2].Value); break; case 2: Channels[(int) channel].NoteShift = new Rpn((short) (_rpns[2].Value - 64)); break; } break; case 38: _rpns[3] = ce; if ((_rpns[1] == null) || (_rpns[2] == null)) break; if (_rpns[1].Value == 1) Channels[(int) channel].Tweak = new Rpn((short) (_rpns[2].Value * 128 + _rpns[3].Value - 8192)); break; case 111: Loop = ce.Tick; break; case 65: Channels[(int) channel].Portament = ce.Value; break; case 5: Channels[(int) channel].PortamentTime = ce.Value; break; } } if (me is PitchEvent) { var native = me.ToNativeEvent(); var pitchdata = native[2] * 128 + native[1] - 8192; Channels[(int) channel].Pitchbend = pitchdata; //Console.WriteLine("Decimal: " + pe.Value + "Hexa: " + pe.Value.ToString("X2") + "Binary: " + Convert.ToString(2, pe.Value)); } if ((cmc != null) && me is MidiEndOfTrack) { Channels[me.Channel.GetValueOrDefault()].End = true; var allend = true; foreach (var c in Channels) if (!c.End) { allend = false; break; } if (allend) if (Loop == -1) cmc.Stop(); else cmc.TickCount = Loop; } }