Skip to content

Parse

The functions listed here enable the parsing of Pitch vectors and derived types to and from strings.

int pitch_from_spn(const char *s, Pitch *out);

Parses a Pitch from Scientific Pitch Notation. Outputs the Pitch via an out-param (you must pass in a pointer to a Pitch). Returns 1 if there is a parsing error.

Safe usage if the string is being passed in dynamically:

Pitch p;
if (pitch_from_spn(str, &p)) {
// handle parsing error
}
bool pitch_spn(Pitch p, char *out);

Returns the Scientific Pitch Notation name of a Pitch as a string. You must pass a char array with at least 8 characters to store the result, which is returned via an out-param.

Returns true if the Pitch’s accidental is more than a quadruple sharp/flat away from a natural — usually a sign of a logic error upstream — but the name is still rendered in full to out as long as it fits in the buffer. Also returns true, writing "ERR" to out instead, if the name genuinely doesn’t fit in 8 characters (an extreme accidental or octave). Returns false otherwise.

Pitch p;
pitch_from_spn("G#5", &p);
char buf[8];
pitch_spn(p, buf); // buf holds "G#5", returns false
pitch_from_spn("F#####4", &p); // an extreme accidental (+5), unlikely from real usage
pitch_spn(p, buf); // buf holds "F5#4", returns true (flagged, but still rendered)
int interval_from_spn(const char *p_str, const char *q_str, Interval *out);

Parses two strings into Pitch vectors from Scientific Pitch Notation to generate an Interval vector from. Outputs via a passed in Interval pointer. Returns 1 if anything went wrong during parsing.

Safe usage if the string is being passed in dynamically:

Interval m;
if (interval_from_spn(str1, str2, &p)) {
// handle parsing error
}
int axis_from_spn(char *p_str, char *q_str, MirrorAxis *out);

Creates a MirrorAxis about which to invert a Pitch by adding two Pitch vectors together. To be used in conjunction with pitch_invert.

Unlike axis_create, axis_from_spn takes two pitch names as SPN strings, and returns the created MirrorAxis via a passed in pointer. Returns 1 if there is a parsing error.

Safe usage if the strings are being passed in dynamically:

MirrorAxis a;
if (axis_from_spn(str1, str2, &a)) {
// handle parsing error
}
int pitch_from_helmholtz(const char *s, Pitch *out);

Parses a Pitch from Helmholtz pitch notation. Outputs the Pitch via an out-param (you must pass in a pointer to a Pitch). Returns 1 if there is a parsing error.

Safe usage if the string is being passed in dynamically:

Pitch p;
if (pitch_from_helmholtz(str, &p)) {
// handle parsing error
}
bool pitch_helmholtz(Pitch p, char *out);

Returns the Helmholtz pitch notation name of a Pitch as a string. You must pass a char array with at least 16 characters to store the result, which is returned via an out-param.

Returns true if the Pitch’s accidental is more than a quadruple sharp/flat away from a natural — usually a sign of a logic error upstream — but the name is still rendered in full to out as long as it fits in the buffer. Also returns true, writing "ERR" to out instead, if the name genuinely doesn’t fit in 16 characters (an extreme accidental or octave). Returns false otherwise.

Pitch p;
pitch_from_helmholtz("g#'", &p);
char buf[16];
pitch_helmholtz(p, buf); // buf holds "g#'", returns false
pitch_from_helmholtz("g#####'", &p); // an extreme accidental (+5), unlikely from real usage
pitch_helmholtz(p, buf); // buf holds "g5#'", returns true (flagged, but still rendered)
int pitch_from_lily(const char *s, Pitch *out);

Parses a Pitch from LilyPond notation (absolute mode, no rhythmic values). Outputs the Pitch via an out-param (you must pass in a pointer to a Pitch). Returns 1 if there is a parsing error.

Safe usage if the string is being passed in dynamically:

Pitch p;
if (pitch_from_lily(str, &p)) {
// handle parsing error
}
bool pitch_lily(Pitch p, char *out);

Returns the LilyPond name of a Pitch as a string. You must pass a char array with at least 16 characters to store the result, which is returned via an out-param.

Unlike pitch_spn/pitch_helmholtz, this is a hard limit: LilyPond has no symbol for anything beyond a double sharp/flat (“isis”/“eses”), so if the Pitch’s accidental goes beyond ±2, pitch_lily makes no attempt to render a name at all — it immediately writes "ERR" to out and returns true. It also returns true (writing "ERR") if the octave alone would overflow the 16-character buffer. Returns false otherwise.

Pitch p;
pitch_from_lily("gis'", &p);
char buf[16];
pitch_lily(p, buf); // buf holds "gis'", returns false
pitch_from_spn("Fx#4", &p); // accidental of +3, beyond LilyPond's double sharp
pitch_lily(p, buf); // buf holds "ERR", returns true
LilyParseContext lily_parse_context_init(Pitch p);

Creates a LilyParseContext for parsing a sequence of LilyPond pitches in relative mode, seeded with p as the starting reference pitch — equivalent to the pitch written immediately after \relative in real LilyPond input.

Pitch p;
pitch_from_lily("c'", &p); // middle C
LilyParseContext ctx = lily_parse_context_init(p);
int pitch_from_relative_lily(LilyParseContext *ctx, const char *s, Pitch *out);

Parses a Pitch from LilyPond notation in relative mode. Rather than reading an absolute octave from s, the octave is chosen so the parsed pitch falls within a fourth of ctx->previous, after which any '/, marks present in s each shift the result a further octave, same as in absolute mode. Outputs via an out-param, and returns 1 if there is a parsing error, same as pitch_from_lily.

ctx->previous is updated to the parsed Pitch after every successful call, so a single LilyParseContext can just be threaded straight through a run of notes, mirroring how \relative mode works in real LilyPond input.

Pitch p;
pitch_from_lily("c'", &p); // middle C
LilyParseContext ctx = lily_parse_context_init(p);
Pitch out;
pitch_from_relative_lily(&ctx, "e", &out); // e', a third above middle C
pitch_from_relative_lily(&ctx, "g", &out); // g', a third above that
pitch_from_relative_lily(&ctx, "c,", &out); // back down to middle C

Safe usage if the string is being passed in dynamically:

Pitch out;
if (pitch_from_relative_lily(&ctx, str, &out)) {
// handle parsing error
}
int pitch_from_abc(const char *s, Pitch *out);

Parses a Pitch from ABC notation. Outputs the Pitch via an out-param (you must pass in a pointer to a Pitch). Returns 1 if there is a parsing error.

Safe usage if the string is being passed in dynamically:

Pitch p;
if (pitch_from_abc(str, &p)) {
// handle parsing error
}
bool pitch_abc(Pitch p, char *out);

Returns the ABC name of a Pitch as a string. You must pass a char array with at least 16 characters to store the result, which is returned via an out-param.

Unlike pitch_spn/pitch_helmholtz, this is a hard limit: ABC notation has no symbol for anything beyond a double sharp/flat (”^^”/”__”), so if the Pitch’s accidental goes beyond ±2, pitch_abc makes no attempt to render a name at all — it immediately writes "ERR" to out and returns true. It also returns true (writing "ERR") if the octave alone would overflow the 16-character buffer. Returns false otherwise.

Pitch p;
pitch_from_abc("^g'", &p);
char buf[16];
pitch_abc(p, buf); // buf holds "^g'", returns false
pitch_from_spn("Fx#4", &p); // accidental of +3, beyond ABC's double sharp
pitch_abc(p, buf); // buf holds "ERR", returns true