|
|
Created:
11 years, 3 months ago by Trevor Daniels Modified:
11 years, 2 months ago CC:
lilypond-devel_gnu.org Visibility:
Public. |
DescriptionIssue 3720: Built-in templates for SATB vocal scores
Many more templates like this could be provided: this
is just a start to see if this approach is worth
pursuing further. As this is exploratory, only
minimal changes have been made to the documentation -
just enough to preserve consistency.
Patch Set 1 #
Total comments: 1
Patch Set 2 : Respond to comments #Patch Set 3 : Respond to further comments #Patch Set 4 : Devon Schudy's template and corresponding documentation #
Total comments: 7
MessagesTotal messages: 25
LGTM, except one typo. https://codereview.appspot.com/41990043/diff/1/Documentation/learning/templat... File Documentation/learning/templates.itely (right): https://codereview.appspot.com/41990043/diff/1/Documentation/learning/templat... Documentation/learning/templates.itely:53: Any of the staves my be omitted. Here, for example, is how the input mAy be omitted
Sign in to reply to this message.
On 2013/12/14 16:15:14, Jean-Charles wrote: > LGTM, except one typo. > > https://codereview.appspot.com/41990043/diff/1/Documentation/learning/templat... > File Documentation/learning/templates.itely (right): > > https://codereview.appspot.com/41990043/diff/1/Documentation/learning/templat... > Documentation/learning/templates.itely:53: Any of the staves my be omitted. > Here, for example, is how the input > mAy be omitted Done - thanks! Trevor
Sign in to reply to this message.
Respond to comments
Sign in to reply to this message.
This interface is unlike any other in Lilypond, in ways that make it less flexible and may surprise users: * It has two separate files that need to be included in the right places. * It requires the user to use certain specific variable names. * The second include file doesn't just add definitions; it directly produces output. * The output isn't accessible for the user to modify (by e.g. \transpose). If there's library code for SATB, shouldn't its interface be a music-function that takes parts and lyrics and returns a music expression? That way the user can use whatever names they want, and can do whatever they want with the output. Something like this: \score { \satb { \soprano \alto \tenor \bass \someLyrics \moreLyrics \piano } } I'm not sure this is much of an improvement on just writing \ChoralStaff,\lyricsto etc. manually, though. Also, the support for specific tags is out of place, since it's unrelated to SATB scores.
Sign in to reply to this message.
On 2013/12/14 22:32:06, Devon Schudy wrote: > This interface is unlike any other in Lilypond, This was intended not as an interface to a built-in bulletproof engine, but rather a template that users can adopt and change. Maybe calling it a 'built-in' template, and its attempt to be as general as feasible, invites misunderstanding of its intended use.
Sign in to reply to this message.
On 2013/12/14 22:32:06, Devon Schudy wrote: > This interface is unlike any other in Lilypond, in ways that make it less > flexible and may surprise users: > * It has two separate files that need to be included in the right places. > * It requires the user to use certain specific variable names. > * The second include file doesn't just add definitions; it directly produces > output. All this is hopefully made clear in the description. You should compare this approach with the existing templates in the Learning Manual. It is an attempt to improve on them by a) clearly separating music from layout; b) requiring no change to the layout part to help newcomers; b) adding flexibility so two templates cover a range of layouts without any layout changes being required. I run a small choir and constantly need to generate, transpose, and reset choral music in 2, 3 or 4 staves, occasionally with descant, both with and without accompaniment. These two templates, so far, have met all my, admittedly rather simple, needs. > * The output isn't accessible for the user to modify (by e.g. \transpose). ? > If there's library code for SATB, There isn't > I'm not sure this is much of an improvement on just writing > \ChoralStaff,\lyricsto etc. manually, though. Previously I used to do this, removing a staff context, adding lyrics contexts, adding or removing piano staves etc, as required. This took time and was error-prone. With these templates all that is unnecessary. I find it remarkably effective; my hope was that many other similar users would do so too.
Sign in to reply to this message.
On 2013/12/14 23:17:55, Keith wrote: > On 2013/12/14 22:32:06, Devon Schudy wrote: > > This interface is unlike any other in Lilypond, > > This was intended not as an interface to a built-in bulletproof engine, but > rather a template that users can adopt and change. Exactly, although the flexibility greatly reduces the need to 'adopt and change'. > Maybe calling it a 'built-in' template, and its attempt to be as general as > feasible, invites misunderstanding of its intended use. Maybe. It's 'built-in' as there is no need to copy and edit the templates, but perhaps a better word to distinguish these templates from the previous ones could be found. Suggestions welcome. Trevor
Sign in to reply to this message.
On Sun, Dec 15, 2013 at 4:51 AM, <tdanielsmusic@googlemail.com> wrote: > > On 2013/12/14 23:17:55, Keith wrote: >> >> On 2013/12/14 22:32:06, Devon Schudy wrote: >> > This interface is unlike any other in Lilypond, > > >> This was intended not as an interface to a built-in bulletproof > > engine, but >> >> rather a template that users can adopt and change. > > > Exactly, although the flexibility greatly reduces the > need to 'adopt and change'. > > >> Maybe calling it a 'built-in' template, and its attempt to be as > > general as >> >> feasible, invites misunderstanding of its intended use. > > > Maybe. It's 'built-in' as there is no need to copy > and edit the templates, but perhaps a better word to > distinguish these templates from the previous ones > could be found. Suggestions welcome. > > Trevor > First question I anticipate from users on this, if we are making a canonical SATB score template in this way: How do I get the altos and sopranos on the same staff, and the tenors and basses on the same staff? For instance, this template doesn't help me at all, since I use the two staves instead of four. I could be wrong, and realize that many use separate staves, but there are also many who don't. Cheers, Carl P. https://codereview.appspot.com/41990043/
Sign in to reply to this message.
On 2013/12/15 17:41:17, Carl P. wrote: > First question I anticipate from users on this, if we are making a > canonical SATB score template in this way: How do I get the altos and > sopranos on the same staff, and the tenors and basses on the same > staff? For instance, this template doesn't help me at all, since I use > the two staves instead of four. I could be wrong, and realize that > many use separate staves, but there are also many who don't. Good point. The SA-TB template pair puts SA on one staff and TB on another, but in this revision it has only verses between. There is no reason why it should not also have soprano lyrics above, bass lyrics below and alto and tenor lyrics in-between, with each aligning to their respective voices. I'll do that in the next revision. I think then all the major SATB layouts will be incorporated in just two template pairs. Trevor
Sign in to reply to this message.
Respond to further comments
Sign in to reply to this message.
On Sun, Dec 15, 2013 at 2:40 PM, <tdanielsmusic@googlemail.com> wrote: > Good point. The SA-TB template pair puts SA on one > staff and TB on another, but in this revision it has > only verses between. There is no reason why it should > not also have soprano lyrics above, bass lyrics below > and alto and tenor lyrics in-between, with each aligning > to their respective voices. I'll do that in the next > revision. I think then all the major SATB layouts will > be incorporated in just two template pairs. > > Trevor > > https://codereview.appspot.com/41990043/ There is that, and I realize after looking at the files again that you did address what I was asking about. But you do bring up a good point. Depending upon whether music is presented as through-composed or in songbook format (with verses), there may be a need for multiple sets of alternate (above or below staff) lyrics. I think I share in what I get to be the general sense of many of the comments that have been made thus far. There is a tradeoff between ease of default use and the customizability. To use a bad and probably over-generalized analogy, we're going from Linux (where you pretty much have to do it yourself, but you can make it do pretty much anything you want) to Mac (where everything is easy IF you are willing to work within the predefined templates, and anything else is almost impossible). We need something in between. I don't know that this is the route to go. If our goal is to get people using LP, I don't think that what we need is a function that hides basic structures from the users, where if they want to go beyond this, they have to move from two include commands to a whole new structure. I think what we need is a stripped-down choral/SATB layout that uses minimal overrides and extra code so that new users can copy-and-paste and start experimenting with. Cheers, Carl P.
Sign in to reply to this message.
Keith wrote: > This was intended not as an interface to a built-in bulletproof engine, but > rather a template that users can adopt and change. Isn't the template-to-modify use case already covered by the SATB templates in the Learning Manual and LSR? ISTM using two include files is harder for a beginner than modifying a template. tdanielsmusic@googlemail.com wrote: > > * The output isn't accessible for the user to modify (by e.g. > > \transpose). > > ? I often apply music functions like \transpose, \articulate and \unfoldRepeats to the whole contents of a score, e.g. \score { \transpose c' g \new ChoralStaff << \triplum \duplum \tenor >> } \score { \articulate \unfoldRepeats << ... >> \midi { \context { \Staff midiInstrument = "oboe" } } } With s-a-t-b.ily, this isn't possible, because the user has no access to the final music-expression. Putting the music-function before the \include doesn't work... \transpose c' g \include "s-a-t-b.ily" ...because \score isn't a music expression (and there are definitions before it). >> If there's library code for SATB, > > There isn't By “library code”, I meant the contents of this patch: it adds code to Lilypond's built-in library of include files. > Previously I used to do this, removing a staff context, > adding lyrics contexts, adding or removing piano staves > etc, as required. This took time and was error-prone. > With these templates all that is unnecessary. I find > it remarkably effective; my hope was that many other > similar users would do so too. I agree that it's useful to separate the layout from the content, and SATB is so common that it's worth having built-in support. I just don't think requiring the user to define certain variable names and include a file in place of \score is a good interface to it. It's compatible with your style of writing scores, but not with other reasonable styles. I'd rather support the same thing through music functions: \score { << \satbTwoStaves << \soprano \alto \VerseOne \VerseTwo \tenor \bass >> \pianoStaff << \rh \pianoDynamics \lh >> >> } ...where \satbTwoStaves creates a ChoirStaff and staves and assigns the music-expressions to them appropriately (keeping lyrics separate), and \pianoStaff makes a PianoStaff etc. (Piano scores are another very common thing that's a bit complicated for beginners, so it may be worth having a convenience for them.) > perhaps a better word to distinguish these templates from > the previous ones could be found. 'Framework'? That's often used for this sort of thing.
Sign in to reply to this message.
On 2013/12/15 20:00:24, Carl P. wrote: > I don't know that this is the route to go. If our goal is to get > people using LP, I don't think that what we need is a function that > hides basic structures from the users, where if they want to go beyond > this, they have to move from two include commands to a whole new > structure. I think what we need is a stripped-down choral/SATB layout > that uses minimal overrides and extra code so that new users can > copy-and-paste and start experimenting with. I believe the rest of the templates in the Appendix to the LM have been in the form you suggest for at least 6 years. They will remain there for those users who want to learn. But many users don't want to learn; they just want an easy way of producing simple music with as little effort as possible. Why not give it to them as an alternative? Trevor
Sign in to reply to this message.
On 2013/12/15 20:06:56, Devon Schudy wrote: > I'd rather support the same thing through music functions: > > \score { > << > \satbTwoStaves << \soprano \alto \VerseOne \VerseTwo \tenor \bass >> > \pianoStaff << \rh \pianoDynamics \lh >> > >> > } > > ...where \satbTwoStaves creates a ChoirStaff and staves and assigns > the music-expressions to them appropriately (keeping lyrics separate), > and \pianoStaff makes a PianoStaff etc. (Piano scores are another very > common thing that's a bit complicated for beginners, so it may be > worth having a convenience for them.) I don't think I'd convince my sceptical pianist friend that LilyPond is easy to use by saying that's how a vocal score is produced. The point of this patch is to make LilyPond more approachable by facilitating the production of quite complex vocal scores by typing _just_ the music, which _is_ quite easy to explain, comprehend and do. Trevor
Sign in to reply to this message.
Trevor Daniels wrote: > The point of this patch is to make LilyPond more approachable by > facilitating the production of quite complex vocal scores by typing > _just_ the music, which _is_ quite easy to explain, comprehend and > do. OK, it's because the structure is much harder to understand than the notation for notes. Here are some ways it could be made easier to use: * The need for separate *-init.ily files can be eliminated by using defined? to set the defaults when using the variables. * The filenames should be all lowercase, like all of the other standard include files, so they'll work on case-sensitive filesystems when users type them in lowercase (as I did on the first try). * All the other standard include files use .ly, not .ily. Do we really want to change this in a user-visible place? * The *Music variables are the most important ones. Should they have shorter names, like Soprano instead of SopranoMusic? * Instrument name variables are easier to set if there's one per voice, so users don't have to use \markup. * Shouldn't "Ladies" be "Women", to be consistent with "Men"? * Short names can default to the first character of the long name. * Shouldn't \lyricsto be implied? * S-A-T-B and SA-TB could be one file, with the number of staves controlled by defining TwoVoicesPerStaff = ##t. * Requiring the \include to be at the end is still odd. Questions of output: * Should instrumentName be off by default, since in simple SATB scores it's obvious which part is which? * Choir aahs and oohs don't sound very good on most MIDI players — they're intended for pads, so they usually have very slow attacks, making it hard to hear rhythm. Perhaps clarinet would be better, since it has faster attacks and sounds a little like voice? Some features seem unnecessary: * The \paper block changes a bunch of defaults, but AFAICT the defaults are fine (and the changes). Why bother? * Small caps also seems unrelated to SATB. * TopMarkup does nothing that can't be done by a top-level \markup. Here's a version with many of these changes: http://codereview.appspot.com/38720045
Sign in to reply to this message.
Got a free moment.. 2013/12/15 Carl Peterson <carlopeterson@gmail.com>: > I think I share in what I get to be the general sense of many of the > comments that have been made thus far. There is a tradeoff between > ease of default use and the customizability. To use a bad and probably > over-generalized analogy, we're going from Linux (where you pretty > much have to do it yourself, but you can make it do pretty much > anything you want) to Mac (where everything is easy IF you are willing > to work within the predefined templates, and anything else is almost > impossible). We need something in between. > > I don't know that this is the route to go. If our goal is to get > people using LP, I don't think that what we need is a function that > hides basic structures from the users, where if they want to go beyond > this, they have to move from two include commands to a whole new > structure. I think what we need is a stripped-down choral/SATB layout > that uses minimal overrides and extra code so that new users can > copy-and-paste and start experimenting with. I believe we need to add an abstraction layer that would make it conceptually simpler to write \score blocks. Please take a look at https://github.com/openlilylib/snippets/tree/master/templates/predefined-inst... I believe that this is exactly what LilyPond needs to allow beginner users easily create score structures. Notice how much it shortens the \score definition. I don't quite understand why nobody seems interested in this... Janek PS this is not to say that i don't like Trevor's templates! I believe they are a useful addition.
Sign in to reply to this message.
Devon Schudy's template and corresponding documentation
Sign in to reply to this message.
Message was sent while issue was closed.
Pushed to staging Closing ...
Sign in to reply to this message.
Message was sent while issue was closed.
https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly File ly/satb.ly (right): https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode1 ly/satb.ly:1: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Missing \version number is causing an error when running convert-ly. https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode68 ly/satb.ly:68: (if (defined? name) name (if (pair? default) (car default) '#{#}))) '#{#} is expensive. I'd rather use *unspecified* here. https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode70 ly/satb.ly:70: #(define (sym . strings) (string->symbol (apply string-append strings))) For an include file (rather than a module), this and some other macro names seem awfully likely to cause collisions. https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode84 ly/satb.ly:84: (let ((above (if (pair? optionals) (car optionals) #f))) (if x y #f) is easier to understand and write as (and x y), in particular if x takes up considerable space. https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode93 ly/satb.ly:93: #{#}))) Why #{#} unquoted? That evaluates at macro placement time. But I'd use *unspecified* anyway. https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode97 ly/satb.ly:97: \new Staff = #(identity ,name) \with { Why #(identity ,name) here instead of #,name ? https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode104 ly/satb.ly:104: \clef #(identity ,clef) What's with the identity? It does not make sense. I'll skip the copious other occurences but they should be fixed.
Sign in to reply to this message.
Message was sent while issue was closed.
On 2014/01/05 01:42:55, dak wrote: > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly > File ly/satb.ly (right): > > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode1 > ly/satb.ly:1: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% > Missing \version number is causing an error when running convert-ly. > > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode68 > ly/satb.ly:68: (if (defined? name) name (if (pair? default) (car default) > '#{#}))) > '#{#} is expensive. I'd rather use *unspecified* here. > > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode70 > ly/satb.ly:70: #(define (sym . strings) (string->symbol (apply string-append > strings))) > For an include file (rather than a module), this and some other macro names seem > awfully likely to cause collisions. > > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode84 > ly/satb.ly:84: (let ((above (if (pair? optionals) (car optionals) #f))) > (if x y #f) is easier to understand and write as (and x y), in particular if x > takes up considerable space. > > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode93 > ly/satb.ly:93: #{#}))) > Why #{#} unquoted? That evaluates at macro placement time. But I'd use > *unspecified* anyway. > > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode97 > ly/satb.ly:97: \new Staff = #(identity ,name) \with { > Why #(identity ,name) here instead of #,name ? > > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode104 > ly/satb.ly:104: \clef #(identity ,clef) > What's with the identity? It does not make sense. > > I'll skip the copious other occurences but they should be fixed. As this patch has already been pushed I'll open a new tracker to cover these issues. Trevor
Sign in to reply to this message.
dak wrote: > https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode97 > ly/satb.ly:97: \new Staff = #(identity ,name) \with { > Why #(identity ,name) here instead of #,name ? #,name didn't work for some reason, so I wrapped it with identity as a workaround. ...but I just tried it again and #,name works now, even in versions from mid-December. I wonder what I did that made it fail?
Sign in to reply to this message.
Devon Schudy <dschudy@gmail.com> writes: > dak wrote: >> https://codereview.appspot.com/41990043/diff/60001/ly/satb.ly#newcode97 >> ly/satb.ly:97: \new Staff = #(identity ,name) \with { >> Why #(identity ,name) here instead of #,name ? > > #,name didn't work for some reason, so I wrapped it with identity as a > workaround. Please try refraining from workarounds before checking back with the developer list. And when you actually use workarounds, try putting comments in so that the next developer has a clue what you have been doing and why. Otherwise we will accumulate a lot of cruft that nobody know the reason for, and possibly cruft that could have been fixed rather than dragged around. > ...but I just tried it again and #,name works now, even in versions > from mid-December. I wonder what I did that made it fail? Following up with a non-space character maybe (note that there are quite a few characters looking like a space that aren't). Or writing ,#name. At any rate, I'm not really happy with the macro usage at top level here: I think it would be better if the basic assembly was rather done by music or Scheme functions (Scheme functions should, when used inside of a music sequence, be able to return either music or *unspecified*, and the latter is ignored completely). As explained in <URL:http://web.archive.org/web/20130808154633/http://news.lilynet.net/?The-LilyPond-Report-27#a_kind_of_magic> (I wish the original website were accessible again), it's a bit of good luck that this even works. The bottom line was The current form of the closures argument as an association list of string offsets to anonymous functions was introduced as an emergency measure because Guile version 2.0 was lacking local-eval, a feature of Guile used previously for the purpose of evaluating Scheme inside of embedded LilyPond in lexical closure (the syntactical environment containing local variables) of the outward Scheme layer. Version 2.0.4 of Guile (released in January 2012) saw a return of "local-eval". Would this kind of construct work using local-eval in either Guile 1.8 or Guile 2.0? Frankly, I don’t know. Capturing a lexical environment in the middle of expanding a quasiquote seems like an audacious enterprise. In afterthought, expecting this to work was somewhat optimistic. But LilyPond delivered. And I am not really convinced that if we move to local-eval at some point of time that we'll be able to get `#{ ... #,... #} to work in a reasonable time frame. Maybe that will be considered a show stopper anyway, so we'll stay with the lambda implementation which manages to survive this rather brutal mixture of Scheme and LilyPond. It's nice that it works, but I'd prefer seeing somewhat more natural seeming approaches here. Macro calls as a user interface don't make me happy. They have their place as work horses in things like the make-relative macro. -- David Kastrup
Sign in to reply to this message.
David Kastrup wrote: > At any rate, I'm not really happy with the macro usage at top level > here: I think it would be better if the basic assembly was rather done > by music or Scheme functions I'm not really happy with it either, because users have no hope of modifying it or learning from it. The macro-generated version is much shorter, but that's not worth the inability to copy and modify. I rewrote it using functions, but that's not much easier for users, and is almost as long as the original version with no attempt to factor out the repetition. The reason for the macros is so the definedness of variables can be checked at macroexpand time, to avoid compiling references to undefined names — that works in Guile 1.8 but not in Guile 2, and it's bad style anyway. But we can avoid the `defaulting` macro by simply defining the variables iff they're not already. Guile 2's define-once does exactly this, and it's easy to recreate it in Guile 1.8. (This also fixes the problem with \Layout.) Using define-once instead of `defaulting` and removing the staff-making functions leaves it almost identical to Trevor's original version, except that there's no separate init file, and there's one conditional for whether to have two voices per staff.
Sign in to reply to this message.
Message was sent while issue was closed.
On 2014/01/12 08:05:30, Devon Schudy wrote: > David Kastrup wrote: > > At any rate, I'm not really happy with the macro usage at top level > > here: I think it would be better if the basic assembly was rather done > > by music or Scheme functions > > I'm not really happy with it either, because users have no hope of > modifying it or learning from it. The macro-generated version is much > shorter, but that's not worth the inability to copy and modify. I > rewrote it using functions, but that's not much easier for users, and > is almost as long as the original version with no attempt to factor > out the repetition. > > The reason for the macros is so the definedness of variables can be > checked at macroexpand time, to avoid compiling references to > undefined names — that works in Guile 1.8 but not in Guile 2, and it's > bad style anyway. Checking for the definedness of variables at macroexpand time? Ugh. How about define-variables = #(define-void-function (parser location syms) (symbol-list?) (for-each (lambda (sym) (if (null? (ly:parser-lookup parser sym)) (ly:parser-define parser sym *unspecified*))))) If you write \name for a variable with value *unspecified*, it simply disappears in the lexer.
Sign in to reply to this message.
Message was sent while issue was closed.
On 2014/01/12 08:59:46, dak wrote: > How about > define-variables = > #(define-void-function (parser location syms) (symbol-list?) > (for-each > (lambda (sym) > (if (null? (ly:parser-lookup parser sym)) > (ly:parser-define parser sym *unspecified*))))) > > If you write \name for a variable with value *unspecified*, it simply disappears > in the lexer. Thanks both. This issue is closed, but I'll check out this solution and raise a new issue to incorporate it Trevor
Sign in to reply to this message.
|