@libraz/libcantus - v1.1.0
    Preparing search index...

    Type Alias KeyMatch

    A candidate key interpretation of a pitch-class set.

    type KeyMatch = {
        key: KeyScale;
        mode: "major" | "minor";
        variant: KeyVariant;
        scaleName: ScaleName;
        fit: number;
        score: number;
        rationale?: string;
        alternatives?: RejectedCandidate[];
    }
    Index

    The scale that scored best for this tonic and mode, variant included.

    mode: "major" | "minor"

    The major or minor key this match is closest to. A modal match reports the mode it leans on — dorian, phrygian and locrian are minor, lydian and mixolydian major — so a caller that reads nothing but mode still gets a musically sane answer; scaleName is where the mode itself is named.

    variant: KeyVariant

    Which scale form key uses. Minor keys report whichever of the natural, harmonic and melodic masks covers the most input weight; the variant does not take part in ranking. A church mode reports 'modal', since its scale is neither of the major nor one of the three minor forms.

    scaleName: ScaleName

    The entry of NAMED_SCALES whose mask is key.modeMask12, naming the scale exactly where mode and variant only place it: 'major', 'naturalMinor', 'harmonicMinor', 'melodicMinor', or one of the church modes when DetectKeyOptions.modes put them in the running. Ionian and Aeolian are reported as 'major' and 'naturalMinor', the names of the candidates they are the same scale as.

    fit: number

    Fraction of the distinct input pitch classes that belong to key, in [0, 1]. Measured against the returned scale, so it always agrees with isScaleTone(pc, match.key). This is a coverage figure, not the ranking: see score.

    score: number

    The value the results are ranked by, in [-1, 1]: the Pearson correlation between the weighted pitch-class distribution of the input and this candidate's key profile rotated onto its tonic. 1 is a distribution shaped exactly like the profile, 0 no relationship, negative an anti-correlation. Unlike fit it is a distribution measure, not a membership count, so where the weight falls among the scale degrees is what separates a key from its relative. Always a finite number; see DetectKeyOptions.profile for the degenerate case.

    rationale?: string

    Why this candidate scored what it did, in the phrasing analyzeVoice uses for a note.

    Present only when DetectKeyOptions.explain asked for it: a ranking is 24 candidates before the modes are counted, and most callers read the first one or two.

    alternatives?: RejectedCandidate[]

    The candidates that were considered and rejected, and why each ranked below this one.

    Carried by the top-ranked match alone — the rivals of a runner-up are the rest of the list, which the caller already holds — and only when DetectKeyOptions.explain asked for it.