forked from tonaljs/tonal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
87 lines (80 loc) · 2.02 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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import {
EmptyPcset,
Pcset,
pcset,
PcsetChroma,
PcsetNum
} from "@tonaljs/pcset";
import data from "./data";
export type ChordQuality =
| "Major"
| "Minor"
| "Augmented"
| "Diminished"
| "Unknown";
export interface ChordType extends Pcset {
name: string;
quality: ChordQuality;
aliases: string[];
optionalIntervals?: string[];
}
const NoChordType: ChordType = {
...EmptyPcset,
name: "",
quality: "Unknown",
intervals: [],
aliases: []
};
type ChordTypeName = string | PcsetChroma | PcsetNum;
const chords: ChordType[] = data.map(dataToChordType);
chords.sort((a, b) => a.setNum - b.setNum);
const index: Record<ChordTypeName, ChordType> = chords.reduce(
(index: Record<ChordTypeName, ChordType>, chord) => {
if (chord.name) {
index[chord.name] = chord;
}
index[chord.setNum] = chord;
index[chord.chroma] = chord;
chord.aliases.forEach(alias => {
index[alias] = chord;
});
return index;
},
{}
);
/**
* Given a chord name or chroma, return the chord properties
* @param {string} source - chord name or pitch class set chroma
* @example
* import { chord } from 'tonaljs/chord-dictionary'
* chord('major')
*/
export function chordType(type: ChordTypeName): ChordType {
return index[type] || NoChordType;
}
/**
* Return a list of all chord types
*/
export function entries(): ChordType[] {
return chords.slice();
}
function getQuality(intervals: string[]): ChordQuality {
const has = (interval: string) => intervals.indexOf(interval) !== -1;
return has("5A")
? "Augmented"
: has("3M")
? "Major"
: has("5d")
? "Diminished"
: has("3m")
? "Minor"
: "Unknown";
}
function dataToChordType([ivls, name, abbrvs, optionalIvls]: string[]) {
const intervals = ivls.split(" ");
const optionalIntervals = (optionalIvls || "").split(" ").filter(i => i);
const aliases = abbrvs.split(" ");
const quality = getQuality(intervals);
const set = pcset(intervals);
return { ...set, name, quality, intervals, aliases, optionalIntervals };
}