Töne aus der Musik mit Tönen aus einer Liste abgleichen

Begonnen von Multimax, Mittwoch, 30. Mai 2018, 18:50

« vorheriges - nächstes »

Multimax

Hallo,
dies ist mein erster Beitrag im Forum. Ich bin absoluter scheme-Anfänger und mache nach tagelangem Lesen meine ersten Versuche.

ZIEL:
Ich versuche anhand des untenstehenden Beispiels (Quelle: https://archiv.lilypondforum.de/index.php/topic,2156.msg11935.html#msg11935, töne aus der musik mit Tönen aus einer vorher definierten Liste abzugleichen. Wenn sie in der Referenzliste vorkommen, sollen sie verändert werden.

Im Prinzip passiert genau das in dem Beispiel Code. Die Referenzliste wird in Zeile 11 mit einer Member-Funktion aufgerufen und beim Treffer wird eine 0 an den Ton im Notenbild gehängt.
Ich würde aber gerne diese Liste vorher oben definieren und dann aufrufen.
Dazu habe ich schon mehrere Versuche gemacht, meine Liste L oben zu definieren:

L={c' d' e'}
#(define L '(c d e))
#(define L '(#{c#}  #{d#} #{ e#}))


Unten dann in der member-funktion habe ich sie versucht, sie aufzurufen mit

list L
einfach nur L
list #{L#}

das alles irgendwann wahlos aus Verzweiflung in allen Kombinationen. Das ergab bis jetzt nur Fehlermeldungen oder anstandsloses kompilieren, aber ohne  0en wenn eigentlich ein Treffer hätte sein sollen.  :P

Könnte mir jemand auf die Sprünge helfen, wie ich eine Liste mit Tonnamen (c' d' e') oben definieren und in der Funktion unten aufrufen kann?

\version "2.18.2"
\language "deutsch"

leeresaiten =
#(define-music-function (parser location music) (ly:music?)
   (music-map
    (lambda (m)
      (if (and
           (music-is-of-type? m 'note-event)
             (member (ly:music-property m 'pitch)
                   (list #{a#} #{gis'#})))
          (begin
           (ly:music-set-property! m 'articulations
             (cons
              (make-music 'FingeringEvent 'digit 0)
              (ly:music-property m 'articulations)))
           m)
          m))
    music))

\leeresaiten \relative {
  d' a c e
  a gis e c
  as a a2
}

\leeresaiten <<
  \new Staff \relative {
    c'1 a
  }
  \new Staff \relative {
    a f
  }
>>



Malte

Hallo Multimax,

willkommen im Forum! Du warst schon nach dran: Statt
'(#{ a #} #{ gis' #})
müßte es
`(,#{ a #} ,#{ gis' #})
oder
(list #{ a #} #{ gis' #})
heißen (beachte den Unterschied zwischen ' und `). Kann dann einfach als L aufgerufen werden.

Leider gerade keine Zeit für Erklärung, erinnere mich im Zweifelsfall daran, die nachzuliefern.

ingmar

Am Rande:

Wir hatten mal ein sehr ähnliches Thema - im alten Forum:
https://archiv.lilypondforum.de/index.php/topic,2156.msg11933.html#msg11933

Vielleicht hilft das hier weiter..?

Gruß,
--ingmar

Malte

Das ist exakt das Thema, das Multimax oben erwähnt und verlinkt hat ;)

Edit: Ich seh grad, daß der Original-Code von mir stammt. Freut mich, daß sowas auch zweieinhalb Jahre später wieder hilft und zeigt, daß es gut ist, das Archiv zu haben :)

ingmar

upps.. stimmt! Manchmal les ich nur so oberflächlich drüber und will dann trotzdem helfen.. : - (

am besten lösch ich meinen Beitrag (und du dann deinen), oder? : - )

--ingmar

Multimax

#5
Vielen Dank für eure Antworten und alle anderen die hier so viel helfen,

ja das Archiv+Forum ist eine echte Hilfe beim Erlernen von Scheme mit Lilypond.

Leider bin ich mit Maltes Tip noch nicht zu einem Erfolg gekommen. Ich definiere also mit einer der beiden möglichen Formen meine Referenzliste L:
#(define L `(,#{ a #} ,#{ gis' #}))
und
#(define L (list #{ a #} #{ gis' #}))
sind ja verscheidene Schreibweisen für die identische Liste, denn quasiquote mit kommas ist das gleiche wie list ohne Kommas.

Dann rufe ich unten in der member-funktion mit "list L" die Liste zum Vergleich auf.

Folgender Code kompiliert ohne Fehler, bringt aber kein Ergebnis :-\
\version "2.18.2"
\language "deutsch"

#(define L `(,#{ a #} ,#{ gis' #}))
%#(define L (list #{ a #} #{ gis' #}))

leeresaiten =
#(define-music-function (parser location music) (ly:music?)
   (music-map
    (lambda (m)
      (if (and
           (music-is-of-type? m 'note-event)
             (member (ly:music-property m 'pitch)
                   (list L)))
          (begin
           (ly:music-set-property! m 'articulations
             (cons
              (make-music 'FingeringEvent 'digit 0)
              (ly:music-property m 'articulations)))
           m)
          m))
    music))

\leeresaiten \relative {
  d' a c e
  a gis e c
  as a a2
}

\leeresaiten <<
  \new Staff \relative {
    c'1 a
  }
  \new Staff \relative {
    a f
  }
>>


Jetzt kann es doch nur noch daran liegen, dass die if-Bedingung nicht erfüllt ist. Das heißt der Vergleich findet keine Treffer, also passiert auch nichts (keine 0en an den Noten). Warum werden also keine Pitches in der Referenzliste gefunden, die denjenigen der Musik gleichen? Jetzt kann es doch nur noch daran liegen, daß der Aufruf von list L falsch ist oder?

Malte

Zitat von: Multimax am Donnerstag, 31. Mai 2018, 12:27
#(define L `(,#{ a #} ,#{ gis' #}))
und
#(define L (list #{ a #} #{ gis' #}))
sind ja verscheidene Schreibweisen für die identische Liste, denn quasiquote mit kommas ist das gleiche wie list ohne Kommas.
Genau.
Zitat
Dann rufe ich unten in der member-funktion die Liste zum Vergleich mit list L auf.
Wie du weiter unten richtig vermutet hast, liegt da der Fehler: L ist schon eine Liste, das mußt du nicht extra nochmal sagen. Stattdessen packt (list L) die Liste in eine Liste, d. h. aus der zweielementigen Liste (a gis') mit den Elementen a und gis' wird die einelementige Liste ((a gis')) mit dem Element (a gis'). Und member vergleicht dann einen Pitch (z. B. gis') mit jedem Element von ((a gis')) und da gis'≠(a gis'), passiert nichts.

L               (list #{ a #} #{ gis' #})

(list L)        (list (list #{ a #} #{ gis' #})

(member
  #{ gis' #}
  L)            #t

(member
  #{ gis' #}
  (list L))     #f


harm6

Hallo,

noch eine Anmerkung.
Einfach und übersichtlich läßt sich eine Liste von pitches so erhalten:
(event-chord-pitches #{ a gis f fis #})

Gruß,
  Harm

Multimax

@Malte
Ja natürlich, jetzt leuchtet es mir ein... Hätt ich auch fast selbst draufkommen müssen :)

@harm6
Danke für den Tip.
Event-chord-pitches steht garnicht in der internals Referenz.

Ist das wieder so eine nicht dokumentierte Funktion, die man nur im Code nachlesen kann? (Ich glaube bei music-map war das auch so...)






harm6

ZitatEvent-chord-pitches steht garnicht in der internals Referenz.

Ist das wieder so eine nicht dokumentierte Funktion, die man nur im Code nachlesen kann?

Ja.

David Nalesnik hat mal folgenden Code entworfen,


#(define (get-binding-list iface)
   (ly:module->alist (resolve-module iface)))

#(define (symbol-closure-list iface)
   (let* ((bindings (get-binding-list iface))
          (closures
           (filter
            (lambda (b) (closure? (cdr b)))
            bindings))
          (closures
           (sort closures
             (lambda (x y) (symbol<? (car x) (car y))))))
     closures))

#(define (omit-markup-functions lst)
   (remove
    (lambda (elt)
      (string-contains (symbol->string (car elt)) "markup"))
    lst))

#(define (symbol-closure-doc-list iface omit-markups?)
   (let* ((closures (symbol-closure-list iface))
          (closures (if omit-markups?
                        (omit-markup-functions closures)
                        closures)))
     (map (lambda (c)
            (list
             (car c)
             (cdr c)
             (or (procedure-documentation (cdr c))
                 "DOCME")))
       closures)))
       
% UNCOMMENT THE FOLLOWING TO SEND TO A FILE:

%#(set-current-output-port (open-output-file "closures.txt"))

%% boolean determines whether markup commands (which are documented
%% in their Lily syntax) are included.

#(format #t "~:{~a~%~a~%~3t~s~%__________~%~%~}" (symbol-closure-doc-list '(lily) #f))


um diese Funktionen, procedures und sonstigen Definitionen sichtbar zu machen.

Ohne markup-commands ergibt das eine Liste mit 973 Einträgen, 1336 mit den markup-commands. Ich kann mich im moment nicht erinneren ob auch die Sachen aus den .ly-files erfasst werden...

Ich sehe nicht wie man all das in die IR packen könnte ohne jeglichen Rahmen zu sprengen.


Im Extending Manual wird übrigens auf music-map verwiesen.

Gruß,
  Harm