fb
**fb is Humdrum's figured-bass
tool run once per chorale: it
reduces the harmony at each moment to the intervals every other voice forms
above the bass, the way a figured-bass symbol would.
fb is one spine per chorale, not one per voice
Unlike other features, fb isn't a property of a single voice, it's a property
of the whole texture at a moment in time. So there's only one **fb spine
per chorale, aligned with the bass line, and every lookup against fb resolves
to it regardless of which voices you asked for in voices. Searching fb with
"voices": "soprano" still reads the same chord-above-the-bass data as
"voices": "bass". voices only affects which voice's kern/deg/mint
onsets you're stepping through if fb is a secondary constraint rather than the
driving feature.
How the **fb spine is generated
The chorale-search binary runs humlib's figured-bass
tool once per chorale with the
flags -c -n --hint:
-c(compound) folds compound intervals down to within one octave, so a 10th above the bass is reported as a 3rd, an 11th as a 4th, and so on. There's no way to distinguish a 10th from a 3rd in the resulting data.-n(normalize) removes the figures1(unison) and8(octave), removes duplicate figures (the same interval sounding in two upper voices at once collapses to a single figure), and sorts the remaining figures by size. The sort order doesn't matter for searching.--hintis what makes each figure carry an interval-quality letter (M,m,P,A,d, …) instead of a plain figured-bass numeral. It's why a token looks likem6 m3rather than a bare6 3, and is what makes the figure- and quality-optional matching below possible.
Special case: 9. A compound 2nd is only ever reported as 9 when the same
chord also contains a (compound-reduced) 3; otherwise it stays 2, even
though both are the same interval folded down by -c. If you want to be sure
not to miss a suspended 9th regardless of whether the chord happens to also
carry a 3rd, search for both figures:
{ "fb": ["7 9", "2 7"] }
Token format
A **fb token is a chord: one or more space-separated intervals, each an
optional quality letter (M, m, P, A, d, …) followed by a diatonic
figure number, e.g. m6 m3 or P5 M3 (a root-position major triad). The
figures don't say which upper voice sings which interval. fb only records
which intervals are sounding above the bass, not their distribution across
alto/tenor/soprano.
Figure- and quality-optional matching
Just like mint, an fb pattern value doesn't have to fully specify a figure.
The quality letter can be omitted to match any quality:
| Pattern value | Matches figure 6 as |
|---|---|
"m6" | only a minor 6th |
"6" | any 6th, any quality |
And a pattern value can itself list several space-separated figures, e.g. "M6 3" or, order doesn't matter, "3 M6". Both mean "the chord contains a major
6th and a (any-quality) 3rd". By default this is a minimum requirement: a
pattern of "2 4" also matches an actual chord of "2 4 6", since both 2 and
4 are present. Use fbCompareExactChord
if you want to require the chord to contain exactly those figures and no
others.
{
"feature": "fb",
"pattern": [
{ "fb": "A6 M3" }
]
}
finds every augmented sixth chord in the corpus, regardless of which voice carries which figure.
Using it in a pattern
fb is most useful either as the driving feature (walking chord-to-chord
through the harmony) or as a secondary constraint alongside kern/deg/mint
(checking "what's the harmony doing when this melodic thing happens"):
{
"feature": "deg",
"voices": "soprano",
"pattern": [
{ "deg": "7", "fb": "6" },
{ "deg": "1", "fb": ["5 3", "3"] }
]
}
matches a soprano leading-tone-to-tonic resolution (7 → 1) where the leading
tone is harmonized with a 6th above the bass and the tonic lands on a
root-position triad (or bare 3rd). See Patterns for OR-lists,
wildcards, multi-feature positions, and negation, all of which work the same way
for fb as for any other feature.