Skip to content

Commit

Permalink
refactor(note): 💥 rewrite splitCircleOfFifths method to return `Ite…
Browse files Browse the repository at this point in the history
…rable`s (#574)

Signed-off-by: Albert Mañosa <26429103+albertms10@users.noreply.github.com>
  • Loading branch information
albertms10 authored Jan 23, 2025
1 parent d5271d2 commit aef2508
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 38 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,10 @@ up to a distance:
Interval.P5.circleFrom(Note.c).take(13).toList();
// [C, G, D, A, E, B, F♯, C♯, G♯, D♯, A♯, E♯, B♯]
Note.c.circleOfFifths(distance: 3); // [Eâ™­, Bâ™­, F, C, G, D, A]
Note.c.splitCircleOfFifths();
// (flats: [F, B♭, E♭, A♭, D♭, G♭], sharps: [G, D, A, E, B, F♯])
Note.c.splitCircleOfFifths.down.take(6).toList();
// [F, Bâ™­, Eâ™­, Aâ™­, Dâ™­, Gâ™­]
Note.c.splitCircleOfFifths.up.take(8).toList();
// [G, D, A, E, B, F♯, C♯, G♯]
Note.d.circleOfFifthsDistance; // 2
Note.a.flat.circleOfFifthsDistance; // -4
Expand Down
6 changes: 4 additions & 2 deletions example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,10 @@ void main() {
Interval.P5.circleFrom(Note.c).take(13).toList();
// [C, G, D, A, E, B, F♯, C♯, G♯, D♯, A♯, E♯, B♯]
Note.c.circleOfFifths(distance: 3); // [Eâ™­, Bâ™­, F, C, G, D, A]
Note.c.splitCircleOfFifths();
// (flats: [F, B♭, E♭, A♭, D♭, G♭], sharps: [G, D, A, E, B, F♯])
Note.c.splitCircleOfFifths.down.take(6).toList();
// [F, Bâ™­, Eâ™­, Aâ™­, Dâ™­, Gâ™­]
Note.c.splitCircleOfFifths.up.take(8).toList();
// [G, D, A, E, B, F♯, C♯, G♯]

Note.d.circleOfFifthsDistance; // 2
Note.a.flat.circleOfFifthsDistance; // -4
Expand Down
46 changes: 19 additions & 27 deletions lib/src/note/note.dart
Original file line number Diff line number Diff line change
Expand Up @@ -300,38 +300,26 @@ final class Note extends Scalable<Note>
/// ```
Pitch inOctave(int octave) => Pitch(this, octave: octave);

/// The circle of fifths starting from this [Note] up to [distance],
/// split by `sharps` and `flats`.
/// The circle of fifths starting from this [Note] split by sharps (`up`) and
/// flats (`down`).
///
/// Example:
/// ```dart
/// Note.c.splitCircleOfFifths(distance: 4) == (
/// sharps: [Note.g, Note.d, Note.a, Note.e],
/// flats: [Note.f, Note.b.flat, Note.e.flat, Note.a.flat],
/// )
///
/// Note.a.splitCircleOfFifths(distance: 4) == (
/// sharps: [Note.e, Note.b, Note.f.sharp, Note.c.sharp],
/// flats: [Note.d, Note.g, Note.c, Note.f],
/// )
/// Note.c.splitCircleOfFifths.up.take(6).toList()
/// == [Note.g, Note.d, Note.a, Note.e, Note.b, Note.f.sharp]
///
/// Note.c.splitCircleOfFifths.down.take(4).toList()
/// == [Note.f, Note.b.flat, Note.e.flat, Note.a.flat]
///
/// Note.a.splitCircleOfFifths.up.take(4).toList()
/// == [Note.e, Note.b, Note.f.sharp, Note.c.sharp]
/// ```
/// ---
/// See also:
/// * [circleOfFifths] for a continuous list version of [splitCircleOfFifths].
({List<Note> sharps, List<Note> flats}) splitCircleOfFifths({
int distance = chromaticDivisions ~/ 2,
}) =>
(
sharps: Interval.P5
.circleFrom(this)
.skip(1)
.take(distance.abs())
.toList(growable: false),
flats: Interval.P4
.circleFrom(this)
.skip(1)
.take(distance.abs())
.toList(growable: false),
({Iterable<Note> up, Iterable<Note> down}) get splitCircleOfFifths => (
up: Interval.P5.circleFrom(this).skip(1),
down: Interval.P4.circleFrom(this).skip(1),
);

/// The continuous circle of fifths up to [distance] including this [Note],
Expand Down Expand Up @@ -359,9 +347,13 @@ final class Note extends Scalable<Note>
/// * [splitCircleOfFifths] for a different representation of the same
/// circle of fifths.
List<Note> circleOfFifths({int distance = chromaticDivisions ~/ 2}) {
final (:flats, :sharps) = splitCircleOfFifths(distance: distance);
final (:down, :up) = splitCircleOfFifths;

return [...flats.reversed, this, ...sharps];
return [
...down.take(distance).toList().reversed,
this,
...up.take(distance),
];
}

/// The distance in relation to the circle of fifths.
Expand Down
14 changes: 7 additions & 7 deletions test/src/note/note_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -341,14 +341,14 @@ void main() {
);
});

group('.splitCircleOfFifths()', () {
group('.splitCircleOfFifths', () {
test('returns the split circle of fifths from this Note', () {
var (:sharps, :flats) = Note.c.splitCircleOfFifths();
var (:up, :down) = Note.c.splitCircleOfFifths;
expect(
sharps,
up.take(6),
[Note.g, Note.d, Note.a, Note.e, Note.b, Note.f.sharp],
);
expect(flats, [
expect(down.take(6), [
Note.f,
Note.b.flat,
Note.e.flat,
Expand All @@ -357,9 +357,9 @@ void main() {
Note.g.flat,
]);

(:sharps, :flats) = Note.a.splitCircleOfFifths(distance: 7);
(:up, :down) = Note.a.splitCircleOfFifths;
expect(
sharps,
up.take(7),
[
Note.e,
Note.b,
Expand All @@ -371,7 +371,7 @@ void main() {
],
);
expect(
flats,
down.take(7),
[
Note.d,
Note.g,
Expand Down

0 comments on commit aef2508

Please sign in to comment.