Giter Site home page Giter Site logo

tonaljs / tonal Goto Github PK

View Code? Open in Web Editor NEW
3.7K 3.7K 206.0 9.85 MB

A functional music theory library for Javascript

Home Page: https://tonaljs.github.io/tonal/docs

TypeScript 99.17% HTML 0.18% JavaScript 0.04% CSS 0.61%
chord-progression chords functional interval javascript key-signatures music music-theory scale transpose typescript

tonal's Introduction

tonal

npm version

tonal is a music theory library. Contains functions to manipulate tonal elements of music (note, intervals, chords, scales, modes, keys). It deals with abstractions (not actual music or sound).

tonal is implemented in Typescript and published as a collection of Javascript npm packages.

It uses a functional programing style: all functions are pure, there is no data mutation, and entities are represented by data structures instead of objects.

Example

import { Chord, Interval, Note, Scale } from "tonal";

Note.midi("C4"); // => 60
Note.freq("a4"); // => 440
Note.accidentals("c#2"); // => '#'
Note.transpose("C4", "5P"); // => "G4"
Interval.semitones("5P"); // => 7
Interval.distance("C4", "G4"); // => "5P"

// Scales
Scale.get("C major").notes; // => ["C", "D", "E", "F", "G", "A", "B"];
[1, 3, 5, 7].map(Scale.degrees("C major")); // => ["C", "E", "G", "B"]

Chord.get("Cmaj7").name; // => "C major seventh"

// Chord inversions
const triad = Chord.degrees("Cm");
[1, 2, 3].map(triad); // => ["C", "Eb", "G"];
[2, 3, 1].map(triad); // => ["Eb", "G", "C"];
[3, 1, 2].map(triad); // => ["G", "C", "Eb"];

Install

Install all packages at once:

npm install --save tonal

You can read CHANGELOG here.

Usage

Tonal is compatible with both ES5 and ES6 modules, and browser.

ES6 import:

import { Note, Scale } from "tonal";

ES5 require:

const { Note, Scale } = require("tonal");

Browser

You can use the browser version from jsdelivr CDN directly in your html:

<script src="https://cdn.jsdelivr.net/npm/tonal/browser/tonal.min.js"></script>
<script>
  console.log(Tonal.Key.minorKey("Ab"));
</script>

Or if you prefer, grab the minified browser ready version from the repository.

Bundle size

tonal includes all published modules.

Although the final bundle it is small, you can reduce bundle sizes even more by installing the modules individually, and importing only the functions you need.

Note that individual modules are prefixed with @tonaljs/. For example:

npm i @tonaljs/note
import { transpose } from "@tonaljs/note";
transpose("A4", "P5");

Documentation

Generally, you just need to install tonal package (before it was called @tonaljs/tonal).

The API documentation is inside README.md of each module ๐Ÿ‘‡

Notes and intervals

Scales and chords

Voicings

Keys, chord progressions

Time, rhythm

Utilities

Contributing

Read contributing document. To contribute open a PR and ensure:

  • If is a music theory change (like the name of a scale) link to reliable references.
  • If is a new feature, add documentation: changes to README of the affected module(s) are expected.
  • Ad tests: changes to the test.ts file of the affected module(s) are expected.
  • All tests are green

Inspiration

This library takes inspiration from other music theory libraries:

Projects using tonal

Showcase of projects that are using Tonal:

Thank you all!

Add your project here by editing this file

License

MIT License

tonal's People

Contributors

ajrussellaudio avatar apalm avatar ashleymays avatar danigb avatar davay42 avatar davidblurton avatar dependabot[bot] avatar euniceong avatar felixroos avatar gabrocheleau avatar grimmdude avatar holden-caulfield avatar honkskillet avatar jumski avatar kousun12 avatar limking24 avatar mannil avatar rakannimer avatar robert-lc avatar rowild avatar sashakhad avatar sashamahalia avatar shayanjavadi avatar stevage avatar szemek avatar tfeldmann avatar victorkolb avatar vpavlenko avatar yaph avatar zenberry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tonal's Issues

aug\Dom\dim chords can't get notes

hi @danigb
The problem was discovered a week later.
aug\Dom\dim chords can't get notes

Chord.notes("Caug") // []
Chord.notes("C","aug") // []

I've found that this function does a little bit more processing

