summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenk Pl <benko.pal@gmail.com>2011-02-22 11:26:05 +0000
committerTrevor Daniels <t.daniels@treda.co.uk>2011-02-22 12:43:08 +0000
commitd245674e0266cde01a425317fa28aeb792ce589d (patch)
treeee55d70d84580e90654ff74795862bccb4e3e5bf
parent1881044742efa5072bad5e31189e610ed3988270 (diff)
Add exact inversion
-rw-r--r--Documentation/notation/pitches.itely17
-rw-r--r--input/regression/modal-transforms.ly2
-rw-r--r--ly/music-functions-init.ly7
-rw-r--r--scm/modal-transforms.scm17
4 files changed, 43 insertions, 0 deletions
diff --git a/Documentation/notation/pitches.itely b/Documentation/notation/pitches.itely
index 78a222794d..4ee236cfda 100644
--- a/Documentation/notation/pitches.itely
+++ b/Documentation/notation/pitches.itely
@@ -594,6 +594,7 @@ This section discusses how to modify pitches.
@menu
* Octave checks::
* Transpose::
+* Inversion::
* Modal transformations::
@end menu
@@ -813,6 +814,22 @@ The relative conversion will not affect @code{\transpose},
To use relative mode within transposed music, an additional
@code{\relative} must be placed inside @code{\transpose}.
+@node Inversion
+@unnumberedsubsubsec Inversion
+
+@cindex inversion
+
+A music expression can be inverted with @code{\inversion}.
+
+@example
+\inversion @var{frompitch} @var{topitch} @var{musicexpr}
+@end example
+
+@noindent
+This means that @code{@var{musicexpr}} is inverted
+interval-by-interval, and transposition is chosen so that
+@code{@var{frompitch}} is mapped to @code{@var{topitch}}.
+
@node Modal transformations
@unnumberedsubsubsec Modal transformations
diff --git a/input/regression/modal-transforms.ly b/input/regression/modal-transforms.ly
index 9070601510..7487f2b8bf 100644
--- a/input/regression/modal-transforms.ly
+++ b/input/regression/modal-transforms.ly
@@ -22,12 +22,14 @@ motif = {
\modalTranspose c' f' \cOctatonicScale \motif
\retrograde \motif
\modalInversion aes' b' \cOctatonicScale \motif
+ \inversion aes' b' \motif
}
{
s1-"Octatonic motif" |
s1-"motif transposed from c to f" |
s1-"motif in retrograde" |
s1-"motif inverted around aes to b" |
+ s1-"motif inverted exactly"
}
>>
}
diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly
index 34261c114b..ac62bffa9a 100644
--- a/ly/music-functions-init.ly
+++ b/ly/music-functions-init.ly
@@ -480,6 +480,13 @@ using @var{scale}.")
(change-pitches music transposer)
music))
+inversion =
+#(define-music-function
+ (parser location around to music) (ly:music? ly:music? ly:music?)
+ (_i "Invert @var{music} about @var{around} and
+transpose from @var{around} to @var{to}.")
+ (music-invert around to music))
+
musicMap =
#(define-music-function (parser location proc mus) (procedure? ly:music?)
(_i "Apply @var{proc} to @var{mus} and all of the music it contains.")
diff --git a/scm/modal-transforms.scm b/scm/modal-transforms.scm
index cdaa015ccc..151fb8c3be 100644
--- a/scm/modal-transforms.scm
+++ b/scm/modal-transforms.scm
@@ -220,3 +220,20 @@ Typically used to construct a scale for input to transposer-factory
(map retrograde-music reversed)
music))
+
+(define-public (pitch-invert around to music)
+ "If @var{music} is a single pitch, inverts it about @var{around}
+and transposes from @var{around} to @var{to}."
+ (let ((p (ly:music-property music 'pitch)))
+ (if (ly:pitch? p)
+ (ly:music-set-property!
+ music 'pitch
+ (ly:pitch-transpose to (ly:pitch-diff around p))))
+ music))
+
+(define-public (music-invert around-pitch to-pitch music)
+ "Applies pitch-invert to all pitches in @var{music}."
+ (let ((around (car (extract-pitch-sequence around-pitch)))
+ (to (car (extract-pitch-sequence to-pitch))))
+ (music-map (lambda (x) (pitch-invert around to x)) music)))
+