/// <summary> /// Builds a scale. /// </summary> /// <param name="tonic">The tonic.</param> /// <param name="pattern">The scale pattern.</param> /// <param name="positionInOctaveToSequenceIndex"> /// Must have 12 elements, and is filled with /// the 0-indexed scale position (or -1) for each position in the octave. /// </param> /// <param name="noteSequence"> /// Must have pattern.Ascent.Length elements, and is filled with /// the notes for each scale degree. /// </param> /// <param name="numAccidentals"> /// Filled with the total number of accidentals in the built /// scale. /// </param> private static void Build(Note tonic, ScalePattern pattern, int[] positionInOctaveToSequenceIndex, Note[] noteSequence, out int numAccidentals) { numAccidentals = 0; for (var i = 0; i < 12; ++i) { positionInOctaveToSequenceIndex[i] = -1; } var tonicPitch = tonic.PitchInOctave(0); for (var i = 0; i < pattern.Ascent.Length; ++i) { var pitch = tonicPitch + pattern.Ascent[i]; Note note; if (pattern.Ascent.Length == 7) { var letter = (char)(i + tonic.Letter); if (letter > 'G') { letter = (char)(letter - 7); } note = pitch.NoteWithLetter(letter); } else { note = pitch.NotePreferringSharps(); } noteSequence[i] = note; positionInOctaveToSequenceIndex[pitch.PositionInOctave()] = i; } }
private readonly int[] _positionInOctaveToSequenceIndex; // for each PositionInOctave, the 0-indexed /// <summary> /// Constructs a scale from its tonic and its pattern. /// </summary> /// <param name="tonic">The tonic note.</param> /// <param name="pattern">The scale pattern.</param> /// <exception cref="ArgumentNullException">tonic or pattern is null.</exception> public Scale(Note tonic, ScalePattern pattern) { if (tonic == null || pattern == null) { throw new ArgumentNullException(); } Tonic = tonic; Pattern = pattern; _positionInOctaveToSequenceIndex = new int[12]; NoteSequence = new Note[pattern.Ascent.Length]; int numAccidentals; Build(Tonic, Pattern, _positionInOctaveToSequenceIndex, NoteSequence, out numAccidentals); }
protected bool Equals(ScalePattern other) { return(string.Equals(Name, other.Name) && Ascent.SequenceEqual(other.Ascent)); }