Class ModulationDetector
Detects key changes, tonicizations, and pivot chords in musical passages, starting from a key the caller knows.
public static class ModulationDetector
- Inheritance
-
ModulationDetector
- Inherited Members
Remarks
This is the harmonic road to a piece's keys; AnalyzeModulations(NoteBuffer, Rational, Rational) is the statistical one. The detector reads chords, and the line between them, tells a tonicization from a modulation, names each change's type and finds its pivot chord; the trajectory reads fixed windows of the notes with no starting key and reports where the key changes. Both decide that by the same rules — a key holds for a phrase, a chord is not a key, a key owns its phrase, its chromatic chords and non-harmonic tones are its own, an arpeggiated chord is that chord, a secondary dominant is not a modulation, a key is entered when its own notes return and heard from where its own chords began, a return to a key the music has been in is a homecoming, a chord sounds while its notes sound and its harmony holds until the next chord — so from the same opening key they place the same modulations, each at the positions it reads at: the detector at every chord, the trajectory at its window positions.
Methods
Analyze(NoteBuffer, KeySignature)
Analyze a note buffer for modulations starting from a known key: each change of key area the music makes, as a modulation where the new key holds for a phrase and as a Tonicization where it does not, each placed at the start of the whole note in which the new key begins.
public static ModulationAnalysisResult Analyze(NoteBuffer buffer, KeySignature startKey)
Parameters
bufferNoteBufferstartKeyKeySignature
Returns
Remarks
Harmonic evidence is taken from chords (2+ onsets struck together — within an eighth, each note moved onto the eighth grid only when that moves it by less than half its own length), each note of a chord from the chord's onset to where that note stops, and from the line between them: the notes that sound alone at their onset, each for its own length, so that a passing tone in the melody can be told from a note of the harmony; a chord's harmony holds under the line until the next chord, a whole note past its notes at most, whatever its notes do. When the buffer is (nearly) monophonic and fewer than two such chords exist, every quantized onset is a pseudo-chord — single notes included — so melodic key changes are still detected; pivot-chord identification is unavailable in that fallback. The chords are judged as DetectModulations() judges its notes: a new key must be read over a phrase (four bars of the music, four whole notes in common time), be decidable and clearly named, fit better than the key the music is in, sound a note it owns and the old key lacks, and own the phrase — the notes it lacks amounting to less than a quarter of a bar in any bar, its own chromatic chords counted as the key's (an applied chord, a major triad or a dominant seventh resolving down a fifth into a chord of the key; a borrowed chord, a major key's minor subdominant, flat sixth or flat seventh resolving into a chord of the key; an augmented sixth resolving into the dominant; a dominant seventh on the key's own tonic — all inside a phrase the key's tonic frames; a minor key's Picardy third closing the piece — but not a chord the key in force owns, while that key stands and the chord resolves into a chord of its own) and its non-harmonic tones weighing nothing: passing and neighbour tones, notes leaning on a sounding harmony and resolving into it, and a note struck with a chord that leans on it; an arpeggiated chord being that chord. It is a modulation if it still reads from where it began through a phrase — or to the end of the piece, closing on a tonic it has already sounded, from a key the music was still in — and its own notes return in a second bar before the old key's are heard again as harmony (a dominant leaving the old key is not the old key back), or the phrase is framed by its tonic chord; a tonicization otherwise, lasting until the music is home again. A return to a key the music has been in that closes the piece on that key's tonic is a homecoming, and needs none of that confirmation, nor the profile's margin over the key it leaves. The new key begins after the last note it does not own, on a chord of its own — not on one of its applied or borrowed chords — at its pivot chord when the bar before is its, or at the start of the phrase in which its own note first sounds when it owns every bar from there, one bar of a foreign key allowed as a parenthesis. Each modulation's Confidence is how clearly the phrase chose the new key over the old, scaled by how much of the stretch that established it the new key owns.
The analysis used to slide a window of half the piece's chords (two to eight) along the chords, read each window's key and check the next few chords for stability. That window was a share of the piece rather than a musical length, and the last window was never judged, so four bars of C followed by four of D flat in block chords reported no modulation at all, nor did thirteen bars that went to the subdominant and came home; a window over one arpeggiated triad was not checked for being able to decide a key, so every arpeggiated I IV V I opened with a modulation to the relative minor of its IV chord and back; the relative minor itself was never reached, its scale being the major key's; and a two-bar V7/V–V was a modulation because a key area of exactly two whole notes was not shorter than the two the rule asked for. Judged on forty passages a musician wrote — nursery tunes and textbook modulations in block chords, arpeggios, melody alone and melody over chords — it was wrong on sixteen; judged by phrase it agrees with the musician on all forty, in every key.
Judged by phrase alone, on sixty-four further passages a reviewer wrote — a pop verse of applied dominants, keys visited for two bars each, a chromatic scale, alternating four-bar areas — it was wrong on nine: a key that left less of a phrase foreign than the key the music was in was taken for the phrase's key, so C Am D7 G | C A7 Dm G7 went to G at its Am and back, and a passage visiting D and E for two bars each read as A major; a chromatic scale in eighths was thirty-six modulations one eighth apart; and C F G C | G C D7 G | C F G C, measured from the D7, held G for two bars and was a tonicization. A key must own the phrase it is named for, be entered by its own notes returning or by a phrase framed by its tonic, and begin with the phrase in which it is heard; the tonicization of C F | E7 Am | F G | C C, once six bars long — to the end of the piece, because A minor owns every note of C — lasts the E7 and the Am. Both roads agree with the musician on all sixty-four.
With only dominant sevenths counted as a key's applied chords and every note weighed alike, on thirty-eight passages a second reviewer wrote — a sonata exposition, a hymn through its relative major, chromatic passing tones in the new key's every bar — it was wrong on four: C F G C | G E Am D7 | G C D7 G and C F G C | G Cm D7 G | G C D7 G reached G two bars late, at the Am and the D7, because the E major triad and the C minor chord were foreign bars; Cm Fm G7 Cm | E♭ A♭ B♭ E♭ | Cm A♭ G7 C, closing on a Picardy third, never came home to C minor and ended in E flat with the C major chord a tonicization; and a melody alone with two chromatic passing eighths in every bar of its G named no key at all, the eighths weighing a quarter of each bar. And on a melody over chords it disagreed with the trajectory road, which reads the melody it never saw, by a bar or more. A key's chromatic chords are its own, the Picardy third is the minor key's cadence, a passing tone is not a foreign note, and the detector hears the line between its chords; both roads agree with the musician on all thirty-eight.
On thirty-one passages a third reviewer wrote it was wrong on twelve — among them a chromatic appoggiatura struck with the chord on every downbeat, which was a chord tone; a passing tone inside an arch and a half-note passing tone, which were foreign notes; the German sixth, the tonic seventh and the V/V of a new key that the old key owns, none of them the new key's chord; a suspension struck over an applied triad, which made it no triad; and arpeggiated chords heard note by note. With the rules the judge states (Celeritas.Core.Analysis.KeyAreaJudge), both roads agree with the musician on all thirty-one; and the detector, whose candidates are every onset, no longer begins a phrase in the middle of an arpeggiated chord, where it read a bar of borrowed C minor's last E flat as E minor.
On twenty-three passages a fourth reviewer wrote — a Mozart transition over a chromatic bass, a Mixolydian folk tune, escape tones, a ground bass, a 5/4 piece, trills, a chorale phrase pair and Schubert's common-tone way to the flat submediant among them — it was wrong on two: the chorale's two-bar return home, Dm G7 C, sounded no C before its last chord, so the homecoming was a one-bar tonicization on this road and nothing on the other; and where Schubert holds the common tone C alone for half a bar before the A flat chord, this road's C major chord went on sounding until the next chord, so A flat could not own the half bar and F minor, whose dominant C major is, was named — the trajectory, hearing the notes stop, named A flat. A return to a key the music has been in is a homecoming; a chord sounds while its notes sound, on both roads, and its harmony holds until the next chord. Both roads agree with the musician on all twenty-three, and with each other on every passage of the six tables.
On thirty-three passages a sixth reviewer wrote — accompaniment textures: a waltz's left hand, a bossa's pushed chords, a ragtime bass, a tremolo, a fermata, the pop loop — it was wrong on four, and the other road on five: a bar of silence inside the new key's first phrase put G at bar 9, the frame that hears a key from where its phrase began reaching only the phrase that holds the F sharp; the Picardy close with the melody arpeggiating up through the final chord was a modulation to A major, three notes struck after the chord making it no last harmony; and Am F C G four times, told A minor, modulated to C at bar 2 — the relative major named by the profile with no cadence and no frame — while told C this road heard none and the other, opening on the A minor chord, heard C. A key is heard from where its phrases began and a silent bar is neither key's, a melody moving through the tones of the closing chord is that chord, and the relative major is confirmed by its cadence or its frame. Both roads agree with the musician on all thirty-three, and with each other on every passage of the seven tables.
On thirty-five passages a seventh reviewer wrote — the pop loops a musician plays every day, told either of their keys; the same loop a tone up; a loop turning into a real move to the relative key; silence around the new key's first phrase; the melody over the Picardy chord — the frame reaching back had swallowed a phrase of V I V I closing on the old tonic (G at bar 5 for bar 9), the cadence that confirms the relative major had been found at the seam of two phrases (C at bar 5 for bar 9), and a scale run or a turn over the closing chord had kept it from ending the piece (a modulation to A major again). A reached-back phrase is framed by the new tonic, opening and closing on it; a confirming cadence closes a phrase of the piece's count; notes on their way by step between the closing chord's tones are that chord's. Both roads agree with the musician on the twenty-four that join the fixture as an eighth table, and with each other on every passage of the eight tables.
Of the seventh reviewer's six passages the library still read otherwise, five are heard on this road now: the minor twelve-bar blues in sevenths, which this road, told A minor, had right while the trajectory opened it in C major (a seventh chord opens the key of its root); the loop Bm G D A after Am F C G twice, told C, which was B minor for the chord it opened on and is D major with vi first, as the first loop was C with vi first (a sequence keeps the reading of its model — the trajectory, told nothing, opens on the A minor chord and hears B minor, the told-A-minor answer); the pair of phrases C Dm G Am between A minor's cadences, which went to C at bar 4 and came home at bar 13 (a loop that comes to rest on the old tonic is the old key's); two bars of silence before the new key, counted as bars of a phrase so that G was a two-bar tonicization (a musician counts the new phrase from the re-entry); and the Picardy chord in tremolo eighths, dyads with no Picardy third among them, so that the close was a modulation to A major (a tremolo is the chord it spells whatever its speed). The relative major from its IV — F G C Am | F G C C after A minor's cadence — is left with its debate: the reviewer plans C from bar 5, the judge hears it from the cadencing phrase at bar 9 with the Am of bar 8 its pivot, because a phrase closing on the minor's tonic is the minor's. Both roads agree with the musician on the twenty-eight of the eighth table, and with each other on every passage of the eight tables.
On forty-seven passages an eighth reviewer wrote — pieces opening on a seventh chord, on ii
or IV, told a key they never sound; the same loop moved a fourth, a minor third, a tone and
two tones, told either key; a real sequence through three keys; a circle of fifths; three
silent bars, a re-entry in the old key; tremolo eighths for a whole passage, on a major
close, on the dominant sevenths; a trill on the Picardy third; the relative major's cadence
inside a phrase and at its end — the sequence rule had fired on the copy alone and not on
its verbatim repeat, so `Am Dm G C` twice then `Bm Em A D` twice, told A minor, was B minor
at the copy and D major at the repeat, whose closing A D read from its second chord was the
cadence that closes the piece; and `Am Dm G C` four times changed to C at its fourth
statement the same way. A phrase repeated is its model at the unison and keeps its key,
judged from the phrase a candidate falls in. Both roads agree with the musician on the
thirty-five that join the fixture as a ninth table, and with each other on every passage of
the nine tables; the four transposed loops told C are the major with vi first on the
detector road and the minor on this one, which opens on the A minor chord, as the fact in
TheTwoRoadsHearEveryTextureAlikeTests pins road by road.
Of the eighth reviewer's eight passages the library still read otherwise, six are heard now, and the lens's residual besides. The minor blues in sevenths told C was C going to A minor at its E7 on this road, where the trajectory heard A minor from bar 1: the given C was taken for opened on, its tonic with a note above it being what Am7 read as — a seventh chord is the tonic of its root's key alone, and a given major key whose tonic chord never sounds in the opening phrase was the caller's guess; C Dm G Am7 twice between A minor's cadences, whose G → Am7 read as C's V–I6, is one key as the loop with a plain A minor triad is. Two silent bars after a fifth bar of tonic — a pause off the phrase grid — and a two-bar fermata after a silent bar each left G a tonicization: a pause between phrases is heard wherever it falls once a phrase has sounded, both counts of the phrases are kept, a fermata closes its phrase, and a held chord's second bar is its own. The Picardy chord as an Alberti bass, restruck in quarters under a melody ending on its second, and in tremolo eighths under a passing tone each closed the piece as a modulation to A major: the closing harmony is what the accompaniment spells, and the tune over it is the line. And the piece opening on IV with its second bar silent, the lens's residual: a phrase that comes to rest on a chord opens in that chord's key, so the trajectory opens F – C C in C as this road, told C, does. The silent 3/4 bar is heard now: the judge reads the bar from the music's own pace and counts its phrases in 3/4 bars. The two loops Am F G C under a tune whose B rises to C at each close stay one key with A minor's cadences around them, as the same chords do without the tune: the G chord already carries the B, and a phrase opening on the minor's tonic is the minor's; the reviewer plans the major, and the lead decides. Both roads agree with the musician on the forty-one of the ninth table, and with each other on every passage of the nine tables in every texture but the Dorian tune with its second bar silent.
On thirty-four passages a ninth reviewer wrote — a piece told its relative major or minor, its dominant, its subdominant, a tritone away, or the key of its own ii7, vi7 or IVmaj7; a tonic voiced as a sixth chord and followed by plain triads; a half-bar rest, a fermata then silence, a general pause in the new key, silence before the return home; closes decorated with quarters under the seventh and the ninth, tremolo under a passing tone, an appoggiatura; 2/4 half notes; the loops under tunes carrying a leading tone or a raised sixth — a piece whose tonic is voiced as a sixth chord had opened in the relative minor and heard its plain triads as a modulation, the four notes of A C E G being A minor's i7 and C major's tonic with a sixth on it alike. An opening named by a seventh chord is a reading of a voicing, which the music may refute as it refutes a guess. Both roads agree with the musician on twenty-eight of them, and on two of the library's own beside; the thirty join the fixture as a tenth table, and the roads agree with each other on every passage of the ten tables in every texture but the Dorian tune with its second bar silent.
Three more of the reviewer's are heard now. A piece told C that opens on A minor's i7 and moves to C — Am7 Dm7 E7 Am7 | C F G C | C F G7 C — was C throughout on the detector road and A minor going to C at bar 4 on the trajectory: a given key is refuted where the piece opens, the tonic chord that confirms it is looked for in the opening phrase alone, and the margin a change must clear does not guard a caller's guess — a relative pair separate by 0.020, a fifth of it. C F G C | R | G C D7 G over a held dominant pedal had no bar of silence, so the pause between its phrases was never heard and the roads read a two-bar tonicization of G and no change at all: a bar in which nothing is STRUCK is a bar of silence for the phrase count, whatever is still sounding from before, and a fermata — a chord held with nothing struck under it — closes its own phrase as it always did. And a trill in sixteenths over the Picardy chord restruck in quarters closed the piece as a modulation to A major on both roads: a restrike carries the chord's harmony on, and the line over it is looked through against the harmony last struck.
Every chord-bearing passage of the tables rebuilt in five textures — the chords
staccato, a melody note held across the chord change, every chord struck twice in its
bar, the second bar silent, every chord an eighth off the beat — asked of both roads in
twelve keys, split them on seventeen of the first five tables' six hundred and
eighty-two cases and missed the
musician's plan on forty-seven. None was the judge's rules failing on music it had seen: a
chord struck twice resolved into its own restrike and was no applied chord; this road
rounded sixteenths struck one after another onto its eighth grid into two-note chords of
neighbouring tones; a silent bar left a given key nothing to refute it and a guessed one
nothing to confirm it, and the roads opened in different keys; and chords an eighth late
spilt a tail into the next clock bar or left the trajectory opening on a lone melody
note. A chord struck twice in its bar is one harmony, a note is rounded onto the grid
only when moved by less than half its length, the piece opens on its first chord — struck,
arpeggiated, or an eighth behind the tune — a given key the piece does not open on is a
guess, and the bars are heard from the music's accents (Celeritas.Core.Analysis.KeyAreaJudge).
The roads now part on five cases of one thousand one hundred and forty-three — a D Dorian tune
with its second bar silent, and C G Am E7 | Am Dm E7 Am | Am Dm E7 Am told C in each of
its four textures, where this road is told a key and the other guesses one from the music
— and miss the plan on seven, which are those five, a pickup passage whose second bar is
silent and a German sixth an eighth off the beat, an eighth outside the bar's tolerance
(TheTwoRoadsHearEveryTextureAlikeTests).
On thirty-four passages a tenth reviewer wrote — one modulating passage in four metres and a piece that changes metre at its modulation; a pedal that changes with the key, one inner voice held across a silent bar, a chord tied across the pivot, a fermata in the upper voices while the bass rests; a piece told a key whose tonic chord arrives only at the end, told the key of its second chord, told the relative minor of a piece opening on I6, a piece opening on a lone bass note or a bare fifth; the closing chord as a two-hand arpeggio over three octaves, the melody arpeggiating it alone in sixteenths; the loop in 3/4 and over its own pedal; a sequence through three keys in 6/8 — thirty are heard as a musician hears them and join the fixture as an eleventh table. The judge reads the bar from the music's own pace, so the same passage is heard at its own fifth bar in 4/4, 3/4, 6/8, 5/4 and 12/8 alike, and in 2/4 while it stays where it goes (a 2/4 piece of four-bar sections that comes home is among the limitations below), and a slow piece of two-whole-note chords is heard at all; a pedal is one note under the harmony and no longer outweighs what is played over it or stands in the chord a phrase opens on; the closing figure may lie above the tune as well as below it; and the bar a phrase closes on in the key it leaves is that key's cadence and no pivot, which moved every Picardy close and every homecoming of the fixture to the bar its own phrase begins in. Two are not heard: a 3/4 piece whose phrases are three bars where the judge's are four, and the Picardy close with the tune crossing below the figure, both in eighths, which reaches this road as a stream of dyads with no pitches to tell the voices apart.
On thirty-eight passages an eleventh reviewer wrote — the same modulating passage in 9/8, 5/8, 7/8, 2/2 and 6/8, a rubato, a pickup, a waltz, an oom-pah and an Alberti bass; four pedals held and one struck again at every bar line; the closing chord rolled upwards, downwards and over two bars, and figures sharing the tune's register; pieces told C that open on vi, iii and ii — thirty-three are heard as a musician hears them and join the fixture as a twelfth table. On thirty more a twelfth reviewer wrote — ordinary music only: pieces told a key they open away from, closes as they are actually written, pedals as they are actually played, and the everyday shapes of hymn, waltz, blues, pop loop, march and folk tune — all thirty are heard as a musician hears them and join the fixture as a thirteenth table. The chord a piece opens on is a chord of its key before it is a key, whichever its mode: a loop is a chord coming back at the music's own phrase length and not a chord that sounds once more somewhere later, so the pop loop Am F C G7 three times over closing on C F G7 C is C with a vi first; and a pedal is one note under the harmony however often it is struck, so a tonic strummed on every beat or repeated in eighths is heard as one is that is struck once a bar. Six shapes are known and unheard, and are written up in the judge's own remarks (Celeritas.Core.Analysis.KeyAreaJudge): the bar of chords of irregular length in no pattern, and of a melody alone, where no gap between harmony changes has a majority and the clock stands; the close under a tune as quick as the figure — a two-hand arpeggio in sixteenths under a trill, and a tune in eighths above the held chord outlining its upper thirds; a pedal struck an eighth before the first chord, which sounds alone at its onset and is therefore a note of the line; and the piece whose opening phrase is the relative major's and whose rest is the minor's, told the major — C G Am E7 | Am Dm E7 Am | Am Dm E7 Am told C, where this road, told C, hears A minor at bar 3 as a musician told C does, and the trajectory, told nothing, hears one key in A minor as a musician told nothing does. the piece in 2/4 that leaves and comes home, whose four-bar sections are two whole notes and shorter than the evidence a key is asked for — a march or a polka in block chords or oom-pah alike; and the bass note struck once a bar under a broken-chord accompaniment, which makes a chord of its own with the notes above it where the same note held, or taken away, is heard rightly. There is no further iteration of this work: those six are the library's documented limits.
Exceptions
- ArgumentNullException
bufferis null.
Analyze(ReadOnlySpan<NoteEvent>, KeySignature)
Analyze a sequence of note events for modulations starting from a known key. See Analyze(NoteBuffer, KeySignature) for what is reported and how it is judged.
public static ModulationAnalysisResult Analyze(ReadOnlySpan<NoteEvent> notes, KeySignature startKey)
Parameters
notesReadOnlySpan<NoteEvent>startKeyKeySignature
Returns
Remarks
Harmonic evidence is taken from chords (2+ onsets struck together on an eighth-note grid, a note rounded onto it only when moved by less than half its own length), each note of a chord sounding from the chord's onset for its own length, and from the notes that sound alone between them, the line. When the input is (nearly) monophonic and fewer than two such chords exist, every quantized onset is a pseudo-chord — single notes included, each for its own length — so melodic key changes are still detected. Pivot-chord identification is unavailable in that fallback.