private void LoadNotes(int numberOfKeys) { if (ActualWidth == 0) { return; } // Find the last white note that fits. If there aren't enough notes above the bottom note in the scale, drop the bottom // note so we get the right number of notes. IScaleNote[] whiteNotesToUse = WhiteKeyNotes.SkipWhile(n => n.MidiNoteNumber < BottomNote.MidiNoteNumber).ToArray(); if (whiteNotesToUse.Length > numberOfKeys) { whiteNotesToUse = whiteNotesToUse.Take(numberOfKeys).ToArray(); } else if (whiteNotesToUse.Length < numberOfKeys) { BottomNote = WhiteKeyNotes.ElementAt(WhiteKeyNotes.Count - numberOfKeys); whiteNotesToUse = WhiteKeyNotes.SkipWhile(n => n.MidiNoteNumber < BottomNote.MidiNoteNumber).ToArray(); } IScaleNote topNote = whiteNotesToUse.Last(); // locate the top and bottom note in the master scale, and use everything between them, inclusive. int startIndex = Scale.EqualTemperedScale.ToList().IndexOf(BottomNote); int endIndex = Scale.EqualTemperedScale.ToList().IndexOf(topNote); ClearNotes(); AddNotes(startIndex, endIndex); }
private void ShiftKeys(int shiftAmount) { int targetNoteNumber; if (shiftAmount < -12) { targetNoteNumber = Scale.EqualTemperedScale.First().MidiNoteNumber; } else if (shiftAmount > 12) { targetNoteNumber = Scale.EqualTemperedScale.Last().MidiNoteNumber - Notes.Count + 1; } else { targetNoteNumber = BottomNote.MidiNoteNumber + shiftAmount; } IScaleNote newNote = Scale.EqualTemperedScale.FirstOrDefault(n => n.MidiNoteNumber == targetNoteNumber); while (newNote != null && !newNote.IsWhiteKey) { targetNoteNumber += Math.Sign(shiftAmount); newNote = Scale.EqualTemperedScale.FirstOrDefault(n => n.MidiNoteNumber == targetNoteNumber); } if (newNote != null) { BottomNote = newNote; LoadNotes(Notes.Count(n => n.Item.IsWhiteKey)); } }
private void SetPitch(SimpleVoice voice) { if (voice.FromMidiNote != null) { // TODO this search could be optimized IScaleNote scaleNote = _scale.FirstOrDefault(n => n.MidiNoteNumber == voice.FromMidiNote.Number); if (scaleNote != null) { voice.Pitch = scaleNote.Pitch + (Pitch.HalfStep * PitchBendRange * _midiSource.PitchBend); } } }