markup = chord_name->get_property ("text");
if (!Text_interface::is_markup (markup))
{
- Stream_event *inversion_event = 0;
for (vsize i = 0; i < notes_.size (); i++)
{
Stream_event *n = notes_[i];
if (!unsmob_pitch (p))
continue;
- if (n->get_property ("inversion") == SCM_BOOL_T)
- {
- inversion_event = n;
- inversion = p;
- }
- else if (n->get_property ("bass") == SCM_BOOL_T)
+ if (n->get_property ("bass") == SCM_BOOL_T)
bass = p;
else
- pitches = scm_cons (p, pitches);
- }
-
- if (inversion_event)
- {
- SCM oct = inversion_event->get_property ("octavation");
- if (scm_is_number (oct))
{
- Pitch *p = unsmob_pitch (inversion_event->get_property ("pitch"));
- int octavation = scm_to_int (oct);
- Pitch orig = p->transposed (Pitch (-octavation, 0, 0));
-
- pitches = scm_cons (orig.smobbed_copy (), pitches);
+ SCM oct = n->get_property ("octavation");
+ if (scm_is_number (oct))
+ {
+ Pitch orig = unsmob_pitch (p)->transposed (Pitch (-scm_to_int (oct), 0, 0));
+ pitches = scm_cons (orig.smobbed_copy (), pitches);
+ }
+ else
+ pitches = scm_cons (p, pitches);
+ if (n->get_property ("inversion") == SCM_BOOL_T)
+ {
+ inversion = p;
+ if (!scm_is_number (oct))
+ programming_error ("inversion does not have original pitch");
+ }
}
- else
- programming_error ("inversion does not have original pitch");
}
pitches = scm_sort_list (pitches, Pitch::less_p_proc);
;;;; along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
;; for define-safe-public when byte-compiling using Guile V2
-(use-modules (scm safe-utility-defs))
+(use-modules (scm safe-utility-defs) (ice-9 receive))
(define-public (construct-chord-elements root duration modifications)
"Build a chord on root using modifiers in @var{modifications}.
(define (make-chord-elements pitches bass duration inversion original-inv-pitch)
"Make EventChord with notes corresponding to PITCHES, BASS and
-DURATION, and INVERSION."
- (define (make-note-ev pitch)
- (make-music 'NoteEvent
- 'duration duration
- 'pitch pitch))
- (let ((nots (map make-note-ev pitches))
- (bass-note (if bass (make-note-ev bass) #f))
- (inv-note (if inversion (make-note-ev inversion) #f)))
- (if bass-note
- (begin
- (set! (ly:music-property bass-note 'bass) #t)
- (set! nots (cons bass-note nots))))
- (if inv-note
- (begin
- (set! (ly:music-property inv-note 'inversion) #t)
- (set! (ly:music-property inv-note 'octavation)
- (- (ly:pitch-octave inversion)
- (ly:pitch-octave original-inv-pitch)))
- (set! nots (cons inv-note nots))))
- nots))
+DURATION, and INVERSION. Notes above INVERSION are transposed downward
+along with the inversion as long as they end up below at least one
+non-inverted note."
+ (define (make-note-ev pitch . rest)
+ (apply make-music 'NoteEvent
+ 'duration duration
+ 'pitch pitch
+ rest))
+ (cond (inversion
+ (let* ((octavation (- (ly:pitch-octave inversion)
+ (ly:pitch-octave original-inv-pitch)))
+ (down (ly:make-pitch octavation 0 0)))
+ (define (invert p) (ly:pitch-transpose down p))
+ (define (make-inverted p . rest)
+ (apply make-note-ev (invert p) 'octavation octavation rest))
+ (receive (uninverted high)
+ (span (lambda (p) (ly:pitch<? p original-inv-pitch))
+ pitches)
+ (receive (invertible rest)
+ (if (null? uninverted)
+ ;; The following line caters for
+ ;; inversions "on the root", turning
+ ;; f/f into <f a' c''> rather than <f a c'>
+ ;; or <f' a' c''>
+ (values '() high)
+ (span (lambda (p)
+ (ly:pitch<? (invert p) (car uninverted)))
+ high))
+ (cons (make-inverted original-inv-pitch 'inversion #t)
+ (append (if bass (list (make-note-ev bass 'bass #t)) '())
+ (map make-inverted invertible)
+ (map make-note-ev uninverted)
+ (map make-note-ev rest)))))))
+ (bass (cons (make-note-ev bass 'bass #t)
+ (map make-note-ev pitches)))
+ (else (map make-note-ev pitches))))
;;;;;;;;;;;;;;;;
;; chord modifiers change the pitch list.