Skip to content

Commit

Permalink
Merge e0995b4 into 24b3cb1
Browse files Browse the repository at this point in the history
  • Loading branch information
albertms10 committed Mar 30, 2024
2 parents 24b3cb1 + e0995b4 commit e3af0f7
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 108 deletions.
2 changes: 1 addition & 1 deletion example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void main() {
Interval.M3.descending(); // M-3

Note.c.interval(Note.g); // P5
Note.d.interval(Note.f.sharp).inverted; // m6
Note.d.interval(Note.f.sharp).inversion; // m6
Note.g.flat.transposeBy(-Interval.m3); // E♭

Interval.P5.circleFrom(Note.c, distance: 12).toList();
Expand Down
22 changes: 12 additions & 10 deletions lib/src/interval/interval.dart
Original file line number Diff line number Diff line change
Expand Up @@ -254,26 +254,28 @@ final class Interval
quality,
);

/// The inverted of this [Interval], regardless of its direction (ascending or
/// descending).
/// The inversion of this [Interval], regardless of its direction (ascending
/// or descending).
///
/// See [Inversion § Intervals](https://en.wikipedia.org/wiki/Inversion_(music)#Intervals).
///
/// Example:
/// ```dart
/// Interval.m3.inverted == Interval.M6
/// Interval.A4.inverted == Interval.d5
/// Interval.M7.inverted == Interval.m2
/// (-Interval.P1).inverted == -Interval.P8
/// Interval.m3.inversion == Interval.M6
/// Interval.A4.inversion == Interval.d5
/// Interval.M7.inversion == Interval.m2
/// (-Interval.P1).inversion == -Interval.P8
/// ```
///
/// If this [Interval.size] is greater than [Size.octave], the simplified
/// inversion is returned instead.
///
/// Example:
/// ```dart
/// Interval.m9.inverted == Interval.M7
/// Interval.P11.inverted == Interval.P5
/// Interval.m9.inversion == Interval.M7
/// Interval.P11.inversion == Interval.P5
/// ```
Interval get inverted => Interval._(size.inverted, quality.inverted);
Interval get inversion => Interval._(size.inversion, quality.inversion);

/// The simplified version of this [Interval].
///
Expand Down Expand Up @@ -349,7 +351,7 @@ final class Interval
}
distance++;
ascendingNotes.add(ascendingNotes.last.transposeBy(this));
descendingNotes.add(descendingNotes.last.transposeBy(inverted));
descendingNotes.add(descendingNotes.last.transposeBy(inversion));
}
}

