Tuesday, October 28, 2014

"hmm_ShowRanges" - a Noteworthy Composer 2 user tool for checking ranges in scores

Contents

  1.   Introduction
  2.   Example 1
  3.   Example 2
  4.   The rules for range chords
  5.   Example 3
  6.   Example 4

Introduction


I have written a small script that can be used to mark notes that fall outside a given range. This should be helpful when writing for instruments or voices with a limited range – in other words, almost always.

I should have written this script years ago, but somehow I waited until yesterday when, in a few hours, I learned (the necessary few pieces of) PHP and concentrated on the little algorithms behind ...

Of course, this piece of code makes heavy reuse of ideas and code already around – I was "standing on the shoulders of giants," so-to-speak: The idea is inspired by the adp_Ranges script, whereas the code uses NW2's nwc2clips library. I have to thank the people who provided one and the other.

The script can be downloaded here (as a ZIP file). It requires the installation of the "NWC2 User Tool Starter Kit", which can be found here.

The following paragraphs contain a short introduction how to use the script. All the examples below use a quite useless melody, which includes some clef changes and strange chords at the end:

Example 1


In the simplest case, one wants to mark all notes outside a given range. The steps for range checking are:
  1. Write a "range chord" at the beginning – here, a simple octave. In real life, one would mark this chord as "Visible: Never," but here, I left it visible to show its effects more clearly:
  1. Mark the range chord and all the notes you want to check:
  1. Run the script.
Here is the result (after deselecting) – all the notes outside the range have been colored like the "range chord":
The "range chord" (octave) specified that the range between (and including) the two C's is the "normal range," which is left unmodified. All notes below the lower C or above the upper C are colored. It is intentional that the notes outside the range are colored, as it is customary that ranges are defined "inclusively," i.e., the boundary notes of the range are considered to be inside the range.

As one can see, the script works also over clef changes and for chords with stems in both directions.

By the way, a simple Ctrl-Z reverts all the changes – so that your next printout will still be black-on-white!

Example 2


Here is another example, this time with two ranges:
  • The inner range from e to b is the "convenient range," which can be sung or played easily.
  • The outer range from c to the upper e is the "complete range," which can be sung or played with some effort.
The notes outside these two ranges are supposed to be "off-limits."
Here is the result when marking all notes and running the tool:
One can see that the notes in the innermost range keep their noteheads and color, the notes in between the inner and the outer range get pink triangular heads, and the notes outside the outer range get red round noteheads.

The rules for range chords


Before I continue with two more examples, let me state the rules for writing a range chord:
  • A range chord must consist of an even number of notes.
  • The outermost (lowest and highest) note define the outermost range. Because of this, they must have the same notehead and the same color.
  • When these two notes are removed ("peeled off"), the now outermost notes define the next range. Again, they must have the same notehead and color.
  • This "layering of note pairs" can be continued arbitrarily (but I have used a maximum of three ranges up to now).
  • The lower notes of two ranges can be equal (but not the upper ones – up to now, I do not need this, and the algorithms would have become even more complicated with identical upper notes).
  • Range chords will be "seen" by tool regardless of their visibility. Therefore, I find it practical to assign them visibility "Never" (except when editing them, so that I can see the noteheads' colors).
If the first chord of the selected notes does not follow these rules, the script will probably behave erratically, as I have not yet added enough error handling. In many cases, it will simply skip the chord and try to use the next chord as "range chord" – probably not what one expects, but so it goes ... But whatever happens, Ctrl-Z should revert to the previous state in all cases!

Example 3


Ranges must "nest properly" – this follows from the rules above; but see example 4! -, but ranges can have the same lower boundary note. Incidentally, this made the internal algorithm quite a bit harder, but it is necessary for standard and extended ranges of brass and other instruments.

Here is an example where both the inner range and the outer range start at middle C. It makes sense to use whole notes ("semibreve") in this case, because they are placed side by side (the heads of shorter double notes are placed on top of each other). For variety, the outer range is green:
Here is the result of marking everything and running the script:

Example 4


At times, it is necessary to range check for different reasons with quite independent range definitions. For example, for a clarinet, one might want to check for notes above the b flat/b "break," in addition to the standard range check.

Of course, one can simply put multiple range chords at the beginning of a system and, depending on the check, start the note selection with the second, third, etc. range chord. The only problem is that this would change included range chords – e.g. the second range chord, if the selection starts at the first one:
However, the script is so nice to not change chords that are marked with "Visibility: Never." This is a useful idea anyway, so that the range chords do not show up in printed scores, but in addition it helps to keep the range chords unchanged.

Here is the result when running the script on the full selection ...
... and here we see what happens when the selection starts at the second chord:

In a way, this allows for overlapping or "non-layered" ranges – i.e., one can subvert the rule that ranges must "nest properly."

This is the end of my description of the "hmm_ShowRanges" script. I'd be happy if it is of some help for you ... or you ... or you!