Create a musical phrase from character strings that define string numbers, fret numbers and note metadata. This function is a wrapper around phrase().

  fret = NULL,
  info = NULL,
  key = "c",
  tuning = "standard",
  to_notes = FALSE,
  bar = NULL

  fret = NULL,
  info = NULL,
  key = "c",
  tuning = "standard",
  to_notes = FALSE,
  bar = NULL





character, space-delimited or vector. String numbers associated with notes. Alternatively, provide all information here in a single space-delimited string and ignore fret and info. See details.


character, space-delimited or vector (or integer vector) of fret numbers associated with notes. Same number of timesteps as string.


character, space-delimited or vector (or integer vector if simple durations) giving metadata associated with notes. Same number of timesteps as string.


character, key signature or just specify "sharp" or "flat".


character, instrument tuning.


logical, return only the mapped notes character string rather than the entire phrase object.


character or NULL (default). Terminates the phrase with a bar or bar check. See details for phrase(). Also see the LilyPond help documentation on bar notation for all the valid options.


arguments passed to sf_phrase().


a phrase.


Note: This alternate specification wrapper is not receiving further support and will be removed in a future version of tabr.

This alternate syntax allows for specifying string/fret combinations instead of unambiguous pitch as is used by phrase(). In order to remove ambiguity, it is critical to specify the instrument string tuning and key signature. It essentially uses string and fret in combination with a known tuning and key signature to generate notes for phrase(). info is passed straight through to phrase(), as is string once it is done being used to help derive notes.

See the main function phrase for general details on phrase construction.

Comparison with phrase()

This function is a wrapper function for users not working with musical notes (what to play), but rather just position on the guitar neck (where to play). This approach has conveniences, but is more limiting. In order to remove ambiguity, it is necessary to specify the instrument tuning and the key signature.

In the standard approach with phrase() you specify what to play; specifying exactly where to play is optional, but highly recommended (by providing string). With sf_phrase(), the string argument is of course required along with fret. But any time the tuning changes, this "where to play" method breaks down and must be redone. It is more robust to provide the string and pitch rather than the string and fret. The key is additionally important because it is the only way to indicate if accidentals should be notated as sharps or flats.

This wrapper also increases redundancy and typing. In order to specify rests r, silent rests s, and tied notes ~, these must now be providing in parallel in both the string and fret arguments, whereas in the standard method using phrase(), they need only be provided once to notes. A mismatch will throw an error. Despite the redundancy, this is helpful for ensuring proper match up between string and fret, which is essentially a dual entry method that aims to reduce itself inside sf_phrase() to a single notes string that is passed internally to phrase().

The important thing to keep in mind is that by its nature, this method of writing out music does not lend itself well to high detail. Tabs that are informed by nothing but string and fret number remove a lot of important information, and those that attempt to compensate with additional symbols in say, an ascii tab, are difficult to read. This wrapper function providing this alternative input method to phrase() does its job of allowing users to create phrase objects that are equivalent to standard phrase()-generated objects, including rests and ties. But practice and comfort working with phrase() is is highly recommended for greater control of development support.

The function sfp() is a convenient shorthand wrapper for sf_phrase(). sf_note() and the alias sfn() are wrappers around sf_phrase() that force to_notes = TRUE.

Single-string input

Another way to use sf_phrase() is to provide all musical input to string and ignore fret and info as explicit arguments. Providing all three explicit arguments more closely mimics the inputs of phrase() and is useful when you have this information as three independent sources. However, in some cases the single-argument input method can reduce typing, though this depends on the phrase. More importantly, it allow you to reason about your musical inputs by time step rather than by argument. If you provide all three components as a single character string to the string argument, leaving both fret and info as NULL, then sf_phrase() will decompose string into its three component parts internally.

There are some rules for single-argument input. The three components are separated by semicolons as "string;fret;info". For example, "3;7x7;4" means begin on the third string (infer higher number strings muted). The frets are 7th and 7th, meaning two notes are played. When an x is present in the second entry it means a string is not played. This is how it is inferred that the string numbers starting from the third string are strings 3 and 1 rather than 3 and 2 in this example. The 4 indicates a quarter note since it is part of the third entry where the additional info is specified. This is contextual. For example, an x here would still indicate a dead note, rather than an unplayed string in the second entry, so this is contextual.

A bonus when using this input method is that explicit string and info values persist from one timestep to the next. Neither needs to be provided again until there is a change in value. For example, "3;7x7;4 7x7 ;7x7;1" repeats the string and info values from timestep one for timestep two. In timestep three, string numbers repeat again, but the duration changes from quarter note to whole note.

Note that except when both string and info are repeating and only fret numbers are provided (see timestep two above), two semicolons must be present so that it is unambiguous whether the sole missing component is a string or info (see timestep three).

Ambiguity would arise from a case like "4;4" without the second semicolon. This type of indexing was chosen over using two different delimiters.

If a rest, r or s, is provided for the fret entry, then the string entry is ignored. When using this input method, ties ~ are given in the info entry.

See the examples for a comparison of two identical phrases specified using both input methods for sf_phrase().

See also


sf_phrase("5 4 3 2 1", "1 3 3 3 1", "8*4 1", key = "b_")
#> <Musical phrase>
#> <bes,\5>8 <f\4>8 <bes\3>8 <d'\2>8 <f'\1>1
sf_phrase("6 6 12 1 21", "133211 355333 11 (13) (13)(13)", "4 4 8 8 4",
          key = "f")
#> <Musical phrase>
#> <f,\6 c\5 f\4 a\3 c'\2 f'\1>4 <g,\6 d\5 g\4 bes\3 d'\2 g'\1>4 <f'\1 c'\2>8 <f''\1>8 <c''\2 f''\1>4
sfp("6*2 1*4", "000232*2 2*4", "4 4 8*4", tuning = "dropD", key = "d")
#> <Musical phrase>
#> <d,\6 a,\5 d\4 a\3 d'\2 fis'\1>4 <d,\6 a,\5 d\4 a\3 d'\2 fis'\1>4 <fis'\1>8 <fis'\1>8 <fis'\1>8 <fis'\1>8

# compare with single-argument input
s <- "3*5 53~*3 543*2 643"
f <- "987*2 775 553 335 77~*3 545 325 210"
i <- "2*3 4. 16 4.*3 4*3"
p1 <- sfp(s, f, i)

# Nominally shorter syntax, but potentially much easier to reason about
p2 <- sfp("3;987;2*2 775 ;553;4. ;335;16 5;7x7;4.~*3 ;545;4 325 6;2x10;")

identical(p1, p2)
#> [1] TRUE