[gsharp-devel] Microtones

Magnus Jonsson magnus at smartelectronix.com
Sat Jun 16 16:49:13 UTC 2007


On Sat, 16 Jun 2007, Christophe Rhodes wrote:

> Magnus Jonsson <magnus at smartelectronix.com> writes:
>
>> I have got basic microtonal support working and I have attached a
>> patch of my changes. There is no integration with the GUI yet (and I
>> am not sure how to do that).
>
> As a temporary solution (maybe for your own experimentation rather
> than to commit anything), a simple command such as Set Tuning would
> do?  There wouldn't necessarily be any need for that to be reflected
> graphically.  (In the longer term, it would be nice to develop a
> status area or other representation of certain global properties of
> the score, such as tempo and intended tuning...)

Yes, that would do I guess. I am still not very at home in clim/esa so I 
can't really say.

>> This patch depends on some bugfixes to the midi package that have
>> not been released yet (I sent the needed changes to Christophe, the
>> maintainer of the midi package).
>
> Are we talking about the things earlier this week or new fixes?  (I

New fixes, see below.

> haven't checked my work mail, and probably won't until Monday; if this
> is blocking you from moving forward, could you resend to this list?)

It is not blocking me other than I don't want to commit to CVS something 
that depends on unreleased code. Here are the (small) changes needed:

1) #:pitch-bend-message is missing in the exports list.

2) In define-midi-message pitch-bend-message, change the slots to:
   :slots ((value :initarg :value :reader message-value))

3) Add #:message-value to the exports also.

> I released on Tuesday an updated version of midi.lisp incorporating
> patches from Magnus which got pitch-bend events a little bit more
> right...

I missed some things which became obvious when I started using it.

>> Are the changes and additions in the patch okay with you guys? If so I
>> will commit it to CVS once the midi package has been updated.
>
> I've got some comments below.
>
>> -   (tempo :initform 128 :initarg :tempo :accessor tempo)))
>> +   (tempo :initform 128 :initarg :tempo :accessor tempo)
>> +   (tuning :initform nil :initarg :tuning :accessor tuning)))
>
> It might be nice to have a slightly more symbolic default: a
> designator for twelve-tone equal temperament of some kind?  Or maybe
> NIL is such a default in the context of Common Practice Notation, at
> least in this day and age...

Okay, changed to :12-edo. Twelve equal divisions of the octave. EDO is 
tuning theory jargon.

>> +(defun cents-adjustment (note)
>> +  (multiple-value-bind (midi-pitch cents-adjustment)
>> +      (midi-pitch note)
>> +    cents-adjustment))
>
> Could be written as (nth-value 1 (midi-pitch note))

Neat! Wasn't aware of that one. Common Lisp is truly bloated in a good way 
:)

>> +(defun average (list &key (key #'identity))
>> +  (let ((sum 0)
>> +        (count 0))
>> +    (dolist (elem list)
>> +      (incf count)
>> +      (incf sum (funcall key elem)))
>> +    (/ sum count)))
>> +
>>  (defun events-from-element (element time channel)
>>    (when (typep element 'cluster)
>> -    (append (mapcar (lambda (note)
>> +    (append (list
>> +             (make-instance 'pitch-bend-message
>> +                            :time time
>> +                            :status (+ #xE0 channel)
>> +                            :value (+ 8192 ;; middle of pitch-bend controller
>> +                                      (round
>> +                                       (* 4096/100 ;; 4096 points per 100 cents
>> +                                          ;; midi can only do per-channel pitch bend,
>> +                                          ;; not per-note pitch bend, so as a sad
>> +                                          ;; compromise we average the pitch bends
>> +                                          ;; of all notes in the cluster
>> +                                          (average (notes element)
>> +                                           :key #'cents-adjustment))))))
>
> Ah.  that's a shame.  I think I'd prefer to see, for my own interest,
> at least a mode of midi export which performs as faithful a set of
> adjustments as possible, even if that means losing the
> one-channel-per-layer mode of playing in the presence of
> unequal-tempered tunings.  I realise that this is significantly harder
> -- needing to optimize channel placements for all simultaneities (and,
> more pertinently, all overlaps), but it would also be much, much
> cooler!
>
> (That's not necessarily to say that what you posted is unacceptable --
> just to suggest aiming a little bit higher if possible :-)

Yeah, it would definitely be more cool to do it that way. That may be a 
future revision if an itch develops. As it is now it should at least work 
with 4-voice choir pieces and the likes, right? I haven't learned yet how 
to make polyphonic music in gsharp and how it is represented internally 
but I assume one layer corresponds to one voice.

This reminds me that the play-buffer command is unimplemented. What is the 
difference between play-buffer and play-segment?

>> +(defclass linear-tuning (tuning)
>> +  ((octave-cents :initform 1200 :initarg :octave-cents :accessor octave-cents)
>> +   (fifth-cents :initform 700 :initarg :fifth-cents :accessor fifth-cents)))
>
> I'm not sure (I Am Not A Tuning System Expert), but isn't this a
> log-tuning scale?  Sure, it's linear, but in log-frequency space,
> rather than frequency space...

For some reason tuning theorists call it linear temperament. I agree it is 
confusing.

> I think there might be value in making 12-tone equal temperament a
> separate class, maybe a subclass of linear-tuning (or log-tuning, if
> I'm right about the terminology).

I added a (defmethod note-cents ((note note) (tuning (eq :12-edo))) ...) 
with simpler calculations in it. Is that good enough?

> Could you say what alternative tunings this linear-tuning admits?  For
> instance, if I set fifth-cents to 702, do I get just intonation (and
> if so, which key am I in? :-)

It is quite useful. Starting with your example, you will get pythagorean 
tuning (actually the fifth should be 701.96 cents). You can approximate 
just (or what you call syntonic) intonation by using for example Fb above 
C instead of E above C to approxiamte a pure 4:5 major third. This is, I 
think, what the paper you referenced in your blog talks about. A pure 
minor third above C would be D#. Natural sevenths are approximated by 
double flats, for example G-G'bb approximates 4:7. This is a bit awkward 
to work with, which is why additional accidentals can help.

For middle eastern sound try fifths of around 709 cents. This tuning 
emphasizes natural sevenths and elevenths and thirteens at the expense of 
major and minor thirds.

quarter-comma meantone: 696.578 (renaissance, common on harpsichord)
fifth-comma meantone: 697.65 (transitional)
sixth-comma meantone: 698.37 (mozart used something close to this)

Meantones make good major thirds using the usual spelling (eg C-E) by 
flattening fifths somewhat. They also approximate natural sevenths well 
through augmented sixths (eg C-A#).

Then there's 11th-comma meantone which is the same as the 12-edo of today 
which doesn't make a difference between enharmonic spellings. It has 
horrible major thirds and natural 7ths, but the fifths are pretty good.

A favorite of mine is to stretch the octave slightly in order to not 
compromise the fifth too much but still have sweet thirds: 1201 cents 
octave and 698 cents fifth (anything thereabouts is fine).

>> +(defmethod note-cents ((note note) (tuning linear-tuning))
>> +    (let ((accidentals (ecase (accidentals tuning)
>                                 ^^^^^^^^^^^^^^^^^^^^
> This doesn't look right, but...
>
>> +(defmethod note-cents ((note note) (tuning linear-tuning))
>
> ... you've got a second definition of the method here anyway.

Hah, I was experimenting with different implementations and I was going to 
delete the first one since the second one was clearer :)

/ Magnus



More information about the gsharp-devel mailing list