Sharps and flats in Pbind's \degree

Noobie question here: I am confused about indicating accidentals in Pbind when using the \degree key.

I (naively) thought that the note between 0 and 1 would be 0.5 but I was sorely mistaken:

Pbind(\degree, Pseq([0,0.5,1])) // plays C A D

Then I found a discussion on Github’s SC’s issue tracker that indicates that sharps are represented by tenth increases, so playing C,C#, D would actually be:

Pbind(\degree, Pseq([0,0.1,1]))

which indeed works as advertised. Indeed, I guessed the rule is that every tenth of a degree from 0.1. to 0.4 sharpens by one semitone up to ####, while 0.7 → 0.5 flatten by 1 semitone up to bbb. There are other rules, I guess, which I am still missing.

I have two questions I hope someone may help me with:

  1. Where is the documentation for this behavior? I could not find by searching though the help files. I must be missing something important in how I read the docs.
  2. Does this coercion of fractions to a symbolic representation of accidentals (n.1 = #, n.2= ##) holds in general, when possibly different scales are used? I tried to find a complete discussion of Pbind’s \degree and indeed of all the keys to bind and their possible interactions and I fell short.

Suggestions greatly appreciated.

1 Like

I think its here in the source for SimpleNumber

		degreeToKey { |scale, stepsPerOctave = 12|
		var scaleDegree = this.round.asInteger;
		var accidental = (this - scaleDegree) * 10.0;
		^scale.performDegreeToKey(scaleDegree, stepsPerOctave, accidental)

and from the source for Scale

	performDegreeToKey { | scaleDegree, stepsPerOctave, accidental = 0 |
		var baseKey;
		stepsPerOctave = stepsPerOctave ? tuning.stepsPerOctave;
		baseKey = (stepsPerOctave * (scaleDegree div: this.size)) + this.wrapAt(scaleDegree);
		^if(accidental == 0) { baseKey } { baseKey + (accidental * (stepsPerOctave / 12.0)) }

So you see that the tenths of a degree translate to steps per octave - so for pentatonic scales in a 12-note domain the tenths will indeed be semitones.

you will want to familiarize yourself with the source for Event which contains all the pitch and duration functions for the default Event…

Here is the relevant part:

Scale Degrees

Integer numbers as scale degrees supports accidentals notation by adding the suffixes s for sharp and b for flat. Accidentals are represented as floating point values.

2s == 2.1 // scale degree two, sharp

2b == 1.9 // scale degree two, flat

2ss == 2.2 // scale degree two, double sharp

2bb == 1.8 // scale degree two, double flat

Up to four:

2ssss == 2.4

2bbbb == 1.6

With negative scale degrees it reverses:

-2s == -1.9

-2b == -2.1

-2ss == -1.8

-2bb == -2.2

Accidentals can also specify cents deviation up to 499 cents:

2b50 == 1.95 // scale degree two, fifty cents flat

2s204 == 2.204 // scale degree two, 204 cents sharp

1 Like

The reason why it isn’t is this:

Take a harmonic minor scale: 0 C, 1 D, 2 Eb, 3 F, 4 G, 5 Ab, 6 Bn, 7 C etc.

Then, using equal division of the scale steps, the accidentals would be C#/Db = 0.5, En = 2.5, F#/Gb = 3.5, An = 5.333333, and Bb = 5.66666667.

A melodic figure G An Bn would be 4, 5.333333, 6.

Now you want to transpose this down by one scale degree: 3, 4.33333333, 5 where 4.3333333 is… 1/3 of the way between G and Ab?

That might sound cool actually, but it’s well outside of the western music theory on which the scale is based. So “divide the scale degree equally” isn’t a useful encoding if you want to implement diatonic transposition.

(Now, transposing an original [4, 5s, 6] to [3, 4s, 5] = F, G#, Ab is also dodgy and composers would adjust for that… but I think numerically it’s easier to parse than the largely meaningless “a third of a scale degree.”)


Thanks! I’ll admit the s/b notation makes a lot more sense to me, old geezer that I am. I will use that tone from now on. I’ll admit also that I would have never thought scale degrees would be considered a literal on their own merits (I mean, they definitely look very much like integers…). SuperCollider is indeed a strange beast. Strange and fascinating.

(Because no one has mentioned this yet, and it can be confusing…)
The degree key of Event refers to the degree on a scale, as specified by the \scale key of Event. By default, this is Scale.major. This probably makes the 1b and 1s notation for sharps/flats even less useful, since the amount this sharpens/flattens a particular note probably depends on the steps of the particular scale it’s in.

The Event system does a lot of work to make common music theory transformations very easy - great for me, a know-nothing about music theory, but possibly distracting for anyone who’s used to doing these transformations in their head. It’s easy to use any of this or none of it at all, but it’s worth looking carefully at the source for Event to see how various keys like \degree, \octave etc. are transformed finally into a raw frequency value.

Specifically, look for pitchEvent in (, which contains all the pitch-related details. You can follow the trail backwards from freq to see how it is calculated from ~midinote, ~ctranspose, ~degree, ~scale etc. You can override any of these keys in a Pbind to inject your own values into that part of the calculation - for example, if you don’t want to work using degrees on a scale, you can specify \note and figure out the scale details yourself.

You can even replace these with functions in case, for example, you truly wanted to use notation like [“C”, “C#”, “D”] - then you might have:

   \degree, Pseq(["C", "C#", "D"], inf),
   \note, {
        switch (~degree, 
           "C", 0,
           "C#", 1
           "D", 2,
           // ...

Not quite. In fact, you’re describing exactly the problem with the “divide the scale degree equally” encoding – (degree + 0.5) does change meaning based on the number of semitones between degree and degree + 1.

In the current definition, 1s is always the second scale degree raised by exactly one semitone. In C major, this is D#, halfway between D and E. In C minor, this is still D# but now it’s enharmonically equivalent to the third degree, Eb.

SC mirrors this enharmonic equivalence – I’m not at my computer now so I can’t check it, but I’d expect (degree: 1s, scale: Scale.major) and (degree: 1s, scale: Scale.minor) to play the same pitch. (2b would resolve differently in major and minor because the third degree is in a different position.)

This means that s and b notation is specifically useful for situations where the scale degrees are not all equivalent.

I sometimes say that half of algorithmic composition is data representation. If you represent pitch in a way that is clunky for the operations you want to perform, then algorithmic composition becomes painful to code.

Twelve-tone composers would prefer a chromatic representation because they’re working with intervals defined in terms of semitones.

But if I want to pull a Debussy and slide triads around a scale, then chromatic representation means doing a lot of extra work to decide when a triad should be major, minor or diminished (this is what’s distracting!)… but it’s trivially easy in a diatonic encoding: \degree, somePattern + [0, 2, 4] and done. Data encoding matters.

Events are one of the really great features in SC btw. Separating musical data from the specific actions to be taken on them is a brilliant move and I’ve gotten a lot of mileage out of that.


1 Like

Ah, the way this is implemented is unexpected (for me), but also probably makes musical sense. Here’s something I just now discovered because of your post - this highlights how I (mis-)understand music theory from a very non-formal background…

Locally, the equivalence you mentioned doesn’t hold for me - these two freqs are not equal. This is because I had a local modification to performDegreeToKey and related methods that interprets non-integer degree values as interpolated along the specified scale - meaning degree: 2.5 is half-way between degree: 2 and degree: 3. I did this because without this, it’s impossible to (easily) produce glissando’s between notes in a scale, because there are discontinuous jumps. This clearly breaks the sharp/flat notation (something I don’t use or really understand :slight_smile: so I’ll probably keep my modification).
This interpretation seems musically sensible for anyone who is used to thinking in terms of sharps/flats, accidentals etc., but complete nonsense to someone (like myself) who thinks of degrees … as numeric values that can be mapped to frequencies via a Scale.

I was recently reading through a nice sort of summary document on chord construction, scales, etc., to reinforce my own knowledge a bit. Something I discovered is that - lots of common musical operations and transformations that I thought I didn’t understand enough to really make use of were actually trivially easy using the Event mechanisms in a very naive way. I was making things MUCH more complicated for myself than they needed to me.

The chromatic system was kind of bolted-on the an older diatonic scheme without accidentals. Originally people were tuning the scale by interval beginning with the 3/2 interval for a fifth and the 5/4 interval for a major third. By composing these you can get a complete 7 note system with perfect major chords (\pythagorean in sclang).

The problem started when ppl wanted to have analogous harmonic movements - just as they could proceed from a chord built on 5 to a chord built on 1 they wanted to proceed from a chord built on the 5 of 5 (2) to 5. and the problem there is that moving from 5-1 the third of 5 (15/16) moves to the 1 of 1 (2) and there is no such relative to 5. so a tone was added to give 15/16 of 3/2. these kinds of tones were called “musica ficta” - they weren’t conceived as being “half-way-between” the other tones, they are borrowed from different roots. And the resulting collection was not intended as a continuum. You would never hear consecutive semitone movements in the Renaissance for example. F# in c was always resolving to g with e below, and bb was always resolving to a with c above.

Sadly the idea of 12 equal tones is ultimately not compatible with forming major chords which are in tune, for example and there are no end of different “solutions” to the problem! The current equal temperament is really recent (20th C IIRC). Ideally, depending on their harmonic function, the in-between notes ought to be a little different! Between d and e for example you can find a note which is the 7th degree of a scale built on e (d#) or the 4th degree of a scale built on b-flat (eb) - and, in the context of c, these are different frequencies. I imagine an ideal system would write all the pitches functionally, in terms of roots. so f# would be 3of5of5 or rather than 4.5of1 !

Computers may give us an advance over the previous generation of tech in terms of scales (the chromatic keyboard).

but to return to the topic: the representation of sharps and flats as tenths corresponding to semitones is unlovely I think! 1.2 has a pretty well established conventional meaning and asking users to understand it differently in this context is asking a lot…

I think what confused me—and sparked this topic—is that the notations for degrees seem like numbers, but they are not. They are symbolic representations. I would not have been confused if the notation had been something like \degree, [I, III, V], unwieldy as that may be for the interpreter to actually manipulate.
In the end, I think adding a line to the Pbind section of the (truly outstanding) Pattern tutorial that indicates how to notate sharps and flats may save beginners like me a lot of headaches.

You’re an optimist—I still remember the very first sentence of my very first computer science class: programs are data representations plus algorithms. And data representations is always 70% of the problem.

That’s true in 5-limit just intonation, but the Pythagorean major third is 81/64, not 5/4.

If I recall music history classes correctly, musica ficta arises from an extension of the two-part cadence [D B] → [C C’] (where D is lower and N is a sixth higher) up to three parts. Fourths above the lowest note were discouraged (and still are, in tonal practice), so they didn’t want D G B → C G C’. That leaves D F B → C G C’ (at this time, ending with a third wouldn’t have been ok either), but the tritone F B was also not recommended at that time – so performers would commonly raise the F to what we now call F#. If the sharp hadn’t been notated then it would be ficta.

The idea of “V/V” originates a few hundred years after this. (Rameau is usually credited with formulating the common-practice tonal system based on root movement, but of course composers had been doing it before then.)

There are exceptional Renaissance composers who pushed chromaticism to a rather far limit (Gesualdo for instance).

I’d disagree that 1.2 has a clearly defined meaning for scale degrees, but… one of the nice things about events in SC is that they leave you the freedom to define your own way. James McCartney’s implementation isn’t a prison – it’s only one of many possible ways, and the event system doesn’t force you into anything.


If we’re really heading into the weeds, our Rennaisance forbears thought in terms of hexachords built on G C and F. To gain the leading tone into G (in whatever variety of contrapuntal situations it felt necessary) they borrowed F# from the hexachord built on D. D being to G as G is to C. They really did call it the third degree of D rather than half way between the fourth and fifth degrees in C! (just as they thought of b as the third degree of G rather than the seventh degree of C.

In the case of b and bb both were available - b was the third degree from G and bb the fourth from F. It’s an interesting scheme!

I guess my fantasy language would be agnostic in regards to scales and degrees etc. just wanted to point out that the idea that scales are subsets of a static larger chromatic collection is recent and has its problems.

I’d put the stuff in the default Event in a quark if I could go back in time…

Again, I think this is assigning too much importance to the default event prototype.

It isn’t the event system.

There is a default event prototype. If you don’t like the way the default event behaves, write a different prototype, and voilà, events behave your way.

If you use the default prototype, you can use as much or as little of it as you want. Scales and degrees are available but you can bypass them.

Except for s and b notation (the use of which is also not forced), the language itself is agnostic. You’re never forced at any time to use Scale or degreeToKey, and you are always free to write your own functions, classes or methods to map pitches however you choose.

I think it’s not quite right to think of the inbuilt methods as being “more natively SC” than other ways. They’re provided as a convenience, but SC is designed to be much more free about pitch than, say, a DAW that basically enforces 12ET by depending on MIDI.

Thanks for the refresher on Renaissance theory – sure, a third from D makes sense. I was just saying that the terminology V/V hadn’t been standardized yet (even though Renaissance theory was already arriving at that result via a different framework).


1 Like