/// <summary> /// Add an interval to this representation. /// </summary> /// <param name="interval">The interval to add.</param> /// <param name="direction">Which direction to go - up or down.</param> /// <returns>Null if there is no supported enharmonically correct representation of the requested interval. For example, /// adding a minor second to a Bb should return a Cb, but this is not supported so the result will be null. If there is /// a valid representation (for example, A# plus a minor second correctly yields B) it will be returned.</returns> public NoteRepresentation AddInterval(Interval interval, IntervalDirection direction = IntervalDirection.Up) { var coefficient = direction == IntervalDirection.Up ? 1 : -1; var newNoteNumber = this.Note.Number + (interval.NumberOfSemitones() * coefficient); var newNoteName = this.Name.AddNoteNames(interval.NumberOfNoteNames() * coefficient); var result = new Note(newNoteNumber).GetRepresentations().SingleOrDefault(r => r.Name == newNoteName); return result; }
public Interval(int pitch, bool isInTonality) { Interval i = Interval.fromPitch(pitch, isInTonality); this.distance = i.distance; this.mode = i.mode; this.direction = i.direction; }
public Interval(int pitch) { Interval i = Interval.fromPitch(pitch, true); this.distance = i.distance; this.mode = i.mode; this.direction = i.direction; }
/// <summary> /// Returns an <see cref="IntervalDefinition"/> by the specified half steps number and /// interval's direction. /// </summary> /// <param name="interval">The interval as a number of half steps away.</param> /// <param name="direction">The direction of an interval (up or down).</param> /// <returns>An <see cref="IntervalDefinition"/> with the specified interval and direction.</returns> /// <exception cref="InvalidEnumArgumentException"><paramref name="direction"/> specified an /// invalid value.</exception> public static IntervalDefinition Get(SevenBitNumber interval, IntervalDirection direction) { ThrowIfArgument.IsInvalidEnumValue(nameof(direction), direction); if (!_cache.TryGetValue(interval, out Dictionary <IntervalDirection, IntervalDefinition> intervalDefinitions)) { _cache.Add(interval, intervalDefinitions = new Dictionary <IntervalDirection, IntervalDefinition>()); } if (!intervalDefinitions.TryGetValue(direction, out IntervalDefinition intervalDefinition)) { intervalDefinitions.Add(direction, intervalDefinition = new IntervalDefinition(interval, direction)); } return(intervalDefinition); }
/// <summary> /// Returns an <see cref="Interval"/> by the specified half steps number and /// interval's direction. /// </summary> /// <param name="intervalSize">The size of an interval as a number of half steps away.</param> /// <param name="direction">The direction of an interval (up or down).</param> /// <returns>An <see cref="Interval"/> with the specified interval and direction.</returns> /// <exception cref="InvalidEnumArgumentException"><paramref name="direction"/> specified an /// invalid value.</exception> public static Interval Get(SevenBitNumber intervalSize, IntervalDirection direction) { ThrowIfArgument.IsInvalidEnumValue(nameof(direction), direction); Dictionary <IntervalDirection, Interval> intervals; if (!_cache.TryGetValue(intervalSize, out intervals)) { _cache.Add(intervalSize, intervals = new Dictionary <IntervalDirection, Interval>()); } Interval cachedInterval; if (!intervals.TryGetValue(direction, out cachedInterval)) { intervals.Add(direction, cachedInterval = new Interval(intervalSize, direction)); } return(cachedInterval); }
/// <summary> /// Initializes a new instance of the <see cref="Interval"/> with the /// specified interval and its direction. /// </summary> /// <param name="size">The size of interval as a number of half steps away.</param> /// <param name="direction">The direction of an interval (up or down).</param> private Interval(SevenBitNumber size, IntervalDirection direction) { Size = size; Direction = direction; }
/// <summary> /// Initializes a new instance of the <see cref="IntervalDefinition"/> with the /// specified interval and its direction. /// </summary> /// <param name="interval">The interval as a number of half steps away.</param> /// <param name="direction">The direction of an interval (up or down).</param> private IntervalDefinition(SevenBitNumber interval, IntervalDirection direction) { Interval = interval; Direction = direction; }
private static Interval fromPitch(int pitch, bool isInTonality) { //Calculate direction IntervalDirection direction = IntervalDirection.INCREASING; if (pitch < 0) { pitch = -pitch; direction = IntervalDirection.DECREASING; } //Reduce pitch change to 1 octave int octave = 0; while (pitch >= Note.PITCH_OCTAVE) { pitch -= Note.PITCH_OCTAVE; octave++; } switch (pitch) { case 0: return(new Interval( 1 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.PERFECT, direction )); case 1: return(new Interval( 2 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MINOR, direction )); case 2: return(new Interval( 2 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MAJOR, direction )); case 3: if (isInTonality) { return(new Interval( 3 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MINOR, direction )); } else { return(new Interval( 2 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.AUGMENTED, direction )); } case 4: if (isInTonality) { return(new Interval( 3 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MAJOR, direction )); } else { return(new Interval( 4 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.DIMINISHED, direction )); } case 5: return(new Interval( 4 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.PERFECT, direction )); case 6: return(new Interval( 5 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.DIMINISHED, direction )); case 7: return(new Interval( 5 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.PERFECT, direction )); case 8: if (isInTonality) { return(new Interval( 6 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MINOR, direction )); } else { return(new Interval( 5 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.AUGMENTED, direction )); } case 9: if (isInTonality) { return(new Interval( 6 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MAJOR, direction )); } else { return(new Interval( 7 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.DIMINISHED, direction )); } case 10: if (isInTonality) { return(new Interval( 7 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MINOR, direction )); } else { return(new Interval( 6 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.AUGMENTED, direction )); } case 11: if (isInTonality) { return(new Interval( 7 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MAJOR, direction )); } else { return(new Interval( 7 + octave * Interval.INTERVAL_OCTAVE, IntervalMode.MAJOR, direction )); } default: return(null); } }
public Interval(int distance, IntervalMode mode, IntervalDirection direction) { this.distance = distance; this.mode = mode; this.direction = direction; }
public void invert(bool invertDistance, bool invertMode, bool invertDirection) { if (invertDistance) { int octave = 0; int newDist = this.distance; //Reduce to 1 octave while (newDist > Interval.INTERVAL_OCTAVE + 1) { newDist -= Interval.INTERVAL_OCTAVE; octave++; } //Inversion: // - newDist : 1-7 // - if 1: inverted interval is 1 // - if 2-7: inverted is 7-2 (9-newDist) if (newDist > 1) { newDist = 9 - newDist; } // Recover octave newDist += Interval.INTERVAL_OCTAVE * octave; this.distance = newDist; } if (invertMode) { switch (this.mode) { case IntervalMode.DIMINISHED: this.mode = IntervalMode.AUGMENTED; break; case IntervalMode.AUGMENTED: this.mode = IntervalMode.DIMINISHED; break; case IntervalMode.MAJOR: this.mode = IntervalMode.MINOR; break; case IntervalMode.MINOR: this.mode = IntervalMode.MAJOR; break; case IntervalMode.PERFECT: //do nothing break; } } if (invertDirection) { if (this.direction == IntervalDirection.DECREASING) { this.direction = IntervalDirection.INCREASING; } else { this.direction = IntervalDirection.DECREASING; } } }