Kieren MacMillan wrote:
Hi all,

I'm engraving a song for voice and piano — the voice is swung (dotted eighth plus sixteenth) while the piano is playing triplets.

I would like to [at least see what it looks like if I] set it so that the dotted sixteenth in the voice lines up visually/vertically with the third eighth note of the triplet in the piano accompaniment — i.e., visually represent the music completely accurately. What's the best hack/trick to accomplish this?


Hi, Kieren,

I just took your question as a motivation to finally add the functionality for *num/den suffixes in the following rhythm snippet. It's mainly taken from the LSR, and I did not bother to reindent it - I don't quite get the correct indentation scheme, anyway - but you'll see the interesting parts in a second.
I guess that's what you're looking for?

@ all:
The string->duration routine certainly is not production-stage or well tested, but it seems to work as long as one does not try to push its limits (in particular, I did not ever call it with whitespaces in the string). Actually I suppose this functionality should be hidden somewhere in the Scheme functions, but I could not find anything. I guess this bit is useful to have, so if it looks good to one of the GUILE gurus, feel free to add it as a helper function. I'll do some tests later, too.


Cheers,
Alexander
%% from: http://lsr.dsi.unimi.it/LSR/Item?id=390
%%
%% rests and skips added to transformEachNote
%% string->duration is modified to take nom/den pairs into account

#(define rhythmVectorIndex 0)

#(define (transformEachNote chordElt rhythmVector)
	(begin		
	 (if (or (eq? 'NoteEvent (ly:music-property chordElt 'name))
				(eq? 'RestEvent (ly:music-property chordElt 'name))
				(eq? 'SkipEvent (ly:music-property chordElt 'name)))
		(set! (ly:music-property chordElt 'duration) (vector-ref rhythmVector rhythmVectorIndex)) 
	)		
	 chordElt
 ))

#(define (getChords musicElt rhythmVector)
	(begin
	 (if (eq? 'EventChord (ly:music-property musicElt 'name))
		(begin
		 (map 			
			(lambda (x) (transformEachNote x rhythmVector))	
			(ly:music-property musicElt 'elements)
		) 
		 (set! rhythmVectorIndex (1+ rhythmVectorIndex))
		 (if (= rhythmVectorIndex (vector-length rhythmVector)) (set! rhythmVectorIndex 0))			
	 )	
	)		
	 musicElt
 )) 

%%%%%%%%%%%%%%%% string functions %%%%%%%%%%%%%%%%%%%%%

#(define (string->duration str)
	(let* (
		(dot-index (string-index str #\.))
		(nom-index (string-index str #\*))
		(den-index (string-index str #\/))

		(end-of-nom (if den-index den-index
								 (string-length str)))
		(end-of-dots (if nom-index nom-index
									end-of-nom))
		(end-of-length (if dot-index dot-index
										end-of-dots))

		(length (ly:intlog2 (string->number (substring str 0 end-of-length))))
		(dot-count (if dot-index
								(- end-of-dots dot-index)
								0))
		(nom (if nom-index
					(string->number (substring str (1+ nom-index) end-of-nom))
					1))
		(den (if den-index
					(string->number (substring str (1+ den-index) (string-length str)))
					1)))
	 
	 (ly:make-duration length dot-count nom den)))


#(define (string->vectorDuration str)
	(let* (
		(i 0)
		(strList (string-split str #\space ))
		(len (length strList))
		(v (make-vector len))
	)
	 (map   
		(lambda (x)
		 (begin
			(vector-set! v i (string->duration x))
			(set! i (1+ i))
		)
		 x
	 )	
		strList
	)
	 v
 ))

%%%%%%%%%%%%%%%%%% the main function %%%%%%%%%%%%%%%%%%%%

applyRhythm  = #(define-music-function (parser location rhythm music) (string? ly:music?)
								(let* (
									(prevWasSpace #t)
									(trimmedStr 
									 (string-delete  
										(string-trim-right rhythm) 
										(lambda (c)
										 (let* 
											(
												(currentIsSpace (char=? c #\space))
												(res (and prevWasSpace currentIsSpace))
											)
											(if (not res) (set! prevWasSpace currentIsSpace))	
											res
										)
									 )
									)
								 )
								)
								 (set! rhythmVectorIndex 0)
								 (music-map 
									(lambda (x) 
									 (getChords x (string->vectorDuration trimmedStr)))
									music
								)
							 )) 
%% End of the scheme functions definitions
%% ( end of rhythm.ly if you use this separate file for them)


inegale = #(define-music-function (parser location music) (ly:music?)
					 #{ \applyRhythm "8. 16" $music #})
pseudoInegale = #(define-music-function (parser location music) (ly:music?)
					 #{ \applyRhythm "8.*8/9 16*4/3" $music #})
egale = #(define-music-function (parser location music) (ly:music?)
					#{ \scaleDurations #'(2 . 3) { \applyRhythm "4 8" $music } #})

\paper { ragged-right = ##f }
<<
	\relative c'' { \voiceOne
									\inegale { c c }
									\pseudoInegale { b b }
									\egale { a a }
									\times 2/3 { g8 g g }
								} \\
	\relative c' { \voiceTwo
								 \repeat unfold 4 \times 2/3 { f8 f f } }
>>

<<inline: rh.preview.png>>

_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to