/// <summary> /// Returns the music string position of the /// <paramref name="targetMusicNote"/> on this instance. /// </summary> /// <param name="targetMusicNote"> /// The <see cref="MusicNote"/> to find the music string position of. /// </param> /// <returns> /// An <see cref="int"/> representing the music string position of /// <paramref name="targetMusicNote"/>. /// </returns> /// <exception cref="MusicNoteExceptions.InvalidMusicNoteComparisonException"> /// This instance of <see cref="MusicNote"/> does not have a valid /// Octave whilst <paramref name="targetMusicNote"/> does, or vice /// versa. /// </exception> /// <exception cref="MusicStringExceptions.MusicStringHasNoSuchMusicNoteException"> /// <paramref name="targetMusicNote"/> does not exist on this /// <see cref="MusicString"/>. /// </exception> public int GetMusicStringPositionOfMusicNote(MusicNote targetMusicNote) { if (RootNote.HasOctave() ^ targetMusicNote.HasOctave()) { var errorMessage = "Cannot compare a MusicNote with an octaveless MusicNote."; throw new MusicNoteExceptions.InvalidMusicNoteComparisonException(errorMessage); } else { if (HasMusicNote(targetMusicNote)) { var semitoneDistance = RootNote.GetSemitoneDistance(targetMusicNote); if (semitoneDistance < 0) { return(AbstractMusicNoteUtilities.GetNotesPerOctave() + semitoneDistance); } else { return(semitoneDistance); } } else { var errorMessage = "Target MusicNote does not exist on this MusicString."; throw new MusicStringExceptions.MusicStringHasNoSuchMusicNoteException(errorMessage); } } }
/// <summary> /// Returns whether or not a given <see cref="MusicNote"/> exists on /// this instance. /// </summary> /// <param name="targetMusicNote"> /// The <see cref="MusicNote"/> to confirm the existence of. /// </param> /// <returns> /// A <see cref="bool"/> representing whether or not /// <paramref name="targetMusicNote"/> exists on this instance. /// </returns> public bool HasMusicNote(MusicNote targetMusicNote) { var bothNotesHaveAnOctave = RootNote.HasOctave() && targetMusicNote.HasOctave(); var neitherNoteHasAnOctave = !RootNote.HasOctave() && !targetMusicNote.HasOctave(); if (bothNotesHaveAnOctave) { if (LastPosition.HasValue) { var lastMusicNote = RootNote.Sharpened((int)LastPosition); return((targetMusicNote.CompareTo(RootNote) >= 0) && (targetMusicNote.CompareTo(lastMusicNote) <= 0)); } else { return(targetMusicNote.CompareTo(RootNote) >= 0); } } else if (neitherNoteHasAnOctave) { if (LastPosition.HasValue) { var lastMusicNote = RootNote.Sharpened((int)LastPosition); if (LastPosition < AbstractMusicNoteUtilities.GetNotesPerOctave()) { for (var position = 0; position <= LastPosition; position++) { if (RootNote.Sharpened(position) == targetMusicNote) { return(true); } } //None of the generated notes matched the note return(false); } else { //There are enough notes on this string that every note is present at least once return(true); } } else { //If there is no LastPosition, the MusicString is essentially infinite and will contain every note return(true); } } else { //Notes cannot be compared return(false); } }
/// <summary> /// Instantiates a new instance of the <see cref="MusicString"/> class. /// </summary> /// <param name="rootNote"> /// The <see cref="MusicNote"/> to be assigned to the new instance. /// </param> /// <param name="lastPosition"> /// An <see cref="int"/> representing the last position on this /// <see cref="MusicString"/>, or null. /// </param> /// <exception cref="ArgumentException"> /// <paramref name="rootNote"/> is null. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="lastPosition"/> is less than /// <see cref="FirstPosition"/>. /// </exception> public MusicString(MusicNote rootNote, int?lastPosition = null) { if (rootNote != null) { RootNote = rootNote; } else { throw new ArgumentException("Root note must not be null."); } if ((lastPosition == null) || (lastPosition >= FirstPosition)) { LastPosition = lastPosition; } else { throw new ArgumentException("lastPosition must be greater than or equal to FirstPosition, or null."); } }
/// <summary> /// Flattens the <see cref="RootNote"/> of this instance by /// <paramref name="decrementQuantity"/> semitones. /// </summary> /// <param name="decrementQuantity"> /// An <see cref="int"/> representing the number of semitones to /// flatten the <see cref="RootNote"/> of this instance by. /// </param> public void Flatten(int decrementQuantity) { RootNote = RootNote.Flattened(decrementQuantity); }
/// <summary> /// Sharpens the <see cref="RootNote"/> of this instance by /// <paramref name="incrementQuantity"/> semitones. /// </summary> /// <param name="incrementQuantity"> /// An <see cref="int"/> representing the number of semitones to /// sharpen the <see cref="RootNote"/> of this instance by. /// </param> public void Sharpen(int incrementQuantity) { RootNote = RootNote.Sharpened(incrementQuantity); }