Beispiel #1
0
        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());
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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");
        }
Beispiel #7
0
 private static int GetNoteKey(int virtualChannel, PitchX pitch)
 {
     return((virtualChannel << 24) | ((int)pitch.note << 16) | (pitch.bend));
 }