Skip to content

Commit

Permalink
refactor(scale_pattern): ♻️ extract bit-related methods into `BinaryS…
Browse files Browse the repository at this point in the history
…equence` extension (#479)

Signed-off-by: Albert Mañosa <26429103+albertms10@users.noreply.github.com>
  • Loading branch information
albertms10 committed Apr 18, 2024
1 parent 676ffa7 commit 3a2dcc0
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 18 deletions.
30 changes: 17 additions & 13 deletions lib/src/scale/scale_pattern.dart
Original file line number Diff line number Diff line change
Expand Up @@ -250,19 +250,12 @@ final class ScalePattern {
return major;
}

static int _bitAt(int sequence, int index) => sequence & 1 << index;

static int _toBit(int sequence, Scalable<PitchClass> scalable) =>
sequence | 1 << scalable.semitones;

/// Creates a new [ScalePattern] from a binary [sequence] in integer form.
///
/// This method and [ScalePattern.toBinary] are inverses of each other.
///
/// Example:
/// ```dart
/// extension on int { int get b => int.parse(toString(), radix: 2); }
///
/// ScalePattern.fromBinary(101010110101.b) == ScalePattern.major
/// ScalePattern.fromBinary(111111111111.b) == ScalePattern.chromatic
/// ScalePattern.fromBinary(1010010101.b) == ScalePattern.majorPentatonic
Expand All @@ -274,15 +267,15 @@ final class ScalePattern {

final degrees = [
for (int i = 0; i < chromaticDivisions; i++)
if (_bitAt(sequence, i) != 0) PitchClass(i),
if (sequence.bitAt(i) != 0) PitchClass(i),
PitchClass.c,
];
final descendingDegrees = descendingSequence == null
? null
: [
PitchClass.c,
for (int i = chromaticDivisions - 1; i >= 0; i--)
if (_bitAt(descendingSequence, i) != 0) PitchClass(i),
if (descendingSequence.bitAt(i) != 0) PitchClass(i),
];

return Scale(degrees, descendingDegrees).pattern;
Expand All @@ -294,21 +287,19 @@ final class ScalePattern {
///
/// Example:
/// ```dart
/// extension on int { int get b => int.parse(toString(), radix: 2); }
///
/// ScalePattern.major.toBinary() == (101010110101.b, null)
/// ScalePattern.chromatic.toBinary() == (111111111111.b, null)
/// ScalePattern.majorPentatonic.toBinary() == (1010010101.b, null)
/// ScalePattern.melodicMinor.toBinary() == (101010101101.b, 10110101101.b)
/// ```
(int sequence, int? descendingSequence) toBinary() {
final scale = on(PitchClass.c);
final sequence = scale.degrees.fold(0, _toBit);
final sequence = scale.degrees.fold(0, BinarySequence.bitFrom);
final cachedDescending = scale.descendingDegrees;
final descendingSequence =
cachedDescending.reversed.isEnharmonicWith(scale.degrees)
? null
: cachedDescending.fold(0, _toBit);
: cachedDescending.fold(0, BinarySequence.bitFrom);

return (sequence, descendingSequence);
}
Expand Down Expand Up @@ -480,3 +471,16 @@ final class ScalePattern {
: null,
);
}

/// A binary sequence int extension.
extension BinarySequence on int {
/// The bit at [index].
int bitAt(int index) => this & 1 << index;

/// The bit from [sequence] and [scalable] semitones.
static int bitFrom(int sequence, Scalable<PitchClass> scalable) =>
sequence | 1 << scalable.semitones;

/// This [int] as a binary integer.
int get b => int.parse(toString(), radix: 2);
}
5 changes: 0 additions & 5 deletions test/src/scale/scale_pattern_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -666,8 +666,3 @@ void main() {
});
});
}

extension on int {
/// Parse this [String] as a binary integer.
int get b => int.parse(toString(), radix: 2);
}

0 comments on commit 3a2dcc0

Please sign in to comment.