Expand Down
26 changes: 16 additions & 10 deletions lib/src/interval/quality.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ sealed class Quality implements Comparable<Quality> {
/// The symbol of this [Quality].
String get symbol;

/// The inverted version of this [Quality].
Quality get inverted;
/// The inversion of this [Quality].
///
/// See [Inversion § Intervals](https://en.wikipedia.org/wiki/Inversion_(music)#Intervals).
Quality get inversion;

/// Whether this [Quality] is dissonant.
bool get isDissonant;
Expand Down Expand Up @@ -140,15 +142,17 @@ final class PerfectQuality extends Quality {
_ => Quality._augmentedSymbol * semitones,
};

/// The inverted version of this [PerfectQuality].
/// The inversion of this [PerfectQuality].
///
/// See [Inversion § Intervals](https://en.wikipedia.org/wiki/Inversion_(music)#Intervals).
///
/// Example:
/// ```dart
/// PerfectQuality.perfect.inverted == PerfectQuality.perfect
/// PerfectQuality.augmented.inverted == PerfectQuality.diminished
/// PerfectQuality.perfect.inversion == PerfectQuality.perfect
/// PerfectQuality.augmented.inversion == PerfectQuality.diminished
/// ```
@override
PerfectQuality get inverted => PerfectQuality(-semitones);
PerfectQuality get inversion => PerfectQuality(-semitones);

/// Whether this [PerfectQuality] is dissonant.
///
Expand Down Expand Up @@ -250,15 +254,17 @@ final class ImperfectQuality extends Quality {
_ => Quality._augmentedSymbol * (semitones - 1),
};

/// The inverted version of this [ImperfectQuality].
/// The inversion of this [ImperfectQuality].
///
/// See [Inversion § Intervals](https://en.wikipedia.org/wiki/Inversion_(music)#Intervals).
///
/// Example:
/// ```dart
/// ImperfectQuality.minor.inverted == ImperfectQuality.major
/// ImperfectQuality.augmented.inverted == ImperfectQuality.diminished
/// ImperfectQuality.minor.inversion == ImperfectQuality.major
/// ImperfectQuality.augmented.inversion == ImperfectQuality.diminished
/// ```
@override
ImperfectQuality get inverted => ImperfectQuality(1 - semitones);
ImperfectQuality get inversion => ImperfectQuality(1 - semitones);

/// Whether this [ImperfectQuality] is dissonant.
///
Expand Down
24 changes: 13 additions & 11 deletions lib/src/interval/size.dart
Original file line number Diff line number Diff line change
Expand Up @@ -148,31 +148,33 @@ extension type const Size._(int size) implements int {
? Interval.perfect(this, PerfectQuality.augmented)
: Interval.imperfect(this, ImperfectQuality.augmented);

static int _inverted(Size size) {
static int _inversion(Size size) {
final diff = 9 - size.simple.size.abs();

return (diff.isNegative ? diff.abs() + 2 : diff) * size.sign;
}

/// The inverted of this [Size].
/// The inversion of this [Size].
///
/// See [Inversion § Intervals](https://en.wikipedia.org/wiki/Inversion_(music)#Intervals).
///
/// Example:
/// ```dart
/// Size.third.inverted == Size.sixth
/// Size.fourth.inverted == Size.fifth
/// Size.seventh.inverted == Size.second
/// (-Size.unison).inverted == -Size.octave
/// Size.third.inversion == Size.sixth
/// Size.fourth.inversion == Size.fifth
/// Size.seventh.inversion == Size.second
/// (-Size.unison).inversion == -Size.octave
/// ```
///
/// If this [Size] is greater than [Size.octave], the simplified inversion
/// is returned instead.
///
/// Example:
/// ```dart
/// Size.ninth.inverted == Size.seventh
/// Size.eleventh.inverted == Size.fifth
/// Size.ninth.inversion == Size.seventh
/// Size.eleventh.inversion == Size.fifth
/// ```
Size get inverted => Size(_inverted(this));
Size get inversion => Size(_inversion(this));

static int _simple(Size size) =>
size.isCompound ? size.absShift.nonZeroMod(octave) * size.sign : size;
Expand Down Expand Up @@ -264,7 +266,7 @@ extension type const PerfectSize._(int size) implements Size {
Interval get perfect => Interval.perfect(this);

@redeclare
PerfectSize get inverted => PerfectSize(Size._inverted(this));
PerfectSize get inversion => PerfectSize(Size._inversion(this));

@redeclare
PerfectSize get simple => PerfectSize(Size._simple(this));
Expand Down Expand Up @@ -311,7 +313,7 @@ extension type const ImperfectSize._(int size) implements Size {
Interval get minor => Interval.imperfect(this, ImperfectQuality.minor);

@redeclare
ImperfectSize get inverted => ImperfectSize(Size._inverted(this));
ImperfectSize get inversion => ImperfectSize(Size._inversion(this));

@redeclare
ImperfectSize get simple => ImperfectSize(Size._simple(this));
Expand Down
14 changes: 11 additions & 3 deletions lib/src/scalable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,18 @@ extension ScalableIterable<T extends Scalable<T>> on Iterable<T> {
Iterable<T> transposeBy(Interval interval) =>
map((item) => item.transposeBy(interval));

/// The inverse of this [ScalableIterable].
/// The inversion of this [ScalableIterable].
///
/// See [Inversion](https://en.wikipedia.org/wiki/Inversion_(music)) and
/// [Retrograde inversion](https://en.wikipedia.org/wiki/Retrograde_inversion)
/// for a combination of both [retrograde] and [inversion].
///
/// Example:
/// ```dart
/// {Note.b, Note.a.sharp, Note.d}.inverse.toSet()
/// {Note.b, Note.a.sharp, Note.d}.inversion.toSet()
/// == {Note.b, Note.c, Note.g.sharp}
/// ```
Iterable<T> get inverse sync* {
Iterable<T> get inversion sync* {
if (isEmpty) return;
yield first;
var last = first;
Expand All @@ -73,6 +77,10 @@ extension ScalableIterable<T extends Scalable<T>> on Iterable<T> {

/// The retrograde of this [ScalableIterable].
///
/// See [Retrograde](https://en.wikipedia.org/wiki/Retrograde_(music)) and
/// [Retrograde inversion](https://en.wikipedia.org/wiki/Retrograde_inversion)
/// for a combination of both [retrograde] and [inversion].
///
/// Example:
/// ```dart
/// {PitchClass.dSharp, PitchClass.g, PitchClass.fSharp}.retrograde.toSet()
Expand Down
96 changes: 48 additions & 48 deletions test/src/interval/interval_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -232,54 +232,54 @@ void main() {
});
});

group('.inverted', () {
test('returns the inverted of this Interval', () {
expect((-Interval.M13).inverted, -Interval.m3);
expect((-Interval.m13).inverted, -Interval.M3);
expect((-Interval.P11).inverted, -Interval.P5);
expect((-Interval.M9).inverted, -Interval.m7);
expect((-Interval.m9).inverted, -Interval.M7);
expect((-Interval.A8).inverted, -Interval.d1);
expect((-Interval.P8).inverted, -Interval.P1);
expect((-Interval.d8).inverted, -Interval.A1);
expect((-Interval.M7).inverted, -Interval.m2);
expect((-Interval.m7).inverted, -Interval.M2);
expect((-Interval.M6).inverted, -Interval.m3);
expect((-Interval.m6).inverted, -Interval.M3);
expect((-Interval.A5).inverted, -Interval.d4);
expect((-Interval.d5).inverted, -Interval.A4);
expect((-Interval.A4).inverted, -Interval.d5);
expect((-Interval.d4).inverted, -Interval.A5);
expect((-Interval.M3).inverted, -Interval.m6);
expect((-Interval.m3).inverted, -Interval.M6);
expect((-Interval.M2).inverted, -Interval.m7);
expect((-Interval.m2).inverted, -Interval.M7);
expect((-Interval.A1).inverted, -Interval.d8);
expect((-Interval.P1).inverted, -Interval.P8);
expect((-Interval.d1).inverted, -Interval.A8);
expect(Interval.d1.inverted, Interval.A8);
expect(Interval.P1.inverted, Interval.P8);
expect(Interval.A1.inverted, Interval.d8);
expect(Interval.m2.inverted, Interval.M7);
expect(Interval.M2.inverted, Interval.m7);
expect(Interval.m3.inverted, Interval.M6);
expect(Interval.M3.inverted, Interval.m6);
expect(Interval.d4.inverted, Interval.A5);
expect(Interval.A4.inverted, Interval.d5);
expect(Interval.d5.inverted, Interval.A4);
expect(Interval.A5.inverted, Interval.d4);
expect(Interval.m6.inverted, Interval.M3);
expect(Interval.M6.inverted, Interval.m3);
expect(Interval.m7.inverted, Interval.M2);
expect(Interval.M7.inverted, Interval.m2);
expect(Interval.d8.inverted, Interval.A1);
expect(Interval.P8.inverted, Interval.P1);
expect(Interval.A8.inverted, Interval.d1);
expect(Interval.m9.inverted, Interval.M7);
expect(Interval.M9.inverted, Interval.m7);
expect(Interval.P11.inverted, Interval.P5);
expect(Interval.m13.inverted, Interval.M3);
expect(Interval.M13.inverted, Interval.m3);
group('.inversion', () {
test('returns the inversion of this Interval', () {
expect((-Interval.M13).inversion, -Interval.m3);
expect((-Interval.m13).inversion, -Interval.M3);
expect((-Interval.P11).inversion, -Interval.P5);
expect((-Interval.M9).inversion, -Interval.m7);
expect((-Interval.m9).inversion, -Interval.M7);
expect((-Interval.A8).inversion, -Interval.d1);
expect((-Interval.P8).inversion, -Interval.P1);
expect((-Interval.d8).inversion, -Interval.A1);
expect((-Interval.M7).inversion, -Interval.m2);
expect((-Interval.m7).inversion, -Interval.M2);
expect((-Interval.M6).inversion, -Interval.m3);
expect((-Interval.m6).inversion, -Interval.M3);
expect((-Interval.A5).inversion, -Interval.d4);
expect((-Interval.d5).inversion, -Interval.A4);
expect((-Interval.A4).inversion, -Interval.d5);
expect((-Interval.d4).inversion, -Interval.A5);
expect((-Interval.M3).inversion, -Interval.m6);
expect((-Interval.m3).inversion, -Interval.M6);
expect((-Interval.M2).inversion, -Interval.m7);
expect((-Interval.m2).inversion, -Interval.M7);
expect((-Interval.A1).inversion, -Interval.d8);
expect((-Interval.P1).inversion, -Interval.P8);
expect((-Interval.d1).inversion, -Interval.A8);
expect(Interval.d1.inversion, Interval.A8);
expect(Interval.P1.inversion, Interval.P8);
expect(Interval.A1.inversion, Interval.d8);
expect(Interval.m2.inversion, Interval.M7);
expect(Interval.M2.inversion, Interval.m7);
expect(Interval.m3.inversion, Interval.M6);
expect(Interval.M3.inversion, Interval.m6);
expect(Interval.d4.inversion, Interval.A5);
expect(Interval.A4.inversion, Interval.d5);
expect(Interval.d5.inversion, Interval.A4);
expect(Interval.A5.inversion, Interval.d4);
expect(Interval.m6.inversion, Interval.M3);
expect(Interval.M6.inversion, Interval.m3);
expect(Interval.m7.inversion, Interval.M2);
expect(Interval.M7.inversion, Interval.m2);
expect(Interval.d8.inversion, Interval.A1);
expect(Interval.P8.inversion, Interval.P1);
expect(Interval.A8.inversion, Interval.d1);
expect(Interval.m9.inversion, Interval.M7);
expect(Interval.M9.inversion, Interval.m7);
expect(Interval.P11.inversion, Interval.P5);
expect(Interval.m13.inversion, Interval.M3);
expect(Interval.M13.inversion, Interval.m3);
});
});

Expand Down
26 changes: 13 additions & 13 deletions test/src/interval/quality_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,36 +56,36 @@ void main() {
});
});

group('.inverted', () {
test('returns the inverted of this Quality', () {
group('.inversion', () {
test('returns the inversion of this Quality', () {
expect(
PerfectQuality.triplyDiminished.inverted,
PerfectQuality.triplyDiminished.inversion,
PerfectQuality.triplyAugmented,
);
expect(PerfectQuality.diminished.inverted, PerfectQuality.augmented);
expect(PerfectQuality.perfect.inverted, PerfectQuality.perfect);
expect(PerfectQuality.augmented.inverted, PerfectQuality.diminished);
expect(PerfectQuality.diminished.inversion, PerfectQuality.augmented);
expect(PerfectQuality.perfect.inversion, PerfectQuality.perfect);
expect(PerfectQuality.augmented.inversion, PerfectQuality.diminished);
expect(
PerfectQuality.triplyAugmented.inverted,
PerfectQuality.triplyAugmented.inversion,
PerfectQuality.triplyDiminished,
);

expect(
ImperfectQuality.doublyDiminished.inverted,
ImperfectQuality.doublyDiminished.inversion,
ImperfectQuality.doublyAugmented,
);
expect(
ImperfectQuality.diminished.inverted,
ImperfectQuality.diminished.inversion,
ImperfectQuality.augmented,
);
expect(ImperfectQuality.minor.inverted, ImperfectQuality.major);
expect(ImperfectQuality.major.inverted, ImperfectQuality.minor);
expect(ImperfectQuality.minor.inversion, ImperfectQuality.major);
expect(ImperfectQuality.major.inversion, ImperfectQuality.minor);
expect(
ImperfectQuality.augmented.inverted,
ImperfectQuality.augmented.inversion,
ImperfectQuality.diminished,
);
expect(
ImperfectQuality.doublyAugmented.inverted,
ImperfectQuality.doublyAugmented.inversion,
ImperfectQuality.doublyDiminished,
);
});
Expand Down
Loading

0 comments on commit e3af0f7

Please sign in to comment.