Chord.tokenize("aug") // ["A", "ug"]

tokenizeThis function is executed twice

...
export const intervals = name => props(tokenize(name)[1]).intervals;
export function notes(nameOrTonic, name) {
  const p = tokenize(nameOrTonic);
  name = name || p[1];
  return intervals(name).map(transpose(p[0]));
}

error thrown in mobile safari

Hey @danigb,

I just noticed that when I try to run your library from mobile Safari, it throws an error:

"SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode."

I don't know if the problem is iOS (9.3.5) not supporting ES6 or if strict mode should't be specified in each of your modules.

Tonal.Key in npm ?

Sorry for the possibly n00b question but after a npm install tonal I don't seem to be able to use the 'extensions'. I'm after Tonal.Key and Tonal.Detect...

Do I need to to anything special in order to use them ?
Thanks !

Doc error for Distance.transposeBy

The manual gives the following example:


import { tranposeBy } from "tonal-distance"
transposeBy("3m", "5P") // => "7m"

Which won't work with two intervals. One should use add instead.

'note-transpose' is not in the npm registry

Hi! I just wanted to try out your library but ran into an error during npm install.

The error I get is this:

npm ERR! 404 Registry returned 404 for GET on https://registry.npmjs.org/note-transpose
npm ERR! 404
npm ERR! 404 'note-transpose' is not in the npm registry.

From your NPM registry page I found that the note-transpose module has an npm invalid flag.
Also the link to the repository is no longer available on github.

Chords from intervals

I'm looking for a way to convert a set of intervals to the chords they make (the inverse of chord.intervals)

Instinctively I've tried tonal.chord.detect('1P 3M 5P') but it didn't work.

It looks like all the information is there but I'm not sure the api allows me to do this. Is there a clever way to do this I didn't see ?

Thanks !

tonal.min.js

Hi, trying to use the minified js file and getting this error:

Uncaught TypeError: Cannot read property 'toFreq' of undefined
    at tonal.min.js:1
    at tonal.min.js:1
    at tonal.min.js:1

Any advice?

enharmonics use case

I have a particular use case for enharmonics. I find enharmonics tricky because you can have more than one accidental. For my case I am only interested in getting the enharmonic for one accidental, and if the note has no accidental it should return the note itself. (I hope this makes sense).
for example:
C => C
C3 => C3
C# => Db
C#3 => Db3
Db3 => C#3

I made a method that could fit in tonal.note. I called it equiv (from equivalent), but that is probably not the right name.

export const equiv = (str) => {
  const a = alt(str)
  const s = step(str)
  const o = oct(str) || undefined // convert null to undefined
 
  return build({step: a + s, alt: -a, oct: o})
}

with two test cases:

test("equiv pc", () => {
    const FLATS = "C Db D Eb E F Gb G Ab A Bb B".split(" ");
    const SHARPS = "C C# D D# E F F# G G# A A# B".split(" ");
    const flatEquivs = FLATS.map(note.equiv)
    const sharpEquivs = SHARPS.map(note.equiv)
    expect(flatEquivs).toEqual(SHARPS)
    expect(sharpEquivs).toEqual(FLATS)
  });
  test("equiv pitch", () => {
    const FLATS = "C3 Db3 D3 Eb3 E3 F3 Gb3 G3 Ab3 A3 Bb3 B3".split(" ");
    const SHARPS = "C3 C#3 D3 D#3 E3 F3 F#3 G3 G#3 A3 A#3 B3".split(" ");
    const flatEquivs = FLATS.map(note.equiv)
    const sharpEquivs = SHARPS.map(note.equiv)
    expect(flatEquivs).toEqual(SHARPS)
    expect(sharpEquivs).toEqual(FLATS)
  });

I am not suggesting this should be in tonal, but I am curious what your thoughts are about this. Does this somehow correspond to a concept in music theory, or does it go against the logic of enharmonics, and maybe shouldn't be handled this way?

thanks

Question on project structure

I was wondering how the main tonal/lib/tonal.js file relates to the individual packages. I don't see how they are connected. Will usage be like:

import tonal from 'tonal'

const myScale = tonal.scales.scale('major', 'A4')

and/or:

import { scale } from 'tonal-scales'

const myScale = scale('major', 'A4')

Solfege support?

