private int[] GetPlayingNoteRawChannels(int virtualChannel, PitchX pitch) { int noteKey = GetNoteKey(virtualChannel, pitch); List <int> cs = null; _playingNotes.TryGetValue(noteKey, out cs); if (cs == null) { return new int[] { } } ; return(cs.ToArray()); }
private void SavePlayingNoteRawChannel(int virtualChannel, PitchX pitch, int rawChannel) { int noteKey = GetNoteKey(virtualChannel, pitch); List <int> cs = null; _playingNotes.TryGetValue(noteKey, out cs); if (cs == null) { cs = new List <int>(); _playingNotes[noteKey] = cs; } cs.Add(rawChannel); }
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 int GetPlayingNoteRawChannel(int virtualChannel, PitchX pitch, bool remove = true) { int noteKey = GetNoteKey(virtualChannel, pitch); List <int> cs = null; _playingNotes.TryGetValue(noteKey, out cs); if (cs == null || cs.Count == 0) { throw new Exception("Playing note not found"); } int rawChannel = cs[0]; if (remove) { cs.RemoveAt(0); } return(rawChannel); }
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"); }
private static int GetNoteKey(int virtualChannel, PitchX pitch) { return((virtualChannel << 24) | ((int)pitch.note << 16) | (pitch.bend)); }