Parse
The functions listed here enable the parsing of Pitch vectors and derived types to and from strings.
Scientific Notation
Section titled “Scientific Notation”pitch_from_spn
Section titled “pitch_from_spn”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}pitch_spn
Section titled “pitch_spn”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 usagepitch_spn(p, buf); // buf holds "F5#4", returns true (flagged, but still rendered)interval_from_spn
Section titled “interval_from_spn”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}axis_from_spn
Section titled “axis_from_spn”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}Helmholtz Notation
Section titled “Helmholtz Notation”pitch_from_helmholtz
Section titled “pitch_from_helmholtz”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}pitch_helmholtz
Section titled “pitch_helmholtz”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 usagepitch_helmholtz(p, buf); // buf holds "g5#'", returns true (flagged, but still rendered)LilyPond Notation
Section titled “LilyPond Notation”pitch_from_lily
Section titled “pitch_from_lily”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}pitch_lily
Section titled “pitch_lily”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 sharppitch_lily(p, buf); // buf holds "ERR", returns truelily_parse_context_init
Section titled “lily_parse_context_init”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);pitch_from_relative_lily
Section titled “pitch_from_relative_lily”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 CLilyParseContext ctx = lily_parse_context_init(p);
Pitch out;pitch_from_relative_lily(&ctx, "e", &out); // e', a third above middle Cpitch_from_relative_lily(&ctx, "g", &out); // g', a third above thatpitch_from_relative_lily(&ctx, "c,", &out); // back down to middle CSafe usage if the string is being passed in dynamically:
Pitch out;if (pitch_from_relative_lily(&ctx, str, &out)) { // handle parsing error}ABC Notation
Section titled “ABC Notation”pitch_from_abc
Section titled “pitch_from_abc”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}pitch_abc
Section titled “pitch_abc”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 sharppitch_abc(p, buf); // buf holds "ERR", returns true