Skip to content

Commit

Permalink
refactor(enharmonic): ♻️ rename ClassMixinEnharmonic mixin (#452)
Browse files Browse the repository at this point in the history
* refactor(enharmonic): ♻️ rename `ClassMixin` → `Enharmonic` mixin

* refactor!(note): 🔥 remove deprecated `toPitchClass` method
  • Loading branch information
albertms10 committed Mar 26, 2024
1 parent b68a92e commit 34eda40
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 40 deletions.
27 changes: 13 additions & 14 deletions lib/src/class_mixin.dart → lib/src/enharmonic.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import 'package:collection/collection.dart' show IterableEquality;

/// A Class mixin.
mixin ClassMixin<Class> {
/// The number of semitones that define this [Class].
/// An enharmonic mixin.
mixin Enharmonic<C> {
/// The number of semitones that define this [C].
int get semitones;

/// Creates a new [Class] from [semitones].
Class toClass();
/// Creates a new [C] from [semitones].
C toClass();

/// Whether [Class] is enharmonically equivalent to [other].
/// Whether [C] is enharmonically equivalent to [other].
///
/// See [Enharmonic equivalence](https://en.wikipedia.org/wiki/Enharmonic_equivalence).
///
Expand All @@ -18,14 +18,13 @@ mixin ClassMixin<Class> {
/// Note.c.isEnharmonicWith(Note.b.sharp) == true
/// Note.e.isEnharmonicWith(Note.f) == false
/// ```
bool isEnharmonicWith(ClassMixin<Class> other) =>
toClass() == other.toClass();
bool isEnharmonicWith(Enharmonic<C> other) => toClass() == other.toClass();
}

/// A Class iterable.
extension ClassIterable<Class> on Iterable<ClassMixin<Class>> {
/// The [Class] representation of this [Iterable].
Iterable<Class> toClass() => map((interval) => interval.toClass());
/// An enharmonic iterable.
extension EnharmonicIterable<C> on Iterable<Enharmonic<C>> {
/// The [C] representation of this [Iterable].
Iterable<C> toClass() => map((interval) => interval.toClass());

/// Whether this [Iterable] is enharmonically equivalent to [other].
///
Expand All @@ -45,6 +44,6 @@ extension ClassIterable<Class> on Iterable<ClassMixin<Class>> {
///
/// const [Interval.m2].isEnharmonicWith(const [Interval.P4]) == false
/// ```
bool isEnharmonicWith(Iterable<ClassMixin<Class>> other) =>
IterableEquality<Class>().equals(toClass(), other.toClass());
bool isEnharmonicWith(Iterable<Enharmonic<C>> other) =>
IterableEquality<C>().equals(toClass(), other.toClass());
}
8 changes: 4 additions & 4 deletions lib/src/interval/interval.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import 'package:meta/meta.dart' show immutable;
import 'package:music_notes/utils.dart';

import '../class_mixin.dart';
import '../enharmonic.dart';
import '../note/note.dart';
import '../scalable.dart';
import 'interval_class.dart';
Expand All @@ -18,7 +18,7 @@ import 'size.dart';
/// * [IntervalClass].
@immutable
final class Interval
with ClassMixin<IntervalClass>
with Enharmonic<IntervalClass>
implements Comparable<Interval> {
/// Number of lines and spaces (or alphabet letters) spanning the two notes,
/// including the beginning and end.
Expand Down Expand Up @@ -327,9 +327,9 @@ final class Interval
/// Example:
/// ```dart
/// Interval.P5.distanceBetween(Note.c, Note.d)
/// == (2, notes: const [Note.c, Note.g, Note.d])
/// == const (2, notes: [Note.c, Note.g, Note.d])
/// Interval.P5.distanceBetween(Note.a, Note.g)
/// == (-2, notes: const [Note.a, Note.d, Note.g])
/// == const (-2, notes: [Note.a, Note.d, Note.g])
/// (-Interval.P5).distanceBetween(Note.b.flat, Note.d)
/// == (-4, notes: [Note.b.flat, Note.f, Note.d, Note.g, Note.d])
/// Interval.P4.distanceBetween(Note.f, Note.a.flat)
Expand Down
2 changes: 1 addition & 1 deletion lib/src/interval/interval_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'size.dart';
/// The shortest distance in pitch class space between two unordered
/// [PitchClass]es.
///
/// The largest [IntervalClass] is [IntervalClass.tritone] (6) since any greater
/// The largest [IntervalClass] is the [tritone] (6 semitones) since any greater
/// interval `n` may be reduced to `chromaticDivisions - n`.
///
/// See [Interval class](https://en.wikipedia.org/wiki/Interval_class).
Expand Down
11 changes: 0 additions & 11 deletions lib/src/note/note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import '../scalable.dart';
import 'accidental.dart';
import 'base_note.dart';
import 'pitch.dart';
import 'pitch_class.dart';

/// A musical note.
///
Expand Down Expand Up @@ -408,16 +407,6 @@ final class Note extends Scalable<Note> implements Comparable<Note> {
);
}

/// Creates a new [PitchClass] from [semitones].
///
/// Example:
/// ```dart
/// Note.c.toPitchClass() == PitchClass.c
/// Note.e.sharp.toPitchClass() == PitchClass.f
/// Note.c.flat.flat.toPitchClass() == PitchClass.aSharp
/// ```
PitchClass toPitchClass() => PitchClass(semitones);

/// The string representation of this [Note] based on [system].
///
/// See [NoteNotation] for all system implementations.
Expand Down
4 changes: 2 additions & 2 deletions lib/src/scalable.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import 'class_mixin.dart';
import 'enharmonic.dart';
import 'interval/interval.dart';
import 'music.dart';
import 'note/pitch_class.dart';
import 'transposable.dart';

/// A interface for items that can form scales.
abstract class Scalable<T extends Scalable<T>>
with ClassMixin<PitchClass>
with Enharmonic<PitchClass>
implements Transposable<T> {
/// Creates a new [Scalable].
const Scalable();
Expand Down
2 changes: 1 addition & 1 deletion lib/src/scale/scale.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:collection/collection.dart'
show ListEquality, UnmodifiableListView;
import 'package:meta/meta.dart' show immutable;

import '../class_mixin.dart';
import '../enharmonic.dart';
import '../harmony/chord.dart';
import '../harmony/harmonic_function.dart';
import '../interval/interval.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/src/scale/scale_pattern.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:collection/collection.dart' show UnmodifiableListView;
import 'package:meta/meta.dart' show immutable;

import '../class_mixin.dart';
import '../enharmonic.dart';
import '../harmony/chord_pattern.dart';
import '../interval/interval.dart';
import '../music.dart';
Expand Down
12 changes: 6 additions & 6 deletions test/src/note/note_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -648,13 +648,13 @@ void main() {
});
});

group('.toPitchClass()', () {
group('.toClass()', () {
test('creates a new PitchClass from semitones', () {
expect(Note.c.toPitchClass(), PitchClass.c);
expect(Note.d.sharp.toPitchClass(), PitchClass.dSharp);
expect(Note.e.flat.toPitchClass(), PitchClass.dSharp);
expect(Note.e.sharp.toPitchClass(), PitchClass.f);
expect(Note.c.flat.flat.toPitchClass(), PitchClass.aSharp);
expect(Note.c.toClass(), PitchClass.c);
expect(Note.d.sharp.toClass(), PitchClass.dSharp);
expect(Note.e.flat.toClass(), PitchClass.dSharp);
expect(Note.e.sharp.toClass(), PitchClass.f);
expect(Note.c.flat.flat.toClass(), PitchClass.aSharp);
});
});

Expand Down

0 comments on commit 34eda40

Please sign in to comment.