private void HandleMidiNotePropertyChanged(object sender, PropertyChangedEventArgs e) { if (sender == null) { return; } IMidiNote sourceNote = sender as IMidiNote; if (sourceNote == null) { throw new ArgumentException("HandleMidiNotePropertyChanged expects an IMidiNote sender, but got a " + sender.GetType()); } if (e.PropertyName == "Pressure") { lock (_voiceLock) { IEnumerable <SimpleVoice> voices = FindMatchingVoices(sourceNote); voices.Where(v => v.IsActive).Execute(v => v.Intensity = v.FromMidiNote.Pressure); } } if (e.PropertyName == "IsReleased" && sourceNote.IsReleased) { if (!ApplyHoldPedalToSustain || !_midiSource.HoldPedal) { lock (_voiceLock) { IEnumerable <SimpleVoice> voices = FindMatchingVoices(sourceNote); _voices.Execute(KillNote); } } } }
private void HandleMidiNotesChanged(object sender, NotifyCollectionChangedEventArgs e) { IMidiNote[] itemsToRemove; IMidiNote[] itemsToAdd; lock (_voiceLock) { if (e.Action == NotifyCollectionChangedAction.Reset) { // itemsToRemove is everything that used to be in the list but is not in the list now itemsToRemove = _lastNoteList.Where(on => !FindMatchingVoices(on).Any()).ToArray(); // itemsToAdd is evertying that is in the list now that wasn't the list before itemsToAdd = _midiSource.ActiveNotes.Where(on => !_lastNoteList.Any(an => an.Number == on.Number)).ToArray(); } else { itemsToRemove = (e.OldItems ?? new IMidiNote[0]).OfType <IMidiNote>().ToArray(); itemsToAdd = (e.NewItems ?? new IMidiNote[0]).OfType <IMidiNote>().ToArray(); } foreach (int i in Enumerable.Range(0, itemsToRemove.Length)) { IMidiNote note = itemsToRemove[i]; IEnumerable <SimpleVoice> toKill = FindMatchingVoices(note); toKill.Execute(KillNote); } foreach (IMidiNote note in itemsToAdd) { SimpleVoice voice = GetLowestPriorityVoice(); // this could only be null if there are zero voices, which is not allowed if (voice == null) { throw new InvalidOperationException("No voices found."); } voice.FromMidiNote = note; if (NumberOfVoices > 1 || !IsLegato) { voice.Intensity = 0; } SetPitch(voice); if (!voice.IsActive || NumberOfVoices > 1 || !IsLegato) { voice.Intensity = note.Velocity; } voice.IsActive = true; } _lastNoteList = _midiSource.ActiveNotes; } }
private IEnumerable <SimpleVoice> FindMatchingVoices(IMidiNote note) { SimpleVoice[] voices = _voices.Where(v => v.FromMidiNote != null && v.FromMidiNote.Number == note.Number).ToArray(); return(voices); }