From bgruber at nyu.edu Fri Jun 1 08:20:31 2007 From: bgruber at nyu.edu (bgruber) Date: Fri, 01 Jun 2007 04:20:31 -0400 Subject: [gsharp-devel] saving score Message-ID: <465FD6CF.9010208@nyu.edu> well, the summer of code is in full swing, and no sooner have a I dug myself into the gsharp code than I find myself stuck in a hole - I can't open gsharp scores that I save. Looking into it further, I discovered that the problem is with the actual scores themselves. I've attached a copy of a simple, one-note score. You can see that in some places the class names are being printed after the first slot, like GSHARP-BUFFER:FIVELINE-STAFF here: :staves (#1=[ :name "default staff" GSHARP-BUFFER:FIVELINE-STAFF :clef [:name :TREBLE GSHARP-BUFFER:CLEF :lineno 2 ] changing this (and similar errors) I can load up the file, so it's not stopping me in my tracks nearly as much as I thought. /brian -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: badscore.gsh URL: From csr21 at cantab.net Sat Jun 2 14:58:49 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Sat, 02 Jun 2007 15:58:49 +0100 Subject: [gsharp-devel] saving score In-Reply-To: <465FD6CF.9010208@nyu.edu> (bgruber@nyu.edu's message of "Fri, 01 Jun 2007 04:20:31 -0400") References: <465FD6CF.9010208@nyu.edu> Message-ID: <87abvi2yja.fsf@cantab.net> bgruber writes: > You can see that in some places the > class names are being printed after the first slot, like > GSHARP-BUFFER:FIVELINE-STAFF here: > > :staves (#1=[ > :name "default staff" GSHARP-BUFFER:FIVELINE-STAFF > :clef [:name :TREBLE GSHARP-BUFFER:CLEF :lineno 2 ] > > changing this (and similar errors) I can load up the file, so it's not > stopping me in my tracks nearly as much as I thought. Thanks. I've merged a fix for this into gsharp CVS: GSHARP-BUFFER:PRINT-GSHARP-OBJECT now has an :AROUND method to print the class name, rather than just a regular method; additionally, the function's method-combination has been changed to progn without the :most-specific-last flag, in order that a subclass can override a superclass's initarg if desired, simply by printing to the stream first (this second change is entirely theoretically motivated at the moment). I hope it now works better... Cheers, Christophe From magnus at smartelectronix.com Wed Jun 13 14:02:09 2007 From: magnus at smartelectronix.com (Magnus Jonsson) Date: Wed, 13 Jun 2007 10:02:09 -0400 (EDT) Subject: [gsharp-devel] Hello! Message-ID: Hi everyone (how many devs are there?), As Robert Strandh and Christophe Rhodes already know I have expressed interest in contributing to Gsharp. Specifically I want to add microtonal support. To start with I will mostly touch the midi back-end. This will be enough to add support for tunings that need only sharps and flats. That will cover most of the tunings that have been popular in European history. If that works out well I may also consider adding support for additional accidentals that are needed for modern microtonalists and non-European music. Right now I'm mostly familiarizing myself with the code. I've found a few things that maybe should be fixed: * in gsharp.asd, add :esa to the :depends-on list * in play.lisp, one play function using "/tmp/test.mid" while the other one uses "test.mid"? * in play.lisp, the function measure-durations duplicates code in buffer.lisp -- the (defmethod duration ((bar bar)) ...) I don't have CVS access yet so I cannot fix them myself yet. I have requested CVS access on common-lisp.net but that may take a few days so I'm posting here for now. If no-one disagrees with my idea to add microtonal support I hope we'll have fun working Gsharp together. I added some limited microtonal support to ABC before and looked at adding support to Lilypond too, but none of those two have as clean internals as Gsharp from what I've seen so far! /Magnus Jonsson From csr21 at cantab.net Thu Jun 14 06:08:31 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Thu, 14 Jun 2007 07:08:31 +0100 Subject: [gsharp-devel] Hello! In-Reply-To: (Magnus Jonsson's message of "Wed, 13 Jun 2007 10:02:09 -0400 (EDT)") References: Message-ID: <87sl8voyow.fsf@cantab.net> Magnus Jonsson writes: > * in gsharp.asd, add :esa to the :depends-on list Ah, I'm not sure about this. I suspect that maybe wonkiness that you're seeing here is attempting to combine a CVS version of gsharp with a released version of McCLIM? The catch is that in CVS versions of McCLIM itself, ESA is now a part of the mcclim system, and not a separate entity any more -- so adding :esa to gsharp's :depends-on is likely wrong -- at least, it wouldn't work for me. Maybe it might be a good idea to prod the McCLIM developers into making a new release... > * in play.lisp, one play function using "/tmp/test.mid" while the > other one uses "test.mid"? > * in play.lisp, the function measure-durations duplicates code in > buffer.lisp -- the (defmethod duration ((bar bar)) ...) Right, these are issues. > If no-one disagrees with my idea to add microtonal support I hope > we'll have fun working Gsharp together. I think this is a very interesting project, and I'm looking forward to seeing what happens! Cheers, Christophe From magnus at smartelectronix.com Sat Jun 16 10:50:40 2007 From: magnus at smartelectronix.com (Magnus Jonsson) Date: Sat, 16 Jun 2007 06:50:40 -0400 (EDT) Subject: [gsharp-devel] Microtones Message-ID: Hello all, 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). 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 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. / Magnus -------------- next part -------------- cvs diff: Diffing . Index: buffer.lisp =================================================================== RCS file: /project/gsharp/cvsroot/gsharp/buffer.lisp,v retrieving revision 1.45 diff -u -d -r1.45 buffer.lisp --- buffer.lisp 15 Jun 2007 16:26:14 -0000 1.45 +++ buffer.lisp 16 Jun 2007 10:34:25 -0000 @@ -987,7 +987,8 @@ ((print-character :allocation :class :initform #\S) (buffer :initform nil :initarg :buffer :accessor buffer) (layers :initform '() :initarg :layers :accessor layers) - (tempo :initform 128 :initarg :tempo :accessor tempo))) + (tempo :initform 128 :initarg :tempo :accessor tempo) + (tuning :initform nil :initarg :tuning :accessor tuning))) (defmethod initialize-instance :after ((s segment) &rest args &key staff) (declare (ignore args)) Index: gsharp.asd =================================================================== RCS file: /project/gsharp/cvsroot/gsharp/gsharp.asd,v retrieving revision 1.15 diff -u -d -r1.15 gsharp.asd --- gsharp.asd 31 Jan 2007 15:25:04 -0000 1.15 +++ gsharp.asd 16 Jun 2007 10:34:25 -0000 @@ -37,6 +37,7 @@ "cursor" "input-state" "modes" + "tuning" "play" "gui" "fontview") Index: packages.lisp =================================================================== RCS file: /project/gsharp/cvsroot/gsharp/packages.lisp,v retrieving revision 1.59 diff -u -d -r1.59 packages.lisp --- packages.lisp 31 Jan 2007 15:25:04 -0000 1.59 +++ packages.lisp 16 Jun 2007 10:34:31 -0000 @@ -73,7 +73,7 @@ #:layer #:lyrics-layer #:melody-layer #:bars #:nb-bars #:barno #:add-bar #:remove-bar #:slice #:make-slice - #:segment #:tempo #:slices #:sliceno + #:segment #:tempo #:tuning #:slices #:sliceno #:make-layer-for-staff #:make-bar-for-staff #:head #:body #:tail #:make-layer #:buffer #:layers #:nb-layers #:layerno @@ -168,9 +168,13 @@ (:shadowing-import-from :gsharp-buffer #:rest) (:export #:draw-buffer #:draw-the-cursor)) +(defpackage :gsharp-tuning (:use :common-lisp :gsharp-buffer) + (:shadowing-import-from :gsharp-buffer #:rest #:tuning) + (:export #:tuning #:note-cents #:linear-tuning)) + (defpackage :gsharp-play - (:use :common-lisp :midi :gsharp-buffer) - (:shadowing-import-from :gsharp-buffer #:rest) + (:use :common-lisp :midi :gsharp-buffer :gsharp-tuning) + (:shadowing-import-from :gsharp-buffer #:rest #:tuning) (:export #:play-layer #:play-segment #:play-buffer)) Index: play.lisp =================================================================== RCS file: /project/gsharp/cvsroot/gsharp/play.lisp,v retrieving revision 1.6 diff -u -d -r1.6 play.lisp --- play.lisp 15 Jun 2007 16:26:14 -0000 1.6 +++ play.lisp 16 Jun 2007 10:34:31 -0000 @@ -1,16 +1,15 @@ (in-package :gsharp-play) +(defvar *tuning*) +(defvar *tempo*) + (defun midi-pitch (note) - (+ (* 12 (+ (floor (pitch note) 7) 1)) - (ecase (mod (pitch note) 7) (0 0) (1 2) (2 4) (3 5) (4 7) (5 9) (6 11)) - (ecase (accidentals note) - (:double-flat -2) - (:flat -1) - (:natural 0) - (:sharp 1) - (:double-sharp 2)))) + (round (note-cents note *tuning*) 100)) -(defvar *tempo*) +(defun cents-adjustment (note) + (multiple-value-bind (midi-pitch cents-adjustment) + (midi-pitch note) + cents-adjustment)) (defun measure-durations (slices) (let ((durations (mapcar (lambda (slice) @@ -21,16 +20,37 @@ collect (reduce #'max (mapcar #'car durations)) do (setf durations (remove nil (mapcar #'cdr durations)))))) +(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)))))) + (mapcar (lambda (note) (make-instance 'note-on-message - :time time + :time time :status (+ #x90 channel) :key (midi-pitch note) :velocity 100)) (remove-if #'tie-left (notes element))) - (mapcar (lambda (note) - (make-instance 'note-off-message + (mapcar (lambda (note) + (make-instance 'note-off-message :time (+ time (* *tempo* (duration element))) :status (+ #x80 channel) :key (midi-pitch note) :velocity 100)) @@ -55,6 +75,8 @@ (let* ((slices (mapcar #'body (layers segment))) (durations (measure-durations slices)) (*tempo* (tempo segment)) + (*tuning* (or (gsharp-buffer:tuning segment) + (make-instance 'linear-tuning :octave-cents 1200 :fifth-cents 700))) (tracks (loop for slice in slices for i from 0 collect (track-from-slice slice i durations))) @@ -85,4 +107,3 @@ (sb-ext:run-program "timidity" '("/tmp/test.mid") :search t) #-(or cmu sbcl) (error "write compatibility layer for RUN-PROGRAM"))) - Index: tuning.lisp =================================================================== RCS file: tuning.lisp diff -N tuning.lisp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tuning.lisp 16 Jun 2007 10:34:32 -0000 @@ -0,0 +1,49 @@ +(in-package :gsharp-tuning) + +(defclass tuning () + ()) + +(defgeneric note-cents (note tuning)) + +(defclass linear-tuning (tuning) + ((octave-cents :initform 1200 :initarg :octave-cents :accessor octave-cents) + (fifth-cents :initform 700 :initarg :fifth-cents :accessor fifth-cents))) + +(defmethod note-cents ((note note) (tuning linear-tuning)) + (let ((accidentals (ecase (accidentals tuning) + (:double-flat -2) + (:flat -1) + (:natural 0) + (:sharp 1) + (:double-sharp 2)))) + (multiple-value-bind (octave pitch) (floor (pitch note) 7) + (+ (* (octave-cents tuning) + (+ (1+ octave) + (ecase pitch (0 0) (1 -1) (2 -2) (3 1) (4 0) (5 -1) (6 -2)) + (* -5 accidentals))) + (* (fifth-cents tuning) + (+ (ecase pitch (0 0) (1 2) (2 4) (3 -1) (4 1) (5 3) (6 5)) + (* 7 accidentals))))))) + +(defmethod note-cents ((note note) (tuning linear-tuning)) + (let ((octave-cents (octave-cents tuning)) + (fifth-cents (fifth-cents tuning))) + (multiple-value-bind (octave pitch) (floor (pitch note) 7) + (+ (* octave-cents (1+ octave)) + (ecase pitch + (0 0) + (1 (+ (* -1 octave-cents) (* 2 fifth-cents))) + (2 (+ (* -2 octave-cents) (* 4 fifth-cents))) + (3 (- octave-cents fifth-cents)) + (4 fifth-cents) + (5 (+ (* -1 octave-cents) (* 3 fifth-cents))) + (6 (+ (* -2 octave-cents) (* 5 fifth-cents)))) + (* (ecase (accidentals note) + (:double-flat -2) + (:flat -1) + (:natural 0) + (:sharp 1) + (:double-sharp 2)) + (- (* 7 fifth-cents) + (* 4 octave-cents))))))) + \ No newline at end of file cvs diff: Diffing Doc cvs diff: Diffing Flexichain cvs diff: Diffing Flexichain/Doc cvs diff: Diffing Fonts cvs diff: Diffing Obseq cvs diff: Diffing Scores From csr21 at cantab.net Sat Jun 16 14:52:58 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Sat, 16 Jun 2007 15:52:58 +0100 Subject: [gsharp-devel] Microtones In-Reply-To: (Magnus Jonsson's message of "Sat, 16 Jun 2007 06:50:40 -0400 (EDT)") References: Message-ID: <87d4zwx86t.fsf@cantab.net> Magnus Jonsson 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...) > 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 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?) I released on Tuesday an updated version of midi.lisp incorporating patches from Magnus which got pitch-bend events a little bit more right... > 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... > +(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)) > +(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 :-) > +(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... 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). 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? :-) > +(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. Cheers, Christophe From magnus at smartelectronix.com Sat Jun 16 16:49:13 2007 From: magnus at smartelectronix.com (Magnus Jonsson) Date: Sat, 16 Jun 2007 12:49:13 -0400 (EDT) Subject: [gsharp-devel] Microtones In-Reply-To: <87d4zwx86t.fsf@cantab.net> References: <87d4zwx86t.fsf@cantab.net> Message-ID: On Sat, 16 Jun 2007, Christophe Rhodes wrote: > Magnus Jonsson 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 From csr21 at cantab.net Sat Jun 16 18:26:38 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Sat, 16 Jun 2007 19:26:38 +0100 Subject: [gsharp-devel] Microtones In-Reply-To: (Magnus Jonsson's message of "Sat, 16 Jun 2007 12:49:13 -0400 (EDT)") References: <87d4zwx86t.fsf@cantab.net> Message-ID: <873b0rycv5.fsf@cantab.net> Magnus Jonsson writes: > On Sat, 16 Jun 2007, Christophe Rhodes wrote: > >> Magnus Jonsson 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. Something like, for instance, (in-package :gsharp) (define-gsharp-command (com-set-tuning :name t) ((tuning '(member :12-edo :quarter-comma :fifth-comma :sixth-comma))) (let ((segment (segment (current-cursor)))) (setf (tuning segment) (find-tuning tuning)))) Where you probably need to define FIND-TUNING (see below). >>> 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. Right, but I'm afraid I wasn't clear enough -- or at least, I think that we'd probably be better served defining some objects with useful introspective properties, rather than bare symbols. So for instance, from a little bit of Wikipedia browsing, there's this hierarchy that I'm expecting to see shredded to bits... regular-temperament p-limit-just-temperament twelve-edo linear-temperament miracle-temperament ... ... We don't necessarily need to add all of these at once, but one thing that we probably /do/ need to think about is saving and loading these things. A TUNING probably needs to inherit from GSHARP-OBJECT, and have a method for saving its slots via PRINT-OBJECT / PRINT-GSHARP-OBJECT (and the method for SEGMENT needs similarly to be adjusted). The idea, however, would be that if the tuning object representing 12-EDO could be of the same general class as one representing a linear-temperament, then the saving and loading code is probably a lot simpler. FIND-TUNING then is a fairly thin wrapper about MAKE-INSTANCE on these classes. (As far as I can tell, despite our previous discussion, 12-EDO is not a linear temperament, as a linear-temperament has two independent generators, one of which is the octave, whereas 12-EDO only has the ET-semitone -- but be careful with believing anything I say; my exposure to mathematical properties and categorization of tuning systems is very recent, limited to one conference I attended last month). >> (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. One layer corresponds to one voice, yes; you get polyphony in the multiple-voice sense by having multiple layers, so for that what you have is enough (to experiment, you can do M-x Add Layer, to get two layers on one staff). The catch is that you can also get simultaneities in a single layer, for e.g. keyboard music; to see that, use capital note-name letters to add notes to the current cluster; these wouldn't be representable with the proposed implementation. (I'm here thinking of notational examples like that at the top of ) > This reminds me that the play-buffer command is unimplemented. What is > the difference between play-buffer and play-segment? I'll have to defer to Robert here, but my understanding is that a buffer is intended to be made up of a sequence of segments, a segment being a sufficiently homogeneous section of musical material that it makes sense to consider it as having some constant properties (when it comes to layout, and so on). >> 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. Linear temperament, yes -- but that's unfortunately not the same as "linear tuning", as far as my limited understanding of the classification goes. > 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). OK, summarizing my understanding here (so correct me if I'm wrong): what's going on here is that putting the origin at a given note, from the fifth and the octave we can generate the other notes by moving around the helix of fifths (it's not a circle unless we've especially arranged that 12*fifth = 7*octave, where those are measured in cents). Which means that my question about "which key are we in?" is almost misguided -- that is, the frequencies of C-D-E-F-G-A-B-C are a constant multiple of those of D-E-F#-G-A-B-C#-D -- the reason that it's not totally misguided is that one of these tunings which arranges that the A above middle C is 440Hz is a constant frequency multiple away from, say, one which arranges that the D above middle C is 293.66 (its 12-EDO value). Cheers, Christophe From csr21 at cantab.net Sat Jun 16 21:25:24 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Sat, 16 Jun 2007 22:25:24 +0100 Subject: [gsharp-devel] some microtonal glyphs Message-ID: <87y7ijwq0r.fsf@cantab.net> Here's a beginning along a different path towards an all-singing all-dancing microtonally enhanced gsharp: some glyphs, implementation of which was suitable for a lazy evening's doodling.) These are the Mildred Couper-like sesquiflat (and a semiflat derived from it): just the glyphs, no UI / placement / saving support. Enjoy, Christophe -------------- next part -------------- A non-text attachment was scrubbed... Name: semisesquiflat.diff Type: text/x-diff Size: 3624 bytes Desc: flat glyphs URL: From strandh at labri.fr Sun Jun 17 08:47:17 2007 From: strandh at labri.fr (Robert Strandh) Date: Sun, 17 Jun 2007 10:47:17 +0200 Subject: [gsharp-devel] Microtones In-Reply-To: <873b0rycv5.fsf@cantab.net> References: <87d4zwx86t.fsf@cantab.net> <873b0rycv5.fsf@cantab.net> Message-ID: <18036.62741.696788.764624@serveur5.labri.fr> Christophe Rhodes writes: > > This reminds me that the play-buffer command is unimplemented. What is > > the difference between play-buffer and play-segment? > > I'll have to defer to Robert here, but my understanding is that a > buffer is intended to be made up of a sequence of segments, a segment > being a sufficiently homogeneous section of musical material that it > makes sense to consider it as having some constant properties (when it > comes to layout, and so on). Right. There is no particular reason not to have a play-buffer command. -- Robert Strandh --------------------------------------------------------------------- Greenspun's Tenth Rule of Programming: any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp. --------------------------------------------------------------------- From magnus at smartelectronix.com Sun Jun 17 16:55:29 2007 From: magnus at smartelectronix.com (Magnus Jonsson) Date: Sun, 17 Jun 2007 12:55:29 -0400 (EDT) Subject: [gsharp-devel] Microtones In-Reply-To: <873b0rycv5.fsf@cantab.net> References: <87d4zwx86t.fsf@cantab.net> <873b0rycv5.fsf@cantab.net> Message-ID: On Sat, 16 Jun 2007, Christophe Rhodes wrote: > Right, but I'm afraid I wasn't clear enough -- or at least, I think > that we'd probably be better served defining some objects with useful > introspective properties, rather than bare symbols. > > So for instance, from a little bit of Wikipedia browsing, there's this > hierarchy that I'm expecting to see shredded to bits... > > regular-temperament > p-limit-just-temperament > twelve-edo > linear-temperament > miracle-temperament At first that seems like a good idea, but on second thought I think a simpler approach is better because otherwise we will run up against the hairy mess that is tuning theory. If we are this careful about classification perhaps twelve-edo should be an equal-temperament. But even with equal temperaments we will have to specify the size of a fifth (because there can be multiple valid choices, especially in high cardinality equal temperaments) and the "octave", ie what it is an equal division of. So it ends up looking very much like linear temperaments anyway. And Western staff notation is based on the assumption of a linear temperament or something resembling it. With the introduction of additional accidentals the sizes of those accidentals will also have to be specified in the tuning as there may be multiple valid choices. I think the distinction between regular and irregular temperaments is the only important one for gsharp. For regular temperaments it should be enough to specify what the sizes of the octave, the fifth and microtonal accidentals are. The user interested in exploring and creating tunings can use other programs such as scala to calculate the various sizes. For irregular temperaments something more complicated is needed. I haven't thought enough about them to say what is needed and I am not currently very interested in them either. > We don't necessarily need to add all of these at once, but one thing > that we probably /do/ need to think about is saving and loading these > things. A TUNING probably needs to inherit from GSHARP-OBJECT, and > have a method for saving its slots via PRINT-OBJECT / > PRINT-GSHARP-OBJECT (and the method for SEGMENT needs similarly to be > adjusted). The idea, however, would be that if the tuning object > representing 12-EDO could be of the same general class as one > representing a linear-temperament, then the saving and loading code is > probably a lot simpler. FIND-TUNING then is a fairly thin wrapper > about MAKE-INSTANCE on these classes. It will probably be good to be able to load/save tunings independently of the song they are in too. I will try to understand how the loading/saving works in gsharp. > (As far as I can tell, despite our previous discussion, 12-EDO is not > a linear temperament, as a linear-temperament has two independent > generators, one of which is the octave, whereas 12-EDO only has the > ET-semitone -- but be careful with believing anything I say; my > exposure to mathematical properties and categorization of tuning > systems is very recent, limited to one conference I attended last > month). Some choices of octave and fifth coincide with equal temperaments. It is not an either/or thing IMO. For an anology consider the polynomial 1+x. Is it linear or quadratic? It is both. 1+x just doesn't utilize all the freedoms that quadratic equations have. > Linear temperament, yes -- but that's unfortunately not the same as > "linear tuning", as far as my limited understanding of the > classification goes. I will use "temperament" henceforth, thanks for the correction. >> 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). > > OK, summarizing my understanding here (so correct me if I'm wrong): > what's going on here is that putting the origin at a given note, from > the fifth and the octave we can generate the other notes by moving > around the helix of fifths (it's not a circle unless we've especially > arranged that 12*fifth = 7*octave, where those are measured in cents). Correct. There are other possible circles of fifth too, such as those of 31-EDO and 19-EDO which are relatively popular. > Which means that my question about "which key are we in?" is almost > misguided -- that is, the frequencies of C-D-E-F-G-A-B-C are a > constant multiple of those of D-E-F#-G-A-B-C#-D -- the reason that > it's not totally misguided is that one of these tunings which arranges > that the A above middle C is 440Hz is a constant frequency multiple > away from, say, one which arranges that the D above middle C is 293.66 > (its 12-EDO value). Yes, it would be a good idea to store somewhere a reference note pitch and a frequency it should be pinned at. That seems like the most flexible and easy to use way. Should it be stored in the segment alongside the tuning or inside the tuning itself? Cheers, Magnus From csr21 at cantab.net Tue Jun 19 13:31:32 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Tue, 19 Jun 2007 14:31:32 +0100 Subject: [gsharp-devel] some microtonal glyphs In-Reply-To: <87y7ijwq0r.fsf@cantab.net> (Christophe Rhodes's message of "Sat, 16 Jun 2007 22:25:24 +0100") References: <87y7ijwq0r.fsf@cantab.net> Message-ID: <874pl4qde3.fsf@cantab.net> Christophe Rhodes writes: > Here's a beginning along a different path towards an all-singing > all-dancing microtonally enhanced gsharp: some glyphs, implementation > of which was suitable for a lazy evening's doodling.) These are the > Mildred Couper-like sesquiflat (and a semiflat derived from it): just > the glyphs, no UI / placement / saving support. I think I understand how to deal with UI and placement. For placement, I've reworked the great big *accidental-offset* table into something a little more dynamic, effectively kerning arrays keyed by right/left symbol pairs, where it's now possible to have a default array for each right-hand symbol, and a default default array. So placing new accidental glyphs is now straightforwardly possible (if sometimes suboptimal from a typesetting point of view) and improvements to the kerning can be made as and when demand arises. My proposed plan for UI is to use Ctrl-# and Ctrl-@ to microtonally sharpen and flatten the current note, much as # and @ currently sharpen and flatten. For my first cut, this will probably just add in the semiflat/sharp and sesquiflat/sharp; that should shake out what needs doing. One thing that needs doing is working out how these things play, and there I'm definitely not sure what is expected. Magnus? (Also, does anyone know how these beasts relate to what support there is in MusicXML? It would be nice if Brian could support whatever it is that makes most sense.) I attach my current diff. Cheers, Christophe -------------- next part -------------- A non-text attachment was scrubbed... Name: sesquiflat.diff Type: text/x-diff Size: 10428 bytes Desc: accidentals URL: From bgruber at nyu.edu Tue Jun 19 18:29:15 2007 From: bgruber at nyu.edu (bgruber) Date: Tue, 19 Jun 2007 14:29:15 -0400 Subject: [gsharp-devel] some microtonal glyphs In-Reply-To: <874pl4qde3.fsf@cantab.net> References: <87y7ijwq0r.fsf@cantab.net> <874pl4qde3.fsf@cantab.net> Message-ID: <4678207B.5010701@nyu.edu> Christophe Rhodes wrote: > (Also, does anyone know how these beasts relate to what support there > is in MusicXML? It would be nice if Brian could support whatever it > is that makes most sense.) so here's the deal w/ musicxml as best as i've been able to understand it (my experience w/ microtones is fairly limited). first off: musicxml deals w/ presentation and playback as almost entirely separate entities (this is w/ everything). For presentation, there is support for a number of microtonal accidentals: quarter-flat, quarter-sharp, three-quarters-flat, and three-quarters-sharp. also, while i'm talking about accidentals gsharp doesn't have, there is also natural-sharp and natural-flat. finally, musicxml supports a sharp-sharp symbol distinct from double-sharp. i'm assuming that while double-sharp is the x, sharp-sharp is intended to be two sharp symbols. i don't believe i am familiar with when this would be used. as for playback, this is controlled by an "alter" element which states the number of semitones a note should be altered by. as such, to get a quarter sharp you just tell it to alter by .25; a half flat, -.5. as far as musicxml is concerned, any number you can write down here will do. on top of this, there is also support for alternate tuning, which i think works by specifying that a line on the staff represents some completely arbitrary note. i think that's how it works anyhow; it doesn't seem to be the best-documented feature of musicxml. /brian From csr21 at cantab.net Thu Jun 21 21:03:50 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Thu, 21 Jun 2007 22:03:50 +0100 Subject: [gsharp-devel] semisharp and friends now in CVS Message-ID: <87ejk558ax.fsf@cantab.net> Hi, The semisharp (&c) support is now in CVS. The commit message (on gsharp-cvs) provides more detail, but in brief here are the things that could do with fixing: * playing quartertones is only implemented in 12-edo; I don't know how they're meant to be played in other temperaments. * no accidental kerning (other than the default default) is implemented. This is particularly noticeable for the semiflat glyph. * the new glyphs share lots of code with glyphs they're related to, implemented by cut-and-paste. It would be nice to make them share code by sharing code... Enjoy (and please don't make me listen to microtonal music ;-) Cheers, Christophe From magnus at smartelectronix.com Mon Jun 25 14:42:09 2007 From: magnus at smartelectronix.com (Magnus Jonsson) Date: Mon, 25 Jun 2007 10:42:09 -0400 (EDT) Subject: [gsharp-devel] semisharp and friends now in CVS In-Reply-To: <87ejk558ax.fsf@cantab.net> References: <87ejk558ax.fsf@cantab.net> Message-ID: On Thu, 21 Jun 2007, Christophe Rhodes wrote: > The semisharp (&c) support is now in CVS. The commit message (on > gsharp-cvs) provides more detail, but in brief here are the things > that could do with fixing: > > * playing quartertones is only implemented in 12-edo; I don't know how > they're meant to be played in other temperaments. Okay, I will implement it once I find time. Thanks for your great work! It shows the way to add sagittal accidentals later on. Cheers, Magnus From stassats at gmail.com Tue Jun 26 21:12:56 2007 From: stassats at gmail.com (Stas Boukarev) Date: Wed, 27 Jun 2007 01:12:56 +0400 Subject: [gsharp-devel] play.lisp Message-ID: <20070626211256.GA14810@slack> There is a code duplication in play.lisp file in functions play-layer & play-segment. New function should also help to deal with compatibility layer. And I have no timidity, and I think it is beterr to make player changeable. (defvar *midi-player* "timidity") (defvar *midi-player-arguments* nil) (defun play-midi-file (midifile) #+cmu (ext:run-program *midi-player* (list *midi-player-arguments* midifile)) #+sbcl (sb-ext:run-program *midi-player* (list *midi-player-arguments* midifile) :search t) #+clisp (ext:run-program *midi-player* :arguments (list *midi-player-arguments* midifile)) #-(or cmu sbcl clisp) (error "write compatibility layer for RUN-PROGRAM")) -- With Best Regards, Stas. From rm at mh-freiburg.de Tue Jun 26 21:27:44 2007 From: rm at mh-freiburg.de (Ralf Mattes) Date: Tue, 26 Jun 2007 23:27:44 +0200 Subject: [gsharp-devel] play.lisp In-Reply-To: <20070626211256.GA14810@slack> References: <20070626211256.GA14810@slack> Message-ID: <1182893265.6196.7.camel@localhost.localdomain> On Wed, 2007-06-27 at 01:12 +0400, Stas Boukarev wrote: > There is a code duplication in play.lisp file in functions play-layer & play-segment. > New function should also help to deal with compatibility layer. > > And I have no timidity, and I think > it is beterr to make player changeable. > > (defvar *midi-player* "timidity") > (defvar *midi-player-arguments* nil) > > (defun play-midi-file (midifile) > #+cmu > (ext:run-program *midi-player* (list *midi-player-arguments* midifile)) > #+sbcl > (sb-ext:run-program *midi-player* (list *midi-player-arguments* midifile) :search t) > #+clisp > (ext:run-program *midi-player* :arguments (list *midi-player-arguments* midifile)) > #-(or cmu sbcl clisp) > (error "write compatibility layer for RUN-PROGRAM")) > I think that '(list *midi-player-arguments* midifile)' is bogus. When *midi-player-arguments* is set to a list of arguments then the lambda-list of run-program is wrong. You probably want something like (sb-ext:run-program `(,@*midi-player-arguments* ,midifile) ... Cheers, Ralf Mattes From magnus at smartelectronix.com Thu Jun 28 13:02:51 2007 From: magnus at smartelectronix.com (Magnus Jonsson) Date: Thu, 28 Jun 2007 09:02:51 -0400 (EDT) Subject: [gsharp-devel] play.lisp In-Reply-To: <20070626211256.GA14810@slack> References: <20070626211256.GA14810@slack> Message-ID: Thanks for your suggestions Stas! I have now fixed these problems. Please see the changes in the CVS. On Wed, 27 Jun 2007, Stas Boukarev wrote: > There is a code duplication in play.lisp file in functions play-layer & play-segment. > New function should also help to deal with compatibility layer. > > And I have no timidity, and I think > it is beterr to make player changeable. > > (defvar *midi-player* "timidity") > (defvar *midi-player-arguments* nil) > > (defun play-midi-file (midifile) > #+cmu > (ext:run-program *midi-player* (list *midi-player-arguments* midifile)) > #+sbcl > (sb-ext:run-program *midi-player* (list *midi-player-arguments* midifile) :search t) > #+clisp > (ext:run-program *midi-player* :arguments (list *midi-player-arguments* midifile)) > #-(or cmu sbcl clisp) > (error "write compatibility layer for RUN-PROGRAM")) > > From csr21 at cantab.net Thu Jun 28 14:15:14 2007 From: csr21 at cantab.net (Christophe Rhodes) Date: Thu, 28 Jun 2007 15:15:14 +0100 Subject: [gsharp-devel] Re: [gsharp-cvs] CVS gsharp In-Reply-To: <20070628135656.D877343222@common-lisp.net> (mjonsson@common-lisp.net's message of "Thu, 28 Jun 2007 09:56:56 -0400 (EDT)") References: <20070628135656.D877343222@common-lisp.net> Message-ID: <87abukp3m5.fsf@cantab.net> "mjonsson" writes: > Fixed keybinding bug for microsharper. > --- /project/gsharp/cvsroot/gsharp/modes.lisp 2007/06/21 11:14:27 1.24 > +++ /project/gsharp/cvsroot/gsharp/modes.lisp 2007/06/28 13:56:53 1.25 > @@ -84,7 +84,7 @@ > > (set-key 'com-sharper 'cluster-table '((#\#))) > (set-key 'com-flatter 'cluster-table '(#\@)) > -(set-key 'com-microsharper 'cluster-table '((#\# :control))) > +(set-key 'com-microsharper 'cluster-table '((#\# :control :shift))) > (set-key 'com-microflatter 'cluster-table '((#\@ :control :shift))) > (set-key 'com-add-note-c 'cluster-table '(#\C)) > (set-key 'com-add-note-d 'cluster-table '(#\D)) Um, no, this doesn't fix any bug; it might mean that your keyboard now allows you to type microsharps, but mine now doesn't. This really needs to be fixed in mcclim itself; in the interim, could we have both bindings please? (I should have remembered that I've done this before: see the bindings for com-more-sharps...) Cheers, Christophe From magnus at smartelectronix.com Thu Jun 28 14:37:49 2007 From: magnus at smartelectronix.com (Magnus Jonsson) Date: Thu, 28 Jun 2007 10:37:49 -0400 (EDT) Subject: [gsharp-devel] Re: [gsharp-cvs] CVS gsharp In-Reply-To: <87abukp3m5.fsf@cantab.net> References: <20070628135656.D877343222@common-lisp.net> <87abukp3m5.fsf@cantab.net> Message-ID: Okay, I committed a fix. On Thu, 28 Jun 2007, Christophe Rhodes wrote: > "mjonsson" writes: > >> -(set-key 'com-microsharper 'cluster-table '((#\# :control))) >> +(set-key 'com-microsharper 'cluster-table '((#\# :control :shift))) > Um, no, this doesn't fix any bug; it might mean that your keyboard now > allows you to type microsharps, but mine now doesn't. > > This really needs to be fixed in mcclim itself; in the interim, could > we have both bindings please? (I should have remembered that I've > done this before: see the bindings for com-more-sharps...)