/// <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> /// Get the number of semitones between this instance and /// <paramref name="targetMusicNote"/>. /// </summary> /// <param name="targetMusicNote"> /// The <see cref="MusicNote"/> whose semitone distance from this /// instance will be returned, or null. /// </param> /// <returns> /// An <see cref="int"/> representing the number of semitones between /// this instance and <paramref name="targetMusicNote"/>. /// </returns> /// <exception cref="ArgumentException"> /// <paramref name="targetMusicNote"/> is null. /// </exception> /// <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> /// <remarks> /// The result reflects how far this instance would need to be either /// flattened or sharpened to get to /// <paramref name="targetMusicNote"/>. /// </remarks> public int GetSemitoneDistance(MusicNote targetMusicNote) { if (targetMusicNote == null) { throw new ArgumentException("Target music note must not be null."); } var noteDifferenceInSemitones = targetMusicNote.Value - Value; if (HasOctave() && targetMusicNote.HasOctave()) { var octaveDifference = (int)targetMusicNote.Octave - (int)Octave; var octaveDifferenceInSemitones = octaveDifference * AbstractMusicNoteUtilities.GetNotesPerOctave(); return(octaveDifferenceInSemitones + noteDifferenceInSemitones); } else if (!HasOctave() && !targetMusicNote.HasOctave()) { return(noteDifferenceInSemitones); } else { var errorMessage = "Cannot compare a MusicNote with an octaveless MusicNote."; throw new MusicNoteExceptions.InvalidMusicNoteComparisonException(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); } }