Skip to content

Commit

Permalink
refactor(scale_degree): ♻️ extract romanNumeral getter
Browse files Browse the repository at this point in the history
  • Loading branch information
albertms10 committed Mar 7, 2024
1 parent c049609 commit a616e0e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 35 deletions.
56 changes: 29 additions & 27 deletions lib/src/scale/scale_degree.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,25 @@ class ScaleDegree implements Comparable<ScaleDegree> {
semitonesDelta: semitonesDelta,
);

/// Returns the roman numeral of this [ScaleDegree] based on [ordinal].
///
/// Example:
/// ```dart
/// ScaleDegree.i.romanNumeral == 'I'
/// ScaleDegree.vii.romanNumeral == 'VII'
/// ScaleDegree.neapolitanSixth.romanNumeral == 'II'
/// ```
String get romanNumeral => switch (ordinal) {
1 => 'I',
2 => 'II',
3 => 'III',
4 => 'IV',
5 => 'V',
6 => 'VI',
7 => 'VII',
_ => '',
};

@override
String toString({
ScaleDegreeNotation system = ScaleDegreeNotation.standard,
Expand Down Expand Up @@ -203,33 +222,16 @@ final class StandardScaleDegreeNotation extends ScaleDegreeNotation {

@override
String scaleDegree(ScaleDegree scaleDegree) {
final buffer = StringBuffer();
if (scaleDegree.semitonesDelta != 0) {
buffer.write(Accidental(scaleDegree.semitonesDelta).symbol);
}
final romanNumeral = switch (scaleDegree.ordinal) {
1 => 'I',
2 => 'II',
3 => 'III',
4 => 'IV',
5 => 'V',
6 => 'VI',
7 => 'VII',
_ => '',
};

if (scaleDegree.quality != null && scaleDegree.quality!.semitones <= 0) {
buffer.write(romanNumeral.toLowerCase());
} else {
buffer.write(romanNumeral);
}

switch (scaleDegree.inversion) {
case 1:
buffer.write('6');
case 2:
buffer.write('64');
}
final buffer = StringBuffer()
..writeAll([
if (scaleDegree.semitonesDelta != 0)
Accidental(scaleDegree.semitonesDelta).symbol,
if (scaleDegree.quality != null && scaleDegree.quality!.semitones <= 0)
scaleDegree.romanNumeral.toLowerCase()
else
scaleDegree.romanNumeral,
switch (scaleDegree.inversion) { 1 => '6', 2 => '64', _ => '' },
]);

return buffer.toString();
}
Expand Down
17 changes: 9 additions & 8 deletions lib/src/scale/scale_pattern.dart
Original file line number Diff line number Diff line change
Expand Up @@ -337,18 +337,19 @@ final class ScalePattern {
return ChordPattern.fromQuality(scaleDegree.quality!);
}

Interval step(int ordinal) =>
intervalSteps[(ordinal - 1) % intervalSteps.length];

Interval addNextStep(int ordinal) => step(ordinal) + step(ordinal + 1);

// Calculate the diatonic pattern from this Scale's `intervalSteps`.
// Deduce the diatonic `ChordPattern` from this `Scale.intervalSteps`.
return ChordPattern.fromIntervalSteps([
addNextStep(scaleDegree.ordinal),
addNextStep(scaleDegree.ordinal + 2),
_addNextStepTo(scaleDegree.ordinal),
_addNextStepTo(scaleDegree.ordinal + 2),
]);
}

Interval _stepFrom(int ordinal) =>
intervalSteps[(ordinal - 1) % intervalSteps.length];

Interval _addNextStepTo(int ordinal) =>
_stepFrom(ordinal) + _stepFrom(ordinal + 1);

/// Whether this [Scale] is enharmonically equivalent to [other].
///
/// Example:
Expand Down
13 changes: 13 additions & 0 deletions test/src/scale/scale_degree_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ void main() {
});
});

group('.romanNumeral', () {
test('returns the roman numeral of this ScaleDegree', () {
expect(ScaleDegree.i.romanNumeral, 'I');
expect(ScaleDegree.ii.minor.romanNumeral, 'II');
expect(ScaleDegree.iii.minor.inverted.romanNumeral, 'III');
expect(ScaleDegree.iv.major.lowered.romanNumeral, 'IV');
expect(ScaleDegree.v.minor.raised.romanNumeral, 'V');
expect(ScaleDegree.vi.romanNumeral, 'VI');
expect(ScaleDegree.vii.romanNumeral, 'VII');
expect(const ScaleDegree(8).romanNumeral, '');
});
});

group('.toString()', () {
test('returns the string representation of this ScaleDegree', () {
expect(ScaleDegree.i.toString(), 'I');
Expand Down

0 comments on commit a616e0e

Please sign in to comment.