Re: scheme night-mare...
On Sun, Jul 11, 2010 at 7:47 PM, Arno Waschk wrote: >>> SCM proc = ly_lily_module_constant ("map-alist-keys"); >>> >>> Call the procedure, using scm_call_2: >>> >>> SCM result = scm_call_2 (proc, arg1, arg2); >>> > > okay, what are arg1 and arg2, and what is the type of result beyond being > called "SCM"? Scheme is dynamically typed, so the answer to this question depends on what map-alist-keys returns. The easiest to deal with this is look at things from the scheme side, the 2nd option is printing out things in gdb. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: scheme night-mare...
On 07/11/2010 07:22 PM, Arno Waschk wrote: Thanks again, that wokrs at least for some displaying, buit still i need that handy conversion from this type of scheme list into something i can deal with with c. Please!!! No, no, the main question is, what are you going to do with that "something"? Ok, the keys are probably Scheme strings, so you can transform them into UTF byte-arrays which you can then feed into functions like "printf". But in Scheme, you frequently work with lists of things (lists themselves, or atoms) -- this is what a "data structure" looks like. So when you say "something i can DEAL with with c", what exactly is this DEALing you want to do? And with which objects? some of them are Scheme wrappers around C structs. For those, there is smob/unsmob. But for true Scheme data structures, you really want to deal with them using Scheme code -- that is, using scm_call_X(), as Carl already suggested. Boris ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: scheme night-mare...
On 07/11/2010 06:47 PM, Arno Waschk wrote: okay, what are arg1 and arg2, and what is the type of result beyond being called "SCM"? An ID for a Scheme entity. This is a fundamental concept in languages such as Scheme, Smalltalk, Self of Java. The value of the SCM itself is completely opaque to the client of the VM. It can be an index into a table, or it can be a direct address. The entity that it refers to, can in turn be any Scheme object: it can be a pair, or an atom, or the entity may even be immediately encoded in the SCM itself (for example, in Guile, #f is encoded in a special SCM). If you are familiar with JNI, then you can think of SCM as something similar to "jobject". In Smalltalk, the equivalent concept is "OOP". If you want to understand the communication between the Scheme and C++ code, the best reading explaining the underlying concepts are books on implementation of functional programming languages. But any VM book will do just as well (I started from Goldberg&Robson's Smalltalk Blue Book back in 1994; Simon Jones is more directly applicable to Scheme). Boris ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Revised autobeam settings patch (issue1682049)
Hi Carl, LGTM. The web snippet granados.ly uses beatLength, so will also need emending. Cheers, Neil http://codereview.appspot.com/1682049/diff/35001/36004 File Documentation/notation/rhythms.itely (right): http://codereview.appspot.com/1682049/diff/35001/36004#newcode1055 Documentation/notation/rhythms.itely:1055: predefined default values for these values can be found in for these properties http://codereview.appspot.com/1682049/diff/35001/36004#newcode1060 Documentation/notation/rhythms.itely:1060: \score{ \score { http://codereview.appspot.com/1682049/diff/35001/36004#newcode1730 Documentation/notation/rhythms.itely:1730: @funindex beamExceptions + beatStructure http://codereview.appspot.com/1682049/diff/35001/36004#newcode1755 Documentation/notation/rhythms.itely:1755: for the beam type, use it to determine the valid places where beam-type ? http://codereview.appspot.com/1682049/diff/35001/36004#newcode1824 Documentation/notation/rhythms.itely:1824: @emph{complete} exceptions list. That is, every exception that should lists http://codereview.appspot.com/1682049/diff/35001/36009 File Documentation/snippets/new/conducting-signs,-measure-grouping-signs.ly (right): http://codereview.appspot.com/1682049/diff/35001/36009#newcode16 Documentation/snippets/new/conducting-signs,-measure-grouping-signs.ly:16: the measure. @code{time} and @code{set-time-signature} both apply @code{\time} http://codereview.appspot.com/1682049/diff/35001/36009#newcode18 Documentation/snippets/new/conducting-signs,-measure-grouping-signs.ly:18: @code{beatStructure} or @code{baseUnit} that are set in baseMoment http://codereview.appspot.com/1682049/diff/35001/36014 File input/regression/auto-beam-beaming-override.ly (right): http://codereview.appspot.com/1682049/diff/35001/36014#newcode11 input/regression/auto-beam-beaming-override.ly:11: \version "2.13.27" 2.13.28 http://codereview.appspot.com/1682049/diff/35001/36016 File input/regression/beaming-ternary-metrum.ly (right): http://codereview.appspot.com/1682049/diff/35001/36016#newcode2 input/regression/beaming-ternary-metrum.ly:2: \version "2.13.27" 2.13.28 http://codereview.appspot.com/1682049/diff/35001/36017 File input/regression/les-nereides.ly (right): http://codereview.appspot.com/1682049/diff/35001/36017#newcode1 input/regression/les-nereides.ly:1: \version "2.13.27" 2.13.28 http://codereview.appspot.com/1682049/diff/35001/36019 File lily/beam-engraver.cc (right): http://codereview.appspot.com/1682049/diff/35001/36019#newcode309 lily/beam-engraver.cc:309: "baseMoment ", move to top http://codereview.appspot.com/1682049/diff/35001/36025 File lily/timing-translator.cc (right): http://codereview.appspot.com/1682049/diff/35001/36025#newcode62 lily/timing-translator.cc:62: context ()->set_property ("baseMoment", add to translator doc (+ others missing) http://codereview.appspot.com/1682049/diff/35001/36026 File ly/bagpipe.ly (right): http://codereview.appspot.com/1682049/diff/35001/36026#newcode12 ly/bagpipe.ly:12: \version "2.13.27" 2.13.28 http://codereview.appspot.com/1682049/diff/35001/36027 File ly/engraver-init.ly (right): http://codereview.appspot.com/1682049/diff/35001/36027#newcode19 ly/engraver-init.ly:19: \version "2.13.27" 2.13.28 http://codereview.appspot.com/1682049/diff/35001/36028 File ly/music-functions-init.ly (right): http://codereview.appspot.com/1682049/diff/35001/36028#newcode21 ly/music-functions-init.ly:21: \version "2.13.27" 2.13.28 http://codereview.appspot.com/1682049/diff/35001/36028#newcode675 ly/music-functions-init.ly:675: (revert-time-signature-setting time-signature context)) indent http://codereview.appspot.com/1682049/diff/35001/36030 File scm/auto-beam.scm (right): http://codereview.appspot.com/1682049/diff/35001/36030#newcode62 scm/auto-beam.scm:62: (not (eq? (member moment beat-structure) #f))) (pair? (member moment beat-structure)) http://codereview.appspot.com/1682049/diff/35001/36030#newcode127 scm/auto-beam.scm:127: ;; no rule applies, so end at beatLength or measure end indent http://codereview.appspot.com/1682049/diff/35001/36030#newcode129 scm/auto-beam.scm:129: ;; end if measure-pos matches a specified ending moment indent http://codereview.appspot.com/1682049/diff/35001/36037 File scm/time-signature-settings.scm (right): http://codereview.appspot.com/1682049/diff/35001/36037#newcode253 scm/time-signature-settings.scm:253: (define (revert-property-setting context property setting) public? http://codereview.appspot.com/1682049/diff/35001/36037#newcode270 scm/time-signature-settings.scm:270: time-signature setting . rest) this indentation is unmaintainable http://codereview.appspot.com/1682049/diff/35001/36037#newcode273 scm/time-signature-settings.scm:273: (context-spec-music indent http://codereview.appspot.com/1682049/diff/35001/36037#newcode287 scm/time-signature-settings.scm:287: time-signature setting 'Score)) move to previous line http://codereview.appspot.com/1682049/show _
Re: scheme night-mare...
On Mon, 12 Jul 2010 01:11:40 +0200, Neil Puttock wrote: On 11 July 2010 23:08, Arno Waschk wrote: Anyway, i came to a point where it seems very helpful to provide an easy option to print somehow the actual content of e. g. a grob at a certain point in the c++ code, or easily do some other voodoo to it, which i do not know yet... If you use the .gdbinit file in the Contributor's Guide, it's easy to set breakpoints in the code and look at the properties of grobs. You can display any SCM object via ly_display_scm () (which is what the .gdbinit file uses for the gdb macros). Cheers, Neil Thanks again, that wokrs at least for some displaying, buit still i need that handy conversion from this type of scheme list into something i can deal with with c. Please!!! Yours, Arno -- Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/ ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: scheme night-mare...
On 11 July 2010 23:08, Arno Waschk wrote: > Anyway, i came to a point where it seems very helpful to provide an easy > option to print somehow the actual content of e. g. a grob at a certain > point in the c++ code, or easily do some other voodoo to it, which i do not > know yet... If you use the .gdbinit file in the Contributor's Guide, it's easy to set breakpoints in the code and look at the properties of grobs. You can display any SCM object via ly_display_scm () (which is what the .gdbinit file uses for the gdb macros). Cheers, Neil ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: scheme night-mare...
On Mon, 12 Jul 2010 00:08:02 +0200, Arno Waschk wrote: On Sun, 11 Jul 2010 20:08:10 +0200, Neil Puttock wrote: On 11 July 2010 15:52, Arno Waschk wrote: How do i use this in a c line? Look up the procedure: SCM proc = ly_lily_module_constant ("map-alist-keys"); Call the procedure, using scm_call_2: SCM result = scm_call_2 (proc, arg1, arg2); okay, what are arg1 and arg2, and what is the type of result beyond being called "SCM"? Thanks, Arno Your question isn't really about converting from scheme to c++, it's really about getting all of the keys and/or properties from an alist. That's not built into scheme. No, it is about easily accessing information buried into some scheme structures by some little c code. As long this is not possible, this information is next to encrypted for me. Why do you need to do this in C/C++ though? If you're running a .ly file, this information's easily available via ly:grob-alist-chain: \relative c' { \override Staff.KeySignature #'after-line-breaking = #(lambda (grob) (for-each (lambda (lst title) (display (format #f "~a:\n" title)) (for-each (lambda (entry) (display (format #f " ~a\n" (car entry lst) (newline)) (ly:grob-alist-chain grob '()) '("mutable" "immutable"))) \key a \major a1 } Cheers, Neil Thanks for your explanations! My main reason for all this is not to do something on the .ly file level (at least not for now) but for learning what is going on on the c++ level, including searching for hints onto my theory that lilypond's processing times grow far more quadratically than i would believe to be necessary (or to prove myself wrong, who knows?? Anyway, i came to a point where it seems very helpful to provide an easy option to print somehow the actual content of e. g. a grob at a certain point in the c++ code, or easily do some other voodoo to it, which i do not know yet... Where dealing with types including the letters S C M proves to be pure horror. Or maybe it is my not-knowledge of those languages? I am musician after all... So i am looking for something fool-proof leading to something easily printable (vulgo: string or the like) and not something hidden within a scheme type labyrinth which i need to translate into a scheme type to call it to have a scheme type result which maybe can or cannot converted into something which might be a scheme type which can be translated into something c++ might be able to convert, you got the point? But thank you a lot for your help! Cheers, Arno -- Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/ ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: scheme night-mare...
On Sun, 11 Jul 2010 20:08:10 +0200, Neil Puttock wrote: On 11 July 2010 15:52, Arno Waschk wrote: How do i use this in a c line? Look up the procedure: SCM proc = ly_lily_module_constant ("map-alist-keys"); Call the procedure, using scm_call_2: SCM result = scm_call_2 (proc, arg1, arg2); Your question isn't really about converting from scheme to c++, it's really about getting all of the keys and/or properties from an alist. That's not built into scheme. No, it is about easily accessing information buried into some scheme structures by some little c code. As long this is not possible, this information is next to encrypted for me. Why do you need to do this in C/C++ though? If you're running a .ly file, this information's easily available via ly:grob-alist-chain: \relative c' { \override Staff.KeySignature #'after-line-breaking = #(lambda (grob) (for-each (lambda (lst title) (display (format #f "~a:\n" title)) (for-each (lambda (entry) (display (format #f " ~a\n" (car entry lst) (newline)) (ly:grob-alist-chain grob '()) '("mutable" "immutable"))) \key a \major a1 } Cheers, Neil Thanks for your explanations! My main reason for all this is not to do something on the .ly file level (at least not for now) but for learning what is going on on the c++ level, including searching for hints onto my theory that lilypond's processing times grow far more quadratically than i would believe to be necessary (or to prove myself wrong, who knows?? Anyway, i came to a point where it seems very helpful to provide an easy option to print somehow the actual content of e. g. a grob at a certain point in the c++ code, or easily do some other voodoo to it, which i do not know yet... Where dealing with types including the letters S C M proves to be pure horror. Or maybe it is my not-knowledge of those languages? I am musician after all... So i am looking for something fool-proof leading to something easily printable (vulgo: string or the like) and not something hidden within a scheme type labyrinth which i need to translate into a scheme type to call it to have a scheme type result which maybe can or cannot converted into something which might be a scheme type which can be translated into something c++ might be able to convert, you got the point? But thank you a lot for your help! Cheers, Arno -- Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/ ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Organ template in fundamental.itely is incomplete
> The organ template given in `fundamental.itely' lacks an important > property, namely the limited stretchability of the pedal staff. > Without this, the distance of the pedal staff w.r.t. the other two > staves can become far too big. Here's a documentation patch. Werner == --- fundamental.itely.old 2010-05-15 16:16:53.0 +0200 +++ fundamental.itely 2010-07-11 19:33:13.0 +0200 @@ -2819,6 +2819,70 @@ @} % end Score context @end example +The above layout of the organ staves is almost perfect; however, +there is a slight defect which is not visible by looking at just a +single system: The distance of the pedal staff to the left hand staff +should behave approximately the same as the right hand staff to the +left hand staff. In particular, the stretchability of staves in a +...@code{pianostaff} context is limited (so that the distance between +the staves for the left and right hand can't become too large), and +the pedal staff should behave similarly. + +Stretchability of staves can be controlled with the +...@code{next-staff-spacing} property of the @code{VerticalAxisGroup} +...@q{graphical object} (commonly called @q{grob}s within the lilypond +documentation) -- don't worry about the details right now; this is +fully explained later. For the curious, have a look at +...@ruser{overview of modifying properties}. Currently, it is not +possible to modify the @code{stretchability} sub-property only, we +thus have to copy the other sub-properties also. Again, for the +curious, you can find the default values in file +...@file{scm/@/define-grobs@/.scm} by looking up the definition of the +...@code{verticalaxisgroup} grob. The value for @code{stretchability} +is taken from the definition of the @code{PianoStaff} context (in +file @file{ly/@/engraver-init@/.ly}) so that the values are +identical. + +...@example +\score @{ + << % PianoStaff and Pedal Staff must be simultaneous +\new PianoStaff << + \new Staff = "ManualOne" << +\keyTime % set key and time signature +\clef "treble" +\new Voice @{ + \voiceOne + \ManualOneVoiceOneMusic +@} +\new Voice @{ + \voiceTwo + \ManualOneVoiceTwoMusic +@} + >> % end ManualOne Staff context + \new Staff = "ManualTwo" \with @{ +\override VerticalAxisGroup + #'next-staff-spacing = #'((space . 9) +(minimum-distance . 8) +(padding . 1) +(stretchability . 5)) + @} << +\keyTime +\clef "bass" +\new Voice @{ + \ManualTwoMusic +@} + >> % end ManualTwo Staff context +>> % end PianoStaff context +\new Staff = "PedalOrgan" << + \keyTime + \clef "bass" + \new Voice @{ +\PedalOrganMusic + @} +>> % end PedalOrgan Staff + >> +...@} % end Score context +...@end example That completes the structure. Any three-staff organ music will have a similar structure, although the number of voices may vary. All that remains now @@ -2862,7 +2926,13 @@ \ManualOneVoiceTwoMusic } >> % end ManualOne Staff context - \new Staff = "ManualTwo" << + \new Staff = "ManualTwo" \with { +\override VerticalAxisGroup + #'next-staff-spacing = #'((space . 9) +(minimum-distance . 8) +(padding . 1) +(stretchability . 5)) + } << \keyTime \clef "bass" \new Voice { ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
moving english doc to a separate subdirectory
What do you think about moving Documentation/contributor Documentation/css Documentation/essay ... to Documentation/en/contributor Documentation/en/css Documentation/en/essay ... for orthogonality with the other languages? Additionally, the `Documentation' directory is already quite crowded... Werner ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: scheme night-mare...
On 11 July 2010 15:52, Arno Waschk wrote: > How do i use this in a c line? Look up the procedure: SCM proc = ly_lily_module_constant ("map-alist-keys"); Call the procedure, using scm_call_2: SCM result = scm_call_2 (proc, arg1, arg2); >> Your question isn't really about converting from scheme to c++, it's >> really >> about getting all of the keys and/or properties from an alist. That's not >> built into scheme. > > No, it is about easily accessing information buried into some scheme > structures by some little c code. > As long this is not possible, this information is next to encrypted for me. Why do you need to do this in C/C++ though? If you're running a .ly file, this information's easily available via ly:grob-alist-chain: \relative c' { \override Staff.KeySignature #'after-line-breaking = #(lambda (grob) (for-each (lambda (lst title) (display (format #f "~a:\n" title)) (for-each (lambda (entry) (display (format #f " ~a\n" (car entry lst) (newline)) (ly:grob-alist-chain grob '()) '("mutable" "immutable"))) \key a \major a1 } Cheers, Neil ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Add support for multi-note tremolo (issue1786041)
On 2010/07/10 09:51:33, Reinhold wrote: Hmm, but that's the first event where I know that the tremolo has ended. Before the stopping spanner event, there is no way to determine whether there will be still some notes or not... It's an unavoidable consequence of the iteration process, since the TremoloRepeatedMusic triggers the creation of the start/stop events; unlike the events generated by manual beaming, they're always running behind. Naturally this doesn't matter if we're restricted to two-note tremolos since we know once a second stem's been acknowledged that the beam should end. Would it be a problem to use announce_end_grob here like before, even though there might be another note coming up? I.e. what side-effects does calling announce_end_grob have? AFAICT, it's only used by the Spanner_break_forbid_engraver, so will only affect beams in a stem tremolo. But it will have the unfortunate side effect of making every tremolo longer than two notes breakable (ignoring 'breakable = ##f) after the second stem. Cheers, Neil http://codereview.appspot.com/1786041/show ___ 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 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: scheme night-mare...
On Sun, 11 Jul 2010 16:35:07 +0200, Carl Sorensen wrote: On 7/11/10 8:18 AM, "Arno Waschk" wrote: On Sun, 11 Jul 2010 16:01:52 +0200, Carl Sorensen wrote: On 7/11/10 7:53 AM, "Arno Waschk" wrote: On Sun, 11 Jul 2010 15:48:57 +0200, Carl Sorensen wrote: On 7/11/10 7:16 AM, "Arno Waschk" wrote: Dear list, in the hope not for the x-th time having to give up due to that type mess scheme/c++ please forgive and help me: how can i convert/process/whatever the result of whateverGrob->get_property_alist_chain (SCM_EOL) into something easily useable in the c++ realm? Alist chains aren't easily handled in c++, as far as I know. But they can be used with scheme functions by using scm_call_3. for the moment i am looking for either a complete dump of those properties, or at least a complete list of which properties could be addressed individually, although that would be less comfortable... If you don't need the alist chain, but just need individual properties, there are c++ functions to get the properties. If your question were a little bit more specific, we could probably help better. well, it is about getting around that types' things generally, too... OK, so here's the place to go to find what you need. The Guile reference has an API reference that lists all of the c++ calls to execute scheme functions. The stuff that deals with alists is found under the compound data types section: http://www.gnu.org/software/guile/manual/html_node/Compound-Data-Types.html# Compound-Data-Types You can do anything that you can do in scheme in c++ with these calls. except for generating the list of keys, it seems... :( There is a scheme function in scm/lily-library.scm map-alist-keys that will apply a function to all the keys in an alist. That might be helpful... How do i use this in a c line? Your question isn't really about converting from scheme to c++, it's really about getting all of the keys and/or properties from an alist. That's not built into scheme. No, it is about easily accessing information buried into some scheme structures by some little c code. As long this is not possible, this information is next to encrypted for me. Just finished a profile run with a larger score- ly_scm2interval is reported to have consumd 16% of computation time. There must be something wrong. Thanks, Arno Sorry, Carl -- Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/ ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: scheme night-mare...
On 7/11/10 7:16 AM, "Arno Waschk" wrote: > Dear list, > > in the hope not for the x-th time having to give up due to that type mess > scheme/c++ please forgive and help me: > > how can i convert/process/whatever the result of > whateverGrob->get_property_alist_chain (SCM_EOL) into something easily > useable in the c++ realm? Alist chains aren't easily handled in c++, as far as I know. But they can be used with scheme functions by using scm_call_3. If you don't need the alist chain, but just need individual properties, there are c++ functions to get the properties. If your question were a little bit more specific, we could probably help better. Thanks, Carl ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
scheme night-mare...
Dear list, in the hope not for the x-th time having to give up due to that type mess scheme/c++ please forgive and help me: how can i convert/process/whatever the result of whateverGrob->get_property_alist_chain (SCM_EOL) into something easily useable in the c++ realm? Thanks, Arno -- Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/ ___ 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