mint
**mint is Humdrum's
mint-tool for melodic-interval
analysis, run against each voice: each token is the interval from the previous
note in that same voice to the current one.
Token format
A **mint token is a signed, qualified diatonic interval:
- an optional leading
+or-for direction (up or down; ties/repeated notes have no sign), - a quality letter
M(major),m(minor),P(perfect),A(augmented),d(diminished), and doubled forms for wider deviations (AA,dd, …), - a diatonic number
2for a 2nd,3for a 3rd, and so on.
So +M2 is a major 2nd up, -m3 a minor 3rd down, P1 a unison (repeated
note).
The very first note of a voice has no previous note to measure from, so instead
of an interval it gets a literal, bracketed pitch name, e.g. [gg]. This is
still a real, non-empty onset, it counts as a mint onset just like any
interval token, but it won't match a normal interval pattern value; only "*"
or the literal bracketed string itself will match it.
Quality- and sign-optional matching
Pattern values for mint don't have to be a complete token. Any part you leave
out is treated as "matches any":
| Pattern value | Matches |
|---|---|
"M2" | a major 2nd, either direction (+M2 or -M2) |
"+2" | any 2nd going up, regardless of quality (+M2, +m2, +A2, …) |
"2" | any 2nd at all, any direction, any quality |
"+M2" | only an ascending major 2nd (fully specified, matches literally) |
"+" | any upward motion at all, regardless of size or quality |
"-" | any downward motion at all, regardless of size or quality |
This makes it easy to search for melodic shape without caring about exact diatonic quality, for a specific quality without caring about direction, or for direction alone without caring how far the voice moves:
{
"feature": "mint",
"voices": "soprano",
"pattern": [
{ "mint": "+" },
{ "mint": "+" },
{ "mint": "+" },
{ "mint": "-" }
]
}
finds three consecutive upward steps of any size followed by a downward one, an arch shape without pinning down the exact intervals.
{
"feature": "mint",
"pattern": [
{ "mint": "+2" },
{ "mint": "+2" },
{ "mint": "+2" },
{ "mint": "+2" },
{ "mint": "+2" }
]
}
finds five consecutive upward steps of any quality. A generic "climbing in seconds" passage, in any voice.
Comparing interval sizes
An interval can be compared by its size with a
comparison, where a greater interval is a wider one. The
value names the size in one of two ways.
A diatonic number, "6", compares the number alone. All intervals of a number are
equally wide, whatever their quality, so
{ "mint": { "operator": "gt", "value": "6" } }
matches every interval wider than a sixth (any seventh, octave and so on), up or down, and no sixth at all, not even a major one.
A number with a quality, "m6", names one particular interval. To tell "wider than
a minor sixth" from "wider than a sixth", the intervals are put in order by their size
in semitones: a minor sixth has 8, a major sixth 9, a minor seventh 10, and an augmented
fourth and a diminished fifth are both 6. So
{ "mint": { "operator": "gt", "value": "m6" } }
matches every interval wider than a minor sixth, which includes the major sixth. A quality a number cannot have (a perfect third, a major fifth) is rejected.
Direction
Give the value a sign to compare in a direction. The interval then has to go that way as
well as be wider or narrower. "+m6" is an interval up, "-m6" an interval down:
{ "mint": { "operator": "gt", "value": "-m6" } }
matches the descending intervals wider than a minor sixth (a major sixth down, a minor
seventh down and so on), and never an ascending interval or a repeated note. In the same way
{ "operator": "gt", "value": "+m6" } matches the ascending ones, and
{ "operator": "lt", "value": "-m6" } the descending ones narrower than a minor sixth.
Without a sign, { "operator": "gt", "value": "m6" } matches the wider intervals in both
directions.
Excluding an interval
Two keys of a position must both hold, so a comparison and a negated mint in the same
position combine. All intervals wider than a minor sixth, except the octave:
{
"feature": "mint",
"voices": "bass",
"pattern": [
{
"mint": { "operator": "gt", "value": "m6" },
"!mint": "P8"
}
]
}
What is compared
The first note of a voice has no interval (see Token format) and no
comparison matches it. The size is the one in the score: compound intervals are not
folded into the octave, and
mintAllowIntervalComplementation does not
apply.
Complementary intervals
A 5th down and a 4th up start and end on the same two pitch classes; the two are
the same melodic move, just an octave apart, and which one a voice actually
takes is often only a question of staying in its range. **mint records what
literally happened, so those are two different tokens (-P5 and +P4), and a
pattern value only ever matches the one it names.
When that difference doesn't matter for your question, the query option
mintAllowIntervalComplementation
lets a value also be satisfied by its complementary interval, the one filling
the rest of the octave in the opposite direction:
{
"feature": "mint",
"voices": "bass",
"pattern": [
{ "mint": "-5" },
{ "mint": "-5" }
],
"mintStartAtPreviousToken": true,
"mintAllowIntervalComplementation": ["5"]
}
matches two descending 5ths in a row and ascending 4ths in their place, which is usually what "the bass
falls a fifth" means in practice. Direction and quality are inverted along with
the number (-P5 ↔ +P4, +M2 ↔ -m7), and only the numbers you
list are opted in. Pass "*" instead of a list of numbers to allow
complementation for every interval size at once. See
Options for the full rules.
Measuring across an ornament
An interval is always measured from the previous attack in the voice, which for
a decorated line is the ornament rather than the note the phrase steps off:
**mint reads chor005's soprano 8a 8g 4a in measure 4 as -M2 and then
+M2, never as the repeated a a listener hears.
metweightSkipUnclassified measures
across such an ornament instead, so the note after it reports the interval out
of the note before it, here the P1 that says the a came back. A note with
no ornament in front of it keeps the interval the spine wrote.
Mixing specificity across positions
Nothing forces every position in a pattern to use the same level of detail. Each position is matched independently, so a fully specified interval can be followed by a direction-only one, then a quality-only one, and so on:
{
"feature": "mint",
"pattern": [
{ "mint": "+2" },
{ "mint": "-M3" },
{ "mint": "P1" },
{ "mint": "3" }
]
}
matches a step up of any quality, then a descending major 3rd specifically, then a repeated note, then a 3rd of any quality in either direction. Pin down exactly as much (or as little) as matters for each note in the run.
mint starts one token late
Because a mint onset describes the interval into a note, the driving onset
for position 0 of your pattern is already the second note of whatever you're
matching. The first note (the one the interval starts from) isn't itself an
onset your pattern checked, so by default it's excluded from the reported
startPosition/ startLine.
If you want the match to start on that first note instead, either:
- set the query option
mintStartAtPreviousToken, or - put an explicit wildcard
{ "mint": "*" }as position 0 of the pattern.
See Options for the full explanation and an example output of the difference this makes.
Using it in a pattern
{
"feature": "mint",
"pattern": [
{ "mint": "-2" },
{ "mint": "-2" },
{ "mint": "+3" }
]
}
matches two consecutive downward steps followed by an upward leap of a 3rd, any
quality throughout. See Patterns for OR-lists, wildcards,
multi-feature positions, and negation, all of which work the same way for mint
as for any other feature.