X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=score.c;h=ba27844fb02e9fc6835188f1409cd36e0442b5d2;hb=367e517451123c7c79ead28eca6d2489bfed6467;hp=e587c2799ed93a6396456b8d929388d56f482a30;hpb=41e993a65ab55db1f3297003fe65dd556a15f85f;p=scherzo diff --git a/score.c b/score.c index e587c27..ba27844 100644 --- a/score.c +++ b/score.c @@ -21,6 +21,7 @@ #include #include +#include #include "score.h" @@ -174,13 +175,25 @@ _score_clef_c_line (score_clef_t clef) } } +/* On which line would 'pitch' appear on 'staff'. + * + * Lines are numbered with line 0 as the top full line of the staff + * and increasing downward. So line values less than 0 will appear as + * ledger lines above the staff while line values greater than 4 will + * appear on ledger lines below the staff. + * + * A line value of 2 will be centered verticall on the staff. + * + * For notes appearing on a space, the line value will be half-way + * between two integers. */ static double -_score_note_to_line (score_staff_t *staff, score_note_t *note) +_score_staff_pitch_to_line (score_staff_t *staff, pitch_t pitch) { - pitch_name_t name = PITCH_NAME (note->pitch); + pitch_name_t name = PITCH_NAME (pitch); + int octave = PITCH_OCTAVE (pitch); int c_line = _score_clef_c_line (staff->clef); - return c_line - (name - PITCH_NAME_C) / 2.0 - 3.5 * (note->octave - 4); + return c_line - (name - PITCH_NAME_C) / 2.0 - 3.5 * (octave - 4); } /* chord->width is updated as a side effect */ @@ -258,7 +271,7 @@ _draw_note (score_t *score, cairo_t *cr, * note on a ledger line above the staff). Values half way between * integers indicate notes appearing on a space between two staff * lines (or ledger lines). */ - line = _score_note_to_line (staff, note); + line = _score_staff_pitch_to_line (staff, note->pitch); cairo_select_font_face (cr, "Gonville-26", 0, 0); cairo_set_font_size (cr, score->staff_height); @@ -593,10 +606,9 @@ score_remove_chord (score_chord_t *chord) } score_note_t * -score_add_note (score_staff_t *staff, - pitch_t pitch, - int octave, - score_duration_t duration) +score_staff_add_note (score_staff_t *staff, + pitch_t pitch, + score_duration_t duration) { score_note_t *note; double line; @@ -606,7 +618,6 @@ score_add_note (score_staff_t *staff, for (i = 0; i < staff->num_notes; i++) { note = staff->notes[i]; if (note->pitch == pitch && - note->octave == octave && note->duration == duration) { return note; @@ -619,14 +630,13 @@ score_add_note (score_staff_t *staff, note->staff = staff; note->pitch = pitch; - note->octave = octave; note->duration = duration; note->color.r = 0.0; note->color.g = 0.0; note->color.b = 0.0; - line = _score_note_to_line (staff, note); + line = _score_staff_pitch_to_line (staff, note->pitch); if (line < 0) { int lines = (int) (- line); if (lines > staff->upper_ledger_lines) @@ -652,6 +662,31 @@ score_add_note (score_staff_t *staff, return note; } +score_note_t * +score_add_note (score_t *score, pitch_t pitch, score_duration_t duration) +{ + score_staff_t *staff, *nearest_staff = NULL; + double distance, nearest_distance = 0.0; + int i; + + /* Nothing to do if we have no staff, (there's no place to add a note) . */ + if (score->num_staves == 0) + return NULL; + + /* Find the staff where the note will be closest to the center of + * the staff. */ + for (i = 0; i < score->num_staves; i++) { + staff = score->staves[i]; + distance = fabs (_score_staff_pitch_to_line (staff, pitch) - 2.0); + if (nearest_staff == NULL || distance < nearest_distance) { + nearest_staff = staff; + nearest_distance = distance; + } + } + + return score_staff_add_note (nearest_staff, pitch, duration); +} + void score_remove_note (score_note_t *note) { @@ -680,6 +715,23 @@ score_remove_note (score_note_t *note) } } +void +score_staff_remove_notes (score_staff_t *staff) +{ + talloc_free (staff->notes); + staff->notes = NULL; + staff->num_notes = 0; +} + +void +score_remove_notes (score_t *score) +{ + int i; + + for (i = 0; i < score->num_staves; i++) + score_staff_remove_notes (score->staves[i]); +} + void score_set_note_color_rgb (score_note_t *note, double r, @@ -694,7 +746,6 @@ score_set_note_color_rgb (score_note_t *note, score_note_t * score_staff_find_note (score_staff_t *staff, pitch_t pitch, - int octave, score_duration_t duration) { int i; @@ -702,12 +753,8 @@ score_staff_find_note (score_staff_t *staff, for (i = 0; i < staff->num_notes; i++) { note = staff->notes[i]; - if (note->pitch == pitch && - note->octave == octave && - note->duration == duration) - { + if (note->pitch == pitch && note->duration == duration) return note; - } } return NULL;