[prev in list] [next in list] [prev in thread] [next in thread] 

List:       lilypond-user
Subject:    Re: audible metronome in MIDI file?
From:       Jean Abou Samra <jean () abou-samra ! fr>
Date:       2022-04-28 5:38:04
Message-ID: 26fd46df-12e7-0fc0-25ab-7bbe3f401742 () abou-samra ! fr
[Download RAW message or body]

Le 28/04/2022 à 04:31, Kieren MacMillan a écrit :
> I was thinking the very same thing — seems like a custom performer (or 
> engraver?) would be amazing for this. I hope Someone™ likes the idea 
> enough to code it up!



Well, I tried that yesterday: it has become possible to write Scheme
performers with change from David K. in the 2.23 series. I arrived at
the following, but ultimately decided not to post it because there
is a big bad bug: if there is  no note or rest or skip or some sort
of event at a point of time, a tick can't get added there. That makes
it practically unusable. A pity that Global_context::add_moment_to_process
is not Scheme-accessible ...


Regards,
Jean



\version "2.23.9"

#(define (Metronome_performer context)
    (make-performer
     ((process-music performer)
      ;; TODO: check is baseMoment is always accurate
      (let ((reg (ly:context-property context 'baseMoment)))
        (when reg
          (let* ((mp (ly:context-property context 'measurePosition))
                 (strength
                  (cond
                   ((equal? mp ZERO-MOMENT)
                    'main)
                   ((integer? (ly:moment-main (ly:moment-div mp reg)))
                    'secondary)
                   (else
                    #f))))
            (when strength
              (let* ((source (ly:context-event-source context))
                     (cls (ly:make-event-class 'note-event))
                     (type (case strength
                             ((main) 'hiwoodblock)
                             ((secondary) 'lowoodblock)))
                     (props `((drum-type . ,type)
                              (length . ,reg)))
                     (ev (ly:make-stream-event cls props)))
                (ly:broadcast source ev)))))))))

\midi {
   \context {
     \name MetronomeTrack
     \type Performer_group
     %% This is veery ugly, but currently it is not possible to
     %% create audio items from Scheme performers, so ...
     \remove Drum_note_performer
     \consists #Metronome_performer
     \consists Drum_note_performer
     midiInstrument = "drums"
   }
   \inherit-acceptability MetronomeTrack DrumVoice
}

\layout {
   \context {
     \Score
     \accepts MetronomeTrack
   }
   \context {
     \Devnull
     \name MetronomeTrack
   }
}

%% Awful, but how to do better?? Of course, ideally the Metronome_performer
%% would be on Score level and create audio items itself, but for the time
%% being we have to use Drum_note_performer, which would duplicate drum 
notes
%% from all the score if it were put on Score level ...

#(set! toplevel-music-functions
        (cons (lambda (m)
                #{
                  <<
                    #m
                    \new MetronomeTrack { #(skip-of-length m) }
                  >>
                #})
              toplevel-music-functions))

\score {
   \midi { }
   \layout { }
   \relative c' {
     c'4( d8 e f g a b) c4( b8 a g f e d) c4-. c'-. c,2-^
   }
}


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic