timecount | R Documentation |
The timecount()
function takes a vector of rhythmic duration values and
counts (in the musical sense) the number of beats (or measures) which have occurred since the starting point,
associating each rhythmic onsets with a beat.
The subpos()
function is paired with timecount()
, computing how far (in rhythmic time) each onset is from its
associated beat; if subpos()
returns 0
, this means that an onset is on the beat.
Finally, onbeat()
is simply a convenient shorthand for subpos() == 0
, returning
a logical
vector for indicating where onsets fall on or off beat.
## Default S3 method:
timecount(
dur,
unit = rational(1L),
start = 1L,
phase = 0,
pickup = NULL,
offBeats = TRUE,
groupby = list(),
...
)
timecount(
dur,
unit = rational(1L),
start = 1L,
phase = 0,
pickup = NULL,
offBeats = TRUE,
groupby = list(),
...
)
## Default S3 method:
subpos(
dur,
unit = rational(1L),
phase = 0,
pickup = NULL,
deparser = duration,
...,
groupby = list()
)
subpos(
dur,
unit = rational(1L),
phase = 0,
pickup = NULL,
deparser = duration,
...,
groupby = list()
)
## Default S3 method:
onbeat(dur, unit = rational(1L), groupby = list(), ...)
onbeat(dur, unit = rational(1L), groupby = list(), ...)
dur |
An input vector of rhythmic durations. Must be a Is parsed using |
unit |
The size of "beat" (or measure) to count. Defaults to a whole-note (one measure of 4/4 time). Must be a Is parsed as a duration using |
start |
The number to start counting from. Must be a single whole-number value (either |
phase |
The phase offset between onsets and beats. Defaults to Must be a Is parsed as a duration using |
pickup |
Indicates which leading values in the input are pickups, if any. Defaults to Must be |
offBeats |
Should off-beat onsets be numbered in the output, or Defaults to Must be a single |
groupby |
Optional vectors to group by and count within. Defaults to empty Must be a |
In many basic use cases, using timecount()
is essentially the same as using floor(timeline())
.
However, timecount()
gives us a few additional options which add musicological power compared to timeline()
.
(timecount()
also starts from 1
not 0
, as timeline()
does.)
The first beat in an input vector is assigned the value of the start
argument, which defaults to start = 1L
.
There is no 'zeroth' count, as the first beat occurs at the instant of the starting time—i.e., the first onset in the input vector.
Every rhythmic onset is associated with one beat, but multiple onsets may occur within the same beat—thus
the output of timecount()
assigns (rounds) each onset to the previous beat onset.
However, if offBeats = FALSE
, only onsets that land on a beat are counted, with offbeat values returning NA
.
The phase
controls how offbeat onsets are associated with nearby beats.
phase
is parsed as a rhythmic value and must be rhythmic values that are smaller than the smallest beat
value.
The phase
argument shifts the "boundary" between beats backwards, before the beat onset.
By default, phase = 0
so the beat-association boundary lands on the beat: only onsets on or after each beat "belong" to that beat.
If phase = '8'
, the beat boundary is pushed back to capture one eighth-note before the beat itself.
This can be used to, for example, associate the last 3/8s of a measure with the next measure (like pick ups);
This could be achieved with a command like timecount(dur, beat = '1', phase = 3/8)
.
The unit
argument is used to indicate what size of beat you want to count.
The default unit
is a whole note, equivalent to a measure of M4/4
time.
The unit
argument uses the rhythm parser, so it can understand unit values input in a variety of formats:
thus, you could specify quarter-note units as either unit = '4'
or unit = 0.25
.
The parser also understands how to parse the (full) duration of time signature: for example, unit = 'M3/4'
would use a dotted-half-note unit ('2.'
).
If your data has changing meters (either between pieces, or within pieces), you can specify
the unit
argument as a vector which is the same length as dur
, indicating the
beat size at each moment/index.
This feature is very easy to use with any dataset that includes time signature interpretations, like "*M4/4"
;
these interpetations, if present, are automatically read into a field called TimeSignature
.
For such a dataset, you can simply pass the TimeSignature
field to the unit
argument of timecount()
, and
the measures of the piece will be correctly counted (even when changing!): timecount(x, unit = TimeSignature)
.
Alternatively, you can use the tactus()
command to extract the tactus beat from a time signature, like timecount(x, unit = tactus(TimeSignature))
.
Some musical meters consist of a pattern of irregular beats.
For example, the meter M7/8
is often realized as two "short" beats (two eigth-notes each) and one "long" beat (three eigth-notes), forming a 2 + 2 + 3 pattern.
If we want to count each eighth-note, we can simply specify unit = '8'
and get the M7/8
beats counted as c(1
, 3
, 5
).
However, if we want to count each short or long beat as a single unit, we must specify the desired pattern as a list
of beat durations: for example, unit = list(c("4", "4", "4."))
.
Let's see what these two cases look like, applied to two M7/8
measures of straight eighth-notes:
rhythm <- rep('8', 14) timecount(rhythm, unit = '8'), # output is: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 timecount(rhythm, unit = list(c('4', '4', '4.'))) # output is: 1 1 2 2 3 3 3 4 4 5 5 6 6 6
To accommodate changing meters, the unit
argument can still accept list
of such patterns, so long as the list is the same length as dur
.
Another option is to pass the pickup
argument a logical vector of the same length as the input dur
.
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 location of beat 1
:
all the earlier (pickup == TRUE
) points will be negative counts, counting backwards from the start.
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, timecount(Token, pickup = Bar < 1)
, which makes the downbeat of
the first complete bar 1
the stating point—any notes in pickup bars are give negative counts.
Note that there is never a 'beat zero'.
Beats before the starting point progress directly from -1
to 1
(the start).
As a result, doing arithmetic or other math with beat "counts" can be problematic when using a pickup
argument.
It may be better to use round(timeline())
in cases where you want to do much math with counts.
timecount()
and subpos()
are closely related to the timeline()
function. The metcount()
function applies timecount()
within a metric framework.
humData <- readHumdrum(humdrumRroot, "HumdrumData/BachChorales/chor00[1-4].krn")
show(within(humData, timecount(Token, unit = TimeSignature, pickup = Bar < 1)))
show(within(humData, timecount(Token, unit = tactus(TimeSignature))))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.