Jump to content

Dynamically Creating Notes with Precise MIDI Velocity Value Control

From LilyPond wiki

This is an example how to control MIDI output with precise velocity control. The visible output is wild and has nothing to see; but the MIDI output is usable.

\version "2.24.0"

\paper { tagline = ##f }

#(define-public (extended-dynamic-absolute-volume s)
     (cond
      ((string? s )
       (default-dynamic-absolute-volume s))
      ((rational? s)
       (exact->inexact s))
      ((number? s )
       s)
      (else throw "this will never happen" )))

vel = #(define-event-function (velocity)(number?)
            (make-music 'AbsoluteDynamicEvent 'text velocity 'direction 1)
           )

sin-wave = #(define-scheme-function () ()
            (define frequency 512)
            (define loop-length 512)
            (make-music 'SequentialMusic
                'elements
                (let loop ((counter 0 ))
                    (let ((v
                           (+ (/ (sin (* PI
                                          (/ counter
                                              (/ frequency 32))))
                                  2 )
                               0.5 )))

                      (let (( v (if (< counter loop-length )
                                  (cons
                                    (make-music 'NoteEvent
                                                'pitch
                                                (ly:make-pitch 1 0 0 )
                                                'duration
                                                (ly:make-duration 8 0 1 )
                                                'articulations
                                                (list (make-music
                                                        'AbsoluteDynamicEvent
                                                        'tweaks '((stencil ()))
                                                        'direction
                                                        -1
                                                        'text
                                                        v ))
                                                )
                                    (loop (+ counter 1)))

                                  '())))
                        (if (= (modulo counter 64) 0 )
                          (append
                            (list
                              (make-music
                                'ContextSpeccedMusic
                                'context-type
                                'Timing
                                'element
                                (make-music
                                  'PropertySet
                                  'value
                                  ""
                                  'symbol
                                  'whichBar))
                              (make-music
                                'LineBreakEvent
                                'break-permission
                                'force))
                            v)
                          v))))))
\score {
    <<
        \set Score.dynamicAbsoluteVolumeFunction = #extended-dynamic-absolute-volume
        \sin-wave
    >>
    \layout {
        indent=0
        \context {
            \Score
        }
    }
    \midi {}
}