Octaves in clefs

Hello!
Is there any way to add an octave down symbol to a clef? something like trebble_8 in lilypond?

see Lilypond Doc

Hi ddgg!

So, your post here and the one a little bit ago on GitHub led me down a bit of a rabbit hole. First of all, to answer your question from GitHub about ottava, SCAMP doesn’t yet do ottava per se, but you can fake them with text annotations. Here’s a function that lets you add ottava to a part after the fact. It uses text brackets for multiple consecutive high notes, and single note text for single high notes:

from scamp import *
import random
import itertools

s = Session()
s.fast_forward()

violin = s.new_part("violin")

s.start_transcribing()
while s.beat() < 50:
    violin.play_note(random.randint(80, 100), 0.5, 0.25)
    
perf = s.stop_transcribing()


def apply_ottava_to_part(part, threshold=90):
    part_notes = list(perf.parts[0].get_note_iterator())
    for i in range(len(part_notes)):
        last_note = part_notes[i - 1] if i > 0 else None
        this_note = part_notes[i]
        next_note = part_notes[i + 1] if i + 1 < len(part_notes) else None
        if last_note and next_note:
            if this_note.pitch > threshold:
                if last_note.pitch <= threshold and next_note.pitch <= threshold:
                    this_note.properties.texts.append(StaffText("8va", italic=True))
                elif last_note.pitch <= threshold:
                    this_note.properties.spanners.append(StartBracket(text="8va", line_type="dashed"))
            elif this_note.pitch <= threshold and last_note.pitch > threshold:
                this_note.properties.spanners.append(StopBracket())
    for note in part_notes:
        if note.pitch > threshold:
            note.pitch -= 12
     
apply_ottava_to_part(perf.parts[0])
perf.to_score().show()

The downside here is that it’s not using the official symbols, and if you export to MusicXML it won’t play back correctly. So depending on your purposes, it may be more trouble than it’s worth. Still, if I add ottava spanners to pymusicxml and SCAMP, I could add this kind of utility function to make thing smooth and easy on the user end. Would be a bit of work though!

As for the question you ask here about the octave altered clefs, they aren’t exactly supported, but if you open up the engraving settings (from scamp import engraving_settings; engraving_settings.open_json_file()), there’s a key called clef_pitch_centers, to which you could add an entry like "treble_8": 100. You can then do something like:

violin = s.new_part("violin", clef_preference="treble_8")

However, as of now, this would only work for lilypond output. It would be pretty doable for me to add this for MusicXML output, but again this takes time…

I’ve actually been thinking about this lately, about how to budget my time, given that the work I do on SCAMP is largely uncompensated (except for patrons — thank you so much if you’re supporting me on Patreon!). A couple ideas that come to mind:

  • If there are features that people particularly want, they could commission me to develop them. For example, in this case you or someone else could commission me to put in 3 or 4 hours of work to really improve SCAMP’s flexibility with clefs.
  • I could solicit suggestions from patrons about where to spend my development energy. I’m less sure of this approach, though, because at least for now, my Patreon is not a significant source of income. If it gets bigger, this might be a good approach.

Regardless, I appreciate your question and your participation here! I think this is something worth developing in SCAMP, since it would help to automate an otherwise tedious manual process, and I see a pretty clear path forward for doing it. So I’ll put it on the list, and if anyone wants to commission me to push it forward on the list, I’m open to something like that!