Deutsches Lilypond Forum (Archiv)

Allgemein => Hilfe beim Einstieg in Lilypond => Thema gestartet von: ulanger am Samstag, 21. März 2015, 20:08

Titel: midi output mit verschiedener dynamic (erst forte, dann piano) für \repeat volta
Beitrag von: ulanger am Samstag, 21. März 2015, 20:08
Hallo,

weiss jemand ob es möglich ist, für eine Wiederholung (\repeat volta 2) unterschiedliche Dynamic zu notieren und dies im MIDI output auch hörbar zu machen?
Ich benutze version 2.14.2.

Vielen Dank im voraus,
ulanger
Titel: Re: midi output mit verschiedener dynamic (erst forte, dann piano) für \repeat volta
Beitrag von: Pierre am Sonntag, 28. Juni 2015, 10:20
Hallo ulanger,

Versuch mal:
\version "2.14.2"

myMusic = \relative c' {
  c d e f
  \once\override Score.RehearsalMark #'direction = #DOWN
  \mark\markup\column {
    \concat\small { "1°: " \musicglyph #"f" }
    \concat\small { "2°: " \musicglyph #"p" }
  }
  \tag #'myScore {
    \bar "|:" g a b c \bar ":|"
  }
  \tag #'myMidi {
    \set Staff.midiMaximumVolume = #1
    g\f a b c
    \set Staff.midiMaximumVolume = #0.3
    g\f a b c
    \set Staff.midiMaximumVolume = #0.5
  }
  b\mf a g f e d c2
  \bar "|."
}

%% pdf output:
\score {
  {
    \keepWithTag #'myScore
    \myMusic
  }
  \layout {}
}

%% midi output:
\score {
  {
    {
    \keepWithTag #'myMidi
    \myMusic
  }
  }
  \midi {}
}

Gruß,  ;)
~PPS
Titel: Re: midi output mit verschiedener dynamik (erst f dann p für \repeat volta
Beitrag von: Arnold am Montag, 29. Juni 2015, 08:51
Hmm,

im LSR http://lsr.di.unimi.it/LSR/Item?u=1&id=871 (http://lsr.di.unimi.it/LSR/Item?u=1&id=871) gibt es eine Funktion \taggedRep, welche ähnliches vollbringt, aber als "Ersatz" für »\repeat unfold« benutzt wird - schon bei der Eingabe.
Eine ähliche Funktion als »musicmap-Prozedur«, welche »Repeat-volta«-Elemente »entwickelt« (in entfaltete »Sequential Music« umsetzt), und dabei in jeder Wiederholung »tags« herausfiltert, könnte die Lösung sein.

Ein kleines Konzept-Problem sehe ich dabei aber noch:
\repeat volta 2 { c'1-\tag #'Rep1 \p -\tag #'Rep2 \f }bedeutet in der Druckausgabe zwei gleichzeitige Dynamik-Events, aber keine »durchnummerierten Dynamik-Grobs«. So müßten diese beiden im Druck deaktiviert werden, und ein weiteres »Mehrzeilen-Dynamic-Event« dazugefügt werden, welches nur druckbar ist aber die MIDI-Ausgabe nciht beeinflußt.

Mal überlegen, heute komme ich eh' nicht zum Programmieren.

Arnold
Titel: Re: midi output mit verschiedener dynamic (erst f, dann p) für \repeat volta
Beitrag von: Arnold am Dienstag, 30. Juni 2015, 10:52
Hallo,

schon einmal etwas tiefergehende Gedanken dazu:

1. Voraussetzungen
a) Repeats werden in Lilypond als Datenstruktur mit folgenden Elementen abgelegt:
- Typ (volta, unfold, tremolo)
- Count (Anzahl der Wiederholungen)
- Basis-Element [element] (normalerweise eine "sequentielle Musik" oder eine "parallele Musik")
- Liste der Ende-Elemente [elements] (Typ wie Basis-Element)
b) das normale \unfoldRepeats ersetzt einfach den Typ mit 'unfold'
c) mit make-dynamic-script kann man sich ein eigenes »absolute dynamic mark« definieren, welches mit einem selbstdefinierten Markup im Druck dargestellt wird (z. Bsp. dreizeilig »1. mf / 2. pp / beim DC: ff«). In solch einem Event kann man noch zusätzlich (wahrscheinlich unter einem neu defnierten Attribut) eine »alist« ablegen, in welcher die Dynamikzuordnungen für die Midi-Ausgabe festgelegt sind, z. Bsp. (list (1 . "mf") (2 . "pp") (DC . "ff"))

