Re: Automatic cross-staff chords - testing help
woops, I used % instead of ; in scheme here the right code :) Davide \version "2.20.0" #(define (split-music dir music ref) (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) (split-music dir x ref)) es))) (if (ly:music? e) (ly:music-set-property! music 'element (split-music dir e ref))) (if (ly:pitch? p) (if ((if (> dir 0) >= <) (ly:pitch-steps p) (ly:pitch-steps ref)) p (ly:music-set-property! music 'name 'SkipEvent) ; works, but produces warnings )) music )) splitMusic = #(define-music-function (parser location dir ref music ) ((ly:dir? 1) (ly:pitch? (ly:make-pitch 0 0)) ly:music? ) (split-music dir music ref)) Il 10/01/2021 22:12, Davide Bonetti ha scritto: I did it! the code works, but produces warnings. Cheers Davide \version "2.20.0" #(define (split-music dir music ref) (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) (split-music dir x ref)) es))) (if (ly:music? e) (ly:music-set-property! music 'element (split-music dir e ref))) (if (ly:pitch? p) (if ((if (> dir 0) >= <) (ly:pitch-steps p) (ly:pitch-steps ref)) p (ly:music-set-property! music 'name 'SkipEvent) ; works, but produces warnings )) music )) splitMusic = #(define-music-function (parser location dir ref music ) ((ly:dir? 1) (ly:pitch? (ly:make-pitch 0 0)) ly:music? ) (split-music dir music ref)) %%% %Examples someMusic = { c d e g c' d' c'' \chordmode{d:7/a} << {c' d' e' f'} \\ {c d e f}>> d'2. \relative c' {c1 b a g} << \chordmode { c4 d e f} \\ \transpose c c, \chordmode {c d e f}>> << {c' b e' f'} \\ {c, e, c2} \\ {g2 a4 b}>> } \markup "Some music" {\someMusic} \markup "\SplitMusic result on piano staff" \new PianoStaff << \new Staff {\splitMusic \someMusic} \new Staff { \clef bass \splitMusic #DOWN \someMusic } >> \markup "\SplitMusic result on SATB (with arbitrary split-points)" \new StaffGroup << \new Staff { \clef soprano \splitMusic #UP f' \someMusic } \new Staff { \clef alto \splitMusic #DOWN f' \splitMusic #UP a \someMusic } \new Staff { \clef tenor \splitMusic #DOWN a \splitMusic #UP d \someMusic } \new Staff { \clef baritone \splitMusic #DOWN d \someMusic } >> Il 08/01/2021 00:55, Thomas Morley ha scritto: Am Do., 7. Jan. 2021 um 13:08 Uhr schrieb Davide Bonetti : Hi, Great work. I've done some testing and found some bugs. Below the code I've tested, attached the PDF with the result (on second page, first page are your examples). \autoSplitChord doesn't works with curly braces, it returns blank output (like a blank space in the score), so it's not possible to work with: - chordmode - more than one chord a time - moltiple voices Also, \autoSplitChord doesn't works with single notes, it returns blank space. It accepts variables, but the result is the same. Pippo = 1 PippoDue = \chordmode {c1:/g} PippoTre = c1 PippoQuattro = {} \new PianoStaff \with { \consists #Span_stem_engraver } << \new Staff = "up" { \key c\major %chord with stem up \autoSplitChord #UP 2 %works %chord without stem \autoSplitChord 4 %works %chord with stem down \autoSplitChord #DOWN %works %chord, whole note \autoSplitChord 1 %works %chordmode \autoSplitChord \chordmode {c:/g} %blank output %chord entered in curly braces \autoSplitChord {} %blank output %more than one chord, in curly braces \autoSplitChord { } %blank output %single note \autoSplitChord c %blank output %single note in a chord \autoSplitChord %works %chord entered in polyphonic style \autoSplitChord <> %works %polyphonic style, different durations \autoSplitChord <> %warning & strange output %polyphonic style, with some curly braces \autoSplitChord <> %notes in curly braces are not printed %polyphonic style, with curly braces \autoSplitChord << {c4 d e f} \\ {c' d' e' f'} >> %blank output %chord in a variable \autoSplitChord \Pippo %works %chord in a variable with chordmode \autoSplitChord \PippoDue %blank output %single note in a variable \autoSplitChord \PippoTre %blank
Re: Automatic cross-staff chords - testing help
I did it! the code works, but produces warnings. Cheers Davide \version "2.20.0" #(define (split-music dir music ref) (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) (split-music dir x ref)) es))) (if (ly:music? e) (ly:music-set-property! music 'element (split-music dir e ref))) (if (ly:pitch? p) (if ((if (> dir 0) >= <) (ly:pitch-steps p) (ly:pitch-steps ref)) p (ly:music-set-property! music 'name 'SkipEvent) % works, but produces warnings )) music )) splitMusic = #(define-music-function (parser location dir ref music ) ((ly:dir? 1) (ly:pitch? (ly:make-pitch 0 0)) ly:music? ) (split-music dir music ref)) %%% %Examples someMusic = { c d e g c' d' c'' \chordmode{d:7/a} << {c' d' e' f'} \\ {c d e f}>> d'2. \relative c' {c1 b a g} << \chordmode { c4 d e f} \\ \transpose c c, \chordmode {c d e f}>> << {c' b e' f'} \\ {c, e, c2} \\ {g2 a4 b}>> } \markup "Some music" {\someMusic} \markup "\SplitMusic result on piano staff" \new PianoStaff << \new Staff {\splitMusic \someMusic} \new Staff { \clef bass \splitMusic #DOWN \someMusic } >> \markup "\SplitMusic result on SATB (with arbitrary split-points)" \new StaffGroup << \new Staff { \clef soprano \splitMusic #UP f' \someMusic } \new Staff { \clef alto \splitMusic #DOWN f' \splitMusic #UP a \someMusic } \new Staff { \clef tenor \splitMusic #DOWN a \splitMusic #UP d \someMusic } \new Staff { \clef baritone \splitMusic #DOWN d \someMusic } >> Il 08/01/2021 00:55, Thomas Morley ha scritto: Am Do., 7. Jan. 2021 um 13:08 Uhr schrieb Davide Bonetti : Hi, Great work. I've done some testing and found some bugs. Below the code I've tested, attached the PDF with the result (on second page, first page are your examples). \autoSplitChord doesn't works with curly braces, it returns blank output (like a blank space in the score), so it's not possible to work with: - chordmode - more than one chord a time - moltiple voices Also, \autoSplitChord doesn't works with single notes, it returns blank space. It accepts variables, but the result is the same. Pippo = 1 PippoDue = \chordmode {c1:/g} PippoTre = c1 PippoQuattro = {} \new PianoStaff \with { \consists #Span_stem_engraver } << \new Staff = "up" { \key c\major %chord with stem up \autoSplitChord #UP 2 %works %chord without stem \autoSplitChord 4%works %chord with stem down \autoSplitChord #DOWN %works %chord, whole note \autoSplitChord 1%works %chordmode \autoSplitChord \chordmode {c:/g} %blank output %chord entered in curly braces \autoSplitChord {} %blank output %more than one chord, in curly braces \autoSplitChord { } %blank output %single note \autoSplitChord c %blank output %single note in a chord \autoSplitChord %works %chord entered in polyphonic style \autoSplitChord <>%works %polyphonic style, different durations \autoSplitChord <>%warning & strange output %polyphonic style, with some curly braces \autoSplitChord <>%notes in curly braces are not printed %polyphonic style, with curly braces \autoSplitChord << {c4 d e f} \\ {c' d' e' f'} >>%blank output %chord in a variable \autoSplitChord \Pippo%works %chord in a variable with chordmode \autoSplitChord \PippoDue%blank output %single note in a variable \autoSplitChord \PippoTre%blank output %chord in curly braces in a variable \autoSplitChord \PippoQuattro%blank output } \new Staff = "down" { \key c\major \clef bass s1 } >> Thank you for the work. Cheers Davide Hi Davide, many thanks for testing. Though, `autoSplitChord` is meant ot be a tool applied to chords, i.e. event-chords. All of: \chordmode { c:/g } { } << {c4 d e f} \\ {c' d' e' f'} is sequential or simultaneous music. A single note-event like c'4 is not an event-chord as well. In all those cases `autoSplitChord` is not expected to work. \autoSplitChord << b \\ e' \\ g'' >> works more by accident. Below is an improved function which will simply returns the input, if it's not an event-chord, avoiding the blank space. \autoSplitChord << b \\ e' \\ g'' >> will stop working as well, all notes are returned unchanged. autoSplitChord = #(define-music-function (stem-dir staff-names pitch chord) ((ly:dir? 0) (pair? '("up
re: Automatic cross-staff chords - testing help
Update: \autoSplitChord \chordmode { c:/g} doesn't work, but: \chordmode { \autoSplitChord c:/g} works. So, if we can make \autoSplitChord accept sequences of music, that can include chords or succession of chords, we'll have our goal. Cheers Davide -- Questa e-mail è stata controllata per individuare virus con Avast antivirus. https://www.avast.com/antivirus
Re: Automatic cross-staff chords - testing help
Hi Harm, many thanks for testing. thanks to you for the reply. Below is an improved function which will simply returns the input, if it's not an event-chord, avoiding the blank space. \autoSplitChord << b \\ e' \\ g'' >> will stop working as well, all notes are returned unchanged. I see you've put an if condition to exclude input that is not event-chord. There is now a problem: the below staff is not printed when there is not an event-chord, and when an event-chord returns, a new staff is printed (with treble clef). Pippo = 1 PippoDue = \chordmode {c1:/g} PippoTre = c1 PippoQuattro = {} \new PianoStaff \with { \consists #Span_stem_engraver } << \new Staff = "up" { \key c\major \autoSplitChord #UP 2 \autoSplitChord 4 \autoSplitChord #DOWN \autoSplitChord 1 \autoSplitChord \chordmode {c:/g} \autoSplitChord {} \autoSplitChord { } \autoSplitChord c \autoSplitChord \autoSplitChord <> \autoSplitChord <> \autoSplitChord <> \autoSplitChord << {c4 d e f} \\ {c' d' e' f'} >> \autoSplitChord \Pippo \autoSplitChord \PippoDue \autoSplitChord \PippoTre \autoSplitChord \PippoQuattro } \new Staff = "down" { \key c\major \clef bass s1 %bass staff appear only at the beginning, then reappears as another staff with treble clef } >> To avoid the problem, one can declare the lenght of the bass staff: [...] \new Staff = "down" { \key c\major \clef bass \repeat unfold 16 s1 %bass staff is shown correctly } >> As shown in the attached files. Perhaps there is a method to let the second staff to be printed without having to declare it's lenght. \autoSplitChord is supposed to work on a single chord of a single Voice. Like \autochange works an single notes of a single Voice. Maybe there's a recursive (or something similar) method so \autoSplitChord can work with chord sequences. \autochange accepts sequential input. Best would be a combination, I'll continue thinking about it. Me too. Scheme is not so intuitive for me, but sometimes I find a solution. Thank you Davide -- Questa e-mail è stata controllata per individuare virus con Avast antivirus. https://www.avast.com/antivirus \version "2.20.0" #(define (make-autosplit-chord chord . ref-pitch) "Return a pair of lists, containing the pitches of @var{chord}, splitted at a reference pitch. The reference pitch is derived from @var{ref-pitch}. If @var{ref-pitch} is empty, @code{c'} is regarded as reference. " (define ref-pitch-steps (if (and (pair? ref-pitch) (car ref-pitch)) (ly:pitch-steps (car ref-pitch)) 0)) (call-with-values (lambda () (partition (lambda (note) (> (ly:pitch-steps (ly:music-property note 'pitch)) ref-pitch-steps)) (event-chord-notes chord))) (lambda (x y) (cons x y autoSplitChord = #(define-music-function (stem-dir staff-names pitch chord) ((ly:dir? 0) (pair? '("up" . "down")) (ly:pitch?) ly:music?) (_i "Split @var{chord} at optional @var{pitch}. The default of @var{pitch} is @code{#f}, which is interpreted by the called procedure @code{make-autosplit-chord} as @code{c'}. The splitted chords are distributed to named staves, relying on optional @var{staff-names}. The optional @var{stem-dir}, determines the direction of the stems and whether the chords may be connected by a cross-staff stem. The default results in unconnected chords. If the @code{Span_stem_engraver} is consisted, the chords may be connected by a cross-staff stem.") (if (music-is-of-type? chord 'event-chord) (let* ((skip (make-duration-of-length (ly:music-length chord))) (devided-pitches (make-autosplit-chord chord pitch)) (upper-chord (if (pair? (car devided-pitches)) (make-event-chord (car devided-pitches)) (make-skip-music skip))) (lower-chord (if (pair? (cdr devided-pitches)) (make-event-chord (cdr devided-pitches)) (make-skip-music skip #{ << \context Staff = #(car staff-names) \context Voice { $(if (negative? stem-dir) #{ \once \override Stem.cross-staff = #cross-staff-connect \once \override Flag.style = #'no-flag <>\noBeam #}) $(if (not (zero? stem-dir)) #{ \once \override Stem.direction = #stem-dir #}) #upper-chord } \context Staff = #(cdr staff-names) \context Voice { $(if (positive? stem-dir) #{ \once \override Stem.cross-staff = #cross-staff-connect \once \override Flag.style = #'no-flag <>\noBeam
Re: Automatic cross-staff chords - testing help
Am Do., 7. Jan. 2021 um 13:08 Uhr schrieb Davide Bonetti : > > Hi, > > Great work. > > I've done some testing and found some bugs. Below the code I've tested, > attached the PDF with the result (on second page, first page are your > examples). > > \autoSplitChord doesn't works with curly braces, it returns blank output > (like a blank space in the score), so it's not possible to work with: > - chordmode > - more than one chord a time > - moltiple voices > > Also, \autoSplitChord doesn't works with single notes, it returns blank > space. > > It accepts variables, but the result is the same. > > Pippo = 1 > PippoDue = \chordmode {c1:/g} > PippoTre = c1 > PippoQuattro = {} > > \new PianoStaff > \with { \consists #Span_stem_engraver } > << >\new Staff = "up" >{ > \key c\major > %chord with stem up > \autoSplitChord #UP 2 %works > %chord without stem > \autoSplitChord 4%works > %chord with stem down > \autoSplitChord #DOWN %works > %chord, whole note > \autoSplitChord 1%works > %chordmode > \autoSplitChord \chordmode {c:/g} %blank output > %chord entered in curly braces > \autoSplitChord {} %blank output > %more than one chord, in curly braces > \autoSplitChord { } %blank output > %single note > \autoSplitChord c %blank output > %single note in a chord > \autoSplitChord %works > %chord entered in polyphonic style > \autoSplitChord <>%works > %polyphonic style, different durations > \autoSplitChord <>%warning & strange output > %polyphonic style, with some curly braces > \autoSplitChord <>%notes in curly braces are > not printed > %polyphonic style, with curly braces > \autoSplitChord << >{c4 d e f} >\\ >{c' d' e' f'} > >>%blank output > %chord in a variable > \autoSplitChord \Pippo%works > %chord in a variable with chordmode > \autoSplitChord \PippoDue%blank output > %single note in a variable > \autoSplitChord \PippoTre%blank output > %chord in curly braces in a variable > \autoSplitChord \PippoQuattro%blank output >} >\new Staff = "down" >{ > \key c\major > \clef bass > s1 >} > >> > > Thank you for the work. > > Cheers > > Davide Hi Davide, many thanks for testing. Though, `autoSplitChord` is meant ot be a tool applied to chords, i.e. event-chords. All of: \chordmode { c:/g } { } << {c4 d e f} \\ {c' d' e' f'} >> is sequential or simultaneous music. A single note-event like c'4 is not an event-chord as well. In all those cases `autoSplitChord` is not expected to work. \autoSplitChord << b \\ e' \\ g'' >> works more by accident. Below is an improved function which will simply returns the input, if it's not an event-chord, avoiding the blank space. \autoSplitChord << b \\ e' \\ g'' >> will stop working as well, all notes are returned unchanged. autoSplitChord = #(define-music-function (stem-dir staff-names pitch chord) ((ly:dir? 0) (pair? '("up" . "down")) (ly:pitch?) ly:music?) (_i "Split @var{chord} at optional @var{pitch}. The default of @var{pitch} is @code{#f}, which is interpreted by the called procedure @code{make-autosplit-chord} as @code{c'}. The splitted chords are distributed to named staves, relying on optional @var{staff-names}. The optional @var{stem-dir}, determines the direction of the stems and whether the chords may be connected by a cross-staff stem. The default results in unconnected chords. If the @code{Span_stem_engraver} is consisted, the chords may be connected by a cross-staff stem.") (if (music-is-of-type? chord 'event-chord) (let* ((skip (make-duration-of-length (ly:music-length chord))) (devided-pitches (make-autosplit-chord chord pitch)) (upper-chord (if (pair? (car devided-pitches)) (make-event-chord (car devided-pitches)) (make-skip-music skip))) (lower-chord (if (pair? (cdr devided-pitches)) (make-event-chord (cdr devided-pitches)) (make-skip-music skip #{ << \context Staff = #(car staff-names) \context Voice { $(if (negative? stem-dir) #{ \once \override Stem.cross-staff = #cross-staff-connect \once \override Flag.style = #'no-flag <>\noBeam #}) $(if (not (zero? stem-dir)) #{ \once \override Stem.direction = #stem-dir #}) #upper-chord } \context Staff = #(cdr staff-names) \context Voice { $(if (positive? stem-dir) #{