private void NoteOnRaw(int virtualChannel, float cents, int velocity = 0x7F) { PitchX pitch = GetPitchX(cents); VirtualChannelState v; int c; // zero-based raw channel index bool setInstrument = false; bool setBend = false; lock (_channelStateLock) { v = _virtualChannels[virtualChannel]; c = FindRawChannel(virtualChannel, pitch); RawChannelState r = _rawChannels[c]; Debug.WriteLine("NoteOnRaw v{0}->r{1} {2}({3}+{4:X})", virtualChannel, (int)c, cents, pitch.note, pitch.bend); if (r.instrument != v.instrument) { r.instrument = v.instrument; setInstrument = true; } if (r.bend != pitch.bend) { r.bend = pitch.bend; setBend = true; } r.playingNotes += 1; SavePlayingNoteRawChannel(virtualChannel, pitch, c); _rawChannels[c] = r; } // Raw midi if (setInstrument) { _device.SendPatchChange(channel: c + 1, v.instrument); } if (setBend) { _device.SendPitchWheelChange(channel: c + 1, pitch.bend); } _device.SendNoteOn(channel: c + 1, noteNumber: pitch.note, velocity); }
private void NoteOffRaw(int virtualChannel, float cents, int velocity = 0x7F) { PitchX pitch = GetPitchX(cents); int c; lock (_channelStateLock) { c = GetPlayingNoteRawChannel(virtualChannel, pitch); RawChannelState r = _rawChannels[c]; Debug.WriteLine("NoteOffRaw v{0}->r{1} {2}({3}+{4:X})", virtualChannel, (int)c, cents, pitch.note, pitch.bend); r.playingNotes -= 1; _rawChannels[c] = r; } // Raw midi _device.SendNoteOff(channel: c + 1, noteNumber: pitch.note, velocity); }
private int FindRawChannel(int virtualChannel, PitchX pitch) // _channelStateLock locked { int[] playingThisNote = GetPlayingNoteRawChannels(virtualChannel, pitch); VirtualChannelState v = _virtualChannels[virtualChannel]; for (int ri = 0; ri < 16; ++ri) { if (playingThisNote.Contains(ri)) { continue; // this note already played on this raw channel } RawChannelState r = _rawChannels[ri]; if (r.playingNotes == 0) { return(ri); } if (r.instrument == v.instrument && r.bend == pitch.bend) { return(ri); } } throw new Exception("No free midi channel"); }