These functions calculate the ammount of time (either in beats, or seconds)
that have unfolded since the beginning of a piece, giving a sense of the timeline in which events unfold.
In music21 this information is described as "offsets"---however,
we prefer to reserve the words "onset" and "offset" to refer
to the beginning (attack) and end (release) of rhythmic events.
If timeline() is applied to a humdrumR data class
you may use the data's fields as arguments.
If no field names are specified, the first selectedField is used as x.
If timestamp() is applied to a humdrumR data class
you may use the data's fields as arguments.
If no field names are specified, the first selectedField is used as x.
Usage
# S3 method for default
timeline(
x,
start = 0,
pickup = NULL,
...,
Exclusive = NULL,
threadNA = TRUE,
parseArgs = list(),
groupby = list()
)
humData |> select(Token) |> timeline()
humData |> timeline(Token)
timeline(
x,
start = 0,
pickup = NULL,
...,
Exclusive = NULL,
threadNA = TRUE,
parseArgs = list(),
groupby = list()
)
# S3 method for default
timestamp(
x,
BPM = 60,
start = 0,
pickup = NULL,
minutes = TRUE,
...,
Exclusive = NULL,
threadNA = TRUE,
parseArgs = list(),
groupby = list()
)
humData |> select(Token) |> timestamp()
humData |> timestamp(Token)
timestamp(
x,
BPM = 60,
start = 0,
pickup = NULL,
minutes = TRUE,
...,
Exclusive = NULL,
threadNA = TRUE,
parseArgs = list(),
groupby = list()
)Arguments
- x
Input rhythm information.
Must be
atomic, orNULL.- start
Where does timeline begin?
Defaults to
0.Must be a single number.
- pickup
Where is there a pickup (anacrusis)?
Defaults to
NULLMust be
logicalof samelength(x), OrNULL. See "Pickups" section below.- threadNA
Should rhythm-less tokens return
NA?Defaults to
TRUE.Must be a singleton
logicalvalue: an on/off switch.- parseArgs
An optional list of arguments passed to the rhythm parser.
Defaults to an empty
list().Must be a
listof named arguments to the rhythm parser.- groupby
A
listof vectors to groupx.Defaults to
list().Must be a
list; every element of the list must be lengthlength(x).To function as a by-record timeline, the
groupbylist music include a namedPieceandRecordfields. Luckily, these are automatically passed by with(in).humdrumR, so you won't need to worry about it!- BPM
The tempo.
Defaults to
60.Must be a single number or a
characterstring in the format"MM120"(for 120 bpm).By default, with(in).humdrumR passes the
BPMfield, if present.- minutes
Should minutes be counted in output?
Defaults to
TRUE.Must be a singleton
logicalvalue: an on/off switch.If
TRUE, output seconds are converted to a character string encoding minutes, seconds, and milliseconds in the formatMM.SS.ms.
Details
Music unfolds over time, and humdrum data typically represents this
by placing simultaneous events in the same record, with successive events
in ever higher records---progressing "top down" through the file.
In some humdrum data, only this (implicit) ordering of data over time is present.
The Record and DataRecord fields capture this ordering in all data parsed by humdrumR.
However, many (probably most) humdrum data files contain at least some information about the relative
duration of events, representing more detailed information about timing and rhythm.
timeline() parses and input vector x as durations,
computes the cumulative sum of the durations, with the start argument appended to the beginning.
The result is a numeric vector representing the total duration since the beginning of the vector (plus the value of start, which defaults to zero).
The cumulative durations of timeline() represent musical duration units, where 1 equals a whole note.
timestamp() converts these durations to seconds, either using the BPM argument/field to determine the tempo or using the
default tempo of 60 beats per minute.
If minutes == TRUE, the output is formatted into "minute:seconds.milliseconds" character strings.
If a groupby argument is provided, localDuration() is used to compute the minimum durations in each group before
computing the cumulative sum only with unique values from each Record in the groupby.
By default, with(in).humdrumR will automatically pass groupby = list(Piece = Piece, Record = Record)
into calls to timeline() or timestamp().
Thus, a call like within(humData, timeline(Token)) will compute the correct timeline position for all
tokens across all spines/paths/stops---all values in the same record will be the same.
Note that, timeline() and timestamp() follow the default behavior of duration() by treating grace-notes as duration 0.
This means that their position on the timeline is simply inherited from the previous event on the timeline, as if they occur
at the same time.
If you want to use the specified duration(s) of grace notes, specify grace = TRUE.
By default, any other tokens without (parsable) rhythm information are returned a NA.
However, if threadNA = FALSE, rhythm-less tokens will be treated as if they have a duration of 0 as well, and thus
have a (shared) position on the timeline.
Pickups
Another option is to pass the pickup argument a logical vector of the same length as the input x.
Within each piece/group, any block of TRUE values at the beginning of the pickup vector
indicate a pickup.
The first index where the pickup logical is FALSE is used as the starting point of the timeline/timecount;
All the earlier (pickup == TRUE) points will be negative numbers, measured backwards from the start index.
In humdrumR, and datapoints before the first barline record (=) are labeled Bar == 0 in the Bar field.
Thus, a common use for the pickup argument is within(humData, timeline(Token, pickup = Bar < 1), which makes the downbeat of
the first complete bar 1 the starting point of the timeline---any notes in pickup bars are negative on the timeline.
See also
The timecount() and metcount() functions provide "higher level" musical interpretations of timeline information.
Examples
tokens <- c('4.GG', '8G', '16E', '16F#', '16G', '16D', 'q8D#', '4E')
timeline(tokens)
#> [1] 0.0000 0.3750 0.5000 0.5625 0.6250 0.6875 0.6875 0.7500
timestamp(tokens, BPM = '90')
#> [1] ":0" ":1" ":1.333" ":1.500" ":1.667" ":1.833" ":1.833" ":2"
if (FALSE) {
B075 <- readHumdrum(humdrumRroot, "HumdrumData/BeethovenVariations/B075_00_0._a.krn")
within(B075, timeline(Token))
}