Skip to content

Commit

Permalink
refactor(interval_size_extension): rename extension (#74)
Browse files Browse the repository at this point in the history
* refactor(interval_size_extension): rename extension

* refactor: use `size` consistently

* style: remove empty line
  • Loading branch information
albertms10 committed Apr 24, 2023
1 parent 920d295 commit bbdd02a
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 77 deletions.
2 changes: 1 addition & 1 deletion lib/music_notes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'utils/num_extension.dart';

part 'src/enharmonic.dart';
part 'src/interval/enharmonic_interval.dart';
part 'src/interval/int_interval_extension.dart';
part 'src/interval/interval_size_extension.dart';
part 'src/interval/interval.dart';
part 'src/interval/quality.dart';
part 'src/music.dart';
Expand Down
18 changes: 9 additions & 9 deletions lib/src/interval/enharmonic_interval.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ class EnharmonicInterval extends Enharmonic<Interval> {
@override
Set<Interval> get items {
final semitones = this.semitones.abs();
final interval = IntIntervalExtension.fromSemitones(semitones);
final size = IntervalSizeExtension.fromSemitones(semitones);

if (interval != null) {
if (size != null) {
return SplayTreeSet<Interval>.of({
if (interval > 1) Interval.fromSemitones(interval - 1, semitones),
Interval.fromSemitones(interval, semitones),
Interval.fromSemitones(interval + 1, semitones),
if (size > 1) Interval.fromSemitones(size - 1, semitones),
Interval.fromSemitones(size, semitones),
Interval.fromSemitones(size + 1, semitones),
});
}

final intervalBelow = IntIntervalExtension.fromSemitones(semitones - 1);
final intervalAbove = IntIntervalExtension.fromSemitones(semitones + 1);
final sizeBelow = IntervalSizeExtension.fromSemitones(semitones - 1);
final sizeAbove = IntervalSizeExtension.fromSemitones(semitones + 1);

return SplayTreeSet<Interval>.of({
Interval.fromSemitones(intervalBelow!, semitones),
Interval.fromSemitones(intervalAbove!, semitones),
Interval.fromSemitones(sizeBelow!, semitones),
Interval.fromSemitones(sizeAbove!, semitones),
});
}

Expand Down
4 changes: 2 additions & 2 deletions lib/src/interval/interval.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Interval implements MusicItem {
/// Creates a new [Interval] allowing only perfect quality [size]s.
const Interval.perfect(this.size, PerfectQuality this.quality)
: assert(size != 0, 'Size must be non-zero'),
// Copied from [IntIntervalExtension.isPerfect] to allow const.
// Copied from [IntervalSizeExtension.isPerfect] to allow const.
assert(
((size < 0 ? -size : size) + (size < 0 ? -size : size) ~/ 8) % 4 < 2,
'Interval must be perfect',
Expand All @@ -75,7 +75,7 @@ class Interval implements MusicItem {
/// Creates a new [Interval] allowing only imperfect quality [size]s.
const Interval.imperfect(this.size, ImperfectQuality this.quality)
: assert(size != 0, 'Size must be non-zero'),
// Copied from [IntIntervalExtension.isPerfect] to allow const.
// Copied from [IntervalSizeExtension.isPerfect] to allow const.
assert(
((size < 0 ? -size : size) + (size < 0 ? -size : size) ~/ 8) % 4 >= 2,
'Interval must be imperfect',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
part of '../../music_notes.dart';

extension IntIntervalExtension on int {
extension IntervalSizeExtension on int {
static const Map<int, int> _sizeToSemitones = {
1: 0,
2: 1,
Expand All @@ -12,35 +12,36 @@ extension IntIntervalExtension on int {
8: 12,
};

/// Returns an [int] interval that matches with [semitones]
/// Returns the [Interval.size] that matches with [semitones]
/// in [_sizeToSemitones], otherwise returns `null`.
///
/// Example:
/// ```dart
/// IntIntervalExtension.fromSemitones(8) == 6
/// IntIntervalExtension.fromSemitones(0) == 1
/// IntIntervalExtension.fromSemitones(-12) == -8
/// IntIntervalExtension.fromSemitones(4) == null
/// IntervalSizeExtension.fromSemitones(8) == 6
/// IntervalSizeExtension.fromSemitones(0) == 1
/// IntervalSizeExtension.fromSemitones(-12) == -8
/// IntervalSizeExtension.fromSemitones(4) == null
/// ```
static int? fromSemitones(int semitones) {
final absoluteSemitones = semitones.abs();
final size = _sizeToSemitones.keys.firstWhereOrNull(
(interval) =>
final matchingSize = _sizeToSemitones.keys.firstWhereOrNull(
(size) =>
(absoluteSemitones == chromaticDivisions
? chromaticDivisions
: absoluteSemitones.chromaticMod) ==
_sizeToSemitones[interval],
_sizeToSemitones[size],
);
if (size == null) return null;
if (absoluteSemitones == 12) return size * semitones.sign;
if (matchingSize == null) return null;
if (absoluteSemitones == 12) return matchingSize * semitones.sign;

final absResult = size + (absoluteSemitones ~/ chromaticDivisions) * 7;
final absResult =
matchingSize + (absoluteSemitones ~/ chromaticDivisions) * 7;

return absResult * (semitones.isNegative ? -1 : 1);
}

/// Returns the number of semitones of this [int] for a perfect interval or a
/// minor interval, where appropriate.
/// Returns the number of semitones of this [Interval.size] for the
/// corresponding perfect or minor interval, where appropriate.
///
/// Example:
/// ```dart
Expand All @@ -59,7 +60,7 @@ extension IntIntervalExtension on int {
sign;
}

/// Returns `true` if this [int] interval is a perfect interval.
/// Returns `true` if this [Interval.size] conforms a perfect interval.
///
/// Example:
/// ```dart
Expand All @@ -73,7 +74,7 @@ extension IntIntervalExtension on int {
return (abs() + abs() ~/ 8) % 4 < 2;
}

/// Returns whether this [int] interval is greater than an octave.
/// Returns whether this [Interval.size] is greater than an octave.
///
/// Example:
/// ```dart
Expand All @@ -90,7 +91,7 @@ extension IntIntervalExtension on int {
return abs() > 8;
}

/// Whether this [int] interval is dissonant.
/// Whether this [Interval.size] is dissonant.
///
/// Example:
/// ```dart
Expand All @@ -105,7 +106,7 @@ extension IntIntervalExtension on int {
return const {2, 7}.contains(simplified.abs());
}

/// Returns a simplified [int] interval.
/// Returns the simplified version of this [Interval.size].
///
/// Example:
/// ```dart
Expand All @@ -119,7 +120,7 @@ extension IntIntervalExtension on int {
return isCompound ? (abs().nModExcludeZero(8) + 1) * sign : this;
}

/// Returns an inverted this [int] interval.
/// Returns the inverted of this [Interval.size].
///
/// Example:
/// ```dart
Expand All @@ -128,8 +129,8 @@ extension IntIntervalExtension on int {
/// (-1).inverted == -8
/// ```
///
/// If an interval is greater than an octave, the simplified
/// [int] interval inversion is returned instead.
/// If this [Interval.size] is greater than an octave, the simplified
/// inversion is returned instead.
///
/// Example:
/// ```dart
Expand Down
6 changes: 3 additions & 3 deletions lib/src/interval/quality.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ abstract class Quality implements MusicItem {
/// Creates a new [Quality] from [semitones].
const Quality(this.semitones);

/// Creates a new [PerfectQuality] or [ImperfectQuality] from [interval].
/// Creates a new [PerfectQuality] or [ImperfectQuality] from interval [size].
///
/// Example:
/// ```dart
/// Quality.fromInterval(5, 0) == PerfectQuality.perfect
/// Quality.fromInterval(3, 1) == ImperfectQuality.major
/// Quality.fromInterval(6, 0) == ImperfectQuality.minor
/// ```
factory Quality.fromInterval(int interval, int semitones) {
factory Quality.fromInterval(int size, int semitones) {
final qualityConstructor =
interval.isPerfect ? PerfectQuality.new : ImperfectQuality.new;
size.isPerfect ? PerfectQuality.new : ImperfectQuality.new;

return qualityConstructor(semitones);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/src/note/notes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ enum Notes {
/// ```
int get ordinal => Notes.values.indexOf(this) + 1;

/// Returns the interval size that conforms between this [Notes] enum item and
/// [other].
/// Returns the [Interval.size] that conforms between this [Notes] enum item
/// and [other].
///
/// Example:
/// ```dart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,45 @@ import 'package:music_notes/music_notes.dart';
import 'package:test/test.dart';

void main() {
group('IntIntervalExtension', () {
group('IntervalSizeExtension', () {
group('.fromSemitones()', () {
test(
'should return the int interval with the corresponding semitones',
'should return the Interval size corresponding to the given semitones',
() {
expect(IntIntervalExtension.fromSemitones(-12), -8);
expect(IntIntervalExtension.fromSemitones(-5), -4);
expect(IntIntervalExtension.fromSemitones(-3), -3);
expect(IntIntervalExtension.fromSemitones(-1), -2);
expect(IntIntervalExtension.fromSemitones(0), 1);
expect(IntIntervalExtension.fromSemitones(1), 2);
expect(IntIntervalExtension.fromSemitones(3), 3);
expect(IntIntervalExtension.fromSemitones(5), 4);
expect(IntIntervalExtension.fromSemitones(7), 5);
expect(IntIntervalExtension.fromSemitones(8), 6);
expect(IntIntervalExtension.fromSemitones(10), 7);
expect(IntIntervalExtension.fromSemitones(12), 8);
expect(IntIntervalExtension.fromSemitones(13), 9);
expect(IntIntervalExtension.fromSemitones(15), 10);
expect(IntIntervalExtension.fromSemitones(17), 11);
expect(IntIntervalExtension.fromSemitones(19), 12);
expect(IntIntervalExtension.fromSemitones(20), 13);
expect(IntIntervalExtension.fromSemitones(22), 14);
expect(IntIntervalExtension.fromSemitones(24), 15);
expect(IntIntervalExtension.fromSemitones(36), 22);
expect(IntervalSizeExtension.fromSemitones(-12), -8);
expect(IntervalSizeExtension.fromSemitones(-5), -4);
expect(IntervalSizeExtension.fromSemitones(-3), -3);
expect(IntervalSizeExtension.fromSemitones(-1), -2);
expect(IntervalSizeExtension.fromSemitones(0), 1);
expect(IntervalSizeExtension.fromSemitones(1), 2);
expect(IntervalSizeExtension.fromSemitones(3), 3);
expect(IntervalSizeExtension.fromSemitones(5), 4);
expect(IntervalSizeExtension.fromSemitones(7), 5);
expect(IntervalSizeExtension.fromSemitones(8), 6);
expect(IntervalSizeExtension.fromSemitones(10), 7);
expect(IntervalSizeExtension.fromSemitones(12), 8);
expect(IntervalSizeExtension.fromSemitones(13), 9);
expect(IntervalSizeExtension.fromSemitones(15), 10);
expect(IntervalSizeExtension.fromSemitones(17), 11);
expect(IntervalSizeExtension.fromSemitones(19), 12);
expect(IntervalSizeExtension.fromSemitones(20), 13);
expect(IntervalSizeExtension.fromSemitones(22), 14);
expect(IntervalSizeExtension.fromSemitones(24), 15);
expect(IntervalSizeExtension.fromSemitones(36), 22);
},
);

test(
'should return null when no int interval correspond to the given '
'should return null when no Interval size corresponds to the given '
'semitones',
() {
expect(IntIntervalExtension.fromSemitones(-4), isNull);
expect(IntIntervalExtension.fromSemitones(-2), isNull);
expect(IntIntervalExtension.fromSemitones(2), isNull);
expect(IntIntervalExtension.fromSemitones(4), isNull);
expect(IntIntervalExtension.fromSemitones(6), isNull);
expect(IntIntervalExtension.fromSemitones(9), isNull);
expect(IntIntervalExtension.fromSemitones(11), isNull);
expect(IntervalSizeExtension.fromSemitones(-4), isNull);
expect(IntervalSizeExtension.fromSemitones(-2), isNull);
expect(IntervalSizeExtension.fromSemitones(2), isNull);
expect(IntervalSizeExtension.fromSemitones(4), isNull);
expect(IntervalSizeExtension.fromSemitones(6), isNull);
expect(IntervalSizeExtension.fromSemitones(9), isNull);
expect(IntervalSizeExtension.fromSemitones(11), isNull);
},
);
});
Expand All @@ -50,7 +50,7 @@ void main() {
expect(() => 0.semitones, throwsA(isA<AssertionError>()));
});

test('should return the number of semitones of this int interval', () {
test('should return the number of semitones of this Interval size', () {
expect((-8).semitones, -12);
expect((-7).semitones, -10);
expect((-4).semitones, -5);
Expand All @@ -72,7 +72,7 @@ void main() {
expect(() => 0.isPerfect, throwsA(isA<AssertionError>()));
});

test('should return whether this int interval is perfect', () {
test('should return whether this Interval size is perfect', () {
expect((-13).isPerfect, isFalse);
expect((-11).isPerfect, isTrue);
expect((-9).isPerfect, isFalse);
Expand Down Expand Up @@ -103,7 +103,7 @@ void main() {
expect(() => 0.isCompound, throwsA(isA<AssertionError>()));
});

test('should return whether this int interval is compound', () {
test('should return whether this Interval size is compound', () {
expect((-14).isCompound, isTrue);
expect((-10).isCompound, isTrue);
expect((-8).isCompound, isFalse);
Expand All @@ -122,7 +122,7 @@ void main() {
expect(() => 0.isDissonant, throwsA(isA<AssertionError>()));
});

test('should return whether this int interval is dissonant', () {
test('should return whether this Interval size is dissonant', () {
expect((-14).isDissonant, isTrue);
expect((-13).isDissonant, isFalse);
expect((-12).isDissonant, isFalse);
Expand Down Expand Up @@ -159,7 +159,7 @@ void main() {
expect(() => 0.simplified, throwsA(isA<AssertionError>()));
});

test('should return the simplified int interval', () {
test('should return the simplified Interval size', () {
expect((-13).simplified, -6);
expect((-10).simplified, -3);
expect((-8).simplified, -8);
Expand All @@ -178,7 +178,7 @@ void main() {
expect(() => 0.inverted, throwsA(isA<AssertionError>()));
});

test('should return the inverted int interval', () {
test('should return the inverted Interval size', () {
expect((-13).inverted, -3);
expect((-10).inverted, -6);
expect((-9).inverted, -7);
Expand Down
2 changes: 1 addition & 1 deletion test/src/interval/quality_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:test/test.dart';
void main() {
group('Quality', () {
group('.fromInterval()', () {
test('should create a new Quality from an interval', () {
test('should create a new Quality from an Interval size', () {
expect(Quality.fromInterval(1, -1), PerfectQuality.diminished);
expect(Quality.fromInterval(1, 0), PerfectQuality.perfect);
expect(Quality.fromInterval(1, 1), PerfectQuality.augmented);
Expand Down
2 changes: 1 addition & 1 deletion test/src/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'enharmonic_test.dart' as enharmonic_test;
import 'interval/enharmonic_interval_test.dart' as enharmonic_interval_test;
import 'interval/int_interval_extension_test.dart'
import 'interval/interval_size_extension_test.dart'
as int_interval_extension_test;
import 'interval/interval_test.dart' as interval_test;
import 'interval/quality_test.dart' as quality_test;
Expand Down
2 changes: 1 addition & 1 deletion test/src/note/notes_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:test/test.dart';
void main() {
group('Notes', () {
group('.intervalSize()', () {
test('should return the interval size between this Notes and other', () {
test('should return the Interval size between this Notes and other', () {
expect(Notes.c.intervalSize(Notes.c), 1);
expect(Notes.d.intervalSize(Notes.e), 2);
expect(Notes.e.intervalSize(Notes.f), 2);
Expand Down

0 comments on commit bbdd02a

Please sign in to comment.