lilypond-user
[Top][All Lists]
Advanced

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

Re: how to get expression in midi


From: Dario Marrini
Subject: Re: how to get expression in midi
Date: Wed, 4 Jan 2017 21:56:34 +0100

many thanks Teoh,
I'll take time to study all you sent me, I see it's hard to understand in a first look... 

may you and anybody suggest me any MIDI editor avaluable for Linux? I don't use Windows anymore, since '99... 

I thought using lilypond might be better to manipulate some stuff like crescendo and diminuendo; simply putting two commands among notes; I have no idea how a midi editor could do that, but in case of a long crescendo (several bars) I think it's not a good idea using lilypond command, instead of changing singular notes' velocity; correct me if I am wrong

bye and thanks again

dario

2017-01-04 21:01 GMT+01:00 H. S. Teoh <address@hidden>:
On Wed, Jan 04, 2017 at 07:59:17PM +0100, Dario Marrini wrote:
[...]
>      * violin part has many 1/8 notes, many are repeating itselves,
>        listening the MIDI output it seems it's not very well, notes'
>        sounds are too much closing, and repeating notes sound like a
>        unique sound almost.  how may I fix this? I think it'd better
>        writing each 1/8 note as 'staccato', but may the Midi output
>        will be according on that?

You need a better midi soundfont or better midi synth.  This isn't
really something specific to Lilypond; it may be best to use a MIDI
editor to edit the notes yourself after generating it from lilypond.
Lilypond's midi capabilities are rather limited; what you're describing
is something that, while it is *possible* to fix using Lilypond, will
probably require much more work than it seems you're willing to spend on
it.

Resources you may find pertinent to your particular issue (note that
these are not specific to lilypond):

        https://www.youtube.com/watch?v=VaSqSieQ4gQ
        https://www.kvraudio.com/forum/viewtopic.php?t=365719
        http://forum.cakewalk.com/TIP-Killing-the-quotmachinegunquot-effect-programming-MIDI-m1520197.aspx


>        besides, it's very hard now to rewrite all the code, so, there
>        is some tool to do that, a sort of 'mass modifier' about the
>        text code? I dont' want to fight with my poor Perl
>        knowledge,,,,

I'm not sure what Perl has to do with this, unless you're talking about
mass textual substitution.  You could possibly write a Scheme function
to turn notes into staccato, but I'm not sure that's necessarily a good
idea (it makes your music harder to edit later).


>      * is it possible to change the velocity (volume?) of a single
>        long note?  example, brass ensemble start with a 'sf', then
>        play crescendo the same note while 'crescendo' from a 'p' to a
>        'f' again; I don't know if it is possible in a MIDI
>        environment, and how to perform this using lilypond notation

It is definitely possible in MIDI.  How to do it in lilypond is another
story. :-P  Lilypond itself doesn't have a built-in way of performing
cresc / decresc on a single note; but it *is* possible to use `\set
Staff.midiExpression` to alter the volume of a note while it is
sounding.

Using this idea, I wrote a Scheme function that generates a series of
gradual changes to Staff.midiExpression to simulate a cresc / decresc.
In fact, it can do "ramps" of almost any numerical context setting,
though I most often use it for midiExpression.  Put the below snippet
into a file, say prop-ramp.ly, then write \include "prop-ramp.ly" at the
top of your input file, and you can use the \propRamp command to
generate these events.

(Scheme experts will probably laugh at the klunky way I wrote this,
since I'm a Scheme n00b, but so far I've used this in several of my
pieces and it works fairly well.  Also, it currently hardcodes settings
to the Staff context; while this works for midiExpression, it may not
work so well for other properties -- you may have to change the
`'context-type 'Staff'` line to something else in those cases.)


------------------------------------snip------------------------------------
%
% Scheme function for generating linear ramping of numerical Staff property
% values to allow for true crescendos/diminuendos.
%
% Usage:
%       \propRamp <property symbol> <start value> <end value> <total duration>
%
% Example:
%       \new Staff {
%               << c'1  % a long note
%
%                  % Ramp midi _expression_ property for the above note
%                  % from 1.0 to 0.0 over a duration of a dotted 1/2 note.
%                  \propRamp #'midiExpression 1.0 0.0 2.
%               >>
%       }
%
\version "2.19.23"