Hi, are there any plans to support solfege/solfa notation?

I recently started using Tonal in a project at SightReadingMastery, and it would be very useful there. I can imagine it would be in many other applications as well. I noticed Teoria supports this feature as well.

Tonal is a fantastic library! Kudos to everyone who has made it possible.

chord.parse docs out of date, proposal

The docs for chord.parse say it returns an Array but it returns an Object.

Speaking of chord.parse, it'd be cool if the returned object contained more granular information about the parsed chord. Right now I'm using tonal in conjunction with another package called chord-magic which does basically the same thing, except its chord parser also gives the following:

  • quality (Major/minor/Augmented/etc)
  • extended (mostly 7ths, I'm not sure if there's a better word for them)
  • suspensions
  • added NCTs
  • overriding root (usually the bottom note of an inversion)

If tonal's chord.parse gave that kind of information I'd only have to depend on one library for chord parsing!

Confusing results from Detect.chord

Calling chord detection returns the '64' form for major chords which I found confusing as I had no idea what it meant.

Detect.chord([ '1P', '3M', '5P' ])
=> detected C64,Em#5

Scale app: Cb drops and B# raized an octave

Occurrences of note Cb in a scale in the scale app, drops one octave. Similarly any B# is raised an octave. Or so it seems, I did not check all the scales and keys, but found this:

B# turns out to be raised in...
... E bebop major
... F# and A hungarian major
... E ionian augmented
...

Cb is dropped in...
... Db, Eb, and Ab aolean
... Eb, Ab, and Bb balinese
... Db and Ab dorian
... Db egyptian
... Ab flat three pentatonic
... Db hungarian major
... Eb and Bb kumoijoshi
...

Converting Scale.notes results to midi values

I can't seem to figure out how to convert the results from Scale.notes('Bb lydian') to MIDI values.

The results from Scale.notes('Bb lydian') are in the form ["Bb", "C", "D" ...]. There's no pitch data . This is causing an issue because I need the MIDI values of this scale. midi(...) doesn't seem to work unless there's a pitch associated with the note.

I have also tried toNote from tonal-abc-notation but the following fails: toNote("Bb"). It returns null for the flat notes. Not sure if that's a bug or intended.

Is there an easier way to get the scale values as midi number as opposed to ABC strings?

tonal-fretboard

Hi @devboell,

I would like to have a tonal-fretboard module, and I thought maybe we can share some ideas before. The API I was thinking is something like this:

  • tuning(name): return an array of notes with the strings in open position. For example, for tuning('guitar') it would return ['E2', 'A2', 'D3', 'G3', 'B3', 'E4']. A kind of dictionary of corded instruments tunings.
  • build(tuning, first, last): build a fretboard with the given tuning, from first fret number to last fret number. It returns an array of arrays, one for each string.
  • buildSet(tuning, set, first, last): the same of above, but nulls instead of note names for the notes that doesn't belong to the set.

What do you think? Do you find useful? Anything missing?

Cheers,
Dani

Towards a 1.0.0 release

Goals

Simplify, reduce API surface and focus

Currently, there are too many functions to learn. Some of them are not relevant to end user, so they should be removed from API. Some other are too obscure features (pcset-dft, for example) than should be moved to a less noisy place.

Focus: some functional functions are provided (like map). That's not the scope of tonal.

  • Split codebase into groups: core, extensions, utilities, incubator, deprecated
  • Move deprecated functions to its own file and provide warnings
  • Remove functional plumbing

Reduce technical debt

Stabilize

All the core should be stable. Extensions should be stable. Incubator packages are allowed to be unstable.

  • Use different versioning number for core and extensions? (lerna?)

Proposed 1.0.0 API

tonal-note

note.split('Eb major')
note.parse('Eb')
note.names() // => ["C", "C#/Db", "D", "D#/Eb", "E", "F", "F#/Gb", ...]
note.name('c3') // => 'C3'
note.chroma('D4') // => 2
note.freq(note)
note.midi(note)
note.octave(note)
note.fromFreq(freq)
note.fromMidi(69) // => 'A4'
note.inOctave(5, "C#3") // => "C#5"

Interval

interval.name("3m") // => "3m"
interval.name("m3") // => "3m"
interval.name("P3") // => null
interval.num("m9")  // => 9
inteval.num("9M") // => 9
interval.type("A4") // => "perfectable"
interval.semitones("5P") // => 7
interval.simplify("9M") // => "2M"
interval.invert("2M") // => "7m"

