Skip to content

Commit

Permalink
fix(pitch): 🐛 address harmonics wrongly forwarding parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
albertms10 committed Mar 27, 2024
1 parent 063679a commit 4c98f15
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 19 deletions.
18 changes: 1 addition & 17 deletions lib/src/note/frequency.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,11 @@ extension type const Frequency._(num hertz) implements num {
///
/// Note.a.inOctave(5).frequency().harmonics(upToIndex: -2)
/// == {const Frequency(880), const Frequency(440), const Frequency(293.33)}
///
/// Note.c.inOctave(1).frequency().harmonics(upToIndex: 7).closestPitches
/// .toString() == '{C1, C2, G2+2, C3, E3-14, G3+2, A♯3-31, C4}'
/// ```
///
/// ---
/// See also:
/// - [FrequencyIterableExtension.closestPitches].
/// * [Pitch.harmonics] for a [ClosestPitch] set of harmonic series.
Set<Frequency> harmonics({required int upToIndex}) => {
for (var i = 0; i <= upToIndex.abs(); i++) harmonic(i * upToIndex.sign),
};
Expand All @@ -136,19 +133,6 @@ extension type const Frequency._(num hertz) implements num {
String format() => '$hertz $hertzUnitSymbol';
}

/// A [Frequency] Iterable extension.
extension FrequencyIterableExtension on Iterable<Frequency> {
/// The set of [ClosestPitch] for each [Frequency] element.
///
/// Example:
/// ```dart
/// Note.c.inOctave(1).frequency().harmonics(upToIndex: 7).closestPitches
/// .toString() == '{C1, C2, G2+2, C3, E3-14, G3+2, A♯3-31, C4}'
/// ```
Set<ClosestPitch> get closestPitches =>
map((frequency) => frequency.closestPitch()).toSet();
}

/// A Frequency extension based on temperature.
extension TemperatureFrequency on Frequency {
/// Speed of sound at [Celsius.zero] in m/s.
Expand Down
14 changes: 12 additions & 2 deletions lib/src/note/pitch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -433,8 +433,18 @@ final class Pitch extends Scalable<Pitch> implements Comparable<Pitch> {
frequency(
referenceFrequency: referenceFrequency,
tuningSystem: tuningSystem,
temperature: temperature,
).harmonics(upToIndex: upToIndex).closestPitches;
// we deliberately omit the temperature here, as the subsequent call to
// `Frequency.closestPitch` will already take it into account.
)
.harmonics(upToIndex: upToIndex)
.map(
(frequency) => frequency.closestPitch(
referenceFrequency: referenceFrequency,
tuningSystem: tuningSystem,
temperature: temperature,
),
)
.toSet();

/// The string representation of this [Pitch] based on [system].
///
Expand Down
35 changes: 35 additions & 0 deletions test/src/note/pitch_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,41 @@ void main() {
'{C1, C2, G2+2, C3, E3-14, G3+2, A♯3-31, C4, D4+4, '
'E4-14, F♯4-49, G4+2, A♭4+41, A♯4-31, B4-12, C5}',
);

expect(
Note.c
.inOctave(1)
.harmonics(
upToIndex: 15,
referenceFrequency: const Frequency(438),
)
.toString(),
'{C1, C2, G2+2, C3, E3-14, G3+2, A♯3-31, C4, D4+4, '
'E4-14, F♯4-49, G4+2, A♭4+41, A♯4-31, B4-12, C5}',
);

expect(
Note.c
.inOctave(1)
.harmonics(
upToIndex: 15,
referenceFrequency: const Frequency(256),
tuningSystem: EqualTemperament.edo12(
referencePitch: Note.c.inOctave(4),
),
)
.toString(),
'{C1, C2, G2+2, C3, E3-14, G3+2, A♯3-31, C4, D4+4, '
'E4-14, F♯4-49, G4+2, A♭4+41, A♯4-31, B4-12, C5}',
);

expect(
Note.c
.inOctave(1)
.harmonics(upToIndex: 7, temperature: const Celsius(18))
.toString(),
'{C1+6, C2+6, G2+8, C3+6, E3-8, G3+8, A♯3-25, C4+6}',
);
});
});

Expand Down

0 comments on commit 4c98f15

Please sign in to comment.