This file is indexed.

/usr/share/lilypond/2.14.2/scm/modal-transforms.scm is in lilypond-data 2.14.2-4.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
;;; modal-transforms.scm --- Modal transposition, inversion, and retrograde.

;; Copyright (C) 2011 Ellis & Grant, Inc.

;; Author: Michael Ellis <michael.f.ellis@gmail.com>

;; COPYRIGHT NOTICE

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
;; for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.


(define (transposer-factory scale)
  "Returns a transposer for the specified @var{scale}.
It is an error if either argument to a transposer is not in the scale
it was created with.  A transposer knows nothing about LilyPond
internals.  It treats scales as an ordered list of arbitrary items and
pitches as members of a scale.
"

  (define (index item lis)
    (list-index (lambda (x) (equal? item x)) lis))

  (lambda (from-pitch to-pitch pitch)
    (cond
     ((not (member from-pitch scale))
      (ly:warning (_i "'from' pitch not in scale; ignoring"))
      pitch)

     ((not (member to-pitch scale))
      (ly:warning (_i "'to' pitch not in scale; ignoring"))
      pitch)

     ((not (member pitch scale))
      (ly:warning (_i "pitch to be transposed not in scale; ignoring"))
      pitch)

     (else
      (list-ref scale
		(modulo
		 (+ (index pitch scale)
		    (- (index to-pitch scale)
		       (index from-pitch scale)))
		 (length scale)))))))

(define (inverter-factory scale)
  "Returns an inverter for the specified @var{scale}.
It is an error if either argument to an inverter
is not in the scale it was created with.  An inverter knows nothing
about LilyPond internals.  It treats scales as an ordered list of
arbitrary items and pitches as members of a scale.
"

  (define (index item lis)
    (list-index (lambda (x) (equal? item x)) lis))

  (lambda (around-pitch to-pitch pitch)
    (cond
     ((not (member around-pitch scale))
      (ly:warning (_i "'around' pitch not in scale; ignoring"))
      pitch)

     ((not (member to-pitch scale))
      (ly:warning (_i "'to' pitch not in scale; ignoring"))
      pitch)

     ((not (member pitch scale))
      (ly:warning (_i "pitch to be inverted not in scale; ignoring"))
      pitch)

     (else
      (list-ref scale
		(modulo
		 (+ (index to-pitch scale)
		    (- (index around-pitch scale)
		       (index pitch scale)))
		 (length scale)))))))

(define (replicate-modify lis n mod-proc)
  "Apply @code{(mod-proc lis n)} to each element of a list and
concatenate the results.  Knows nothing of LilyPond internals."
  (cond
   ((< n 0)
    (ly:warning (_i "negative replication count; ignoring")))
   ((= n 0)
    '())
   ((= n 1)
    (mod-proc lis 1))
   ((> n 1)
    (append
     (replicate-modify lis (- n 1) mod-proc)
     (mod-proc lis n)))))



(define-public (change-pitches music converter)
  "Recurse through @var{music}, applying @var{converter} to pitches.
Converter is typically a transposer or an inverter as defined above in
this module, but may be user-defined.  The converter function must take
a single pitch as its argument and return a new pitch.  These are
LilyPond scheme pitches, e.g. @code{(ly:make-pitch 0 2 0)}
"
  (let ((elements (ly:music-property music 'elements))
	(element (ly:music-property music 'element))
	(pitch (ly:music-property music 'pitch)))

    (cond
     ((ly:pitch? pitch)
      (ly:music-set-property! music 'pitch (converter pitch)))

     ((pair? elements)
      (map (lambda (x) (change-pitches x converter)) elements))

     ((ly:music? element)
      (change-pitches element converter)))))


(define (extract-pitch-sequence music)
  "Recurse through @var{music}, extracting pitches.
Returns a list of pitch objects, e.g
@code{'((ly:make-pitch 0 2 0) (ly:make-pitch 0 4 0) ... )}
Typically used to construct a scale for input to transposer-factory
(see).
"

  (let ((elements (ly:music-property music 'elements))
	(element (ly:music-property music 'element))
	(pitch (ly:music-property music 'pitch)))

    (cond
     ((ly:pitch? pitch)
      pitch)

     ((pair? elements)
      (map
       (lambda (x) (extract-pitch-sequence x))
       elements))

     ((ly:music? element)
      (extract-pitch-sequence element)))))

(define (make-scale music)
  "Convenience wrapper for extract-pitch-sequence."
  (map car (extract-pitch-sequence music)))


(define (make-extended-scale music)
  "Extend scale given by @var{music} by 5 octaves up and down."
  ;; This is a bit of a hack since, in theory, someone might want to
  ;; transpose further than 5 octaves from the original scale
  ;; definition.  In practice this seems unlikely to occur very often.
  (define extender
    (lambda (lis n)
      (map
       (lambda (i)
	 (ly:make-pitch
	  (+ (- n 6) (ly:pitch-octave i))
	  (ly:pitch-notename i)
	  (ly:pitch-alteration i)))
       lis)))

  (let ((scale (make-scale music)))
    (replicate-modify scale 11 extender)))


;; ------------- PUBLIC FUNCTIONS -----------------------------

(define-public (make-modal-transposer from-pitch to-pitch scale)
  "Wrapper function for transposer-factory."
  (let ((transposer (transposer-factory (make-extended-scale scale)))
	(from (car (extract-pitch-sequence from-pitch)))
	(to (car (extract-pitch-sequence to-pitch))))

    (lambda (p)
      (transposer from to p))))

(define-public (make-modal-inverter around-pitch to-pitch scale)
  "Wrapper function for inverter-factory"
  (let ((inverter (inverter-factory (make-extended-scale scale)))
	(around (car (extract-pitch-sequence around-pitch)))
	(to (car (extract-pitch-sequence to-pitch))))

    (lambda (p)
      (inverter around to p))))


(define-public (retrograde-music music)
  "Returns @var{music} in retrograde (reversed) order."
  ;; Copied from LSR #105 and renamed.
  ;; Included here to allow this module to provide a complete set of
  ;; common formal operations on motives, i.e transposition,
  ;; inversion and retrograding.

  (let* ((elements (ly:music-property music 'elements))
         (reversed (reverse elements))
         (element (ly:music-property music 'element))
         (span-dir (ly:music-property music 'span-direction)))

    (ly:music-set-property! music 'elements reversed)

    (if (ly:music? element)
        (ly:music-set-property!
         music 'element
         (retrograde-music element)))

    (if (ly:dir? span-dir)
        (ly:music-set-property! music 'span-direction (- span-dir)))

    (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)))