Re: Chromatic transposition -- a very small starting step
On 9 July 2010 22:35, Carl Sorensen wrote: > Yes, but it's only in LilyPond miscellany, so it's really not important ;) Heh, not important enough to deserve a separate menu node. ;) > BTW, are you OK with me pushing the auto-beaming stuff? Sorry, I was expecting another patch set for some reason, though having just looked, I see most of the issues raised have been dealt with. I'll look at it in more detail later. Cheers, Neil ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 07/10/2010 12:25 PM, Joseph Wakeling wrote: > On second thoughts, it seems like transposition constraints for the > whole of LP could be set by four naturalize-limits: upper and lower > limits respectively for c, e, f, b; and upper and lower limits for > everything else. OK, done. The attached example now contains a "complete" naturalize-pitch which allows the user to define the too-high and too-low rules for e, b and c, f respectively, as well as for the rest of the notes. This allows the definition of a "naturalizeMusicTonal" expression which seems to leave properly-transposed stuff (by Lilypond's defaults) untouched. The aim would be to allow the user to define custom naturalization rules alongside defaults, e.g: \withMusicProperty #'naturalize = ##f % don't employ naturalization, use Lilypond's default % functionality \withMusicProperty #'naturalize = #'chromatic % typical naturalize-music function \withMusicProperty #'naturalize = #'harp % naturalize with nothing > 1/2-tone \withMusicProperty #'naturalize = #'tonal % superfluous since Lilypond 2.13.14+ already handles this, % but if the user wants to be sure ... :-) \withMusicProperty #'naturalize = #((naturalize-limit >= 1) (naturalize-limit < (/ -1 2)) (naturalize-limit >= (/ 1 2)) (naturalize-limit < (/ -1 2))) % custom choice of user (my notation may be wrong here, but it % gives the idea of what the user could do). I see why Lisp is % sometimes referred to as "Lost in sodding parentheses" ... ! Note that the naturalization process could be employed in transposition_mutable() or it could be employed after transposition (if any) has been carried out, so the naturalization rules could be used to enforce style choices anywhere in the composition. e.g. \naturalizeChromatic ... bes8 \naturalizeOff ces % I really, really want this c-flat. \naturalizeOn % default option, same as \naturalizeChromatic There could even be two different music properties (#'naturalize or #'transposition-style?) depending on at what stage one wishes to apply naturalization; or with warnings if untransposed music is nevertheless altered by the naturalization process. Are there any other thoughts for what more needs to be done with the naturalize-pitch function itself? Or is it good to go in terms of hooking into Lilypond ... ? Thanks & best wishes, -- Joe #(define (naturalize-limit lim val) (define (limit a) (lim a val)) limit) #(define (naturalize-pitch p high low higheb lowcf) (let ((o (ly:pitch-octave p)) (n (ly:pitch-notename p)) (a (ly:pitch-alteration p))) (do ((aa 0)) ((= aa a) (ly:make-pitch o n a)) (set! aa a) (cond ((and (higheb a) (or (eq? n 2) (eq? n 6))) (set! a (- a (/ 1 2))) (set! n (+ n 1))) ((and (lowcf a) (or (eq? n 0) (eq? n 3))) (set! a (+ a (/ 1 2))) (set! n (- n 1 (cond ((high a) (set! a (- a 1)) (set! n (+ n 1))) ((low a) (set! a (+ a 1)) (set! n (- n 1 (if (< n 0) (begin (set! o (- o 1)) (set! n (+ n 7 (if (> n 6) (begin (set! o (+ o 1)) (set! n (- n 7))) #(define (naturalize music high low higheb lowcf) (let ((es (ly:music-property music 'elements)) (e (ly:music-property music 'element)) (p (ly:music-property music 'pitch))) (if (pair? es) (ly:music-set-property! music 'elements (map (lambda (x) (naturalize x high low higheb lowcf)) es))) (if (ly:music? e) (ly:music-set-property! music 'element (naturalize e high low higheb lowcf))) (if (ly:pitch? p) (begin (set! p (naturalize-pitch p high low higheb lowcf)) (ly:music-set-property! music 'pitch p))) music)) naturalizeMusic = #(define-music-function (parser location m) (ly:music?) (naturalize m (naturalize-limit >= 1) (naturalize-limit <= -1) (naturalize-limit >= (/ 1 2)) (naturalize-limit <= (/ -1 2 naturalizeMusicHarp = #(define-music-function (parser location m) (ly:music?) (naturalize m (naturalize-limit > (/ 1 2)) (naturalize-limit < (/ -1 2)) (naturalize-limit >= (/ 1 2)) (naturalize-limit <= (/ -1 2 naturalizeMusicTonal = #(define-music-function (parser location m) (ly:music?) (naturalize m (naturalize-limit > 1) (naturalize-limit < -1) (naturalize-limit > (/ 1 2)) (naturalize-limit < (/ -1 2 music = \relative c' { c4 d e g } microphrase = \relative c'' { geses4 geseh ges geh g gih gis gisih gisis } \score { \new Staff { \set Staff.extraNatural = ##f \transpose c ais { \music } \bar ":" \naturalizeMusic \transpose c ais { \music } \bar ":" \naturalizeMusicHarp
Re: Chromatic transposition -- a very small starting step
On 07/10/2010 12:16 PM, Joseph Wakeling wrote: > In principle I can also use these to define custom cases for the notes > c, e, f, b as well; not sure if I should, since the whole point of the > naturalizeMusic function is to kill things like c-flats and e-sharps, > and tonal transposition is already taken care of by Lilypond's default > options. On second thoughts, it seems like transposition constraints for the whole of LP could be set by four naturalize-limits: upper and lower limits respectively for c, e, f, b; and upper and lower limits for everything else. so (naturalize-limit > 1) (naturalize-limit < -1) (naturalize-limit > (/ 1 2)) (naturalize-limit < (/ -1 2)) should cover regular tonal transposition; make it >= and <= to get my naturalizeMusic function. ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 07/09/2010 10:34 PM, Neil Puttock wrote: > Sounds good to me. So, here we go ... (faster to achieve than I expected, thanks to a conversation with a friend who is Scheme-experienced). I've defined a Scheme function "naturalize-limit" which can be used to define limits for different cases, and given two examples -- one where the maximum alteration must be less than a whole tone, and one where the maximum alteration must be less than or equal to 1/2-tone (the old naturalizeMusic). In principle I can also use these to define custom cases for the notes c, e, f, b as well; not sure if I should, since the whole point of the naturalizeMusic function is to kill things like c-flats and e-sharps, and tonal transposition is already taken care of by Lilypond's default options. (Other possible improvements -- getting rid of the (set! ...) functions? My Schemer friend laughed at these...:-) Next step, hooking this into the transpose_mutable() function... :-) #(define (naturalize-limit lim val) (define (limit a) (lim a val)) limit) #(define (naturalize-pitch p high low) (let ((o (ly:pitch-octave p)) (n (ly:pitch-notename p)) (a (ly:pitch-alteration p))) (do ((aa 0)) ((= aa a) (ly:make-pitch o n a)) (set! aa a) (cond ((and (>= a (/ 1 2)) (or (eq? n 2) (eq? n 6))) (set! a (- a (/ 1 2))) (set! n (+ n 1))) ((and (<= a (/ -1 2)) (or (eq? n 0) (eq? n 3))) (set! a (+ a (/ 1 2))) (set! n (- n 1 (cond ((high a) (set! a (- a 1)) (set! n (+ n 1))) ((low a) (set! a (+ a 1)) (set! n (- n 1 (if (< n 0) (begin (set! o (- o 1)) (set! n (+ n 7 (if (> n 6) (begin (set! o (+ o 1)) (set! n (- n 7))) #(define (naturalize music high low) (let ((es (ly:music-property music 'elements)) (e (ly:music-property music 'element)) (p (ly:music-property music 'pitch))) (if (pair? es) (ly:music-set-property! music 'elements (map (lambda (x) (naturalize x high low)) es))) (if (ly:music? e) (ly:music-set-property! music 'element (naturalize e high low))) (if (ly:pitch? p) (begin (set! p (naturalize-pitch p high low)) (ly:music-set-property! music 'pitch p))) music)) naturalizeMusic = #(define-music-function (parser location m) (ly:music?) (naturalize m (naturalize-limit >= 1) (naturalize-limit <= -1))) naturalizeMusicHarp = #(define-music-function (parser location m) (ly:music?) (naturalize m (naturalize-limit > (/ 1 2)) (naturalize-limit < (/ -1 2 music = \relative c' { c4 d e g } microphrase = \relative c'' { geses4 geseh ges geh g gih gis gisih gisis } \score { \new Staff { \set Staff.extraNatural = ##f \transpose c ais { \music } \naturalizeMusic \transpose c ais { \music } \transpose c deses { \music } \naturalizeMusic \transpose c deses { \music } \bar "||" \naturalizeMusicHarp \transpose c ais { \music } \naturalizeMusicHarp \transpose c deses { \music } \bar "||" \break \time 9/4 \microphrase \bar ":" \naturalizeMusic { \microphrase } \bar ":" \naturalizeMusicHarp { \microphrase } \break \transpose c ais { \microphrase } \bar ":" \naturalizeMusic \transpose c ais { \microphrase } \bar ":" \naturalizeMusicHarp \transpose c ais { \microphrase } \break \transpose c deses { \microphrase } \bar ":" \naturalizeMusic \transpose c deses { \microphrase } \bar ":" \naturalizeMusicHarp \transpose c deses { \microphrase } \break \transpose c cih { \microphrase } \bar ":" \naturalizeMusic \transpose c cih { \microphrase } \bar ":" \naturalizeMusicHarp \transpose c cih { \microphrase } } \layout { } } ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 7/9/10 2:34 PM, "Neil Puttock" wrote: > On 9 July 2010 21:02, Joseph Wakeling wrote: >> Neil -- thanks ever so much for the detailed explanations. > > You're welcome. > > I hope what I've said is correct, since Carl's pinched my post and > added it to the Contributor's Guide. :) Yes, but it's only in LilyPond miscellany, so it's really not important ;) BTW, are you OK with me pushing the auto-beaming stuff? Thanks, Carl ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 9 July 2010 21:02, Joseph Wakeling wrote: > Neil -- thanks ever so much for the detailed explanations. You're welcome. I hope what I've said is correct, since Carl's pinched my post and added it to the Contributor's Guide. :) > The transpose_mutable() function seems to be where it's at ... :-) Yep. > I note the following lines which are surely responsible for cleaning up > anything larger than a double flat: Correct. See issue 1009 for the background to the fix (and my post here: http://lists.gnu.org/archive/html/lilypond-devel/2010-02/msg00373.html) > So, thinking about the way to implement the various chromatic > transpositions, what seems natural is that once new_val has been > generated in the transpose_mutable() function, to run through one of the > naturalize-pitch Scheme functions (or perhaps a C++ version of it). Sounds good to me. Cheers, Neil ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
Neil -- thanks ever so much for the detailed explanations. > Take a look at lily/music.cc to see where the transposition takes place. The transpose_mutable() function seems to be where it's at ... :-) I note the following lines which are surely responsible for cleaning up anything larger than a double flat: if (transposed.get_alteration ().abs () > Rational (1,1)) { string delta_str; if (delta.get_alteration ().abs () > Rational (1, 1)) delta_str = (delta.normalized ().to_string () + " " + _ ("(normalized pitch)")); else delta_str = delta.to_string (); warning (_f ("Transposing %s by %s makes alteration larger than double", p->to_string (), delta_str)); transposed = transposed.normalized (); } So, thinking about the way to implement the various chromatic transpositions, what seems natural is that once new_val has been generated in the transpose_mutable() function, to run through one of the naturalize-pitch Scheme functions (or perhaps a C++ version of it). Anyway, first port of call, I'm going to try and implement those toohigh and toolow options for the naturalize-pitch Scheme function... ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 8 July 2010 23:20, Joseph Wakeling wrote: > Can you explain more precisely ... ? This seems like something I should > understand very well in order to provide an effective solution. Context properties (using \set & \unset) are tied to engravers: they provide information relevant to the generation of graphical objects. Since transposition occurs at the music interpretation stage, it has no direct connection with engravers: the pitch of a note is fixed before a notehead is created. Consider the following minimal snippet: { c' } This generates (simplified) a NoteEvent, with its pitch and duration as event properties, (make-music 'NoteEvent 'duration ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 0 0) which the Note_heads_engraver hears. It passes this information on to the NoteHead grob it creates from the event, so the head's correct position and duration-log can be determined once it's ready for printing. If we transpose the snippet, \transpose c d { c' } the pitch is changed before it reaches the engraver (in fact, it happens just after the parsing stage with the creation of a TransposedMusic music object): (make-music 'NoteEvent 'duration (ly:make-duration 2 0 1 1) 'pitch (ly:make-pitch 0 1 0) You can see an example of a music property relevant to transposition: untransposable. \transpose c d { c'2 \withMusicProperty #'untransposable ##t c' } -> the second c' remains untransposed. Take a look at lily/music.cc to see where the transposition takes place. Cheers, Neil ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 07/09/2010 12:09 AM, Neil Puttock wrote: > That sounds like a useful enhancement, except that it would be a music > property rather than a context property, since transposition happens > before translation. Can you explain more precisely ... ? This seems like something I should understand very well in order to provide an effective solution. ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 8 July 2010 22:06, Joseph Wakeling wrote: > On 07/08/2010 10:25 PM, Neil Puttock wrote: > ('original' and 'revised' refer to the original and my version of > naturalizeMusic?) Yes. > So ... other than that it might be nice to have the snippet for 2.12, is > there any contribution that I can meaningfully make to 2.13 with this? > The ensuring-convergence-of-naturalization seems superfluous now, but > the variable determination of maximum alteration might be worthwhile. There's still room for improvement, I think. Have a play around with 2.13.27 to get a feel for how this bugfix changes things. > The reason I was working on this was with the longer-term aim of being > able to have an option to set transposition style in music: > > \set Staff.transpositionStyle = #'chromatic > % what follows will be transposed in chromatic fashion > > \set Staff.transpositionStyle = #'tonal > % tonal transposition > > \set Staff.transpositionStyle = #'chromatic-harp > % chromatic transposition tailored for harp, so > % no alterations of > 1/2-tone That sounds like a useful enhancement, except that it would be a music property rather than a context property, since transposition happens before translation. Cheers, Neil ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 07/08/2010 10:25 PM, Neil Puttock wrote: > On 8 July 2010 19:47, Joseph Wakeling wrote: > >>(Example: take the music of bb. 9-10 in the sample music, and >>put it through the _original_ naturalizeMusic function. You get >>left with a g-double-flat instead of an f-natural.) > > You're using 2.12, I assume? Yup. > Since 2.13.14, transpositions greater than a double are normalized > automatically, so the original \naturalizeMusic also produces an f > natural here (see attached output using latest git). Hah! I've not kept up, I missed that being introduced ... :-P ('original' and 'revised' refer to the original and my version of naturalizeMusic?) So ... other than that it might be nice to have the snippet for 2.12, is there any contribution that I can meaningfully make to 2.13 with this? The ensuring-convergence-of-naturalization seems superfluous now, but the variable determination of maximum alteration might be worthwhile. The reason I was working on this was with the longer-term aim of being able to have an option to set transposition style in music: \set Staff.transpositionStyle = #'chromatic % what follows will be transposed in chromatic fashion \set Staff.transpositionStyle = #'tonal % tonal transposition \set Staff.transpositionStyle = #'chromatic-harp % chromatic transposition tailored for harp, so % no alterations of > 1/2-tone In any case, I should clearly update to 2.13.x before making further revisions ... ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Chromatic transposition -- a very small starting step
On 8 July 2010 19:47, Joseph Wakeling wrote: > (Example: take the music of bb. 9-10 in the sample music, and > put it through the _original_ naturalizeMusic function. You get > left with a g-double-flat instead of an f-natural.) You're using 2.12, I assume? Since 2.13.14, transpositions greater than a double are normalized automatically, so the original \naturalizeMusic also produces an f natural here (see attached output using latest git). Cheers, Neil <>___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel