- New
Key.majorKeyChords
andKey.minorKeyChords
functions.
import * as Key from "tonal";
Key.majorKeyChords("C").find((chord) => chord.name === "Em"); // => { name: "Em", roles: ["T", "ii/II"] }
- Renamed fields of key results.
secondaryDominantsMinorRelative
is nowsecondaryDominantSupertonics
andsubstituteDominantsMinorRelative
is nowsubstituteDominantSupertonics
. Previous names are kept for compatibility as deprecated (will be removed in next major version)
Using default exports for single packages are deprecated, so instead of:
import Note from "@tonaljs/note";
You should do this:
import * as Note from "@tonaljs/note";
The same for all modules.
The documentation said Note.distance
was available, but was not.
Now you can do:
import { Note } from "tonal";
Note.distance("c4", "e7"); // => "24M"
New rhythm-pattern
package:
import { RhythmPattern } from "tonal";
RhythmPattern.euclid(8, 3); // => [1, 0, 0, 1, 0, 0, 1, 0]
RhythmPattern.binary(12, 13); // => [1, 1, 0, 0, 1, 1, 0, 1]
RhythmPattern.hex("8f"); // => [1, 0, 0, 0, 1, 1, 1, 1]
RhythmPattern.onsets(1, 2, 2, 1); // => [1, 0, 1, 0, 0, 1, 0, 0, 1, 0]
RhythmPattern.random(4); // => [1, 0, 0, 1]
RhythmPattern.probability([0.6, 0, 0.2, 0.5]); // => [0, 0, 0, 1]
RhythmPattern.rotate([1, 0, 0, 1], 2); // => [0, 1, 1, 0]
Scale.get ignores case.
Now both calls returns the same scale:
Scale.get("C Major");
Scale.get("c major");
#### Breaking change: chord uses pitch classes, never notes with octaves
Chords now uses only pitch classes. Before Chord.getChord('M', 'C4')
would consider C4
to be the tonic and now is `C``
So before:
Chord.get("M", "C4"); // =>
// {
// name: 'C4 major',
// tonic: 'C4',
// notes: [ 'C4', 'E4', 'G4' ]
// ...
// }
Now:
Chord.get("M", "C4"); // =>
// {
// name: 'C major',
// tonic: 'C',
// notes: [ 'C', 'E', 'G' ]
// }
- Chord now accepts a slash and a bass. The bass must be a pitch class
- Chord properties include
bass
that is a pitch class that could or could not belong to the chord itself.
Example:
Chord.get("Cmaj7/B");
Chord.get("Eb/D");
Now notes
property of a chord are always pitch classes, there's a new function to get the actual notes:
Chord.notes("Cmaj7", "C4"); // => ['C4', 'E4', 'G4', 'B4']
Chord.notes("maj7", "D5"); // => ['D5', 'F#5', 'A5', 'C#6']
- 48fecc4: Fix typo (breaking change):
substract
is nowsubtract
- 48fecc4: Breaking change: remove
NoInterval
interface. ReturnInterval
type (withemtpy: true
) when parsing invalid intervals. - 48fecc4: Breaking change:
NoNote
interface is removed. Always returnNote
type (withempty: true
) when parsing invalid notes.
Updated dependencies
Updated dependencies
- Add
Pcset.notes()
function that returns the ordered pitch class notes of the given set
- Updated dependencies [f21525b]
- Named type was renamed to NamedPitch. Add old export for backwards compatibility
- Updated dependencies
- Move core into pitch modules
- Updated dependencies
- @tonaljs/core@4.10.2
- Restructure code to use new
@tonaljs/pitch
. No changes to functionality - Updated dependencies
- @tonaljs/core@4.10.1
-
Publish voicing packages. Now there a three new namespaces:
import { VoiceLeading, Voicing, VoicingDictionary } from "tonal";
-
Updated dependencies [15017c0]
- @tonaljs/voicing-dictionary@5.0.0
- @tonaljs/voice-leading@5.0.0
- @tonaljs/voicing@5.0.0
- Add -maj7 chord alias
- Updated dependencies
- @tonaljs/chord-type@5.0.2
Breaking change: Chord.get
and Chord.tokenize
assumes all numbers are part of the chord type, and never the tonic octave, when using with a single string parameter.
Before, in v4.x:
Chord.get("C4maj7"); // => { symbol: 'Cmaj7', tonic: 'C4' ... }
Now, in > 5.x:
Chord.get("C4maj7"); // => { empty: true } <- there is no "4maj7" chord type, so no chord is returned
The old behaviour can be replicated by using an array as parameter.
This works both in v4.x and v5.x:
Chord.get(["C4", "maj7"]); // => { symbol: 'Cmaj7', tonic: 'C4' ... }
The reasons for this change are:
- Chord symbols never use octaves
- The old behavior is confusing and arbitrary
- Updated dependencies [b07a54c0]
- @tonaljs/chord-type@5.0.0
- @tonaljs/chord@5.0.0
- @tonaljs/scale@4.12.2
- @tonaljs/progression@4.8.1
- pcset - Fix setNumToChroma: it must return a string of length in order to work correctly
- 96df1a19: Add 6add9 to chord types aliases. Rename to "sixth added ninth"
- Updated dependencies [96df1a19]
- @tonaljs/chord-type@4.8.1
- @tonaljs/chord@4.10.1
- 52c5c9cc: Numeric ranges support negative numbers
Range.numeric([-5, 5]); // => [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
- 6fcd52db: Add Scale.steps and Chord.steps
import { Range, Scale, Chod } from "tonal";
Range.numeric([-3, 3]).map(Scale.steps("C4 major"));
Range.numeric([-3, 3]).map(Chord.steps(["C4", "aug"]));
// => ["G3", "A3", "B3", "C4", "D4", "E4", "F4"]
- Add Scale.detect function
Scale.detect(["C", "D", "E", "F", "G", "A", "B"]);
// => ["C major", "C bebop", "C bebop major",
// "C ichikosucho", "C chromatic"];
-
New midi functions
- Midi.pcset
- Midi.pcsetSteps
- Midi.pcsetDegrees
- Midi.pcsetNearest
Midi.pcset([62, 63, 60, 65, 70, 72]); // => [0, 2, 3, 5, 10]
Midi.pcset("100100100101"); // => [0, 3, 6, 9, 11]
const steps = Midi.pcsetSteps(Scale.get("D dorian").chroma, 60);
[-2, -1, 0, 1, 2, 3].map(steps); // => [ 57, 58, 60, 62, 63, 65 ]
const steps = Midi.pcsetDegrees(Scale.get("D dorian").chroma, 60);
[-2, -1, 1, 2, 3, 4].map(steps); // => [ 57, 58, 60, 62, 63, 65 ]
const nearest = Midi.pcsetNearest(Scale.get("D dorian").chroma);
[60, 61, 62, 63, 64, 65, 66].map(nearest); // => [60, 62, 62, 63, 65, 65, 67]
- Scale.degrees
[1, 2, 3, 4].map(Chord.degrees("C4")) => ["C4", "E4", "G4", "C5"]`
- Scale.degrees new function
[1, 2, 3].map(Scale.degrees("C major")) => ["C", "D", "E"]
[1, 2, 3].map(Scale.degrees("C4 major")) => ["C4", "D4", "E4"]
[-1, -2, -3].map(Scale.degrees("C major")) => ["B", "A", "G"]
-
10056eff: Add triads to key.
For example:
Key.majorKey("C").triads
orKey.minorKey("C").melodic.triads
- Updated dependencies [10056eff]
- 3f4e78ee: Fix browser build
-
- fix time signature parsing
- add support for irrational time signatures
- add option
assumePerfectFifth
toChord.detect
function
- Updated dependencies
- Unify package versions
- Updated dependencies
- fix npm publish problem
- Updated dependencies
- b120fc42: Publish tonal in
tonal
package. So usenpm install tonal
instead ofnpm install @tonaljs/tonal
- fix memory leak
- Updated dependencies
- Updated dependencies [b120fc42]
- Add
Note.enharmonic
- Bug fixing
- Updated dependencies
- Mode notes, triads, seventhChords and relativeTonic #221
- Scale.rangeOf #220
- Improve chord detection and remove invalid chord #209
- Fixes #218, #208, #207, #215
Adopt a fixed/locked mode with lerna. Before, each module has it's own version. Now the same version is used for all modules. More info
Deprecated modules:
- @tonaljs/modules (use tonal)
- @tonaljs/array (use @tonaljs/collection)
Before 4.5.0 there's no changelog, sorry 🙏. I'm afraid you have to dive into commits.
To make things worse, each module had it's own version, making difficult to know what was released when.
At least I'll try to keep this one up to date
Theres a migration guide for older versions (pre 4)