2

I am looking for a Lilypond function to transpose sequences of notes between modes that have different intervallic structure (e. g. from major to harmonic minor). My assumption is that the modes have identical number of pitches.

For example, I'd like to transpose this C-major sequence:

music = { c b d e}

to relative harmonic minor key, expecting these notes as the output:

a gis b c
  1. If use the \transpose function I will get transposition to A major:
\transpose c' a {\music}
% result: a gis b cis
  1. If I use the \modalTranspose function I will get transposition to A natural minor (not harmonic minor, as I expect):
majorScale = { \relative { c' d e f g a b  } }
\modalTranspose c' a \majorScale { \music }
% result: a g b c

It does not help to define a harmonic minor scale in the same way as majorScale, pitches that do not overlap will be left unmodified.

Is there a way to do this kind of transposition using built-in functions? Or do you perhaps have an example of a custom function for this?

1 Answer 1

2

\transpose will shift all pitches while keeping the relations between all pitches the same. \modalTranspose will not change the mode, but simply transpose to a specific different step while keeping the scale.

What you want is basically changing the scale while keeping the steps. This could be some somewhat like this:

transposeScale =
#(define-music-function (scaleA scaleB music) (ly:music? ly:music? ly:music?)
   (let* ((scaleA (ly:music-property scaleA 'elements))
          (scaleB (ly:music-property scaleB 'elements))
          (scaleA (map (lambda (x) (ly:music-property x 'pitch)) scaleA))
          (scaleB (map (lambda (x) (ly:music-property x 'pitch)) scaleB))
          (rootsA (map ly:pitch-notename scaleA)))
   (map-some-music
    (lambda (m)
      (let ((p (ly:music-property m 'pitch)))
        (if (not (null? p))
            (let* ((nn (ly:pitch-notename p))
                   (oct (ly:pitch-octave p))
                   (alt (ly:pitch-alteration p))
                   (pos (list-index (lambda (x) (= x nn)) rootsA))
                   (p2 (list-ref scaleA pos))
                   (oct2 (ly:pitch-octave p2))
                   (alt2 (ly:pitch-alteration p2))
                   (p3 (list-ref scaleB pos))
                   (new-pitch (ly:pitch-transpose p3 (ly:make-pitch (- oct oct2) 0 (- alt alt2)))))
              (ly:music-set-property! m 'pitch new-pitch)
              m)
            #f)))
    music)
   music))

\transposeScale { c d e f g a b } { c d es f g as b } { c' d' e' d' g' gis' a' b' c'' }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.