diff --git a/.changeset/stale-roses-unite.md b/.changeset/stale-roses-unite.md
new file mode 100644
index 00000000..62e2083d
--- /dev/null
+++ b/.changeset/stale-roses-unite.md
@@ -0,0 +1,27 @@
+---
+"@tonaljs/abc-notation": minor
+"@tonaljs/chord": minor
+"@tonaljs/chord-detect": minor
+"@tonaljs/chord-type": minor
+"@tonaljs/collection": minor
+"@tonaljs/duration-value": minor
+"@tonaljs/interval": minor
+"@tonaljs/key": minor
+"@tonaljs/midi": minor
+"@tonaljs/mode": minor
+"@tonaljs/modules": minor
+"@tonaljs/note": minor
+"@tonaljs/pcset": minor
+"@tonaljs/progression": minor
+"@tonaljs/range": minor
+"@tonaljs/roman-numeral": minor
+"@tonaljs/scale": minor
+"@tonaljs/scale-type": minor
+"@tonaljs/time-signature": minor
+"tonal": minor
+"@tonaljs/voice-leading": minor
+"@tonaljs/voicing": minor
+"@tonaljs/voicing-dictionary": minor
+---
+
+Publish tonal in `tonal` package. So use `npm install tonal` instead of `npm install @tonaljs/tonal`
diff --git a/README.md b/README.md
index 8013ae61..78547079 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# tonal
-[](https://www.npmjs.com/package/@tonaljs/tonal)
+[](https://www.npmjs.com/package/tonal)
[](https://github.com/tonaljs/tonal/actions)


@@ -18,7 +18,7 @@ mutation, and entities are represented by data structures instead of objects.
## Example
```js
-import { Interval, Note, Scale } from "@tonaljs/tonal";
+import { Interval, Note, Scale } from "tonal";
Note.midi("A4"); // => 60
Note.freq("a4").freq; // => 440
@@ -34,7 +34,7 @@ Scale.get("C major").notes; // =>["C", "D", "E", "F", "G", "A", "B"];
Install all packages at once:
```bash
-npm install --save @tonaljs/tonal
+npm install --save tonal
```
## Usage
@@ -44,13 +44,13 @@ Tonal is compatible with both ES5 and ES6 modules, and browser.
#### ES6 `import`:
```js
-import { Note, Scale } from "@tonaljs/tonal";
+import { Note, Scale } from "tonal";
```
#### ES5 `require`:
```js
-const { Note, Scale } = require("@tonaljs/tonal");
+const { Note, Scale } = require("tonal");
```
#### Browser
@@ -58,7 +58,7 @@ const { Note, Scale } = require("@tonaljs/tonal");
You can use the browser version from jsdelivr CDN directly in your html:
```html
-
+
@@ -70,11 +70,13 @@ from the repository.
#### Bundle size
-`@tonaljs/tonal` includes all published modules.
+`tonal` includes all published modules.
-Although the final bundle it is small (~10kb minified and gzipped), you can
+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:
+importing only the functions you need.
+
+Note that individual modules are prefixed with `@tonaljs`. For example:
```bash
npm i @tonaljs/note
@@ -87,11 +89,11 @@ transpose("A4", "P5");
## Documentation
-Generally, you just need to install:
+Generally, you just need to install `tonal` package (before it was called `@tonaljs/tonal`).
-- [@tonaljs/tonal](/packages/tonal): All modules bundled in one package
+- [tonal](/packages/tonal): All modules bundled in one package
-The API documentation lives inside README.md file of each module
+The API documentation is inside README.md of each module 👇
#### Notes and intervals
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 83971179..bca6a1b0 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -6,7 +6,7 @@ Adopt a fixed/locked mode with lerna. Before, each module has it's own version.
Deprecated modules:
-- @tonaljs/modules (use @tonaljs/tonal)
+- @tonaljs/modules (use tonal)
- @tonaljs/array (use @tonaljs/collection)
#### Releases
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index 418e3f7a..3731771e 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -39,7 +39,21 @@ To create a new module:
- Add a new folder inside packages: `packages/my-module`
- Add a new package.json inside the folder (see any of them as an example)
- Add required dependencies to "dependencies" inside package.json. Ensure correct dependency versions. For example, if your module needs to use `tonal/core` look at core's package.json to see what version to use
-- After adding your dependencies, use lerna to wire them up: run `yarn lerna` at root folder
- Add your functionality and tests
- Ensure everything works: run `yarn test:ci` at root folder
- Create a pull request
+
+## Release
+
+Releases are built using changesets: https://turbo.build/repo/docs/handbook/publishing-packages/versioning-and-publishing:
+
+```
+# Add a new changeset
+yarn changeset
+
+# Create new versions of packages
+yarn changeset version
+
+# Publish all changed packages to npm
+yarn changeset publish
+```
diff --git a/package.json b/package.json
index 317bba41..2a8fb89b 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,5 @@
{
- "name": "tonal-workspace",
+ "name": "workspace",
"private": true,
"workspaces": [
"packages/*"
diff --git a/packages/abc-notation/README.md b/packages/abc-notation/README.md
index bb46cfd2..dbd69974 100644
--- a/packages/abc-notation/README.md
+++ b/packages/abc-notation/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { AbcNotation } from "@tonaljs/tonal";
+import { AbcNotation } from "tonal";
```
nodejs:
```js
-const { AbcNotation } = require("@tonaljs/tonal");
+const { AbcNotation } = require("tonal");
```
## API
diff --git a/packages/chord-detect/README.md b/packages/chord-detect/README.md
index 05d6ffa4..4a1af813 100644
--- a/packages/chord-detect/README.md
+++ b/packages/chord-detect/README.md
@@ -5,13 +5,13 @@
With ES6 `import`:
```js
-import { Chord } from "@tonaljs/tonal";
+import { Chord } from "tonal";
```
With ES5 `require`:
```js
-const { Chord } = require("@tonaljs/tonal");
+const { Chord } = require("tonal");
```
Standalone:
diff --git a/packages/chord-detect/package.json b/packages/chord-detect/package.json
index 15a7a176..a92a2366 100644
--- a/packages/chord-detect/package.json
+++ b/packages/chord-detect/package.json
@@ -6,7 +6,7 @@
"chord-detect",
"music",
"theory",
- "@tonaljs/tonal"
+ "tonal"
],
"main": "dist/index.js",
"module": "dist/index.mjs",
diff --git a/packages/chord-type/README.md b/packages/chord-type/README.md
index fb05428f..8e67e642 100644
--- a/packages/chord-type/README.md
+++ b/packages/chord-type/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { ChordType } from "@tonaljs/tonal";
+import { ChordType } from "tonal";
```
node:
```js
-const { ChordType } = require("@tonaljs/tonal");
+const { ChordType } = require("tonal");
```
## API
@@ -71,8 +71,8 @@ add(["1P", "3M", "5P"], ["M"], "mayor");
```js
ChordType.all()
- .filter(get => get.length === 3)
- .map(get => get.name);
+ .filter((get) => get.length === 3)
+ .map((get) => get.name);
```
#### How to add a chord type to the dictionary?
diff --git a/packages/chord/README.md b/packages/chord/README.md
index 374aa8c4..5673503d 100644
--- a/packages/chord/README.md
+++ b/packages/chord/README.md
@@ -5,13 +5,13 @@
ES6:
```js
-import { Chord } from "@tonaljs/tonal";
+import { Chord } from "tonal";
```
Nodejs:
```js
-const { Chord } = require("@tonaljs/tonal");
+const { Chord } = require("tonal");
```
## API
diff --git a/packages/collection/README.md b/packages/collection/README.md
index f265a2fd..b70b99f9 100644
--- a/packages/collection/README.md
+++ b/packages/collection/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { Collection } from "@tonaljs/tonal";
+import { Collection } from "tonal";
```
node:
```js
-const { Collection } = require("@tonaljs/tonal");
+const { Collection } = require("tonal");
```
## API
diff --git a/packages/duration-value/README.md b/packages/duration-value/README.md
index 7d422e10..2644a039 100644
--- a/packages/duration-value/README.md
+++ b/packages/duration-value/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { DurationValue } from "@tonaljs/tonal";
+import { DurationValue } from "tonal";
```
node:
```js
-const { DurationValue } = require("@tonaljs/tonal");
+const { DurationValue } = require("tonal");
```
single module:
diff --git a/packages/interval/README.md b/packages/interval/README.md
index 07be22c3..ecc449c2 100644
--- a/packages/interval/README.md
+++ b/packages/interval/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { Interval } from "@tonaljs/tonal";
+import { Interval } from "tonal";
```
nodejs:
```js
-const { Interval } = require("@tonaljs/tonal");
+const { Interval } = require("tonal");
```
## API
diff --git a/packages/key/README.md b/packages/key/README.md
index db6982a3..f39acc13 100644
--- a/packages/key/README.md
+++ b/packages/key/README.md
@@ -9,13 +9,13 @@ Get scale and chords of major and minor keys.
ES6:
```js
-import { Key } from "@tonaljs/tonal";
+import { Key } from "tonal";
```
nodejs:
```js
-const { Key } = require("@tonaljs/tonal");
+const { Key } = require("tonal");
```
## API
diff --git a/packages/midi/README.md b/packages/midi/README.md
index 96e191be..38ed6100 100644
--- a/packages/midi/README.md
+++ b/packages/midi/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { Midi } from "@tonaljs/tonal";
+import { Midi } from "tonal";
```
nodejs:
```js
-const { Midi } = require("@tonaljs/tonal");
+const { Midi } = require("tonal");
```
## API
diff --git a/packages/mode/README.md b/packages/mode/README.md
index 056dda97..d64521de 100644
--- a/packages/mode/README.md
+++ b/packages/mode/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { Mode } from "@tonaljs/tonal";
+import { Mode } from "tonal";
```
node:
```js
-const { Mode } = require("@tonaljs/tonal");
+const { Mode } = require("tonal");
```
## API
@@ -109,7 +109,7 @@ Mode.relativeTonic("minor", "major", "C"); // => "A"
For example, "A major" mode:
```js
-import { Mode, Note } from "@tonaljs/tonal";
+import { Mode, Note } from "tonal";
Mode.get("major").intervals.map(Note.transposeFrom("A"));
["A", "B", "C#", "D", "E", "F#", "G#"];
diff --git a/packages/modules/CHANGELOG.md b/packages/modules/CHANGELOG.md
index bbd60a96..da979317 100644
--- a/packages/modules/CHANGELOG.md
+++ b/packages/modules/CHANGELOG.md
@@ -6,4 +6,4 @@
- Bug fixing
- Updated dependencies
- - @tonaljs/tonal@4.6.10
+ - tonal@4.6.10
diff --git a/packages/modules/README.md b/packages/modules/README.md
index 02ec9985..7d8f7640 100644
--- a/packages/modules/README.md
+++ b/packages/modules/README.md
@@ -1,3 +1,3 @@
# Deprecated
-## Use: [@tonaljs/tonal](/packages/tonal)
+## Use: [tonal](/packages/tonal)
diff --git a/packages/modules/index.ts b/packages/modules/index.ts
index 800a2249..b3735713 100644
--- a/packages/modules/index.ts
+++ b/packages/modules/index.ts
@@ -1 +1 @@
-export * from "@tonaljs/tonal";
+export * from "tonal";
diff --git a/packages/modules/package.json b/packages/modules/package.json
index d55a6efd..b8e272e8 100644
--- a/packages/modules/package.json
+++ b/packages/modules/package.json
@@ -10,7 +10,7 @@
],
"types": "dist/index.d.ts",
"dependencies": {
- "@tonaljs/tonal": "^4.6.10"
+ "tonal": "^4.6.10"
},
"author": "danigb@gmail.com",
"license": "MIT",
diff --git a/packages/note/README.md b/packages/note/README.md
index b31b035f..fd2510de 100644
--- a/packages/note/README.md
+++ b/packages/note/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { Note } from "@tonaljs/tonal";
+import { Note } from "tonal";
```
nodejs:
```js
-const { Note } = require("@tonaljs/tonal");
+const { Note } = require("tonal");
```
## API
diff --git a/packages/pcset/README.md b/packages/pcset/README.md
index 47d7c5ec..681c5726 100644
--- a/packages/pcset/README.md
+++ b/packages/pcset/README.md
@@ -9,13 +9,13 @@ A pitch class set is a set (no repeated) of pitch classes (notes without octaves
ES6:
```js
-import { Pcset } from "@tonaljs/tonal";
+import { Pcset } from "tonal";
```
nodejs:
```js
-const { Pcset } = require("@tonaljs/tonal");
+const { Pcset } = require("tonal");
```
## API
@@ -104,5 +104,5 @@ Take a look to [@tonal/scale-type]() or [@tonal/chord-type]() that are, in fact,
import { chromas, pcset } from "@tonaljs/pcset";
import { transposeFrom } from "@tonaljs/note";
-chromas().map(chroma => pcset(chroma).intervals.map(transposeFrom("C")));
+chromas().map((chroma) => pcset(chroma).intervals.map(transposeFrom("C")));
```
diff --git a/packages/progression/README.md b/packages/progression/README.md
index 2aae281c..e2ef4bad 100644
--- a/packages/progression/README.md
+++ b/packages/progression/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { Progression } from "@tonaljs/tonal";
+import { Progression } from "tonal";
```
node:
```js
-const { Progression } = require("@tonaljs/tonal");
+const { Progression } = require("tonal");
```
## API
diff --git a/packages/range/README.md b/packages/range/README.md
index 4d626557..dba3da23 100644
--- a/packages/range/README.md
+++ b/packages/range/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { Range } from "@tonaljs/tonal";
+import { Range } from "tonal";
```
nodejs:
```js
-const { Range } = require("@tonaljs/tonal");
+const { Range } = require("tonal");
```
Single module:
diff --git a/packages/roman-numeral/README.md b/packages/roman-numeral/README.md
index cfc3179e..99173b27 100644
--- a/packages/roman-numeral/README.md
+++ b/packages/roman-numeral/README.md
@@ -9,13 +9,13 @@ A roman numeral symbol is a string like `"bVIImaj7"` that can be used to represe
ES6:
```js
-import { RomanNumeral } from "@tonaljs/tonal";
+import { RomanNumeral } from "tonal";
```
node:
```js
-const { RomanNumeral } = require("@tonaljs/tonal");
+const { RomanNumeral } = require("tonal");
```
## API
@@ -49,7 +49,7 @@ RomanNumeral.get("bVIIMaj7");
`romanNumeral` function accepts a `Pitch` as argument:
```js
-import { Interval, RomanNumeral } from "@tonaljs/tonal";
+import { Interval, RomanNumeral } from "tonal";
RomanNumeral.get(Interval.get("3m")).name; // => "bIII"
```
diff --git a/packages/scale-type/README.md b/packages/scale-type/README.md
index 8f2283e5..8094cf14 100644
--- a/packages/scale-type/README.md
+++ b/packages/scale-type/README.md
@@ -9,13 +9,13 @@
ES6:
```js
-import { ScaleType } from "@tonaljs/tonal";
+import { ScaleType } from "tonal";
```
nodejs:
```js
-const { ScaleType } = require("@tonaljs/tonal");
+const { ScaleType } = require("tonal");
```
## API
@@ -68,8 +68,8 @@ ScaleType.add(["1P", "5P"], null, ["5"]);
```js
ScaleType.all()
- .filter(scaleType => scaleType.intervals.length === 5)
- .map(scaleType => scaleType.name);
+ .filter((scaleType) => scaleType.intervals.length === 5)
+ .map((scaleType) => scaleType.name);
```
#### How do to add a scale to the dictionary?
@@ -84,7 +84,7 @@ ScaleType.scale("quinta justa"); // => { name: "quinta", intervals: ... }
Some sources explaining various scale systems:
-- [Modes](https://en.wikipedia.org/wiki/Mode_(music))
+- [Modes]()
- [Blues Scales](https://en.wikipedia.org/wiki/Blues_scale)
- [Jazz Scales](https://en.wikipedia.org/wiki/Jazz_scale)
- [Messiaen's "Modes of Limited Transposition" (wikipedia, en)](https://en.wikipedia.org/wiki/Mode_of_limited_transposition)
diff --git a/packages/scale/README.md b/packages/scale/README.md
index 86c811b2..db6bbc93 100644
--- a/packages/scale/README.md
+++ b/packages/scale/README.md
@@ -9,13 +9,13 @@
ES6:
```js
-import { Scale } from "@tonaljs/tonal";
+import { Scale } from "tonal";
```
nodejs:
```js
-const { Scale } = require("@tonaljs/tonal");
+const { Scale } = require("tonal");
```
Single module:
diff --git a/packages/time-signature/README.md b/packages/time-signature/README.md
index c878544e..886eea17 100644
--- a/packages/time-signature/README.md
+++ b/packages/time-signature/README.md
@@ -7,13 +7,13 @@
ES6:
```js
-import { TimeSignature } from "@tonaljs/tonal";
+import { TimeSignature } from "tonal";
```
node:
```js
-const { TimeSignature } = require("@tonaljs/tonal");
+const { TimeSignature } = require("tonal");
```
single module:
diff --git a/packages/tonal-tonal/CHANGELOG.md b/packages/tonal-tonal/CHANGELOG.md
new file mode 100644
index 00000000..c238fac4
--- /dev/null
+++ b/packages/tonal-tonal/CHANGELOG.md
@@ -0,0 +1,27 @@
+# tonal
+
+## 4.6.10
+
+### Patch Changes
+
+- Bug fixing
+- Updated dependencies
+ - @tonaljs/abc-notation@4.6.10
+ - @tonaljs/array@4.6.10
+ - @tonaljs/chord@4.6.10
+ - @tonaljs/chord-type@4.6.10
+ - @tonaljs/collection@4.6.10
+ - @tonaljs/core@4.6.10
+ - @tonaljs/duration-value@4.6.10
+ - @tonaljs/interval@4.6.10
+ - @tonaljs/key@4.6.10
+ - @tonaljs/midi@4.6.10
+ - @tonaljs/mode@4.6.10
+ - @tonaljs/note@4.6.10
+ - @tonaljs/pcset@4.6.10
+ - @tonaljs/progression@4.6.10
+ - @tonaljs/range@4.6.10
+ - @tonaljs/roman-numeral@4.6.10
+ - @tonaljs/scale@4.6.10
+ - @tonaljs/scale-type@4.6.10
+ - @tonaljs/time-signature@4.6.10
diff --git a/packages/tonal-tonal/LICENSE b/packages/tonal-tonal/LICENSE
new file mode 100644
index 00000000..77ac35ab
--- /dev/null
+++ b/packages/tonal-tonal/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 danigb
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/packages/tonal-tonal/README.md b/packages/tonal-tonal/README.md
new file mode 100644
index 00000000..de839c41
--- /dev/null
+++ b/packages/tonal-tonal/README.md
@@ -0,0 +1,3 @@
+# tonal  [](https://www.npmjs.com/package/tonal)
+
+[Use `tonal` package directly.](https://www.npmjs.com/package/tonal)
diff --git a/packages/tonal-tonal/index.ts b/packages/tonal-tonal/index.ts
new file mode 100644
index 00000000..e3258744
--- /dev/null
+++ b/packages/tonal-tonal/index.ts
@@ -0,0 +1,54 @@
+import AbcNotation from "@tonaljs/abc-notation";
+import * as Array from "@tonaljs/array";
+import Chord from "@tonaljs/chord";
+import ChordType from "@tonaljs/chord-type";
+import Collection from "@tonaljs/collection";
+import * as Core from "@tonaljs/core";
+import DurationValue from "@tonaljs/duration-value";
+import Interval from "@tonaljs/interval";
+import Key from "@tonaljs/key";
+import Midi from "@tonaljs/midi";
+import Mode from "@tonaljs/mode";
+import Note from "@tonaljs/note";
+import Pcset from "@tonaljs/pcset";
+import Progression from "@tonaljs/progression";
+import Range from "@tonaljs/range";
+import RomanNumeral from "@tonaljs/roman-numeral";
+import Scale from "@tonaljs/scale";
+import ScaleType from "@tonaljs/scale-type";
+import TimeSignature from "@tonaljs/time-signature";
+
+export * from "@tonaljs/core";
+
+// deprecated (backwards compatibility)
+const Tonal = Core;
+const PcSet = Pcset;
+const ChordDictionary = ChordType;
+const ScaleDictionary = ScaleType;
+
+export {
+ AbcNotation,
+ Array,
+ Chord,
+ ChordType,
+ Collection,
+ Core,
+ DurationValue,
+ Note,
+ Interval,
+ Key,
+ Midi,
+ Mode,
+ Pcset,
+ Progression,
+ Range,
+ RomanNumeral,
+ Scale,
+ ScaleType,
+ TimeSignature,
+ // backwards API compatibility (3.0)
+ Tonal,
+ PcSet,
+ ChordDictionary,
+ ScaleDictionary,
+};
diff --git a/packages/tonal-tonal/package.json b/packages/tonal-tonal/package.json
new file mode 100644
index 00000000..fb023a78
--- /dev/null
+++ b/packages/tonal-tonal/package.json
@@ -0,0 +1,52 @@
+{
+ "name": "@tonaljs/tonal",
+ "version": "4.6.10",
+ "description": "tonal music theory full library",
+ "keywords": [
+ "music",
+ "theory",
+ "music-theory"
+ ],
+ "main": "dist/index.js",
+ "module": "dist/index.mjs",
+ "files": [
+ "dist",
+ "browser"
+ ],
+ "types": "dist/index.d.ts",
+ "dependencies": {
+ "@tonaljs/abc-notation": "^4.6.10",
+ "@tonaljs/array": "^4.6.10",
+ "@tonaljs/chord": "^4.6.10",
+ "@tonaljs/chord-type": "^4.6.10",
+ "@tonaljs/collection": "^4.6.10",
+ "@tonaljs/core": "^4.6.10",
+ "@tonaljs/duration-value": "^4.6.10",
+ "@tonaljs/interval": "^4.6.10",
+ "@tonaljs/key": "^4.6.10",
+ "@tonaljs/midi": "^4.6.10",
+ "@tonaljs/mode": "^4.6.10",
+ "@tonaljs/note": "^4.6.10",
+ "@tonaljs/pcset": "^4.6.10",
+ "@tonaljs/progression": "^4.6.10",
+ "@tonaljs/range": "^4.6.10",
+ "@tonaljs/roman-numeral": "^4.6.10",
+ "@tonaljs/scale": "^4.6.10",
+ "@tonaljs/scale-type": "^4.6.10",
+ "@tonaljs/time-signature": "^4.6.10"
+ },
+ "author": "danigb@gmail.com",
+ "license": "MIT",
+ "publishConfig": {
+ "access": "public"
+ },
+ "scripts": {
+ "build": "tsup index.ts --sourcemap --dts --format esm,cjs",
+ "test": "jest"
+ },
+ "jest": {
+ "transform": {
+ ".(ts|tsx)": "ts-jest"
+ }
+ }
+}
diff --git a/packages/tonal-tonal/test.ts b/packages/tonal-tonal/test.ts
new file mode 100644
index 00000000..f4178a24
--- /dev/null
+++ b/packages/tonal-tonal/test.ts
@@ -0,0 +1,275 @@
+import * as Tonal from "./index";
+
+describe("tonal", () => {
+ test("exported modules and functions", () => {
+ const exportedNames = Object.keys(Tonal).sort();
+ expect(exportedNames).toEqual([
+ "AbcNotation",
+ "Array",
+ "Chord",
+ "ChordDictionary",
+ "ChordType",
+ "Collection",
+ "Core",
+ "DurationValue",
+ "Interval",
+ "Key",
+ "Midi",
+ "Mode",
+ "Note",
+ "PcSet", // <- deprecated
+ "Pcset",
+ "Progression",
+ "Range",
+ "RomanNumeral",
+ "Scale",
+ "ScaleDictionary",
+ "ScaleType",
+ "TimeSignature",
+ "Tonal",
+ "accToAlt",
+ "altToAcc",
+ "coordToInterval",
+ "coordToNote",
+ "decode",
+ "deprecate",
+ "distance",
+ "encode",
+ "fillStr",
+ "interval",
+ "isNamed",
+ "isPitch",
+ "note",
+ "stepToLetter",
+ "tokenizeInterval",
+ "tokenizeNote",
+ "transpose",
+ ]);
+ });
+ test("Modules exports functions", () => {
+ const modNames = Object.keys(Tonal)
+ .sort()
+ .filter((name) => name[0] === name.toUpperCase()[0]);
+
+ const exportedFunctions = modNames.reduce((exported, modName) => {
+ const mod = (Tonal as any)[modName];
+ exported[modName] = Object.keys(mod).sort();
+ return exported;
+ }, {} as Record);
+
+ expect(exportedFunctions).toEqual({
+ AbcNotation: [
+ "abcToScientificNotation",
+ "distance",
+ "scientificToAbcNotation",
+ "tokenize",
+ "transpose",
+ ],
+ Array: [
+ "compact",
+ "permutations",
+ "range",
+ "rotate",
+ "shuffle",
+ "sortedNoteNames",
+ "sortedUniqNoteNames",
+ ],
+ Chord: [
+ "chord",
+ "chordScales",
+ "detect",
+ "extended",
+ "get",
+ "getChord",
+ "reduced",
+ "tokenize",
+ "transpose",
+ ],
+ ChordDictionary: [
+ "add",
+ "all",
+ "chordType",
+ "entries",
+ "get",
+ "keys",
+ "names",
+ "removeAll",
+ "symbols",
+ ],
+ ChordType: [
+ "add",
+ "all",
+ "chordType",
+ "entries",
+ "get",
+ "keys",
+ "names",
+ "removeAll",
+ "symbols",
+ ],
+ Collection: ["compact", "permutations", "range", "rotate", "shuffle"],
+ Core: [
+ "accToAlt",
+ "altToAcc",
+ "coordToInterval",
+ "coordToNote",
+ "decode",
+ "deprecate",
+ "distance",
+ "encode",
+ "fillStr",
+ "interval",
+ "isNamed",
+ "isPitch",
+ "note",
+ "stepToLetter",
+ "tokenizeInterval",
+ "tokenizeNote",
+ "transpose",
+ ],
+ DurationValue: ["fraction", "get", "names", "shorthands", "value"],
+ Interval: [
+ "add",
+ "addTo",
+ "distance",
+ "fromSemitones",
+ "get",
+ "invert",
+ "name",
+ "names",
+ "num",
+ "quality",
+ "semitones",
+ "simplify",
+ "substract",
+ "transposeFifths",
+ ],
+ Key: ["majorKey", "majorTonicFromKeySignature", "minorKey"],
+ Midi: ["freqToMidi", "isMidi", "midiToFreq", "midiToNoteName", "toMidi"],
+ Mode: [
+ "all",
+ "distance",
+ "entries",
+ "get",
+ "mode",
+ "names",
+ "notes",
+ "relativeTonic",
+ "seventhChords",
+ "triads",
+ ],
+ Note: [
+ "accidentals",
+ "ascending",
+ "chroma",
+ "descending",
+ "enharmonic",
+ "freq",
+ "fromFreq",
+ "fromFreqSharps",
+ "fromMidi",
+ "fromMidiSharps",
+ "get",
+ "midi",
+ "name",
+ "names",
+ "octave",
+ "pitchClass",
+ "simplify",
+ "sortedNames",
+ "sortedUniqNames",
+ "tr",
+ "trBy",
+ "trFifths",
+ "trFrom",
+ "transpose",
+ "transposeBy",
+ "transposeFifths",
+ "transposeFrom",
+ ],
+ PcSet: [
+ "chroma",
+ "chromas",
+ "filter",
+ "get",
+ "intervals",
+ "isEqual",
+ "isNoteIncludedIn",
+ "isSubsetOf",
+ "isSupersetOf",
+ "modes",
+ "num",
+ "pcset",
+ ],
+ Pcset: [
+ "chroma",
+ "chromas",
+ "filter",
+ "get",
+ "intervals",
+ "isEqual",
+ "isNoteIncludedIn",
+ "isSubsetOf",
+ "isSupersetOf",
+ "modes",
+ "num",
+ "pcset",
+ ],
+ Progression: ["fromRomanNumerals", "toRomanNumerals"],
+ Range: ["chromatic", "numeric"],
+ RomanNumeral: ["get", "names", "romanNumeral"],
+ Scale: [
+ "extended",
+ "get",
+ "modeNames",
+ "names",
+ "rangeOf",
+ "reduced",
+ "scale",
+ "scaleChords",
+ "scaleNotes",
+ "tokenize",
+ ],
+ ScaleDictionary: [
+ "add",
+ "all",
+ "entries",
+ "get",
+ "keys",
+ "names",
+ "removeAll",
+ "scaleType",
+ ],
+ ScaleType: [
+ "add",
+ "all",
+ "entries",
+ "get",
+ "keys",
+ "names",
+ "removeAll",
+ "scaleType",
+ ],
+ TimeSignature: ["get", "names", "parse"],
+ Tonal: [
+ "accToAlt",
+ "altToAcc",
+ "coordToInterval",
+ "coordToNote",
+ "decode",
+ "deprecate",
+ "distance",
+ "encode",
+ "fillStr",
+ "interval",
+ "isNamed",
+ "isPitch",
+ "note",
+ "stepToLetter",
+ "tokenizeInterval",
+ "tokenizeNote",
+ "transpose",
+ ],
+ });
+ });
+});
diff --git a/packages/tonal/CHANGELOG.md b/packages/tonal/CHANGELOG.md
index 8eabc09d..c238fac4 100644
--- a/packages/tonal/CHANGELOG.md
+++ b/packages/tonal/CHANGELOG.md
@@ -1,4 +1,4 @@
-# @tonaljs/tonal
+# tonal
## 4.6.10
diff --git a/packages/tonal/README.md b/packages/tonal/README.md
index c1305c50..ab21c0ba 100644
--- a/packages/tonal/README.md
+++ b/packages/tonal/README.md
@@ -1,35 +1,180 @@
-# @tonaljs/tonal  [](https://www.npmjs.com/package/@tonaljs/tonal)
+# tonal
-`@tonaljs/tonal`
+[](https://www.npmjs.com/package/tonal)
+[](https://github.com/tonaljs/tonal/actions)
+
+
-Tonal library
+`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
+
+```js
+import { Interval, Note, Scale } from "tonal";
+
+Note.midi("A4"); // => 60
+Note.freq("a4").freq; // => 440
+Note.accidentals("c#2"); // => '#'
+Note.transpose("C4", "5P"); // => "G4"
+Interval.semitones("5P"); // => 7
+Interval.distance("C4", "G4"); // => "5P"
+Scale.get("C major").notes; // =>["C", "D", "E", "F", "G", "A", "B"];
+```
## Install
+Install all packages at once:
+
```bash
-npm i --save @tonaljs/tonal
-# or
-yarn add @tonaljs/tonal
+npm install --save tonal
```
## Usage
-Import:
+Tonal is compatible with both ES5 and ES6 modules, and browser.
+
+#### ES6 `import`:
```js
-// ES6
-import { Note, Key } from "@tonaljs/tonal";
-// node
-const { Note, Key } = require("@tonaljs/tonal");
-// browser
-const { Note, Key } = window.Tonal;
+import { Note, Scale } from "tonal";
```
-Use:
+#### ES5 `require`:
```js
-Note.transpose("A4", "5P");
-Key.majorKey("Gb");
+const { Note, Scale } = require("tonal");
+```
+
+#### Browser
+
+You can use the browser version from jsdelivr CDN directly in your html:
+
+```html
+
+
```
-See [README.md](/#documentation) for documentation.
+Or if you prefer, grab the
+[minified browser ready version](https://raw.githubusercontent.com/tonaljs/tonal/master/packages/tonal/browser/tonal.min.js)
+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:
+
+```bash
+npm i @tonaljs/note
+```
+
+```js
+import { transpose } from "@tonaljs/note";
+transpose("A4", "P5");
+```
+
+## Documentation
+
+Generally, you just need to install `tonal` package (before it was called `@tonaljs/tonal`).
+
+- [tonal](/packages/tonal): All modules bundled in one package
+
+The API documentation is inside README.md of each module 👇
+
+#### Notes and intervals
+
+- [@tonaljs/note](/packages/note): Note operations (simplify, transposeBy )
+- [@tonaljs/midi](/packages/midi): Midi number conversions
+- [@tonaljs/interval](/packages/interval): Interval operations (add, simplify,
+ invert)
+- [@tonaljs/pitch-notation-abc](/packages/pitch-notation-abc): Parse ABC
+ notation notes
+
+#### Scales and chords
+
+- [@tonaljs/scale](/packages/scale): Scales
+- [@tonaljs/scale-type](/packages/scale-type): A dictionary of scales
+- [@tonaljs/chord](/packages/chord): Chords
+- [@tonaljs/chord-type](/packages/chord-type): A dictionary of chords
+- [@tonaljs/chord-detect](/packages/chord-detect): Detect chords from notes
+- [@tonaljs/pcset](/packages/pcset): Pitch class sets. Compare note groups.
+
+#### Keys, chord progressions
+
+- [@tonaljs/key](/packages/key): Major and minor keys, it's scales and chords
+- [@tonaljs/mode](/packages/mode): A dictionary of Greek modes (ionian,
+ dorian...)
+- [@tonaljs/progression](/packages/progression): Chord progressions
+- [@tonaljs/roman-numeral](/packages/roman-numeral): Parse roman numeral symbols
+
+#### Time, rhythm
+
+- [@tonaljs/time-signature](/packages/time-signature): Parse time signatures
+- [@tonaljs/duration-value](/packages/duration-value): Note duration values
+
+#### Utilities
+
+- [@tonaljs/core](/packages/core): Core functions (note, interval, transpose and
+ distance)
+- [@tonaljs/collection](/packages/collection): Utility functions to work with
+ collections (range, shuffle, permutations)
+- [@tonaljs/range](/packages/range): Create note ranges
+
+## Contributing
+
+Read [contributing document](/docs/CONTRIBUTING.md) for instructions
+
+## Inspiration
+
+This library takes inspiration from other music theory libraries:
+
+- Teoria: https://github.com/saebekassebil/teoria
+- Impro-Visor: https://www.cs.hmc.edu/~keller/jazz/improvisor/
+- MusicKit: https://github.com/benzguo/MusicKit
+- Music21: http://web.mit.edu/music21/doc/index.html
+- Sharp11: https://github.com/jsrmath/sharp11
+- python-mingus: https://github.com/bspaans/python-mingus
+
+## Projects using tonal
+
+Showcase of projects that are using Tonal:
+
+- [Solfej](https://www.solfej.io/) by
+ [Shayan Javadi](https://github.com/ShayanJavadi)
+- [EarBeater](https://www.earbeater.com/online-ear-training/) by
+ [Morten Vestergaard](https://github.com/vellebelle)
+- [Sonid](https://sonid.app/)
+ ([play store](https://play.google.com/store/apps/details?id=org.stroopwafel.music.app),
+ [apple store](https://apps.apple.com/us/app/sonid/id1490221762?ls=1)) by
+ [martijnmichel](https://github.com/martijnmichel)
+- [Songcraft](https://songcraft.io/) by
+ [Gabe G'Sell](https://github.com/gabergg)
+- [React Guitar](https://react-guitar.com/) by
+ [4lejandrito](https://github.com/4lejandrito)
+- [Fretty.app](https://fretty.app/) by [tfeldmann](https://github.com/tfeldmann)
+- [Chordify](https://ashleymays.github.io/Chordify) by [ashleymays](https://github.com/ashleymays)
+- [Chordal](https://chordal.vercel.app) by [kad1kad](https://github.com/kad1kad)
+- [muted.io](https://muted.io/) by [thisisseb](https://github.com/thisisseb)
+
+Thank you all!
+
+Add your project here by
+[editing this file](https://github.com/tonaljs/tonal/edit/main/README.md)
+
+## License
+
+[MIT License](docs/LICENSE)
diff --git a/packages/tonal/package.json b/packages/tonal/package.json
index 87ad6e4d..228ab718 100644
--- a/packages/tonal/package.json
+++ b/packages/tonal/package.json
@@ -1,7 +1,7 @@
{
- "name": "@tonaljs/tonal",
+ "name": "tonal",
"version": "4.6.10",
- "description": "@tonaljs music theory full library",
+ "description": "tonaljs music theory library",
"keywords": [
"music",
"theory",
diff --git a/packages/tonal/test.ts b/packages/tonal/test.ts
index 612e7a0b..f4178a24 100644
--- a/packages/tonal/test.ts
+++ b/packages/tonal/test.ts
@@ -1,7 +1,6 @@
-import { modeNames } from "@tonaljs/scale";
import * as Tonal from "./index";
-describe("@tonaljs/tonal", () => {
+describe("tonal", () => {
test("exported modules and functions", () => {
const exportedNames = Object.keys(Tonal).sort();
expect(exportedNames).toEqual([
diff --git a/packages/voice-leading/README.md b/packages/voice-leading/README.md
index 55a2065d..414589e8 100644
--- a/packages/voice-leading/README.md
+++ b/packages/voice-leading/README.md
@@ -7,13 +7,13 @@ Contains a collection functions to find optimal transitions between chord voicin
ES6:
```js
-import { VoiceLeading } from '@tonaljs/tonal';
+import { VoiceLeading } from "tonal";
```
Nodejs:
```js
-const { VoiceLeading } = require('@tonaljs/tonal');
+const { VoiceLeading } = require("tonal");
```
## API
@@ -21,7 +21,10 @@ const { VoiceLeading } = require('@tonaljs/tonal');
### VoiceLeading
```ts
-declare type VoiceLeadingFunction = (voicings: string[][], lastVoicing: string[]) => string[];
+declare type VoiceLeadingFunction = (
+ voicings: string[][],
+ lastVoicing: string[]
+) => string[];
```
A function that decides which of a set of voicings is picked as a follow up to lastVoicing.
@@ -34,8 +37,10 @@ const topNoteDiff: VoiceLeadingFunction = (voicings, lastVoicing) => {
// if no lastVoicing is given
return voicings[0];
}
- const topNoteMidi = (voicing: string[]) => Note.midi(voicing[voicing.length - 1]) || 0;
- const diff = (voicing: string[]) => Math.abs(topNoteMidi(lastVoicing) - topNoteMidi(voicing));
+ const topNoteMidi = (voicing: string[]) =>
+ Note.midi(voicing[voicing.length - 1]) || 0;
+ const diff = (voicing: string[]) =>
+ Math.abs(topNoteMidi(lastVoicing) - topNoteMidi(voicing));
return voicings.sort((a, b) => diff(a) - diff(b))[0]; // return voicing with least diff
};
```
@@ -45,10 +50,10 @@ Usage
```ts
topNoteDiff(
[
- ['F3', 'A3', 'C4', 'E4'], // top note = E4
- ['C4', 'E4', 'F4', 'A4'], // top note = A4
+ ["F3", "A3", "C4", "E4"], // top note = E4
+ ["C4", "E4", "F4", "A4"], // top note = A4
],
- ['C4', 'E4', 'G4', 'B4'] // top note = B4
+ ["C4", "E4", "G4", "B4"] // top note = B4
);
// ['C4', 'E4', 'F4', 'A4'] // => A4 is closer to B4 than E4
```
diff --git a/packages/voicing-dictionary/README.md b/packages/voicing-dictionary/README.md
index 4cb7b804..5c158fb1 100644
--- a/packages/voicing-dictionary/README.md
+++ b/packages/voicing-dictionary/README.md
@@ -7,13 +7,13 @@ Contains dictionaries for many chord voicings. Used by [@tonaljs/voicings](../vo
ES6:
```js
-import { VoicingDictionary } from '@tonaljs/tonal';
+import { VoicingDictionary } from "tonal";
```
Nodejs:
```js
-const { VoicingDictionary } = require('@tonaljs/tonal');
+const { VoicingDictionary } = require("tonal");
```
## API
@@ -24,18 +24,18 @@ Maps a chord symbol to a set of voicings:
```ts
const lefthand = {
- m7: ['3m 5P 7m 9M', '7m 9M 10m 12P'],
- '7': ['3M 6M 7m 9M', '7m 9M 10M 13M'],
- '^7': ['3M 5P 7M 9M', '7M 9M 10M 12P'],
- '69': ['3M 5P 6A 9M'],
- m7b5: ['3m 5d 7m 8P', '7m 8P 10m 12d'],
- '7b9': ['3M 6m 7m 9m', '7m 9m 10M 13m'],
- '7b13': ['3M 6m 7m 9m', '7m 9m 10M 13m'],
- o7: ['1P 3m 5d 6M', '5d 6M 8P 10m'],
- '7#11': ['7m 9M 11A 13A'],
- '7#9': ['3M 7m 9A'],
- mM7: ['3m 5P 7M 9M', '7M 9M 10m 12P'],
- m6: ['3m 5P 6M 9M', '6M 9M 10m 12P'],
+ m7: ["3m 5P 7m 9M", "7m 9M 10m 12P"],
+ "7": ["3M 6M 7m 9M", "7m 9M 10M 13M"],
+ "^7": ["3M 5P 7M 9M", "7M 9M 10M 12P"],
+ "69": ["3M 5P 6A 9M"],
+ m7b5: ["3m 5d 7m 8P", "7m 8P 10m 12d"],
+ "7b9": ["3M 6m 7m 9m", "7m 9m 10M 13m"],
+ "7b13": ["3M 6m 7m 9m", "7m 9m 10M 13m"],
+ o7: ["1P 3m 5d 6M", "5d 6M 8P 10m"],
+ "7#11": ["7m 9M 11A 13A"],
+ "7#9": ["3M 7m 9A"],
+ mM7: ["3m 5P 7M 9M", "7M 9M 10m 12P"],
+ m6: ["3m 5P 6M 9M", "6M 9M 10m 12P"],
};
```
diff --git a/packages/voicing/README.md b/packages/voicing/README.md
index bd6f09fa..859e8669 100644
--- a/packages/voicing/README.md
+++ b/packages/voicing/README.md
@@ -7,13 +7,13 @@ Contains functions to generate voicings. If you're not sure what voicings are, [
ES6:
```js
-import { Voicing } from '@tonaljs/tonal';
+import { Voicing } from "tonal";
```
Nodejs:
```js
-const { Voicing } = require('@tonaljs/tonal');
+const { Voicing } = require("tonal");
```
## API
@@ -27,7 +27,7 @@ Voicing.search(chord: string, range?: [string, string], dictionary?: VoicingDict
This method returns all possible voicings of the given chord, inside the given range, as defined in the dictionary:
```ts
-Voicing.search('C^7', ['E3', 'D5'], { '^7': ['3M 5P 7M 9M', '7M 9M 10M 12P'] });
+Voicing.search("C^7", ["E3", "D5"], { "^7": ["3M 5P 7M 9M", "7M 9M 10M 12P"] });
/* => [
['E3', 'G3', 'B3', 'D4'],
['E4', 'G4', 'B4', 'D5'],
@@ -38,8 +38,8 @@ Voicing.search('C^7', ['E3', 'D5'], { '^7': ['3M 5P 7M 9M', '7M 9M 10M 12P'] });
The VoicingDictionary param uses the format of [@tonaljs/voicing-dictionary](../voicing-dictionary). Instead of defining your own, you could also use an existing dictionary from there:
```ts
-import { VoicingDictionary } from '@tonaljs/voicing-dictionary';
-Voicing.search('C^7', ['E3', 'D5'], VoicingDictionary.lefthand);
+import { VoicingDictionary } from "@tonaljs/voicing-dictionary";
+Voicing.search("C^7", ["E3", "D5"], VoicingDictionary.lefthand);
/* => [
['E3', 'G3', 'B3', 'D4'],
['E4', 'G4', 'B4', 'D5'],
@@ -50,7 +50,7 @@ Voicing.search('C^7', ['E3', 'D5'], VoicingDictionary.lefthand);
If no range and/or dictionary is given, there is a fallback to [default values](./index.ts) (look for defaultRange / defaultDictionary):
```ts
-Voicing.search('C^7');
+Voicing.search("C^7");
/* => [
['E3', 'G3', 'B3', 'D4'],
['E4', 'G4', 'B4', 'D5'],
@@ -73,21 +73,19 @@ Voicing.get(
Returns the best voicing for **chord** inside the given **range**, as contained in the **dictionary**, using **voiceLeading** to decide which voicing to pick after **lastVoicing**. Internally calls Voicing.search to generate the available voicings:
```ts
-Voicing.get('Dm7');
+Voicing.get("Dm7");
/* ['F3', 'A3', 'C4', 'E4']); */
-Voicing.get('Dm7', ['F3', 'A4'], lefthand, topNoteDiff);
+Voicing.get("Dm7", ["F3", "A4"], lefthand, topNoteDiff);
/* ['F3', 'A3', 'C4', 'E4']; */
-const last = ['C4', 'E4', 'G4', 'B4'];
-Voicing.get('Dm7', ['F3', 'A4'], lefthand, topNoteDiff, last);
+const last = ["C4", "E4", "G4", "B4"];
+Voicing.get("Dm7", ["F3", "A4"], lefthand, topNoteDiff, last);
/* ['C4', 'E4', 'F4', 'A4']; */ // => A4 is closest to B4
```
## Optional: Voicing.analyze
```ts
-export declare function analyze(
- voicing: string[]
-): {
+export declare function analyze(voicing: string[]): {
topNote: string;
bottomNote: string;
midiAverage: number;
@@ -97,9 +95,9 @@ export declare function analyze(
Returns some useful info on the given voicing:
```ts
-expect(Voicing.analyze(['C4', 'E4', 'G4', 'B4'])).toEqual({
- topNote: 'B4',
- bottomNote: 'C4',
+expect(Voicing.analyze(["C4", "E4", "G4", "B4"])).toEqual({
+ topNote: "B4",
+ bottomNote: "C4",
midiAverage: 85.4, // did not check :)
// many more values possible
});
@@ -121,7 +119,9 @@ export declare function analyzeTransition(
Returns some useful info on the given voice transition
```ts
-expect(Voicing.analyzeTransition(['C4', 'E4', 'G4', 'B4'], ['D4', 'F4', 'A4', 'C5'])).toEqual({
+expect(
+ Voicing.analyzeTransition(["C4", "E4", "G4", "B4"], ["D4", "F4", "A4", "C5"])
+).toEqual({
topNoteDiff: 1,
bottomNoteDiff: 2,
movement: 5,
@@ -133,15 +133,22 @@ Could also use intervals instead of semitones (but semitones are easier to compa
## Optional: Voicing.intervalSets
```ts
-export declare function intervalSets(chordSymbol: string, dictionary: VoicingDictionary);
+export declare function intervalSets(
+ chordSymbol: string,
+ dictionary: VoicingDictionary
+);
```
Get possible interval sets for given chord in given dictionary:
```ts
-expect(Voicing.intervalSets('M7', lefthand)).toEqual([['3M 5P 7M 9M', '7M 9M 10M 12P']]);
+expect(Voicing.intervalSets("M7", lefthand)).toEqual([
+ ["3M 5P 7M 9M", "7M 9M 10M 12P"],
+]);
// could also be used with chord symbol (ignore root)
-expect(Voicing.intervalSets('CM7', lefthand)).toEqual([['3M 5P 7M 9M', '7M 9M 10M 12P']]);
+expect(Voicing.intervalSets("CM7", lefthand)).toEqual([
+ ["3M 5P 7M 9M", "7M 9M 10M 12P"],
+]);
```
Note that it works, even if the chord symbol "M7" is just an alias of the "^7" symbol used in the dictionary.
@@ -149,7 +156,11 @@ Note that it works, even if the chord symbol "M7" is just an alias of the "^7" s
## Optional: Voicing.searchSets
```ts
-export declare function searchSets(intervalSets: string[][], range: string[], root: string);
+export declare function searchSets(
+ intervalSets: string[][],
+ range: string[],
+ root: string
+);
```
Renders all sets of notes that represent any of the interval sets inside the given range, relative to the root:
@@ -158,16 +169,16 @@ Renders all sets of notes that represent any of the interval sets inside the giv
expect(
Voicing.searchSets(
[
- ['1P', '3M', '5P'],
- ['3M', '5P', '8P'],
+ ["1P", "3M", "5P"],
+ ["3M", "5P", "8P"],
],
- ['C3', 'G4'],
- 'C'
+ ["C3", "G4"],
+ "C"
)
).toEqual([
- ['C3', 'E3', 'G3'],
- ['E3', 'G3', 'C4'],
- ['C4', 'E4', 'G4'],
+ ["C3", "E3", "G3"],
+ ["E3", "G3", "C4"],
+ ["C4", "E4", "G4"],
]);
```