tonal-distance

distance.transpose(note, interval) 
distance.transposeBy(interval, note)
distance.interval(from, to)
distance.intervalTo(to, from)
distance.add("2M", "2m") // => "3m"
distance.subtract("2M", "5P") // => "4P"

tonal-array

array.split(arr) strings to arrays
array.notes(arr) remove all but notes
array.pcset(arr) pcset, ordered starting from C
array.scale(arr) pcset, ordered, the first note is preserved
array.chord(arr) sorted, remove repetitions

// utility
array.sort(notes)
array.rotate(notes, preserveOctaves: boolean)

// range(['C4', 'C5'], [filter])
range(['C4', 'C5'])
range(['C4', 'C5', 'C3'])
range('C4 C5 C3');
range('C4 C5', 'c d e f g a b')

// filterBy(notes)
const inC = filterBy('c d e f g a b') // => function
inC('C4') // => true
inC('C#4') // => false

cycle('P5', 'C4', 4)

Scale

type scale = note[]

// types(aliases)
types(false) // => ['major', 'melodic minor', ...]

// fromName(name, [tonic]) // tonic === null => intervals
fromName('C major') // => ['C', 'D', ...]
fromName('major', 'C') // => ['C', 'D', ...]
fromName('major') // => ['1P', '2M', ...]

// find(notes) => { exact: "", modes: [], includedIn: [], extendedBy: [] }
find('c d e f g') // => {
// exact: null,
// modes: [],
// included: ['C major', ...],
// extendedBy: [] 
// }

// degree(name)(step)

Chord

type chord = note[]

types(false) // => ['major', 'melodic minor', ...]
fromName('Cmaj7') // => ['C', 'E', 'G', 'B']
fromName('maj7', 'C') // => ['C', 'E', 'G', 'B']
fromName('maj7') // => ['1P', '3M', ..]

// find(notes)

// triad(notes)(length)
triad('c d e f g a b c', 3) // => ['C', 'E', 'G']
triad('c d e f g a b c', 3) // => ['C', 'E', 'G']

Extensions

Key

type key = string

altered('F major') // => ['Bb']
signature(name) // ### or bbb
scales() // => ["C major"] , ["A minor", "A melodic minor", "A harmonic minor" ]

Modes

names() // ionian, dorian (major, minor are aliases)
relative(mode, type)
scale(mode)
chord(mode)
modes(mode) // modes("C major") // => ["D dorian", ...]

Incubator

Harmony