2. Ausführung:
a) eine neu zu definierende Funktion \unfoldRepeatsWithDynamicSplit (auf Basis von \musicmap zu programmieren) entfaltet
\repeat volta 2 { a1\mfxppyff } \alternative { { b1 } { c'1 } }
nicht in
\repeat unfold 2 { a1\mfxppyff } \alternative { { b1 } { c'1 } }
sondern erst einmal in eine sequentielle Musik, also
{ { a1\mfxppyff } { b1 } { a1\mfxppyff }  { c'1 } }
b) und bearbeitet dabei im "Teil A" die "splittable absolute Dynamic Events" entsprechend der darin abgelegten "alist" zu
{ { a1\mf } { b1 } { a\pp }  { c'1 } }.
Ist diese Bearbeitungsfunktion auch "extern" aufrufbar, dann ließe sich damit auch das "Da Capo" relativ einfach hinten anhängen:
\selectSplittedDynamic #'DC \senazRipet \music

Das scheint mir mit absehbarem Aufwand realisierbar.
Wenn jemand noch Probleme dabei sieht, bitte melden.

Arnold
Titel: Re: midi output mit verschiedener dynamic (erst f, dann p) für \repeat volta
Beitrag von: Arnold am Donnerstag, 2. Juli 2015, 08:37
Hallo,

eine erste Version hätte ich jetzt.
Sie erkennt noch keine Dynamik, welche an "Skips" oder Pausen hängt.
Ein eventuelles \tag direkt an einem \repeat geht verloren.
Eine Variante für alle \repeats (nicht nur \repeat volta) soll noch folgen.
\version "2.18.2"
% Definitionen und Deklarationen:

#(define (make-dynamic-script-with-unfold-data str ufd)
  (make-music 'AbsoluteDynamicEvent
              'text str
              'unfold-list ufd))

#(define (select-dynamic-by-key key mus)
  (define (selection-to-use-countdown al k)
   (if (pair? al)
    (let ((sel (ly:assoc-get k al '())))
     (if (and (null? sel) (integer? k) (> k 0))
      (selection-to-use-countdown al (1- k))
      sel))
    '()))
  (define (select-this-dynamic-by-key key ade)
   (let ((switchlist (ly:music-property ade 'unfold-list)))
    ;; (for-each display (list "\n  unfold-list = " switchlist "."))
    (if (not (null? switchlist))
     (let ((new-text (selection-to-use-countdown switchlist key)))
      ;; (for-each display (list "\n  new-text = »" new-text "«."))
      (if (and (null? new-text)
               (pair? switchlist)
               (pair? (car switchlist)))
       (set! new-text (cdar switchlist)))
      ;; (for-each display (list "\n  new-text for " key " = »" new-text "«."))
      (if (not (null? new-text)) (begin
        (ly:music-set-property! ade 'text new-text)
        (ly:music-set-property! ade 'unfold-list #f)))))))
  (let
   ((name (ly:music-property mus 'name))
    (key-is-integer (integer? key))
    (key-is-symbol (symbol? key)))
   ;; (for-each display (list "\n name = »" name "«, key " key " is "
   ;;  (if key-is-integer "integer" (if key-is-symbol "symbol" "unknown type")) "."))
   (if (eq? name 'NoteEvent)
    (let ((articul (ly:music-property mus 'articulations)))
     ;; (display "\n*NoteEvent* - find in 'articulations")
     (for-each (lambda (a) (let ((sname (ly:music-property a 'name)))
        ;; (for-each display (list "\n  sname = " sname "."))
        (if (eq? sname 'AbsoluteDynamicEvent)
         (select-this-dynamic-by-key key a))
      )) articul))
    (if (eq? name 'EventChord)
     (let ((es (ly:music-property mus 'elements)))
      ;; (display "\n*EventChord* - find in 'elements")
      (for-each (lambda (a) (let ((sname (ly:music-property a 'name)))
         ;; (for-each display (list "\n  sname = " sname "."))
         (if (eq? sname 'AbsoluteDynamicEvent)
          (select-this-dynamic-by-key key a))
       )) es))
     ;; (display "\n* other *")
   )))
  mus)

#(define (unfold-volta-repeats-with-dynamic-switch all-reps mus)
  (let
   ((name (ly:music-property mus 'name)))
   ;; (for-each display (list "\n name = " name "."))
   (if (eq? name 'VoltaRepeatedMusic)
    (let
     ((count (ly:music-property mus 'repeat-count))
      (e (ly:music-property mus 'element))
      (es (ly:music-property mus 'elements))
      (len (length (ly:music-property mus 'elements)))
      (new-es '()))
     ;; (for-each display (list "\n count = " count ", len = " len "."))
     (do ((i 1 (1+ i))) ((> i count))
      ;; (for-each display (list "\n loop " i "."))
      (set! new-es (append new-es (cons
         (music-map (lambda (m) (select-dynamic-by-key i m))
           (ly:music-deep-copy e))
         '())))
      (if (not (null? es))
       (let ((idx (1- (if (> i len) len i))))
        (set! new-es (append new-es (cons
           (music-map (lambda (m) (select-dynamic-by-key i m))
             (ly:music-deep-copy (list-ref es idx)))
           '())))))
      (set! mus (make-music 'SequentialMusic 'elements new-es))))))
  mus)

#(define (int-or-symb? x)
  (or (integer? x) (symbol? x)))

selectDynamic =
#(define-music-function (parser location key mus)
  (int-or-symb? ly:music?)
  (music-map (lambda (m) (select-dynamic-by-key key m)) mus))

unfoldVoltaRepeatsWithDynamicSwitch =
#(define-music-function (parser location mus)
  (ly:music?)
  (music-map
   (lambda (m) (unfold-volta-repeats-with-dynamic-switch #f m))
   mus))


% Anwender-Setup:

mfxppyffText = \markup \center-align \column {
  \center-align \line { \normal-text "1." \dynamic "mf" }
  \center-align \line { \normal-text "2." \dynamic "pp" }
  \center-align \line { \normal-text "beim D.C." \dynamic "ff" }
}

mfxppyffList = #'(( 1 . "mf")
                  ( 2 . "pp")
                  (DC . "ff"))

mfxppyff = #(make-dynamic-script-with-unfold-data mfxppyffText mfxppyffList)

music = {
  \repeat volta 2 {
    a'1\mfxppyff
  }
  \alternative {
    { b'1 }
    { <e' c''>1 }
  }
}

% Anzeigen und Ausführung:

\markup "geschriebene Musik:"
{ \music }

\markup "davon die »DC«-Dynamik übernehmen:"
{ \selectDynamic #'DC \music }
% { \selectDynamic #1 \music } % oder die Nummer 1 (Ganzzahl)
% { \selectDynamic #2 \music } % oder die Nummer 2 (Ganzzahl)
% { \selectDynamic #3 \music } % bei Ganzzahl: eventuell nächst kleinere Nummer nehmen
% { \selectDynamic #0 \music } % oder das erste Element der 'alist' nehmen

\markup "Entfalten mit Dynamik:"
{ \unfoldVoltaRepeatsWithDynamicSwitch \music }


Arnold

(Tippfehler nachträglich korrigiert)
Titel: Re: midi output mit verschiedener dynamic (erst forte, dann piano) für \repeat volta
Beitrag von: ingmar am Freitag, 3. Juli 2015, 13:19
Ich komme nochmal mit meinem an anderer Stelle geäußerten Vorschlag: Was spricht dagegen, die Formteile in Variablen abzulegen und für die Partitur so und für MIDI anders zusammenzumontieren?

Also, in Pseudocode:
A-Teil = { .. musik 1 ..}
B-Teil = { .. musik 2 ..}

score = ||: \A :||: \B :||
midi = \forte \A \piano \A \forte \B \piano \B

Es kommt natürlich darauf an, was du genau willst und brauchst, aber manchmal muss man nicht alles automatisieren.


Gruß,
--ingmar
Titel: Re: midi output mit verschiedener dynamic (erst f, dann p) für \repeat volta
Beitrag von: Arnold am Montag, 6. Juli 2015, 09:42
Ich komme nochmal mit meinem an anderer Stelle geäußerten Vorschlag: Was spricht dagegen, die Formteile in Variablen abzulegen und für die Partitur so und für MIDI anders zusammenzumontieren?

...

Hallo,

der ganze Aufwand eigentlich nur, damit ich die Definitionen beisammen halten kann.
Da diese wiederholungslaufabhängige Dynamik auch in der Mitte dieser Abschnitte vorkommen kann, habe ich in der Vergangenheit auch schon drei, mit Tags versehene Dynamikeintragungen gesetzt: a) für den Druck b) für den ersten Lauf c) für den zweiten Lauf.
Ich spare mir mit diesen Routinen (zumindest weitgehend) den parallelen Aufbau von zwei Wiederholungsstrukturen (PDF mit \repeat und MIDI mit sequentieller Musik).
Und bei den parallelen Musikstrukturen (für die Partitur / gesamtmidi) das ganze noch einmal parallel aufbauen.
Es sähe also in etwa so aus, dabei benutze ich aber schon eine Funktion welche erste mit 2.20.0 kommen wird um Code zu sparen:
\tagGroup #'(PDF RunOne RunTwo) % in der aktuellen 2.19.x enthalten

musicPDF = {
  \A
  \repeat volta 2 { \keepWithTag #'PDF \B }
  \alternative { { \C } { \D } }
  \repeat volta 2 { \keepWithTag #'PDF \E }
  \F
  \bar "|."
}

musicMIDI = {
  \A
  \keepWithTag #'RunOne \B
  \C
  \keepWithTag #'RunTwo \B
  \D
  \keepWithTag #'RunOne \E
  \keepWithTag #'RunTwo \E
  \F
  \bar "|."
}
Und bei Vielfach-Wiederholungen (repeat volta 3 oder mehr) und gemeinsamen Volta-Klammern (1.-2. | 3.) kommen noch mehr \keepWithTag hinzu.

Selbstredend, ein höherer Aufwand loht sich nur bei entsprechender Nutzung, also bei längeren Stücken.


Arnold
Titel: Re: midi output mit verschiedener dynamic (erst f, dann p) für \repeat volta
Beitrag von: Arnold am Montag, 6. Juli 2015, 10:34
So, und jetzt mein Ergebnis, das alle meine Test bestanden hat.
Dabei habe ich noch ein paar Funktionen umbenannt, damit die Namen sich besser in des Gefüge der Standardnamen einfügen. Und es gibt jetzt auch eine Funktion, nur die \repeat-Kommandos welche mit einem Tag markiert sind aufzufalten.

Der Code:\version "2.18.2"
% getestet mit den Versionen 2.14.2, 2.16.0, 2.18.2 und 2.19.13
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definitionen und Deklarationen:

#(define (make-dynamic-script-with-unfold-data str ufd)
  (make-music 'AbsoluteDynamicEvent
              'text str
              'unfold-list ufd))

#(define (select-dynamic-by-key key mus)
  (define (selection-to-use-countdown al k)
   (if (pair? al)
    (let ((sel (ly:assoc-get k al '())))
     (if (and (null? sel) (integer? k) (> k 0))
      (selection-to-use-countdown al (1- k))
      sel))
    '()))
  (define (select-this-dynamic-by-key key ade)
   (let ((switchlist (ly:music-property ade 'unfold-list)))
    (if (not (null? switchlist))
     (let ((new-text (selection-to-use-countdown switchlist key)))
      (if (and (null? new-text)
               (pair? switchlist)
               (pair? (car switchlist)))
       (set! new-text (cdar switchlist)))
      (if (not (null? new-text)) (begin
        (ly:music-set-property! ade 'text new-text)
        (ly:music-set-property! ade 'unfold-list '())))))))
  (let
   ((name (ly:music-property mus 'name))
    (key-is-integer (integer? key))
    (key-is-symbol (symbol? key)))
   (if (or (eq? name 'NoteEvent)
           (eq? name 'SkipEvent)
           (eq? name 'RestEvent)
           (eq? name 'MultiMeasureRestMusic))
    (let ((articul (ly:music-property mus 'articulations)))
     (for-each (lambda (a) (let ((sname (ly:music-property a 'name)))
        (if (eq? sname 'AbsoluteDynamicEvent)
         (select-this-dynamic-by-key key a)))) articul))
    (if (eq? name 'EventChord)
     (let ((es (ly:music-property mus 'elements)))
      (for-each (lambda (a) (let ((sname (ly:music-property a 'name)))
         (if (eq? sname 'AbsoluteDynamicEvent)
          (select-this-dynamic-by-key key a)))) es)))))
  mus)

#(define (split-dynamic-and-unfold-repeats tagged-reps symb mus)
  (define (any-eq? tags tag-or-taglist)
   (if (pair? tag-or-taglist)
    (if (memq (car tag-or-taglist) tags)
     #t
     (any-eq? tags (cdr tag-or-taglist)))
    (if (memq tag-or-taglist tags) #t #f)))
  (define (mus-is-tagged mus tag-or-taglist)
   (if (boolean? tag-or-taglist)
    tag-or-taglist
    (let ((tags (ly:music-property mus 'tags)))
     (any-eq? tags tag-or-taglist))))
  (let
   ((name (ly:music-property mus 'name)))
   (if (or (and (not tagged-reps)
                (eq? name 'VoltaRepeatedMusic))
           (and tagged-reps
                (or (eq? name 'VoltaRepeatedMusic)
                    (eq? name 'UnfoldedRepeatedMusic)
                    (eq? name 'TremoloRepeatedMusic)
                    (eq? name 'PercentRepeatedMusic))
                (mus-is-tagged mus symb)))
    (let
     ((count (ly:music-property mus 'repeat-count))
      (e (ly:music-property mus 'element))
      (es (ly:music-property mus 'elements))
      (len (length (ly:music-property mus 'elements)))
      (new-es '()))
     (do ((i 1 (1+ i))) ((> i count))
      (set! new-es (append new-es (cons
         (music-map (lambda (m) (select-dynamic-by-key i m))
           (ly:music-deep-copy e))
         '())))
      (if (not (null? es))
       (let ((idx (1- (if (> i len) len i))))
        (set! new-es (append new-es (cons
           (music-map (lambda (m) (select-dynamic-by-key i m))
             (ly:music-deep-copy (list-ref es idx)))
           '())))))
      (set! mus (make-music 'SequentialMusic 'elements new-es))))))
  mus)

#(define (int-or-symb? x)
  (or (integer? x) (symbol? x)))

selectDynamic =
#(define-music-function (parser location key mus)
  (int-or-symb? ly:music?)
  (music-map (lambda (m) (select-dynamic-by-key key m)) mus))

splitDynamicsUnfoldVoltaRepeats =
#(define-music-function (parser location mus)
  (ly:music?)
  (music-map
   (lambda (m) (split-dynamic-and-unfold-repeats #f '() m))
   mus))

splitDynamicsUnfoldRepeatsWithTag =
#(define-music-function (parser location tags mus)
  (scheme? ly:music?)
  (music-map
   (lambda (m) (split-dynamic-and-unfold-repeats #t tags m))
   mus))

splitDynamicsUnfoldAllRepeats =
#(define-music-function (parser location mus)
  (ly:music?)
  (music-map
   (lambda (m) (split-dynamic-and-unfold-repeats #t #t m))
   mus))


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Anwender-Setup:

mfxppyffText = \markup \center-align \column {
  \center-align \line { \normal-text "1." \dynamic "mf" }
  \center-align \line { \normal-text "2." \dynamic "pp" }
  \center-align \line { \normal-text "beim D.C." \dynamic "ff" }
}

mfxppyffList = #'(( 1 . "mf")
                  ( 2 . "pp")
                  (DC . "ff"))

mfxppyff = #(make-dynamic-script-with-unfold-data mfxppyffText mfxppyffList)

music = {
  \repeat volta 2 {
    a'1\mfxppyff
  }
  \alternative {
    { b'1 }
    { c''1 }
  }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Anzeigen und Ausführung:

\markup \bold "geschriebene Musik:"
{ \music }

\markup \bold "diese entfalten unter Berücksichtigung der wechselnden Dynamik:"
{ \splitDynamicsUnfoldVoltaRepeats \music }

\markup \column {
  \bold "von der geschriebenen Musik die »Da Capo«-Dynamik übernehmen:"
  "(mit Wiederholung, ansonsten suche »senzaRipet« im LSR)"
}
{ \selectDynamic #'DC \music }


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%{ %%% weitere Beispiele:

{ \selectDynamic #1 \music } % oder die Nummer 1 (Ganzzahl)
{ \selectDynamic #2 \music } % oder die Nummer 2 (Ganzzahl)
{ \selectDynamic #3 \music } % bei Ganzzahl: eventuell nächst kleinere Nummer nehmen
{ \selectDynamic #0 \music } % oder das erste Element der 'alist' nehmen

musicII = {
  \tag #'TAG1 \repeat unfold 2 { a'1\mfxppyff }
  \tag #'TAG2 \repeat unfold 2 { a'1\mfxppyff }
  \tag #'TAG3 \repeat volta 2 { a'1\mfxppyff }
}

{ \splitDynamicsUnfoldRepeatsWithTag #'TAG1 \musicII }
{ \splitDynamicsUnfoldRepeatsWithTag #'(TAG1 TAG3) \musicII }
{ \splitDynamicsUnfoldAllRepeats \musicII }

%}

Also auf zu großen Taten! (Partitur mit 50 Einzeielstimmen, jede mit 10 Wiederholungen welche wechselnde Dynamik enthalten - ich habe zuhause eine modifizierte Version von timidity, damit kann ich eine von Lilypond erstellte MIDI-Datei mit 60 Musikspuren in eine WAV-Datei umwandeln).

Arnold
Titel: Re: midi output mit verschiedener dynamic (erst forte, dann piano) für \repeat volta
Beitrag von: ulanger am Sonntag, 27. September 2015, 16:07
Hallo zusammen,

vielen Dank für eure Mühe. Entschuldigt meine verspätete Reaktion, nachdem es innerhalb der ersten Wochen keine Reaktion gab, glaubte ich keiner weiß eine Lösung, oder ich hätte (unbewust) gegen die Netikette  verstoßen.

Heute gab es seit Monaten für mich erneut konkreten Anlass das Forum wieder aufzusuchen (Frage zum Cantus Firmus) und stelle mit Freude fest: Manchmal braucht's einfach nur Geduld.

Also nochmals vielen Dank an Alle; ich mach mich jetzt daran eure Beiträe zu verstehen und umzusetzen.
Liebe Grüße, ulanger