lilypond-user
[Top][All Lists]
Advanced

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

Re: midi volume single note


From: Caagr98
Subject: Re: midi volume single note
Date: Tue, 14 Nov 2017 15:03:01 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0

You could also generate it dynamically at runtime, with something like this 
(please note that I haven't tested it):

gradual = #(define-music-function (f mus) (procedure? ly:music?)
  (make-simulaneous-music
    (list mus (make-sequential-music
                (let ((len (lambda (l) (ly:music-length (make-sequential-music 
l))))
                      (l '()))
                  (do () ((ly:moment<? (ly:music-length mus) (len l)) (reverse 
(cddr l)))
                    (set! l (cons (f (ly:moment-main (len l))) l))
                    (set! l (cons (make-skip-music (ly:make-duration 5)) l))
                    ))))))

crescNote = #(define-usic-function (from to mus) (number? number? ly:music?)
  (gradual (lambda (t)
             (let* ((e (/ t (ly:moment-main (ly:music-length mus))))
                    (e2 (+ from (* e (to - from)))))
               (make-property-set 'midiExpression e2)))
           mus))

Used as `\crescNote #0.5 1 c1`. It doesn't have anything to reset the 
expression back to 1 at the end, you'll have to add that manually. Also, there 
could possibly be instances where the generated extra part is slightly longer 
than the music (such as notes in triplets), which could throw off timing. 
Shouldn't be very hard to change, but I don't feel like doing that right now.

P.S. Scheme supports fractions as number literals. You could write `\set 
Voice.midiExpression=#31/32` and avoid all that hassle with decimals and 
rounding and stuff.

On 11/14/17 14:47, Gianmaria Lari wrote:
> On 14 November 2017 at 11:30, David Kastrup <address@hidden 
> <mailto:address@hidden>> wrote:
> 
>     Gianmaria Lari <address@hidden <mailto:address@hidden>> writes:
> 
>     > On 13 November 2017 at 13:31, Caagr98 <address@hidden 
> <mailto:address@hidden>> wrote:
>     >
>     >> I was thinking of something like this:
>     >>
>     >> <<
>     >>   { c'1 }
>     >>   { s8 \set Voice.midiExpression=#0.5 s2.. Voice.midiExpression=#1 }
>     >> >> c'1
>     >>
>     >> That is, simultaneously: a) play a note, b) wait a short while, reduce
>     >> volume, wait until rest of the note is finished (2.. is 7/8 of a 
> measure),
>     >> then reset to normal.
>     >>
>     >
>     > Thank you, perfect!!!!
>     >
>     > In case other people need it, here it is a complete example where c1 
> note
>     > is played reducing volume from maximum to minimum in step of 1/32.
>     >
>     > \version "2.19.80"
>     > right = \fixed c'' { c1 }
>     >
>     > dynamics = {
>     > s32 \set Voice.midiExpression=#1
>     > s32 \set Voice.midiExpression=#0.96774
>     > s32 \set Voice.midiExpression=#0.93548
>     > s32 \set Voice.midiExpression=#0.90323
>     [...]
>     > }
>     >
>     > \score {
>     >   \new Staff \with { midiInstrument = "accordion"}
>     >   \new Voice <<\right \dynamics>>
>     >   \midi {}
>     >   \layout {}
>     > }
> 
>     Well, that calls for something programmatic I think.
> 
> 
> Well, I was hoping that a nice guy pop up with your nice lily/scheme code:)  
> Thanks !!!
> 
> P.S.
> I didn't wrote the long list of "s32 \set Voice.midiExpression=#xxxxx" by 
> hand; I wrote some lines of code to generate them programmatically (much less 
> practical then your code but better than write them by hand). Here it is the 
> function I used:
> 
>         public string setVolume(float duration, int resolution, float 
> volumeStart, float volumeEnd)
>         {
>             int steps = (int)((1 / duration) / (1 / (float)resolution));
>             float val = (volumeStart - volumeEnd) / (steps - 1);
>             string s = "";
>             for (int i = 1; i <= steps; i++)
>             {
>                 s += "s" + resolution.ToString()+ " " + "\\set 
> Voice.midiExpression=#";
>                 s += Math.Round(volumeStart, 5).ToString() + "\n";
>                 volumeStart -= val;
>             }
>             return s;
>         }
> 



reply via email to

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