-
Notifications
You must be signed in to change notification settings - Fork 208
/
index.ts
56 lines (52 loc) · 1.91 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { compact, range } from "@tonaljs/collection";
import { midiToNoteName, toMidi, ToNoteNameOptions } from "@tonaljs/midi";
/**
* Create a numeric range. You supply a list of notes or numbers and it will
* be connected to create complex ranges.
*
* @param {Array} notes - the list of notes or midi numbers used
* @return {Array} an array of numbers or empty array if not valid parameters
*
* @example
* numeric(["C5", "C4"]) // => [ 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60 ]
* // it works midi notes
* numeric([10, 5]) // => [ 10, 9, 8, 7, 6, 5 ]
* // complex range
* numeric(["C4", "E4", "Bb3"]) // => [60, 61, 62, 63, 64, 63, 62, 61, 60, 59, 58]
*/
export function numeric(notes: (string | number)[]): number[] {
const midi: number[] = compact(
notes.map((note) => (typeof note === "number" ? note : toMidi(note))),
);
if (!notes.length || midi.length !== notes.length) {
// there is no valid notes
return [];
}
return midi.reduce(
(result, note) => {
const last: number = result[result.length - 1];
return result.concat(range(last, note).slice(1));
},
[midi[0]],
);
}
/**
* Create a range of chromatic notes. The altered notes will use flats.
*
* @function
* @param {Array} notes - the list of notes or midi note numbers to create a range from
* @param {Object} options - The same as `midiToNoteName` (`{ sharps: boolean, pitchClass: boolean }`)
* @return {Array} an array of note names
*
* @example
* Range.chromatic(["C2, "E2", "D2"]) // => ["C2", "Db2", "D2", "Eb2", "E2", "Eb2", "D2"]
* // with sharps
* Range.chromatic(["C2", "C3"], { sharps: true }) // => [ "C2", "C#2", "D2", "D#2", "E2", "F2", "F#2", "G2", "G#2", "A2", "A#2", "B2", "C3" ]
*/
export function chromatic(
notes: (string | number)[],
options?: ToNoteNameOptions,
): string[] {
return numeric(notes).map((midi) => midiToNoteName(midi, options));
}
export default { numeric, chromatic };