harmony() => [
  { tonic: "C", degree: 'I', types: ["M", "Maj7", "M9", f: "tonic" },
  { tonic: "D", degree: 'I', types: ["m", "m7"], f: "subdominant" },
  ...
]

the results are different by 'Chord.tokenize'

hello again

Tonal.Chord.tokenize('C11')  // ["C11", ""]
Tonal.Chord.tokenize('aug')  // ["A", "ug"]

The following functions are also associated.
Chord.intervals

Tonal.Chord.intervals('C13no5') // []
Tonal.Chord.intervals('aug') // []

[question] Why is 'Major' represented as 'Maj' in some cases and 'M' in others?

I am trying to use Chord.supersets() to generate a list of subnames that produce computable chord names when joined into a string.

I would expect, for example, 'AMaj7' to give 'AMaj7add13' as a subset. Removing the original chord from this string leaves me with 'add13' which would be used to populate a select-button.

But 'AMaj7add13' is actually 'AM7add13' in the tonal library.

Wondering if this was done for any reason besides brevity...

I'm considering forking and having 'Maj' be the only representation used. Do you forsee any complications with this?

Fantastic work, thank you for this awesome contribution to npm!

tonal.scaleRange behaving differently to range.scale

With latest versions from NPM:

> range = require('tonal-ranges')
> range.scale('C D E F G A B', 'C3', 'C2')
[ 'C3', 'B2', 'A2', 'G2', 'F2', 'E2', 'D2', 'C2' ]
> tonal = require('tonal']
> tonal.scaleRange('C D E F G A B', 'C3', 'C2')
[ 'C3' ]

Issues with Note.midi

As requested by @danigb in #57 (comment)

#57 addresses two main issues with Note.midi.

First, it fixes a few bugs with the current Note.midi implementation:

  • Note.midi(0) returns null. It should return 0.
  • Note.midi("c-1") returns null. It should return 0.
  • Note.midi(true) returns 1. It should return null.

Second, it changes Note.midi to only return numbers in the range of 0 to 127. Currently, Note.midi returns numbers outside this range, which I consider to be a bug. For example:

  • Note.midi(128) returns 128. It should return null.

Does that make sense?

Proposal: adding a flag for triad chords on Key.chords

Hey @danigb what do you think about adding a second, boolean, parameter to Key.chords to return the triad chords instead of the seventh chords.

I believe that, as an exception, for the case of a major scale, the 5th grade should still be returned as a seventh chord to keep its dominant quality

So something like:

Key.chords('A minor', true) // [ 'Am', 'Bmb5', 'C', 'Dm', 'Em', 'F', 'G' ]
Key.chords('C minor', true) // [ 'C', 'Dm', 'Em', 'F', 'G7', 'Am', 'Bmb5' ]

What do you think? As always, if you like the feature, I can do a PR to include it

problems installing current tonal-0.50.x branch

I'll just copy the terminal commands I used:

git clone -b tonal-0.50.x --single-branch https://github.com/danigb/tonal.git
cd tonal
npm install
npm test

this resulted in

65 passing (125ms)
  3 failing

  1) collections filter filter lists:
     TypeError: undefined is not a function
      at Array.filter (native)
      at dist/tonal.js:616:68
      at Object.filter (dist/tonal.js:616:43)
      at Context.<anonymous> (test/collections-test.js:86:26)

  2) intervals isIntervalStr test if its interval string:
     TypeError: _.isIntervalStr is not a function
      at Context.<anonymous> (test/interval-test.js:12:22)

  3) intervals isIntervalStr interval strings are recognized:
     TypeError: undefined is not a function
      at Array.map (native)
      at dist/tonal.js:603:65
      at Context.<anonymous> (test/interval-test.js:18:24)

then I continued with:

npm run packages-install
npm run packages-build
npm run packages-test

which gives this error:

module.js:339
    throw err;
    ^

Error: Cannot find module 'tonal-pitches'
    at Function.Module._resolveFilename (module.js:337:15)
    at Function.Module._load (module.js:287:25)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)

Tonal Parses 7(something) chords incorrectly

