Skip to content

Commit

Permalink
📖 docs(README): write comprehensive API walkthrough (#243)
Browse files Browse the repository at this point in the history
* 📖 docs(README): write comprehensive API walkthrough

* 📖 docs(README): finish documenting Chords and Frequencies

* 📖 docs(README): add more examples for missing classes
  • Loading branch information
albertms10 committed Aug 28, 2023
1 parent 5d9501c commit d055632
Showing 1 changed file with 220 additions and 59 deletions.
279 changes: 220 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,72 +23,231 @@ Import the package into your Dart code:
import 'package:music_notes/music_notes.dart';
```

Now, you can use the provided APIs to perform various music theory operations. Here's briefly how it looks:

```dart
void main() {
// Notes
Note.a.flat; // A♭
Note.c.sharp; // C♯
Note.parse('fx'); // F𝄪
PositionedNote.parse("g''"); // G5
PositionedNote.parse('Bb3'); // B♭3
// Intervals
Note.c.interval(Note.g); // P5
Note.d.interval(Note.f.sharp).inverted; // m6
Note.g.flat.transposeBy(-Interval.m3); // E♭
Interval.P5.circleFrom(Note.c, distance: 12);
// [C, G, D, A, E, B, F♯, C♯, G♯, D♯, A♯, E♯, B♯]
Note.c.circleOfFifths();
// (flats: [F, B♭, E♭, A♭, D♭, G♭], sharps: [G, D, A, E, B, F♯])
// Scales
Note.a.flat.major.scale; // A♭ Major (ionian) (A♭ B♭ C D♭ E♭ F G A♭)
ScalePattern.lydian.on(Note.d).degree(ScaleDegree.iv); // G♯
Note.c.major.scale.functionChord(
HarmonicFunction.dominantV / HarmonicFunction.dominantV,
); // D maj. (D F♯ A)
// Chords
Note.c.majorTriad; // C maj. (C E G)
ChordPattern.augmentedTriad.add11().add13().on(Note.d.sharp);
// D♯ aug. (D♯ F𝄪 A𝄪 G♯ B♯)
Note.f.minorTriad.add7().add9(ImperfectQuality.minor);
// F min. (F A♭ C E♭ G♭)
Note.e.flat.diminishedTriad.add7().transposeBy(Interval.m2);
// F♭ dim. (F♭ A𝄫 C𝄫 E𝄫)
// Frequencies
Note.a.inOctave(4).equalTemperamentFrequency(); // 440.0 Hz
Note.b.flat.inOctave(4).equalTemperamentFrequency(
referenceNote: Note.c.inOctave(4),
referenceFrequency: const Frequency(256),
); // 456.1401436878537 Hz
// Crazy chaining
ScalePattern.lydian // Lydian (M2 M2 M2 m2 M2 M2 m2)
.on(Note.parse('a')) // A Lydian (A B C♯ D♯ E F♯ G♯ A)
.transposeBy(Interval.M2) // B Lydian (B C♯ D♯ E♯ F♯ G♯ A♯ B)
.degree(ScaleDegree.iii) // D♯
.respelledUpwards // E♭
.major // E♭ major
.relative // C minor
.scale // C Natural minor (aeolian) (C D E♭ F G A♭ B♭ C)
.degreeChord(ScaleDegree.v) // G min. (G B♭ D)
.add9(); // G min. (G B♭ D A)
}
```

For more detailed usage instructions and examples, please refer to the [API documentation](https://pub.dev/documentation/music_notes/latest/).
Now, you can use the provided APIs to perform various music theory operations. For more detailed usage instructions and examples, please refer to the [API documentation](https://pub.dev/documentation/music_notes/latest/).

### Notes

Define `Note`s from the musical scale:

```dart
Note.c; // C
Note.d; // D
Note.f; // D
```

Alter them:

```dart
Note.c.sharp; // C♯
Note.d.flat; // D♭
Note.g.flat.flat // G𝄫
Note.f.sharp.sharp.sharp; // F𝄪♯
```

And position them in the octave, resulting in `PositionedNote`s:

```dart
Note.f.inOctave(4); // F4
Note.b.flat.inOctave(5); // B♭5
```

Or just parse them in both scientific and Helmholtz notations:

```dart
Note.parse('a#'); // A♯
PositionedNote.parse("g''"); // G5
PositionedNote.parse('Bb3'); // B♭3
```

### Intervals

Create an `Interval`:

```dart
Interval.perfect(5, PerfectQuality.perfect); // P5
Interval.P4; // P4
```

Or turn it descending:

```dart
-Interval.P4; // desc P4
Interval.M3.descending(); // desc M3
```

Calculate the `Interval` between two notes:

```dart
Note.c.interval(Note.g); // P5
Note.d.interval(Note.f.sharp).inverted; // m6
Note.g.flat.transposeBy(-Interval.m3); // E♭
```

And even play with the circle of fifths or any circle of intervals up to a distance:

```dart
Interval.P5.circleFrom(Note.c, distance: 12);
// [C, G, D, A, E, B, F♯, C♯, G♯, D♯, A♯, E♯, B♯]
Note.c.circleOfFifths();
// (flats: [F, B♭, E♭, A♭, D♭, G♭], sharps: [G, D, A, E, B, F♯])
```

### Tonalities

Create a `Tonality` or get it from a given `Note`:

```dart
Tonality(Note.e, TonalMode.minor); // E minor
Note.a.flat.major; // A♭ major
```

Know its `KeySignature`:

```dart
Note.d.major.keySignature; // 2 (F♯ C♯)
Note.e.flat.minor.keySignature; // -6 (B♭ E♭ A♭ D♭ G♭ C♭)
```

And its relative `Tonality`:

```dart
Note.d.major.relative; // B minor
Note.c.minor.relative; // E♭ major
```

### Key signatures

Create a `KeySignature`:

```dart
KeySignature([Note.b.flat, Note.e.flat]); // 2 (B♭ E♭)
KeySignature.fromDistance(4); // 4 (F♯ C♯ G♯ D♯)
```

And know its tonalities:

```dart
KeySignature([Note.f.sharp]).tonalities.major; // G major
KeySignature.fromDistance(-3).tonalities.minor; // C minor
```

### Modes

Get each `Mode`’s `ScalePattern`:

```dart
TonalMode.minor.scale; // ScalePattern.minor
ModalMode.locrian.scale; // ScalePattern.locrian
```

Their [Dorian Brightness Quotient]:

```dart
ModalMode.lydian.brightness; // 3
ModalMode.dorian.brightness; // 0
ModalMode.aeolian.brightness; // -1
```

Or its mirrored version:

```dart
ModalMode.ionian.mirrored; // ModalMode.phrygian
ModalMode.aeolian.mirrored; // ModalMode.mixolydian
```

### Scales

Create a `Scale` from a `ScalePattern`:

```dart
ScalePattern.lydian.on(Note.d); // D Lydian (D E F♯ G♯ A B C♯ D)
ScalePattern.majorPentatonic.on(Note.g.flat); // G♭ Major pentatonic (G♭ A♭ B♭ D♭ E♭ G♭)
ScalePattern.wholeTone.on(Note.f); // F Whole-tone (F G A B C♯ D♯ F)
```

Or get it from a `Tonality`:

```dart
Note.a.flat.major.scale; // A♭ Major (ionian) (A♭ B♭ C D♭ E♭ F G A♭)
Note.d.minor.scale; // D Natural minor (aeolian) (D E F G A B♭ C D)
```

Even play with any `ScaleDegree` or `HarmonicFunction`:

```dart
ScalePattern.lydian.on(Note.e).degree(ScaleDegree.iv); // A♯
Note.c.major.scale.functionChord(
HarmonicFunction.dominantV / HarmonicFunction.dominantV,
); // D maj. (D F♯ A)
```

### Chords

Create a `Chord` from a series of `Note`s or from a `ChordPattern`:

```dart
Chord([Note.a, Note.c.sharp, Note.e]); // A maj. (A C♯ E)
ChordPattern.augmentedTriad.add11().add13().on(Note.d.sharp);
// D♯ aug. (D♯ F𝄪 A𝄪 G♯ B♯)
```

Or build it on top of a `Note`:

```dart
Note.f.minorTriad.add7().add9(ImperfectQuality.minor);
// F min. (F A♭ C E♭ G♭)
Note.e.flat.diminishedTriad.add7().transposeBy(Interval.m2);
// F♭ dim. (F♭ A𝄫 C𝄫 E𝄫)
```

Or modify its root triad:

```dart
Note.g.minorTriad.major; // G maj. (G B D)
Note.f.sharp.majorTriad.add9().diminished; // F♯ dim. (F♯ A C G♯)
```

### Frequencies

Get the `Frequency` of a `PositionedNote`:

```dart
Note.a.inOctave(4).equalTemperamentFrequency(); // 440.0 Hz
Note.b.flat.inOctave(4).equalTemperamentFrequency(
referenceNote: Note.c.inOctave(4),
referenceFrequency: const Frequency(256),
); // 456.1401436878537 Hz
```

Or even get the closest note from a given `Frequency`:

```dart
const Frequency(415).closestPositionedNote();
// (G♯4, cents: -1.2706247484469828, hertz: -0.3046975799451275)
```

### In a nutshell

```dart
ScalePattern.lydian // Lydian (M2 M2 M2 m2 M2 M2 m2)
.on(Note.parse('a')) // A Lydian (A B C♯ D♯ E F♯ G♯ A)
.transposeBy(Interval.M2) // B Lydian (B C♯ D♯ E♯ F♯ G♯ A♯ B)
.degree(ScaleDegree.iii) // D♯
.respelledUpwards // E♭
.major // E♭ major
.relative // C minor
.scale // C Natural minor (aeolian) (C D E♭ F G A♭ B♭ C)
.degreeChord(ScaleDegree.v) // G min. (G B♭ D)
.add9(); // G min. (G B♭ D A)
```

## Inspiration

This library is inspired by a range of music theory projects.

- [Teoria.js](https://github.com/saebekassebil/teoria)
- [Tonal](https://github.com/tonaljs/tonal)
- [Tonic](https://github.com/osteele/dart-tonic)

## Contributing

Expand All @@ -97,3 +256,5 @@ Contributions are welcome! If you encounter any issues or have suggestions for i
## License

This package is released under the [BSD-3-Clause License](LICENSE).

[Dorian Brightness Quotient]: https://mynewmicrophone.com/dorian-brightness-quotient

0 comments on commit d055632

Please sign in to comment.