Skip to content

Commit

Permalink
Fix function mismatching on key
Browse files Browse the repository at this point in the history
  • Loading branch information
hanakla committed Sep 10, 2024
1 parent a05a1fb commit da32488
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 46 deletions.
32 changes: 23 additions & 9 deletions pkgs/harnica-midi/src/analysis/getChordFunctionOnKey.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,31 @@ describe("getChordFunctionOnKey", () => {
it.only.each(
// prettier-ignore
[
{ chord: "I", key: "C", actual: { ...allFalse, tonic: "perfect", } },
{ chord: "V", key: "C", actual: { ...allFalse, dominant: "perfect" } },
{ chord: "IV", key: "C", actual: { ...allFalse, subdominant: "perfect" } },
{ chord: "IIm", key: "C", actual: { ...allFalse, secondSubDominant: "perfect" } },
{ chord: "IIIm", key: "C", actual: { ...allFalse, secondTonic: "perfect" } },
{ chord: "VIm", key: "C", actual: { ...allFalse, thirdTonic: "perfect" } },
{ chord: "VIIm-5", key: "C", actual: { ...allFalse, secondDominant: "perfect" } },
{ chord: "I7", key: "C", actual: { ...allFalse, tonic: "perfect" } },
{ chord: "I", key: "C", actual: { ...allFalse, tonic: true, } },
{ chord: "V", key: "C", actual: { ...allFalse, dominant: true } },
{ chord: "IV", key: "C", actual: { ...allFalse, subdominant: true } },
{ chord: "IIm", key: "C", actual: { ...allFalse, secondSubDominant: true } },
{ chord: "IIIm", key: "C", actual: { ...allFalse, secondTonic: true } },
{ chord: "VIm", key: "C", actual: { ...allFalse, thirdTonic: true } },
{ chord: "VIIm-5", key: "C", actual: { ...allFalse, secondDominant: true } },
{ chord: "I7", key: "C", actual: { ...allFalse, tonic: true } },

{ chord: "I", key: "D", actual: { ...allFalse, tonic: true, } },
{ chord: "V", key: "D", actual: { ...allFalse, dominant: true } },
{ chord: "IV", key: "D", actual: { ...allFalse, subdominant: true } },
{ chord: "IIm", key: "D", actual: { ...allFalse, secondSubDominant: true } },
{ chord: "IIIm", key: "D", actual: { ...allFalse, secondTonic: true } },
{ chord: "VIm", key: "D", actual: { ...allFalse, thirdTonic: true } },
{ chord: "VIIm-5", key: "D", actual: { ...allFalse, secondDominant: true } },
{ chord: "I7", key: "D", actual: { ...allFalse, tonic: true } },

{ chord:'D', key: 'D', actual: { ...allFalse, tonic: true } },
{ chord: 'G', key: 'D', actual: { ...allFalse, subdominant: true } },
{ chord: 'A', key: 'D', actual: { ...allFalse, dominant: true } },
{ chord: 'F#m', key: 'D', actual: { ...allFalse, secondTonic: true } },

// sameroot
{ chord: "IVsus4", key: "F", actual: { ...allFalse, dominant: "sameRoot" } },
// { chord: "IVsus4", key: "F", actual: { ...allFalse, dominant: "sameRoot" } },
] satisfies Array<{ chord: string; key: string; actual: ChordFunctionMatch }>,
)("works for $chord on $key", ({ chord, key, actual }) => {
expect(getChordFunctionOnKey(chord, key).data).toMatchObject(actual);
Expand Down
26 changes: 9 additions & 17 deletions pkgs/harnica-midi/src/analysis/getChordFunctionOnKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import { formatNote } from "@/internals/chord-assembler";
import { getDegreeDetailByChordName } from "@/internals/conversion/getDegreeDetailByChordName";
import { Maybe, maybe } from "@/utils/Maybe";

type MatchLevel = "perfect" | "sameRoot" | false;

export type ChordFunctionMatch = {
tonic: MatchLevel;
secondTonic: MatchLevel;
thirdTonic: MatchLevel;
dominant: MatchLevel;
secondDominant: MatchLevel;
subdominant: MatchLevel;
secondSubDominant: MatchLevel;
tonic: boolean;
secondTonic: boolean;
thirdTonic: boolean;
dominant: boolean;
secondDominant: boolean;
subdominant: boolean;
secondSubDominant: boolean;
};

/**
Expand Down Expand Up @@ -57,14 +55,8 @@ export function getChordFunctionOnKey(
return maybe.ok(
Object.fromEntries(
Object.entries(harmonicsResult.data).map(([key, harmony]) => {
return [
key,
// prettier-ignore
normalized.chordName === harmony.chordName ? "perfect"
: normalized.rootName === harmony.root ? "sameRoot"
: false,
];
return [key, normalized.rootName === harmony.root];
}, {}),
) as Record<keyof typeof harmonicsResult.data, MatchLevel>,
) as Record<keyof typeof harmonicsResult.data, boolean>,
);
}
2 changes: 1 addition & 1 deletion pkgs/harnica-midi/src/suggests/getTDSChordsByKeyName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function getTDSChordsByKeyName(

const buildSet = (chord: NoteFragment.ChordData): ChordSuggest => ({
root: opt.degree
? getDegreeNameFromKeyValue(chord.keyValues[0])
? getDegreeNameFromKeyValue(chord.keyValues[0], undefined, { key })
: getKeyNameByKeyValue(chord.keyValues[0]),
chordName: getChordDetailFromKeyValues(
chord.keyValues,
Expand Down
8 changes: 1 addition & 7 deletions pkgs/web/src/features/ScoreEditor/components/NoteDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -591,13 +591,7 @@ export function NoteDetail({
onClickListen={onClickChordSuggest}
onClickReplace={handleClickChordSuggest}
onClickInsertNoteAfter={handleClickInsertAfter}
highlight={
noteFunctions[_key] === "perfect"
? "green"
: noteFunctions[_key] === "sameRoot"
? "yellow"
: false
}
highlight={noteFunctions[_key] ? "green" : false}
/>
</TipItemLI>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ type Props = {
onRequestRelativelizeAllNotes: () => void;
};

export const LeafRichText = memo(function LeafRichText(props: Props) {
return <NoteLeaf {...props} />;
});

const NoteLeaf = memo(function NoteLeaf({
export const LeafRichText = memo(function NoteLeaf({
fragment,
className,
onReplaceNote,
Expand Down Expand Up @@ -138,7 +134,9 @@ const NoteLeaf = memo(function NoteLeaf({
).data;
if (!functions) return [];

return Object.entries(functions).filter(([k, v]) => v != false) as Array;
return Object.entries(functions).filter(([k, v]) => v != false) as Array<
[keyof typeof functions, boolean]
>;
}, [chord]);

return (
Expand Down Expand Up @@ -206,15 +204,11 @@ const NoteLeaf = memo(function NoteLeaf({
{noteFunctions.length === 0 ? (
<span className="block opacity-40">N/A</span>
) : (
noteFunctions.map(([harmFunc, matchness]) =>
matchness === "perfect" ? (
noteFunctions.map(([harmFunc, isMatched]) =>
isMatched ? (
<span key={harmFunc} className="block font-bold">
🔑{t(`noteFunctions.${harmFunc}_abbre`)}
</span>
) : matchness === "sameRoot" ? (
<span key={harmFunc} className="block">
🔑{t(`noteFunctions.${harmFunc}_abbre`)}
</span>
) : null,
)
)}
Expand Down

0 comments on commit da32488

Please sign in to comment.