Browse Source

Fix half-diminished analysis

Use lowered fifth notation for half-diminished analysis.
master
TheoryOfNekomata 1 year ago
parent
commit
8e4ddd19da
3 changed files with 322 additions and 277 deletions
  1. +17
    -0
      package.json
  2. +42
    -14
      src/analyze.ts
  3. +263
    -263
      src/index.ts

+ 17
- 0
package.json View File

@@ -45,5 +45,22 @@
"author": "TheoryOfNekomata <allan.crisostomo@outlook.com>",
"publishConfig": {
"access": "public"
},
"types": "./dist/types/index.d.ts",
"main": "./dist/cjs/production/index.js",
"module": "./dist/esm/production/index.js",
"exports": {
".": {
"development": {
"require": "./dist/cjs/development/index.js",
"import": "./dist/esm/development/index.js"
},
"require": "./dist/cjs/production/index.js",
"import": "./dist/esm/production/index.js",
"types": "./dist/types/index.d.ts"
}
},
"typesVersions": {
"*": {}
}
}

+ 42
- 14
src/analyze.ts View File

@@ -125,12 +125,13 @@ const getChordSeventh = (
normalizedIntervals: Interval[],
priorAnalysis: ChordAnalysis,
) => {
const { extensions: priorExtensions = [] } = priorAnalysis;
const { extensions: priorExtensions = [], base: oldBase, modifications = [] } = priorAnalysis;
const {
[CHORD_COMPONENT_ORDERS.indexOf(ChordComponent.THIRD)]: third,
[CHORD_COMPONENT_ORDERS.indexOf(ChordComponent.SIXTH)]: sixth,
[CHORD_COMPONENT_ORDERS.indexOf(ChordComponent.SEVENTH)]: seventh,
} = normalizedIntervals;
if (priorAnalysis.base === ChordBase.DIMINISHED && sixth === Interval.DIMINISHED_SEVENTH) {
if (oldBase === ChordBase.DIMINISHED && sixth === Interval.DIMINISHED_SEVENTH) {
return {
...priorAnalysis,
extensions: [...priorExtensions, {
@@ -140,25 +141,52 @@ const getChordSeventh = (
};
}

switch (seventh) {
case Interval.MAJOR_SEVENTH:
return {
...priorAnalysis,
extensions: [...priorExtensions, {
type: ChordExtensionType.MAJOR,
component: ChordComponent.SEVENTH,
}],
};
case Interval.MINOR_SEVENTH:
if (seventh === Interval.MINOR_SEVENTH) {
let newBase: ChordBase | undefined;
if (third === Interval.MINOR_THIRD) {
newBase = ChordBase.MINOR;
} else if (third === Interval.MAJOR_THIRD) {
newBase = ChordBase.MAJOR;
} else {
newBase = oldBase;
}

if (oldBase === ChordBase.DIMINISHED) {
return {
...priorAnalysis,
base: newBase,
extensions: [...priorExtensions, {
type: ChordExtensionType.DOMINANT,
component: ChordComponent.SEVENTH,
}],
modifications: [
...modifications,
{
type: ChordModificationType.LOWERED,
component: ChordComponent.FIFTH,
},
],
};
default:
break;
}

return {
...priorAnalysis,
base: newBase,
extensions: [...priorExtensions, {
type: ChordExtensionType.DOMINANT,
component: ChordComponent.SEVENTH,
}],
};
}

if (seventh === Interval.MAJOR_SEVENTH) {
return {
...priorAnalysis,
extensions: [...priorExtensions, {
type: ChordExtensionType.MAJOR,
component: ChordComponent.SEVENTH,
}],
};
}

return priorAnalysis;


+ 263
- 263
src/index.ts View File

@@ -9,266 +9,266 @@
export * from './analyze';
export * from './common';
export * from './utils';
const CHORD_DICTIONARY = [
{
name: 'Augmented',
symbol: 'aug',
id: 'aug',
notes: [0, 4, 8],
},
{
name: 'Augmented eleventh',
symbol: '<sup>(♯11)</sup>',
id: '(#11)',
notes: [0, 4, 7, 10, 14, 18],
},
{
name: 'Augmented major seventh',
symbol: 'aug<sup>maj7</sup>',
id: 'augmaj7',
notes: [0, 4, 8, 11],
},
{
name: 'Augmented seventh',
symbol: 'aug<sup>7</sup>',
id: 'aug7',
notes: [0, 4, 8, 10],
},
{
name: 'Diminished',
symbol: 'dim',
id: 'dim',
notes: [0, 3, 6],
},
{
name: 'Diminished major seventh',
symbol: 'dim<sup>maj7</sup>',
id: 'dimmaj7',
notes: [0, 3, 6, 11],
},
{
name: 'Diminished seventh',
symbol: 'dim<sup>7</sup>',
id: 'dim7',
notes: [0, 3, 6, 9],
},
{
name: 'Dominant eleventh',
symbol: '<sup>11</sup>',
id: '11',
notes: [0, 4, 7, 10, 14, 17],
},
{
name: 'Dominant minor ninth',
symbol: '<sup>7♭9</sup>',
notes: [0, 4, 7, 10, 13],
},
{
name: 'Dominant ninth',
symbol: '<sup>9</sup>',
notes: [0, 4, 7, 10, 14],
},
{
name: 'Dominant seventh',
symbol: '<sup>7</sup>',
notes: [0, 4, 7, 10],
},
{
name: 'Dominant seventh flat five',
symbol: '<sup>7♭5</sup>',
notes: [0, 4, 6, 10],
},
{
name: 'Dominant seventh sharp nine',
symbol: '<sup>(♯9)</sup>',
notes: [0, 4, 7, 10, 15],
},
{ name: 'Dominant thirteenth', symbol: '<sup>13</sup>', notes: [0, 4, 7, 10, 14, 17, 21] },
{ name: 'Half-diminished seventh', symbol: 'm<sup>7(♭5)</sup>', notes: [0, 3, 6, 10] },
{
name: 'Major',
symbol: '',
id: '',
notes: [0, 4, 7],
},
{ name: 'Major eleventh', symbol: '<sup>maj11</sup>', notes: [0, 4, 7, 11, 14, 17] },
{
name: 'Major seventh',
symbol: '<sup>maj7</sup>',
notes: [0, 4, 7, 11],
},
{ name: 'Major seventh sharp eleventh', symbol: '<sup>maj7♯11</sup>', notes: [0, 4, 8, 11, 18] },
{
name: 'Major sixth',
symbol: '<sup>6</sup>',
notes: [0, 4, 7, 9],
},
{
name: 'Major sixth ninth',
symbol: '<sup>6(9)</sup>',
notes: [0, 4, 7, 9, 14],
},
{ name: 'Major ninth', symbol: '<sup>maj9</sup>', notes: [0, 4, 7, 11, 14] },
{
name: 'Major thirteenth',
symbol: '<sup>maj13</sup>',
notes: [0, 4, 7, 11, 14, 18, 21],
},
{
name: 'Minor',
symbol: 'm',
notes: [0, 3, 7],
},
{ name: 'Minor eleventh', symbol: 'm<sup>11</sup>', notes: [0, 3, 7, 10, 14, 17] },
{
name: 'Minor major seventh',
symbol: 'm<sup>maj7</sup>',
notes: [0, 3, 7, 11],
},
{ name: 'Minor ninth', symbol: 'm<sup>9</sup>', notes: [0, 3, 7, 10, 14] },
{
name: 'Minor seventh',
symbol: 'm<sup>7</sup>',
notes: [0, 3, 7, 10],
},
{ name: 'Minor sixth', symbol: 'm<sup>6</sup>', notes: [0, 3, 7, 9] },
{
name: 'Minor sixth ninth (6/9)',
symbol: 'm<sup>6(9)</sup>',
notes: [0, 3, 7, 9, 14],
},
{ name: 'Minor thirteenth', symbol: 'm<sup>13</sup>', notes: [0, 3, 7, 10, 14, 17, 21] },
{
name: 'Ninth augmented fifth',
symbol: '<sup>9♯5</sup>',
notes: [0, 4, 8, 10, 14],
},
{ name: 'Ninth flat fifth', notes: [0, 4, 6, 10, 14], symbol: '<sup>9♭5</sup>' },
{
name: 'Seven six',
symbol: '<sup>7(6)</sup>',
notes: [0, 4, 7, 9, 10],
},
{ name: 'Seventh suspension four', symbol: '<sup>7sus4</sup>', notes: [0, 5, 7, 10] },
{
name: 'Suspended fourth',
symbol: '<sup>sus4</sup>',
notes: [0, 5, 7],
},
{
name: 'Suspended second',
symbol: '<sup>sus2</sup>',
notes: [0, 2, 7],
},
{
name: 'Thirteenth flat ninth',
symbol: '<sup>13♭9</sup>',
notes: [0, 4, 7, 10, 13, 21],
},
{
name: 'Thirteenth flat ninth flat fifth',
symbol: '<sup>13♭9(♭5)</sup>',
notes: [0, 4, 6, 10, 13, 21],
},
];
export enum ConstructChordFormat {
PITCH_ARRAY,
NOTATION,
SOUND,
}
enum NotationType {
STANDARD,
TABLATURE,
}
interface ConstructChordOptions {
format?: ConstructChordFormat;
}
enum ConstructChordStyle {
CHORD = 'CHORD',
ARPEGGIO = 'ARPEGGIO',
ARPEGGIO_THEN_CHORD = 'ARPEGGIO_THEN_CHORD',
CHORD_THEN_ARPEGGIO = 'CHORD_THEN_ARPEGGIO',
}
interface ConstructChordSoundOptions extends ConstructChordOptions {
format?: ConstructChordFormat.SOUND;
midiInstrument?: number;
style?: ConstructChordStyle;
mimeType?: string;
}
interface ConstructChordNotationOptions extends ConstructChordOptions {
format?: ConstructChordFormat.NOTATION;
notationType?: NotationType;
mimeType?: string;
}
export enum PitchClass {
C,
B_SHARP = C,
C_SHARP,
D_FLAT = C_SHARP,
D,
D_SHARP,
E_FLAT = D_SHARP,
E,
F_FLAT = E,
F,
E_SHARP = F,
F_SHARP,
G_FLAT = F_SHARP,
G,
G_SHARP,
A_FLAT = G_SHARP,
A,
A_SHARP,
B_FLAT = A_SHARP,
B,
C_FLAT = B,
}
interface ChordParams {
pitchClass: PitchClass;
chord?: string;
inversion?: number;
}
const constructChordPitchArray = (params: ChordParams) => {
const { pitchClass, chord = '', inversion = 0 } = params;
const chordDefinition = CHORD_DICTIONARY.find((c) => c.id === chord);
if (!chordDefinition) {
throw new Error(`Chord ${chord} not found`);
}
const { notes } = chordDefinition;
const pitchArray = notes.map((note) => note + pitchClass);
return pitchArray;
};
const constructChordNotation = (params: ChordParams, options: ConstructChordNotationOptions) => {
return constructChordPitchArray(params);
};
const constructChordSound = (params: ChordParams, options: ConstructChordSoundOptions) => {
return constructChordPitchArray(params);
};
export const constructChord = (params: ChordParams, options = {} as ConstructChordOptions) => {
const { format = ConstructChordFormat.PITCH_ARRAY } = options;
switch (format) {
case ConstructChordFormat.PITCH_ARRAY:
return constructChordPitchArray(params);
case ConstructChordFormat.NOTATION:
return constructChordNotation(params, options as ConstructChordNotationOptions);
case ConstructChordFormat.SOUND:
return constructChordSound(params, options as ConstructChordSoundOptions);
default:
break;
}
throw new TypeError(`Unknown format ${format as string}`);
};
//
// const CHORD_DICTIONARY = [
// {
// name: 'Augmented',
// symbol: 'aug',
// id: 'aug',
// notes: [0, 4, 8],
// },
// {
// name: 'Augmented eleventh',
// symbol: '<sup>(♯11)</sup>',
// id: '(#11)',
// notes: [0, 4, 7, 10, 14, 18],
// },
// {
// name: 'Augmented major seventh',
// symbol: 'aug<sup>maj7</sup>',
// id: 'augmaj7',
// notes: [0, 4, 8, 11],
// },
// {
// name: 'Augmented seventh',
// symbol: 'aug<sup>7</sup>',
// id: 'aug7',
// notes: [0, 4, 8, 10],
// },
// {
// name: 'Diminished',
// symbol: 'dim',
// id: 'dim',
// notes: [0, 3, 6],
// },
// {
// name: 'Diminished major seventh',
// symbol: 'dim<sup>maj7</sup>',
// id: 'dimmaj7',
// notes: [0, 3, 6, 11],
// },
// {
// name: 'Diminished seventh',
// symbol: 'dim<sup>7</sup>',
// id: 'dim7',
// notes: [0, 3, 6, 9],
// },
// {
// name: 'Dominant eleventh',
// symbol: '<sup>11</sup>',
// id: '11',
// notes: [0, 4, 7, 10, 14, 17],
// },
// {
// name: 'Dominant minor ninth',
// symbol: '<sup>7♭9</sup>',
// notes: [0, 4, 7, 10, 13],
// },
// {
// name: 'Dominant ninth',
// symbol: '<sup>9</sup>',
// notes: [0, 4, 7, 10, 14],
// },
// {
// name: 'Dominant seventh',
// symbol: '<sup>7</sup>',
// notes: [0, 4, 7, 10],
// },
// {
// name: 'Dominant seventh flat five',
// symbol: '<sup>7♭5</sup>',
// notes: [0, 4, 6, 10],
// },
// {
// name: 'Dominant seventh sharp nine',
// symbol: '<sup>(♯9)</sup>',
// notes: [0, 4, 7, 10, 15],
// },
// { name: 'Dominant thirteenth', symbol: '<sup>13</sup>', notes: [0, 4, 7, 10, 14, 17, 21] },
// { name: 'Half-diminished seventh', symbol: 'm<sup>7(♭5)</sup>', notes: [0, 3, 6, 10] },
// {
// name: 'Major',
// symbol: '',
// id: '',
// notes: [0, 4, 7],
// },
// { name: 'Major eleventh', symbol: '<sup>maj11</sup>', notes: [0, 4, 7, 11, 14, 17] },
// {
// name: 'Major seventh',
// symbol: '<sup>maj7</sup>',
// notes: [0, 4, 7, 11],
// },
// { name: 'Major seventh sharp eleventh', symbol: '<sup>maj7♯11</sup>', notes: [0, 4, 8, 11, 18] },
// {
// name: 'Major sixth',
// symbol: '<sup>6</sup>',
// notes: [0, 4, 7, 9],
// },
// {
// name: 'Major sixth ninth',
// symbol: '<sup>6(9)</sup>',
// notes: [0, 4, 7, 9, 14],
// },
// { name: 'Major ninth', symbol: '<sup>maj9</sup>', notes: [0, 4, 7, 11, 14] },
// {
// name: 'Major thirteenth',
// symbol: '<sup>maj13</sup>',
// notes: [0, 4, 7, 11, 14, 18, 21],
// },
// {
// name: 'Minor',
// symbol: 'm',
// notes: [0, 3, 7],
// },
// { name: 'Minor eleventh', symbol: 'm<sup>11</sup>', notes: [0, 3, 7, 10, 14, 17] },
// {
// name: 'Minor major seventh',
// symbol: 'm<sup>maj7</sup>',
// notes: [0, 3, 7, 11],
// },
// { name: 'Minor ninth', symbol: 'm<sup>9</sup>', notes: [0, 3, 7, 10, 14] },
// {
// name: 'Minor seventh',
// symbol: 'm<sup>7</sup>',
// notes: [0, 3, 7, 10],
// },
// { name: 'Minor sixth', symbol: 'm<sup>6</sup>', notes: [0, 3, 7, 9] },
// {
// name: 'Minor sixth ninth (6/9)',
// symbol: 'm<sup>6(9)</sup>',
// notes: [0, 3, 7, 9, 14],
// },
// { name: 'Minor thirteenth', symbol: 'm<sup>13</sup>', notes: [0, 3, 7, 10, 14, 17, 21] },
// {
// name: 'Ninth augmented fifth',
// symbol: '<sup>9♯5</sup>',
// notes: [0, 4, 8, 10, 14],
// },
// { name: 'Ninth flat fifth', notes: [0, 4, 6, 10, 14], symbol: '<sup>9♭5</sup>' },
// {
// name: 'Seven six',
// symbol: '<sup>7(6)</sup>',
// notes: [0, 4, 7, 9, 10],
// },
// { name: 'Seventh suspension four', symbol: '<sup>7sus4</sup>', notes: [0, 5, 7, 10] },
// {
// name: 'Suspended fourth',
// symbol: '<sup>sus4</sup>',
// notes: [0, 5, 7],
// },
// {
// name: 'Suspended second',
// symbol: '<sup>sus2</sup>',
// notes: [0, 2, 7],
// },
// {
// name: 'Thirteenth flat ninth',
// symbol: '<sup>13♭9</sup>',
// notes: [0, 4, 7, 10, 13, 21],
// },
// {
// name: 'Thirteenth flat ninth flat fifth',
// symbol: '<sup>13♭9(♭5)</sup>',
// notes: [0, 4, 6, 10, 13, 21],
// },
// ];
//
// export enum ConstructChordFormat {
// PITCH_ARRAY,
// NOTATION,
// SOUND,
// }
//
// enum NotationType {
// STANDARD,
// TABLATURE,
// }
//
// interface ConstructChordOptions {
// format?: ConstructChordFormat;
// }
//
// enum ConstructChordStyle {
// CHORD = 'CHORD',
// ARPEGGIO = 'ARPEGGIO',
// ARPEGGIO_THEN_CHORD = 'ARPEGGIO_THEN_CHORD',
// CHORD_THEN_ARPEGGIO = 'CHORD_THEN_ARPEGGIO',
// }
//
// interface ConstructChordSoundOptions extends ConstructChordOptions {
// format?: ConstructChordFormat.SOUND;
// midiInstrument?: number;
// style?: ConstructChordStyle;
// mimeType?: string;
// }
//
// interface ConstructChordNotationOptions extends ConstructChordOptions {
// format?: ConstructChordFormat.NOTATION;
// notationType?: NotationType;
// mimeType?: string;
// }
//
// export enum PitchClass {
// C,
// B_SHARP = C,
// C_SHARP,
// D_FLAT = C_SHARP,
// D,
// D_SHARP,
// E_FLAT = D_SHARP,
// E,
// F_FLAT = E,
// F,
// E_SHARP = F,
// F_SHARP,
// G_FLAT = F_SHARP,
// G,
// G_SHARP,
// A_FLAT = G_SHARP,
// A,
// A_SHARP,
// B_FLAT = A_SHARP,
// B,
// C_FLAT = B,
// }
//
// interface ChordParams {
// pitchClass: PitchClass;
// chord?: string;
// inversion?: number;
// }
//
// const constructChordPitchArray = (params: ChordParams) => {
// const { pitchClass, chord = '', inversion = 0 } = params;
// const chordDefinition = CHORD_DICTIONARY.find((c) => c.id === chord);
// if (!chordDefinition) {
// throw new Error(`Chord ${chord} not found`);
// }
// const { notes } = chordDefinition;
// const pitchArray = notes.map((note) => note + pitchClass);
// return pitchArray;
// };
//
// const constructChordNotation = (params: ChordParams, options: ConstructChordNotationOptions) => {
// return constructChordPitchArray(params);
// };
//
// const constructChordSound = (params: ChordParams, options: ConstructChordSoundOptions) => {
// return constructChordPitchArray(params);
// };
//
// export const constructChord = (params: ChordParams, options = {} as ConstructChordOptions) => {
// const { format = ConstructChordFormat.PITCH_ARRAY } = options;
// switch (format) {
// case ConstructChordFormat.PITCH_ARRAY:
// return constructChordPitchArray(params);
// case ConstructChordFormat.NOTATION:
// return constructChordNotation(params, options as ConstructChordNotationOptions);
// case ConstructChordFormat.SOUND:
// return constructChordSound(params, options as ConstructChordSoundOptions);
// default:
// break;
// }
//
// throw new TypeError(`Unknown format ${format as string}`);
// };

Loading…
Cancel
Save