I'm using tonal in combination with Midiguchi, and one thing that is happening for me right now, which i think is an issue with the library.
I'm using tonal.chord.detect([notes]) to get the chord name and then later on i use tonal.chord.parse([chordname that i got from detect]) to get the chord type.
This all works fine, but one issues i'm having right now is that whenever tonal.chord.notes() encounters a 7something chord (7sus4, 7sus2, 7add6) it won't return notes (it'll just return an empty array) and when i try to parse it i get back { type: 'add6', tonic: 'Eb7' } (if the chord was a "Eb7add6").
Is there anything i can do to fix this?
Thanks

Tonal.transpose() returns scale with notes in wrong register

Working beautifully on my app in the key of C. Registral errors occurring when tranposing to other keys. Console logged some of these out:

Interval structure returned is correct.
myscale = Tonal.scale('major');
=>["1P", "2M", "3M", "4P", "5P", "6M", "7M"]

Great in the key of C.
myscale.map(Tonal.transpose('C2'));
=>["C2", "D2", "E2", "F2", "G2", "A2", "B2"]

We start to see registral problems when transposing to other keys.
myscale.map(Tonal.transpose('D2'));
=> ["D2", "E2", "F#2", "G2", "A2", "B2", "C#3"]

myscale.map(Tonal.transpose('E2'));
=> ["E2", "F#2", "G#2", "A2", "B2", "C#3", "D#3"]

etc...

Can't wait to introduce this functionality to my app! Thanks again!

Proposal: add a 'set' function on tonal-note

First of all @danigb thanks for this awesome library.

I'd like to propose a small addition that I would find useful. Adding a set function to the tonal-note module

The docs for such a function would be somewhat like this:

(static, constant) set

Given a note (string) and an object with props, return the note that results from overriding the given note with those props

Example:
Note.set("C4", {alt: 1, oct: 3}) // => "C#3"

Happy to make a PR with the change if you find it useful. I'm thinking the implementation of this as a combination of build and props

Proposal: modes

Hi,
are modes implemented (o can they) in any way?
From a computing point it could simply be a circular shift of a scale notes array, possibly having a name (but not necessarily, for the library purpose, could be up to the programmer to associate e.g. "Aeolian" name - also in different languages - to the Scale.mode(6).

This could be applied to any scale (programmer has to be aware of what he's doing)...
so that if a C major scale is [C, D, E, F, G, A, B]
with two circular shift we could obtain a Phrygian scale
like: C_major_scale.mode(3) = [E, F, G, A, B, C, D]

this could be used mainly for the common scales (major, melodic minor, harmonic minor, harmonic major) but since it'd be a generic mechanism, it could be applied to any scale, so that
Any_Major_scale.mode(6) = Aeolian array scale (natural minor)
Any_Aeolian_scale.mode(2) = Ionian array scale (major scale)
Any_Melodic_minor_scale.mode(4) = Lydian augmented array scale
.. etc etc...

Moreover, comes in mind a scale transformation function, to obtain parallel modes by dropping the right degrees, so that, e.g. you can obtain a melodic minor scale by flatting the 3rd degree of any major scale object...

I'll take some time to browse through the code, although I think my JS skills still are still lacking a bit...

diminished not harmonizing

There's a bug detecting diminisheds in harmonize. The example from the README states:

tonal.harmonize('P1 m3 d5', 'C') // => ['C', 'Eb', 'Gb']

yet only ['C', 'Eb'] is yielded

note-range package status

Hi there,

I was wondering about the note-range package. It appears it is not part of the current npm install of tonal and has the 'npm invalid' tag. Will it be included in a next release, or is there another way I can use it?

thanks

Scale detection

I'm replacing some of my half-baked code by your awesome tonal but converting my tests I'm getting puzzled by the output of scale detect. Here's what I'm doing:

`tonal = require("tonal");

processChordList = function(chordArray)
{
var notes = [];
chordArray.forEach(function(chordName)
{
var chordNotes = tonal.chord.notes(chordName);
notes = notes.concat(chordNotes);
})

result = tonal.scale.detect(notes);

console.log("-----------------------------------------------------");
console.log("Input chords: " + chordArray.join());
console.log("Notes: " + notes.join());
console.log("");
console.log("Resulting scales");
console.log(result);
}

processChordList(["cm"]);
processChordList(["cm", "a#"]);
processChordList(["cm", "a#", "fm"]);
processChordList(["cm", "a#", "fm", "g#"]);
processChordList(["cm", "bb", "fm", "ab"]);
`

That leads to

`$ node test/test-scale-detection.js

Input chords: cm
Notes: C,Eb,G

Resulting scales
[]

Input chords: cm,a#
Notes: C,Eb,G,A#,C##,E#

Resulting scales
[ 'E# piongio' ]

Input chords: cm,a#,fm
Notes: C,Eb,G,A#,C##,E#,F,Ab,C

Resulting scales
[ 'C aeolian',
'C locrian',
'C## major',
'Eb dorian',
'E# phrygian',
'F lydian',
'G mixolydian' ]

Input chords: cm,a#,fm,g#
Notes: C,Eb,G,A#,C##,E#,F,Ab,C,G#,B#,D#

Resulting scales
[ 'C aeolian',
'B# locrian',
'C major',
'C## dorian',
'D# phrygian',
'Eb lydian',
'E# mixolydian' ]

Input chords: cm,bb,fm,ab
Notes: C,Eb,G,Bb,D,F,F,Ab,C,Ab,C,Eb

Resulting scales
[ 'C aeolian',
'C locrian',
'C major',
'D dorian',
'Eb phrygian',
'Eb lydian',
'F mixolydian' ]
`
I'm expecting c minor to show everytime and certainly not C Major to show up.

Am I doing something wrong ?

status of enharmonics?

I am a bit lost about where to find the old tonal.note.enharmonics. I see you made enharmonics package in extensions, but this is not in the final release? Do you plan to add it?

thanks

Deprecation on chord.detect question

Hi
When I log the example Tonal.chord.detect('g f# d b'),
I got the following warning pcset.chromaModes deprecated. Renamed to pcset.modes

Sounds not so good... and a bit lost
How can I handle it?

Thank you

404s in docs

Looks like there's a lot of missing pages in the GitHub.io docs ๐Ÿ˜•

Is this a mistake, or is the documentation incomplete?

Tonal scale source/docs are outdated

NPM has version 0.50.5 and the package.json on here says 0.50.0. The docs seem to be outdated on both GitHub and NPM since there is no scale.get but a scale.scale function.

Thanks for this amazing library of useful bits!

import error when trying new release

Hi Dani, how are you?

I thought I'd try the new version, but I get an error when I import tonal.
F.i. if I try to use the tonal-note package,

import * as tonal from 'tonal'
console.log('tonal.note.midi', tonal.note.midi('C3'))

I get:

dev/experiments/tonal-exp/node_modules/tonal-note/index.js:36
    export function tokenize(str) {
    ^^^^^^
    
    SyntaxError: Unexpected token export
      
      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
      at Object.<anonymous> (node_modules/tonal/build/index.js:5:13)
      at Object.<anonymous> (src/tests/index.test.js:2:14)

It seems that tonal/index.js is exporting the tonal-note/index.js, and not the transpiled tonal-note/build/index.js. Could that be the reason?

tonal-chords example does not work

The example given here is broken.

> Bjorns-MacBook-Pro:zeitgeber bjornwestergard$ node
> var tonal = require('tonal')
undefined
> tonal.chord('C7')
TypeError: tonal.chord is not a function
    at repl:1:7
    at REPLServer.defaultEval (repl.js:252:27)
    at bound (domain.js:287:14)
    at REPLServer.runBound [as eval] (domain.js:300:12)
    at REPLServer.<anonymous> (repl.js:417:12)
    at emitOne (events.js:82:20)
    at REPLServer.emit (events.js:169:7)
    at REPLServer.Interface._onLine (readline.js:211:10)
    at REPLServer.Interface._line (readline.js:550:8)
    at REPLServer.Interface._ttyWrite (readline.js:827:14)

How to use npm/yarn link with a local copy of tonal

When I use yarn link in the root of the tonal package, it links tonal-core. I can import tonal-core in my own project, and it works, but is this the expected behaviour?

If I cd to packages/tonal and link there, it links tonal, but when I import * as tonal from 'tonal' in my project I get:

dev/experiments/tonal-exp/node_modules/tonal/node_modules/tonal-array/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import { midi, name } from "tonal-note";
                                                                                             ^^^^^^
    
    SyntaxError: Unexpected token import
      
      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
      at Object.<anonymous> (node_modules/tonal/build/transpiled.js:5:13)
      at Object.<anonymous> (src/tests/index.test.js:3:13)

This also happens when I use const tonal = require('tonal')

Chooords detection

I try to understand how to detect chords from a group of notes.
I am using the simple method Tonal.chords.detect(notes)

var test= [
   Tonal.chord.detect('g f# d b'),
   Tonal.chord.detect('g5 f5# d5 b5')
];
console.log(test);

Output:

["GMaj7"]
["GM","Bm#5"]

Why dont we get the union of the two in each case?

Note : if there is useful litterature/links on the subjects, I am willing to study it and try implemting something.

How do you transpose down?

I want to transpose notes an octave down and tried tonal.transpose(note, '-P8'); but that didn't work and I couldn't find anything in the docs pertaining to direction of the interval you wish to transpose by.

[question] Convert PcSet to Scale

Hello @danigb,
Thank you for this amazing library!
Very impressive piece of work.

Is there a way to convert a list of notes to a scale?
e.g. I have the following array:

["a", "c", "e", "g"]

and what I'd like to achieve is

["A4", "C5", "E5", "G5"]

Thank you again!

trouble with rollup and json imports

tonal-scale seems to rely on rollup-plugin-json. the only thing is that since I'm using rollup in my project, I had to figure out that I needed to use rollup-plugin-json in my rollup configuration too. This seems like a funky area with rollup/es6 modules.

Transposing through multiple octaves?

Hey there, thanks for the great library!

I'm wondering if there is a way to transpose a note through multiple registers (ex: C3 -> C5, etc) using Tonal.transpose().

I'm making an app that dynamically generates tables of numbers and assigns notes to the numbers using modular arithmetic. Note names are right, just need to find a way to scale them to their proper register :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.