#(define genPropertyRamp
    (lambda (propertySym start end i n duration)
        (if (>= i n)
            '()

            ; start + (end - start)*i/n
            (let ((curValue (+ start (/ (* i (- end start)) n))))

                ;(display "start = ")(display start)
                ;(display " end = ")(display end)
                ;(display " i = ")(display i)
                ;(display " curValue = ")(display curValue)
                ;(display "\n")

                (cons
                    ; \set Staff.midiExpression = #curValue
                    (make-music 'ContextSpeccedMusic
                        'context-type 'Staff
                        'element (make-music
                            'PropertySet
                            'symbol propertySym
                            'value curValue)
                    )
                    (cons
                        (make-music 'SkipEvent
                            'duration duration
                        )
                        (genPropertyRamp propertySym start end (+ i 1) n duration)
                    )
                )
            )
        )
    )
)

propRamp = #(define-music-function
    (propertySym startValue endValue totalDur)
    (symbol? number? number? ly:duration?)

    (let (
          ; Minimum number of midiExpression events such that consecutive
          ; values differ by not more than 1/128, which is the resolution of
          ; the coarse _expression_ control.
          (minEvents (inexact->exact
                      (round (* (abs (- endValue startValue)) 128))))
         )
         (let (
                ; Scale totalDur by 1/minEvents
                (eventDur
                    (let ((l (ly:duration-log totalDur))
                          (d (ly:duration-dot-count totalDur))
                          (factor (ly:duration-factor totalDur)))

                    (ly:make-duration l d (car factor)
                        ; Scale denominator of duration by minEvents
                        (* (cdr factor) minEvents)))
                )
            )
            (make-music
                'SequentialMusic
                'elements (genPropertyRamp propertySym startValue endValue
                           0 minEvents eventDur)
            )
        )
    )
)
------------------------------------snip------------------------------------


Note that the \propRamp command has some limitations:

- It cannot translate dynamic markings into _expression_ levels (e.g., \mf
  -> 0.5, \ff -> 0.75, etc.), so you have to use numerical values from
  0.0 to 1.0. See the scm/midi.scm file in your lilypond installation to
  find the default definitions of the built-in dynamic markings.

- If you default midiExpression to 1.0, then strictly speaking it's not
  possible to do crescendos, because you can't go above 1.0.  So if you
  want crescendo on a single note, say from p to f, then you have to
  write the final dynamic (\f) for the entire note, then start the
  \propRamp from a lower fraction corresponding to the starting dynamic,
  for example:

        <<
                c1\f
                { \propRamp #'midiExpression 0.5 1.0 1 }
        >>

  where 0.5 is my rough guess at the relative volume of \p to \f.  You
  can adjust this as necessary.

  Note that this means you probably have to use a different \score block
  for your music, so that the printed score has the correct dynamics
  (i.e., c1\p\<  ...\f instead of c1\f ...).  This is one of the reasons
  I always recommend putting your music in a variable, and writing two
  \score blocks, one for layout, and one for midi. Then use \tag and
  \removeWithTag for indicating what is intended for the printed score,
  and what's intended for midi only, e.g.:

        myMusic = <<
                \tag #'layout { c1\p\<  <>\f }  % "real" score
                \tag #'midi <<
                        c1\f
                        { \propRamp #'midiExpression 0.5 1.0 1 }
                >>
        >>

        % This score is only for layout
        \score {
                \removeWithTag #'midi \myMusic
                \layout {}
        }

        % This score is only for midi
        \score {
                \removeWithTag #'layout \myMusic
                \midi {}
        }

  Alternatively, you can change the default setting of midiExpression to
  0.5 at the beginning of your score, then you can do ramps from 0.5 to
  1.0 to double the starting volume of the note, for example, and write
  dynamics the "usual" way.  (But either way, I still recommend
  separating the layout and midi scores, because to get decent midi
  output from lilypond you almost inevitably need to write some
  "unusual" things only meant for controlling midi output, that you
  don't want to appear in the printed score.)


--T

_______________________________________________
lilypond-user mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/lilypond-user


reply via email to

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