Re: How should I convert an existing ".ly" file to a MIDI file containing audible arpeggios?

2020-12-06 Thread Thomas Morley
Am Sa., 5. Dez. 2020 um 21:42 Uhr schrieb Petr Pařízek
:
>
> Thomas Morley wrote:
>
>
>  > Amending the shared code, you could probably do
>
> [snip]
>
> Could you explain what your suggested piece of code actually does --
> i.e. what's the supposed input data and what's the supposed output?
> Thanks.
>
> Petr
>
>
>
> --
> Tento e-mail byl zkontrolován na viry programem AVG.
> http://www.avg.cz
>
>

Not sure I understand your question.
Iiuc, it does what you want:
It takes a music-expression and transforms every found chord with
\arpeggio into simultaneous music (via applying `midiArpeggio`).
As a result you'll hear an arpeggio in midi.

Full example attached.

Cheers,
  Harm
%% by H. S. Teoh
%% https://lists.gnu.org/archive/html/lilypond-user/2020-12/msg00036.html
%
% A scheme function that unpacks a rolled chord into displaced notes with
% adjusted lengths such that it will render nicely in MIDI.
%
\version "2.20.1"

% Returns: A skip followed by the given note, with the skip scaled by n/d of
% the note's length, and the note scaled by (d-n)/d of its original length.
#(define shiftedNote (lambda (num denom note)
(if (= num 0)
; First note is unchanged
note
; Construct a skip + the note, both appropriately scaled
(let ((dLog (ly:duration-log (ly:music-property note 'duration)))
  (dDot (ly:duration-dot-count (ly:music-property note 'duration)))
  (dFac (ly:duration-factor (ly:music-property note 'duration)))
  (scaledNote (ly:music-deep-copy note)))
(set! (ly:music-property scaledNote 'duration)
  (ly:make-duration dLog dDot (*
(/ (car dFac) (cdr dFac))
(/ (- denom num) denom
(make-music 'SequentialMusic
'elements (list
(make-music 'SkipEvent
'duration (ly:make-duration dLog dDot
(* (/ (car dFac) (cdr dFac)) (/ num denom
scaledNote))

% Generate a rolled chord from the given notes. Each subsequent note is shifted
% by num/denom.
#(define genArpeggio (lambda (num denom notes)
(if (pair? notes) ; Test for empty list
; Recursive case
(if (null? (ly:music-property (car notes) 'duration))
; Skip objects that have no duration
(genArpeggio (+ 1 num) denom (cdr notes))
; Shift notes
(cons
(shiftedNote num denom (car notes))
(genArpeggio (+ 1 num) denom (cdr notes
; Base case
'(

% Params:
%   chord = The chord to arpeggiate.
%   denom = The fraction of the chord's length to use as a rest for each note
%   of the arpeggiated chord. This must not be less than the number of
%   notes in the chord. If it's greater than the number of chord notes, the
%   top note will be held longer.
midiArpeggio = #(define-music-function (denom chord) (number? ly:music?)
(let ((chordTones (ly:music-property chord 'elements)))
(make-music 'SimultaneousMusic
'elements (genArpeggio 0 denom chordTones

% vim:set sw=4 ts=4 et:

%% by Harm
%% https://lists.gnu.org/archive/html/lilypond-user/2020-12/msg00039.html

getMidiArpeggios =
#(define-music-function (val mus) (number? ly:music?)
  (map-some-music
(lambda (m)
  (and (music-is-of-type? m 'event-chord)
   (any
 (lambda (elt)
   (eq? (ly:music-property elt 'name) 'ArpeggioEvent))
 (ly:music-property m 'elements))
   (midiArpeggio val m)))
mus))


%% EXAMPLES


mus =
\new Staff \relative c' {
  4\arpeggio
  r2.
  |
  2
  \arpeggio
}
  
\score { \mus }

\score {
  \getMidiArpeggios 24
  \mus
  \midi { }
}

Re: How should I convert an existing ".ly" file to a MIDI file containing audible arpeggios?

2020-12-05 Thread Thomas Morley
Am Sa., 5. Dez. 2020 um 13:17 Uhr schrieb Petr Pařízek
:
>
> H. S. Teoh wrote:
>
>  > For example:
>  >
>  > \midiArpeggio 24 4
>  >
>  > divides a quarter note into 24 units, and plays the first c on-beat, the
>  > e 1/24th of a quarter note past the beat, g 2/24th of a quarter note
>  > past the beat, and the last c 3/24th of a quarter note past the beat.
>
> Thanks for sharing.
> Unfortunately, if I wanted to convert an existing ".ly" file either from
> one that uses \arpeggio to one that uses \midiArpeggio or vice versa, I
> still couldn't do it with a tool like some sort of "Find and replace".
> Unlike \arpeggio which is given after the notes of the chord,
> \midiArpeggio needs to be used before them. So I'm afraid I would still
> have to rewrite it manually for each single chord. And if I wanted to
> avoid doing it all manually, I would have to know how to write code that
> would do it for me (which I have no idea which programming language
> would be the most appropriate for doing something of that sort).
>
> Petr
>
>
>
> --
> Tento e-mail byl zkontrolován na viry programem AVG.
> http://www.avg.cz
>
>

Amending the shared code, you could probably do

getMidiArpeggios =
#(define-music-function (val mus) (number? ly:music?)
  (map-some-music
(lambda (m)
  (and (music-is-of-type? m 'event-chord)
   (any
 (lambda (elt)
   (eq? (ly:music-property elt 'name) 'ArpeggioEvent))
 (ly:music-property m 'elements))
   (midiArpeggio val  m)))
mus))

\getMidiArpeggios 24
\new Staff \relative c' {
  4\arpeggio
  r2.
  |
  2
  \arpeggio
}

HTH,
  Harm



Re: How should I convert an existing ".ly" file to a MIDI file containing audible arpeggios?

2020-12-05 Thread Petr Pařízek

H. S. Teoh wrote:

> For example:
>
> \midiArpeggio 24 4
>
> divides a quarter note into 24 units, and plays the first c on-beat, the
> e 1/24th of a quarter note past the beat, g 2/24th of a quarter note
> past the beat, and the last c 3/24th of a quarter note past the beat.

Thanks for sharing.
Unfortunately, if I wanted to convert an existing ".ly" file either from
one that uses \arpeggio to one that uses \midiArpeggio or vice versa, I
still couldn't do it with a tool like some sort of "Find and replace".
Unlike \arpeggio which is given after the notes of the chord,
\midiArpeggio needs to be used before them. So I'm afraid I would still
have to rewrite it manually for each single chord. And if I wanted to
avoid doing it all manually, I would have to know how to write code that
would do it for me (which I have no idea which programming language
would be the most appropriate for doing something of that sort).

Petr



--
Tento e-mail byl zkontrolován na viry programem AVG.
http://www.avg.cz




Re: How should I convert an existing ".ly" file to a MIDI file containing audible arpeggios?

2020-12-04 Thread Martin Tarenskeen




On Fri, 4 Dec 2020, H. S. Teoh wrote:


Some time ago I wrote a little .ly snippet to generate midi arpeggios
(see attached).  It takes a number N and a chord, and generates an
arpeggio where the start of each subsequent note of the chord (in the
order they are spelled in the input) is delayed from the previous note
by a duration equal to the length of the chord divided into N units.
For example:

\midiArpeggio 24 4



Thanks, nice snippet. Could use it one day :-)

MT



Re: How should I convert an existing ".ly" file to a MIDI file containing audible arpeggios?

2020-12-04 Thread H. S. Teoh
On Sat, Dec 05, 2020 at 06:34:52AM +0100, Petr Pařízek wrote:
>On 5.12.2020 1:07, Knute Snortum wrote:
> 
>  > I'm confused.  Why doesn't the notation create arpeggios in MIDI?  
>
>  The \arpeggio command only prints the relevant symbols in the
>  notated score (i.e. in the PDF output) but does not have any
>  effect on the MIDI file.
>
>  The final part of the documentation on "Ties" contains a snippet
>  that explains that written-out arpeggios can be typed more
>  efficiently by applying the "tieWaitForNote" property and then
>  reseting it again:
>  
> [1]https://lilypond.org/doc/v2.20/Documentation/notation/writing-rhythms#ties
>  But I can't imagine rewriting it manually for every single
>  arpeggiated chord of my original file, considering how many they
>  are there. I'd love to find a way of automating this process but
>  I don't know how I would do that.
[...]

Some time ago I wrote a little .ly snippet to generate midi arpeggios
(see attached).  It takes a number N and a chord, and generates an
arpeggio where the start of each subsequent note of the chord (in the
order they are spelled in the input) is delayed from the previous note
by a duration equal to the length of the chord divided into N units.
For example:

\midiArpeggio 24 4

divides a quarter note into 24 units, and plays the first c on-beat, the
e 1/24th of a quarter note past the beat, g 2/24th of a quarter note
past the beat, and the last c 3/24th of a quarter note past the beat. By
varying the first argument you can control how fast the chord is rolled
(useful for adapting the generated midi to the current tempo of the
music so that it doesn't sound too fast or too slow).

Unfortunately, the output will look like a horrendous mess if you
typeset it; so I usually use it in a midi-only score tagged by #'midi,
with a layout-only score tagged by #'layout that uses lilypond's
built-in \arpeggio command, e.g., something like this:

\include "arpeggio.ly"
myMusic = {
...
\tag #'layout { \arpeggio }
\tag #'midi { \midiArpeggio 24  }
...
}

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

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


T

-- 
My program has no bugs! Only unintentional features...
%
% A scheme function that unpacks a rolled chord into displaced notes with
% adjusted lengths such that it will render nicely in MIDI.
%
\version "2.20.1"

% Returns: A skip followed by the given note, with the skip scaled by n/d of
% the note's length, and the note scaled by (d-n)/d of its original length.
#(define shiftedNote (lambda (num denom note)
(if (= num 0)
; First note is unchanged
note

; Construct a skip + the note, both appropriately scaled
(let ((dLog (ly:duration-log (ly:music-property note 'duration)))
  (dDot (ly:duration-dot-count (ly:music-property note 'duration)))
  (dFac (ly:duration-factor (ly:music-property note 'duration)))
  (scaledNote (ly:music-deep-copy note)))
(set! (ly:music-property scaledNote 'duration)
  (ly:make-duration dLog dDot (*
(/ (car dFac) (cdr dFac))
(/ (- denom num) denom
(make-music 'SequentialMusic
'elements (list
(make-music 'SkipEvent
'duration (ly:make-duration dLog dDot
(* (/ (car dFac) (cdr dFac)) (/ num denom
scaledNote
)
)
)
)
))

% Generate a rolled chord from the given notes. Each subsequent note is shifted
% by num/denom.
#(define genArpeggio (lambda (num denom notes)
(if (pair? notes) ; Test for empty list
; Recursive case
(if (null? (ly:music-property (car notes) 'duration))
; Skip objects that have no duration
(genArpeggio (+ 1 num) denom (cdr notes))

; Shift notes
(cons
(shiftedNote num denom (car notes))
(genArpeggio (+ 1 num) denom (cdr notes))
)
)

; Base case
'()
)
))

% Params:
%   chord = The chord to arpeggiate.
%   denom = The fraction of the chord's length to use as a rest for each note
%   of the arpeggiated chord. This must not be less than the number of
%   notes in the chord. If it's greater than the number of chord notes, the
%   top note will be held longer.
midiArpeggio = #(define-music-function (denom chord) (number? ly:music?)
(let ((chordTones (ly:music-property chord 'elements)))
(make-music 'SimultaneousMusic
'elements (genArpeggio 0 denom chordTones)
 

Re: How should I convert an existing ".ly" file to a MIDI file containing audible arpeggios?

2020-12-04 Thread Knute Snortum
I'm confused.  Why doesn't the notation create arpeggios in MIDI?

--
Knute Snortum



On Fri, Dec 4, 2020 at 1:50 PM Petr Pařízek 
wrote:

> Hello,
> I have a ".ly" file containing one pair of staves for two flutes and
> another pair of staves for the piano.
> The piano part contains a lot of arpeggios and I'd like to make a MIDI
> file in which the arpeggios will indeed be heard. The "articulate"
> script doesn't seem to offer this sort of thing. However, rewriting the
> entire score (using the "tieWaitForNote" property, as the documentation
> suggests) would be very time-consuming because the piano part contains
> really a lot of these arpeggios.
> Do you have any suggestion as to how I should go about doing it at least
> in some kind of semi-automated way?
> Thanks in advance.
> Petr Pařízek
>
>
>
> --
> Tento e-mail byl zkontrolován na viry programem AVG.
> http://www.avg.cz
>
>
>