lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Midi program channels


From: Heikki Tauriainen
Subject: Re: Midi program channels
Date: Sat, 09 Aug 2014 11:42:26 +0300

Hi,

On Thu, 2014-08-07 at 14:46 -0500, Guy Stalnaker wrote:
> Has anyone given thought to the possibility of having the MIDI
> instrument names correspond to a given soundfont's program
> instruments?
> 
> ...
>
> What would happen if one were to edit midi.scm and remove the
> instrument names as specified and replace them with Inst001, Inst002,
> etc--very generic--which at least makes the kind of mapping I'm
> talking about a bit less odd when MIDIInstrument is shown in the
> lilypond file as "Acoustic Piano" but what sounds is something else
> entirely when the soundfont is not a GM soundfont.

Modifying the instrument names directly in midi.scm's
instrument-names-alist would break compatibility with existing LilyPond
files: changes in MIDI instruments in those files would no longer have
the intended effect because the pre-defined instrument names would have
changed.

However, it could be possible to define an auxiliary mapping from MIDI
program numbers to instrument names, and a helper function to fetch the
instrument name corresponding to a program number by adding the
following lines of code to midi.scm (just before the comment line
starting with "90 == 90/127 == 0.71 is supposed to..."):

----

(define midi-program-number-to-midi-instrument (make-vector 128))

(letrec ((update-mapping
         (lambda (instrument-list)
           (if (null? instrument-list)
               #t
               (let ((instrument-name (caar instrument-list))
                     (midi-program-number (cdar instrument-list)))
                 (if (< midi-program-number 128)
                     (vector-set! midi-program-number-to-midi-instrument
                                  midi-program-number
                                  instrument-name))
                 (update-mapping (cdr instrument-list)))))))
  (update-mapping instrument-names-alist))

(define-public (midi-instrument-from-program-number midi-program-number)
  "Return the name of the instrument corresponding to a program number."

  (if (and (integer? midi-program-number)
           (>= midi-program-number 1)
           (<= midi-program-number 128))
      (vector-ref midi-program-number-to-midi-instrument
                  (- midi-program-number 1))
      #f))

----

The above code will define a "midi-instrument-from-program-number"
function which maps MIDI program numbers (between 1-128; the drum kit
numbers defined in instrument-names-alist are not supported) to their
corresponding General MIDI instrument names.  It could be used in
LilyPond code as follows:

----

\score {
  \new Staff {
    % select "trumpet" as the MIDI instrument using the program number
    \set Staff.midiInstrument = #(midi-instrument-from-program-number
57)
    a'1
  }
  \midi { }
}

----

This workaround solution still has the minor inconvenience that LilyPond
will still keep emitting bogus (General MIDI) instrument names to
generated MIDI files on instrument changes in the input.  Fixing this
would probably require changes to the C++ internals.

(I've wondered myself whether the Staff.midiInstrument context property
could be extended to accept both numeric program numbers and string
instrument names, to make using custom sets of MIDI instruments more
convenient, that is, without the need to map program numbers to General
MIDI instrument names.)

Regards,
Heikki

-- 
Heikki Tauriainen





reply via email to

[Prev in Thread] Current Thread [Next in Thread]