Grace Notes

Hi Marc,
I see that GraceNote is available as a subclass of Note in the pymusicxml package. But, can’t find anything about grace notes in the scamp package. Could you point me towards how you tackle grace notes in scamp? Is there something in playback_implementations or note_properties that we can use to make grace notes?
Thanks,
Neil

Not everything in pymusicxml is implemented in SCAMP, and grace notes are one of those things. It’s a bit tricky, because grace notes have no real duration, or at least no fixed duration; they steal from the notes or rests around them.

If grace notes did exist, what would you want the API to look like? How would the code for playing one go?

Hmm. Good question.

Right now I’m trying to do ruffs for percussion. Something like this:

I could imagine there is a requirement for a rest or note, preceding the grace notes, that is long enough you can steal time from it.

Such as an 8th note to steal two 32nds from.

Imagining how I would try to write this:

def rest_and_grace_notes(instrument,
                         written_rest_length, 
                         grace_note_pitches: int | float | list,
                         grace_note_notated_lengths: int | float | list,
                         grace_note_volumes: int |float | list)
    # assuming grace notes playback at half of notated value:
    grace_length = sum(grace_note_notated_lengths)/2
    play_back_rest = rest_length - grace_length
    grace_wait(play_back_rest, written_rest_length)
    data = zip(grace_note_pitches, grace_note_volumes, grace_note_notated_lengths)
    for p, v, l in data:
        instrument.play_note(p, v, l/2, transcribe=False)
    
    # and then the magical gracenote transcription:
    for p, v, l, in data:
        write_grace_note(p, v, l)

And then something similar for note_and_grace_notes

I keep thinking about this situation and bumping into places I want to create grace notes with scamp. I see in MusicXML there is a flag to steal time from previous or steal time from following when creating gracenotes. However, that doesn’t help steal-time in realtime playback. And I see that you transcribe a gracenote at the end of glissandi without playing it separately from the gliss in scamp.

Some more thoughts on how this might work for grace notes preceding the beat:

  1. grace notes following a rest:

play_grace_notes_after_rest([grace_note_pitches], volume, length, properties)

  • Play notes at an appropriate fraction of length to sound as grace notes
  • transcribe rest time equivalent to the played grace notes
  • transcribe the grace notes with steal from previous flag
  1. grace notes following a note:

play_note_and_grace_notes(note_and_properties_list, grace_notes_and_properties_list):

  • play_note of length minus time needed for grace notes
  • transcribe full note
  • play grace notes
  • transcribe grace notes with steal time from previous flag

Hmm, I wonder if there could just be a property like:

inst.play_note(pitch, volume, duration, grace="after"/"before")

So if you wanted, say, half note, 2 grace notes, half note, and you wanted the grace notes to be part of the preceding half-note, you would do:

inst.play_note(70, 0.5, 1.75)
inst.play_note(69, 0.5, 0.125, grace="before")
inst.play_note(70, 0.5, 0.125, grace="before")
inst.play_note(72, 0.5, 2)

…and if you wanted the grace notes on the beat (i.e. to steal from the second half-note), you could do:

inst.play_note(70, 0.5, 2)
inst.play_note(69, 0.5, 0.125, grace="after")
inst.play_note(70, 0.5, 0.125, grace="after")
inst.play_note(72, 0.5, 1.75)

That way, it doesn’t mess with playback at all, you still just say exact, actual durations, but then in creating the notation, the grace=“before” flag would tell scamp to add the duration back to the previous note, and notate the note as a grace note that steals from the note before, and vice-versa with “after”.

Does that make sense?

Absolutely. This is essentially the approach I’m taking right now and then manually changing to grace notes and fixing the values after the fact in Finale.