[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Rootless slash chords, 2017 edition
From: |
Thomas Morley |
Subject: |
Re: Rootless slash chords, 2017 edition |
Date: |
Thu, 30 Mar 2017 00:06:23 +0200 |
2017-03-28 19:49 GMT+02:00 Thomas Morley <address@hidden>:
> 2017-03-28 0:39 GMT+02:00 Dmitry <address@hidden>:
>> - in Chord_name_engraver::process_music, track repeating root parts of
>> slash chords and pass NIL pitches to a chordNameFunction in case of
>> repetition. Everything should be similar to handling chordChanges,
>> however this time we should remember and compare whole chord
>> structures, not markup.
>
> %% Tries to compare the relevant parts of the markups for current and previous
> %% chord.
> %%
> %% Probably it would be far easier to compare actual pitches
Below some code actually tracking and comparing pitches.
The bass-only feature can be switched on/off.
One limitation persists, inversions are not recognized, see third example.
\version "2.19.57"
#(define (define-translator-property symbol type? description)
(if (not (and (symbol? symbol)
(procedure? type?)
(string? description)))
(ly:error "error in call of define-translator-property"))
(if (not (equal? (object-property symbol 'translation-doc) #f))
(ly:error (_ "symbol ~S redefined") symbol))
(set-object-property! symbol 'translation-type? type?)
(set-object-property! symbol 'translation-doc description)
symbol)
#(for-each
(lambda (x)
(apply define-translator-property x))
`(
(dropEqualRoot
,boolean?
"To be used in @code{ChordName}-context. If set @code{#t}, successive
chords, which differ only in their bass, will have only this bass printed.")
))
#(define (test-engraver ctx)
(let ((prev '())
(notes '())
(chord-name-grobs '()))
(make-engraver
(listeners
((note-event engraver ev)
(set! notes (cons (ly:prob-property ev 'music-cause) notes))))
(acknowledgers
((chord-name-interface engraver grob source-engraver)
(set! chord-name-grobs (cons grob chord-name-grobs))))
((stop-translation-timestep translator)
(let* (;; not sure yet, whether 'sorted-notes' is needed and should
;; replace 'notes' in 'current-bass+elts'
;(sorted-notes
; (sort
; notes
; (lambda (n1 n2)
; (ly:pitch<?
; (ly:music-property n1 'pitch)
; (ly:music-property n2 'pitch)))))
;
(current-bass+elts
(call-with-values
(lambda ()
(partition
(lambda (n)
(or (boolean? (ly:music-property n 'bass))
(boolean? (ly:music-property n 'inversion))))
notes))
(lambda (a b)
(list
(map (lambda (n) (ly:music-property n 'pitch)) a)
(map (lambda (n) (ly:music-property n 'pitch)) b))))))
(if (and (pair? prev)
(pair? (car current-bass+elts))
(not (equal? (car current-bass+elts) (car prev)))
(ly:context-property ctx 'dropEqualRoot)
(equal? (cdr current-bass+elts) (cdr prev)))
(ly:grob-set-property! (car chord-name-grobs) 'text
(make-line-markup
(list
(ly:context-property ctx 'slashChordSeparator)
(note-name->markup (caar current-bass+elts) #f)))))
(set! prev current-bass+elts)
(set! chord-name-grobs '())
(set! notes '())))
((finalize translator)
(set! prev '())))))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% EXAMPLES
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paper {
indent = 0
ragged-right = ##f
}
\layout {
\context {
\Score
\override RehearsalMark.self-alignment-X = #LEFT
}
\context {
\Staff
\accidentalStyle forget
}
\context {
\ChordNames
dropEqualRoot = ##t
\consists \test-engraver
}
}
%%%%%%%
%% I
%%%%%%%
\markup
\rounded-box \fill-line { "Various tests" }
tstI =
\chordmode {
c4:m/e c:m c:m/+g c:m/fes c/fes c/d c:7/d c:7/+g d e e:m f:m f:m f
}
<<
\new ChordNames \tstI
\new Staff \tstI
>>
%%%%%%%
%% II
%%%%%%%
\markup
\rounded-box \fill-line { "Test switching on/off via \"dropEqualRoot\"" }
tstII =
\chordmode {
\mark "dropEqualRoot = ##t in \\layout"
c4
c/f
c:m7
c:m7/+bes
c:m7
c:m7/cis
r2
\break
\set dropEqualRoot = ##f
\mark "\\set dropEqualRoot = ##f"
c4
c/f
c:m7
c:m7/+bes
c:m7
c:m7/cis
r2
\break
\unset dropEqualRoot
\mark "\\set dropEqualRoot = ##t"
c4
c/f
c:m7
c:m7/+bes
c:m7
c:m7/cis
r2
}
<<
\new ChordNames \tstII
\new Staff \tstII
>>
%%%%%%%
%% III
%%%%%%%
\markup
\rounded-box \fill-line {
\column {
"Limitation:"
\wordwrap-string
%% jEdit highlighting is not smart enough, thus the strange line-break ...
#"Here the \"root
\"-part is never dropped, because the main-chords are always different, which
can't be observed in ChordNames, though.
All chords but the last are inversions!"
}
}
tstIII =
\chordmode {
c:m7
c:m7/bes
c:m7/g
c:m7/ees
c:m7/+bes
}
<<
\new ChordNames \tstIII
\new Staff \tstIII
>>
HTH,
Harm