Check whether a string is comprised exclusively of valid syntax for music strings. A music object can be built from such a string. It combines a noteworthy string and a note info string.

musical(x)

as_music(
  notes,
  info = NULL,
  lyrics = NA,
  key = "c",
  time = "4/4",
  tempo = "2 = 60",
  accidentals = NULL,
  format = NULL,
  labels = NULL,
  at = seq_along(labels)
)

is_music(x)

music_split(x)

Arguments

x

character or music, a string to be coerced or an existing music object.

notes, info

noteworthy and note info strings. For as_music(), a complete music string is assumed for notes when info = NULL.

lyrics

optional lyrics object or NA, attached to output as an attribute.

key

character, store the key signature as a music attribute. Defaults to "c". See details.

time

character, store the time signature as a music attribute. Defaults to "4/4". See details.

tempo

character or NA, defaults to "2 = 60". See details.

accidentals

NULL or character, represent accidentals, "flat" or "sharp".

format

NULL or character, the timestep delimiter format, "space" or "vector".

labels

character, text annotations to attach to timesteps using notate.

at

integer, timesteps for labels, defaults to starting from time one.

Value

depends on the function

Details

With note info strings, you are required to enter something at every timestep, even if it is only the duration. This makes sense because if you do not enter something, there is simply no indication of a timestep. A nice feature of music strings is that explicit timesteps are achieved just by having notes present, allowing you to leave out durations entirely when they repeat, inheriting them from the previous timestep where duration was given explicitly. There is no need to enter the same number across consecutive timesteps; the first will suffice and the rest are automatically filled in for you when the object is constructed.

musical() returns a scalar logical result indicating whether all timesteps contain exclusively valid entries.

as_music() can be used to coerce to the music class. Coercion will fail if the string is not musical. The music class has its own print() and summary() methods. music objects are primarily intended to represent an aggregation of a noteworthy object and a noteinfo. You can optionally fold in a lyrics object as well. However, for music data analysis, any operations will involve first splitting the object into its component parts. The value of this class is for the more efficient data entry it provides.

When accidentals or format are NULL, these settings are inferred from the musical string input. When mixed formats are present, flats are the default for accidentals.

Other attributes are attached to a music object. key uses the tabr syntax, e.g., "c", "b_", "f#m", etc. time and tempo use the LilyPond string format. For music programming and analysis, key, time and tempo can most likely be ignored. They are primarily relevant when rendering a music snippet directly from a music object with LilyPond. These additional attributes provide more complete context for the rendered sheet music.

If you plan to render music snippets from a music object that you are defining from a new character string, and the context you have in mind is a stringed and fretted instrument like guitar, you can specify string numbers at the end of each timestep with numbers following a semicolon delimiter. This would still precede any * timestep multiplier number. See examples.

Note that if you convert a music object to a phrase object, you are changing contexts. The phrase object is the simplest LilyPond-format music structure. Coercion with phrase() strips all attributes of a music object and retains only notes, note info and string numbers.

Examples

# note durations inherit from previous timestep if missing
x <- "a#4-+ b_[staccato] c,x d''t8( e)( g_')- a4 c,e_,g, ce_g4. a~8 a1"
is_music(x)
#> [1] FALSE
musical(x)
#> [1] TRUE
x <- as_music(x)
is_music(x)
#> [1] TRUE
x
#> <Music string>
#>   Format: space-delimited time
#>   Values: b_4-+ b_4[staccato] c,4x d''t8( et8)( g_'t8)- a4 <c,e_,g,>4 <ce_g>4. a~8 a1

y <- lyrics_template(x)
y[3:8] <- strsplit("These are some song ly- rics", " ")[[1]]
y
#> <Lyrics string>
#>   Format: space-delimited time
#>   Values: . . These are some song ly- rics . . .

x <- as_music(x, lyrics = y, accidentals = "sharp")
summary(x)
#> <Music string>
#>   Timesteps: 11 (9 notes, 2 chords)
#>   Octaves: tick
#>   Accidentals: sharp
#>   Key signature: c
#>   Time signature: 4/4
#>   Tempo: 2 = 60
#>   Lyrics: . . These are some song ly- rics . ...
#>   Format: space-delimited time
#>   Values: a#4-+ a#4[staccato] c,4x d''t8( et8)( f#'t8)- a4 <c,d#,g,>4 <cd#g>4. a~8 a1

# Starting string = 5: use ';5'. Carries over until an explicit change.
x <- "a,4;5*5 b,4-+ c4[staccato] cgc'e'~4 cgc'e'1 e'4;2 c';3 g;4 c;5 ce'1;51"
x <- as_music_df(as_music(x))
x$string
#>  [1] "5"    "5"    "5"    "5"    "5"    "5"    "5"    "5432" "5432" "2"   
#> [11] "3"    "4"    "5"    "51"