Skip to content

Commit

Permalink
refactor!(pitch_class): ♻️ move integerNotation to toString (#315)
Browse files Browse the repository at this point in the history
  • Loading branch information
albertms10 committed Nov 27, 2023
1 parent 7e85546 commit 61a38db
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 40 deletions.
56 changes: 38 additions & 18 deletions lib/src/note/pitch_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,23 +182,6 @@ final class PitchClass implements Scalable<PitchClass>, Comparable<PitchClass> {
@override
int difference(PitchClass other) => other.chroma - chroma;

/// Returns the integer notation for this [PitchClass].
///
/// See [Integer notation](https://en.wikipedia.org/wiki/Pitch_class#Integer_notation).
///
/// Example:
/// ```dart
/// PitchClass.c.integerNotation == '0'
/// PitchClass.f.integerNotation == '5'
/// PitchClass.aSharp.integerNotation == 't'
/// PitchClass.b.integerNotation == 'e'
/// ```
String get integerNotation => switch (chroma) {
10 => 't',
11 => 'e',
final chroma => '$chroma',
};

/// Performs a pitch-class multiplication modulo [chromaticDivisions] of this
/// [PitchClass].
///
Expand All @@ -224,8 +207,36 @@ final class PitchClass implements Scalable<PitchClass>, Comparable<PitchClass> {
/// See [Pitch-class multiplication modulo 12](https://en.wikipedia.org/wiki/Multiplication_(music)#Pitch-class_multiplication_modulo_12).
PitchClass operator *(int factor) => PitchClass(chroma * factor);

String get _enharmonicSpellingsNotation => '{${spellings().join('|')}}';

String get _integerNotation => switch (chroma) {
10 => 't',
11 => 'e',
final chroma => '$chroma',
};

/// Returns the string representation of this [PitchClass] based on
/// [notation].
///
/// Example:
/// ```dart
/// PitchClass.c.toString() == '{C}'
/// PitchClass.g.toString() == '{G}'
/// PitchClass.dSharp.toString() == '{D♯|E♭}'
///
/// PitchClass.c.toString(notation: PitchClassNotation.integer) == '0'
/// PitchClass.f.toString(notation: PitchClassNotation.integer) == '5'
/// PitchClass.aSharp.toString(notation: PitchClassNotation.integer) == 't'
/// PitchClass.b.toString(notation: PitchClassNotation.integer) == 'e'
/// ```
@override
String toString() => '{${spellings().join('|')}}';
String toString({
PitchClassNotation notation = PitchClassNotation.enharmonicSpellings,
}) =>
switch (notation) {
PitchClassNotation.enharmonicSpellings => _enharmonicSpellingsNotation,
PitchClassNotation.integer => _integerNotation,
};

@override
bool operator ==(Object other) =>
Expand All @@ -237,3 +248,12 @@ final class PitchClass implements Scalable<PitchClass>, Comparable<PitchClass> {
@override
int compareTo(PitchClass other) => chroma.compareTo(other.chroma);
}

/// Pitch-class notations.
enum PitchClassNotation {
/// See [Tonal counterparts](https://en.wikipedia.org/wiki/Pitch_class#Other_ways_to_label_pitch_classes).
enharmonicSpellings,

/// See [Integer notation](https://en.wikipedia.org/wiki/Pitch_class#Integer_notation).
integer;
}
94 changes: 72 additions & 22 deletions test/src/note/pitch_class_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -306,23 +306,6 @@ void main() {
});
});

group('.integerNotation', () {
test('should return the integer notation for this PitchClass', () {
expect(PitchClass.c.integerNotation, '0');
expect(PitchClass.cSharp.integerNotation, '1');
expect(PitchClass.d.integerNotation, '2');
expect(PitchClass.dSharp.integerNotation, '3');
expect(PitchClass.e.integerNotation, '4');
expect(PitchClass.f.integerNotation, '5');
expect(PitchClass.fSharp.integerNotation, '6');
expect(PitchClass.g.integerNotation, '7');
expect(PitchClass.gSharp.integerNotation, '8');
expect(PitchClass.a.integerNotation, '9');
expect(PitchClass.aSharp.integerNotation, 't');
expect(PitchClass.b.integerNotation, 'e');
});
});

group('operator *', () {
test(
'should return the pitch-class multiplication modulo 12 of this '
Expand Down Expand Up @@ -350,11 +333,78 @@ void main() {
});

group('.toString()', () {
test('should return a string representation of this PitchClass', () {
expect(PitchClass.c.toString(), '{C}');
expect(PitchClass.g.toString(), '{G}');
expect(PitchClass.dSharp.toString(), '{D♯|E♭}');
});
test(
'should return the enharmonic spellings string representation of '
'this PitchClass',
() {
expect(PitchClass.c.toString(), '{C}');
expect(PitchClass.cSharp.toString(), '{C♯|D♭}');
expect(PitchClass.d.toString(), '{D}');
expect(PitchClass.dSharp.toString(), '{D♯|E♭}');
expect(PitchClass.e.toString(), '{E}');
expect(PitchClass.f.toString(), '{F}');
expect(PitchClass.fSharp.toString(), '{F♯|G♭}');
expect(PitchClass.g.toString(), '{G}');
expect(PitchClass.gSharp.toString(), '{G♯|A♭}');
expect(PitchClass.a.toString(), '{A}');
expect(PitchClass.aSharp.toString(), '{A♯|B♭}');
expect(PitchClass.b.toString(), '{B}');
},
);

test(
'should return the integer string representation of this PitchClass',
() {
expect(
PitchClass.c.toString(notation: PitchClassNotation.integer),
'0',
);
expect(
PitchClass.cSharp.toString(notation: PitchClassNotation.integer),
'1',
);
expect(
PitchClass.d.toString(notation: PitchClassNotation.integer),
'2',
);
expect(
PitchClass.dSharp.toString(notation: PitchClassNotation.integer),
'3',
);
expect(
PitchClass.e.toString(notation: PitchClassNotation.integer),
'4',
);
expect(
PitchClass.f.toString(notation: PitchClassNotation.integer),
'5',
);
expect(
PitchClass.fSharp.toString(notation: PitchClassNotation.integer),
'6',
);
expect(
PitchClass.g.toString(notation: PitchClassNotation.integer),
'7',
);
expect(
PitchClass.gSharp.toString(notation: PitchClassNotation.integer),
'8',
);
expect(
PitchClass.a.toString(notation: PitchClassNotation.integer),
'9',
);
expect(
PitchClass.aSharp.toString(notation: PitchClassNotation.integer),
't',
);
expect(
PitchClass.b.toString(notation: PitchClassNotation.integer),
'e',
);
},
);
});

group('.hashCode', () {
Expand Down

0 comments on commit 61a38db

Please sign in to comment.