Autor Thema: Indexnummer eines Staff  (Gelesen 2670 mal)

jps

  • Member
Indexnummer eines Staff
« am: Sonntag, 13. März 2016, 16:21 »
Hallo!

Diese Frage hat sich als schwieriger herausgestellt, als es zu erwarten war.

Wie kann man möglichst einfach auf den Index eines Staff (von oben nach unten innerhalb einer Akkolade durchnummeriert) zugreifen?

Das Einzige, das mir zunächst mal eingefallen ist, ist

#(string->number(substring (ly:context-id aktuelle-notenzeile) 13))
Hier verwende ich die einem nicht von Hand benannten Staff offenbar automatisch zugewiesene context-id der Form uniqueContextXXX. Aber es wäre natürlich hübscher, wenn es so etwas wie eine staffNumber-property gäbe(?).

Herzliche Grüße
Jost
« Letzte Änderung: Sonntag, 13. März 2016, 16:23 von jps »

harm6

  • Member
Re: Indexnummer eines Staff
« Antwort #1 am: Sonntag, 13. März 2016, 16:35 »
Zitat
es wäre natürlich hübscher, wenn es so etwas wie eine staffNumber-property gäbe(?).
Gibts nicht...
Da wirst Du nicht wirklich weiterkommen.
Bedenke auch, daß LilyPond die Möglichkeit bietet contexte später und/oder temporär zu erzeugen bzw auszuschalten, sowie die Anordnung innerhalb der Akkolade abweichend von der Reihenfolge der Eingabe zu setzen. Die contexte durchzuzählen wird dann schwierig bis unmöglich
Insofern solltest Du eine andere Methode finden um zu erreichen was Du willst.

Also: was willst Du erreichen? bzw wozu wolltest Du das staffNumber-property haben?

Gruß,
  Harm

jps

  • Member
Re: Indexnummer eines Staff
« Antwort #2 am: Montag, 14. März 2016, 11:27 »
Danke für die warnenden Hinweise. Es ist für die Arbeit innerhalb von Lilypond aus den genannten Gründen ohne Zweifel besser, die Contexte explizit zu benennen, oder z.B. mit der instrumentName-property des Voice-Contextes zu arbeiten.

Ich möchte aber in diesem Fall einfach nur Daten aus unterschiedlichen Partituren zur weiteren Verarbeitung in anderen Programmen auslesen, und für die Weiterverarbeitung brauche ich halt die Indexnummern der Einzelsysteme (wobei ich sicher sein kann, dass die genannten Modifikationen der Reihenfolge nicht auftreten).

Für diesen Zweck funktioniert meine Vorgehensweise offenbar ganz gut. Ich wollte mit meiner Frage nur sichergehen, dass ich es nicht umständlich mache, wenn es auch einfacher geht.

By the way: Auch auf die Zahl der Einzelsysteme in einem Gesamtsystem kann man offenbar nicht direkt zugreifen, sondern muss sie ebenfalls umständlicher ermitteln?

Herzliche Grüße
Jost

harm6

  • Member
Re: Indexnummer eines Staff
« Antwort #3 am: Dienstag, 15. März 2016, 01:31 »
Hallo Jost,

mir ist noch nicht klar was Du machst. Kannst Du den code posten?
Ich hab' immer Schwierigkeiten mit bloßen Beschreibungen, code ist da hilfreicher.

Gruß,
  Harm

jps

  • Member
Re: Indexnummer eines Staff
« Antwort #4 am: Dienstag, 15. März 2016, 18:32 »
Meine Fragen beziehen sich auf eine - aus Zeitgründen längerfristig angelegte – Bastelarbeit; im Prinzip geht es dabei letzten Endes um die Darstellung von Partituren und das interaktive Abspielen von Stellen/Stimmen im Browser.

Dazu brauche ich als Basis eine aus einer Partitur automatisch erzeugte Tabelle mit den folgenden Informationen zu jeder Note:

1. x/y-Koordinate
2. Index der Stimme bzw. des Notensystems
3. Zeitpunkt note-on
4. Zeitpunkt note-off
5. Note angebunden oder Ton neu beginnend?

Eigentlich kann ich alle Daten problemlos und in einem Rutsch mithilfe eines selbst zusammengeklimperten Parsers aus dem MusicXML-Output eines Notenprogramms gewinnen.

Da sich der MusicXML-Output von Lilypond (das ich eigentlich den anderen Notensatzprogrammen gegenüber vorziehen würde) aber offenbar noch im Experimentalstadium befindet, war mein Gedanke, alternativ mal zu versuchen, diejenigen Informationen (2.-5.), die nicht sowieso direkt im SVG-Output enthalten sind, ähnlich wie in der Lilypond-Datei event-listener.ly zu gewinnen.

Prinzipiell mache ich bei meinen bisherigen Tests nichts anderes, als was dort auch gemacht wird, insofern lohnt es sich nicht, hier etwas eigenes zu posten. Was mich noch stört, weil es mir ziemlich unelegant vorkommt, ist die Tatsache, dass in event-listener.ly die Daten nicht erst gesammelt und dann - passend strukturiert - gemeinsam in eine Datei ausgegeben werden, sondern dass dort für jedes registrierte Event immer eine Datei aufgeklappt, einzeilig beschrieben und wieder zugeklappt wird.

Ich vermute aber, das geht nicht anders, weil man mit Scheme offenbar auf kein Event reagieren kann, das das Partiturende signalisiert? Das wäre ja Voraussetzung dafür, dass man ganz am Schluss, bevor das Programm terminiert, noch die gesammelten Informationen in eine Datei schreiben könnte.

Herzliche Grüße
Jost

P.S.: Die MIDI-Daten helfen mir übrigens nicht direkt weiter, weil dort hinterlegt ist, wann Töne an und ausgehen, und nicht, wann ein neues Notenzeichen kommt (was ja wegen Überbindungen nicht immer identisch ist).


harm6

  • Member
Re: Indexnummer eines Staff
« Antwort #5 am: Dienstag, 15. März 2016, 20:42 »
Zitat
Da sich der MusicXML-Output von Lilypond (das ich eigentlich den anderen Notensatzprogrammen gegenüber vorziehen würde) aber offenbar noch im Experimentalstadium befindet

Da ich mich mit MusicXml nicht auskenne korrigiere mich bitte, falls ich hier etwas unzutreffendes poste, aber nach allem was ich höre steckt MusicXml selbst noch in den Kinderschuhen.
Ist es nicht gedacht als ein Format welches Kodierungen von Musik zwischen den verschiedenen Notensatzprogrammen austauschbar machen soll?
Aber Sibelius->Finale scheint schon nicht so besonders zu klappen. (Zahlreiche Berichte in den Archiven der internationalen mailing-list).
Was zu fehlen scheint ist ein allgemein anerkannter Konsens über die MusicXml-standards, der über einen kleinsten gemeinsamen Nenner hinausgeht.

Bei LilyPond ist es eher eine Gemengelage von fehlenden Developern mit gesteigertem Interesse an MusicXml (und natürlich den nötigen programming-skills) sowie einer gewissen abwartenden Haltung wohin sich die ganze Chose wohl entwickeln wird.
Das ist zumindest mein Eindruck.

Zitat
Was mich noch stört, weil es mir ziemlich unelegant vorkommt, ist die Tatsache, dass in event-listener.ly die Daten nicht erst gesammelt und dann - passend strukturiert - gemeinsam in eine Datei ausgegeben werden, sondern dass dort für jedes registrierte Event immer eine Datei aufgeklappt, einzeilig beschrieben und wieder zugeklappt wird.

Ich vermute aber, das geht nicht anders, weil man mit Scheme offenbar auf kein Event reagieren kann, das das Partiturende signalisiert? Das wäre ja Voraussetzung dafür, dass man ganz am Schluss, bevor das Programm terminiert, noch die gesammelten Informationen in eine Datei schreiben könnte.

Nun, hier mal ein engraver der, so meine ich, genau das tut.
Erst werden die note-events in einer Liste akkumuliert und dann deren Listenlänge ausgegeben.

Natürlich ist das nur das bloße Gerippe der Funktionalität. Man kann die Ausgabe durch eine geeignete printing-procedure natürlich sonstwo hinschreiben lassen, sowie anstatt nur die Länge der Listen (und damit die Anzahl der Noten pro score) auszugeben, könnte man ja etwas tun mit diesen gesammelten note-events...

\version "2.19.36"

\layout {
  \context {
    \Voice
    \consists
      #(let ((notes '()))
         (make-engraver
           (listeners
            ((note-event engraver event)
              (set! notes (cons event notes))))
           ((finalize engraver)
               (write-me "\nHow-many-notes? " (length notes))
               (set! notes '()))))
  }
}

\score {
  \new Staff \repeat unfold 13 c''1
}

\score {
  \new Staff \repeat unfold 17 des''1
}

Gruß,
  Harm

jps

  • Member
Re: Indexnummer eines Staff
« Antwort #6 am: Mittwoch, 16. März 2016, 00:09 »
Saaa-gen-haft!

Genau das habe ich gesucht und nicht gefunden (der Rest ist ja dann nicht weiter schwer). Ich muss sicher noch beträchtlich länger mit Scheme hantieren, bevor ich weiß, was ich wo suchen muss ...

Was MusicXML angeht, kann ich mir auch nicht anmaßen, die inzwischen erreichte Qualität wirklich zu beurteilen. Da ich aber für meine Zwecke nur sehr elementare Dinge auslesen muss, und da der MusicXML- und der SVG-Output jeweils aus der gleichen Quelle kommen, hat sich die Sache bei meinen bisherigen Tests als sehr zuverlässig erwiesen.

Jetzt hat's mich doch grad mal in den Fingern gejuckt, und ich hab mal schnell versuchsweise eine komplette Bachkantate per MusicXML von Finale nach Sibelius und von Sibelius nach Finale exportiert (ich gestehe, ich habe sie beide in Gebrauch). Das hat perfekt geklappt. Der MusicXML-Import in Lilypond hat im großen und Ganzen auch sehr gut funktioniert, aber es sind doch auch ein paar sehr schwere Schnitzer drin. Dafür sieht es viiiel schöner aus ;) - Den Teil, der fehlerfrei ist (auch nach Auskunft der Log-Datei beim Kompilieren) habe ich mal versucht, mit Frescobaldi als MusicXML zu exportieren, aber das bricht mir immer mit einer Fehlermeldung ab. Natürlich ist ein einziger Test nicht aussagekräftig, aber die Sache mit den event-listenern scheint ja gut zu funktionieren; dann verlass ich mich lieber darauf.

Tausend Dank und herzliche Grüße
Jost

P.S.: Gibt's für die Anzahl der Einzel-Notensysteme in einem Gesamtsystem evtl. auch so was Knackiges?

harm6

  • Member
Re: Indexnummer eines Staff
« Antwort #7 am: Mittwoch, 16. März 2016, 00:36 »
Weiter zu MusicXml:
Vielleicht ist dieser aktuelle Thread von Interesse:
http://lilypond.1069038.n5.nabble.com/Best-support-programs-for-Lilypond-td188133.html
Insbesondere die posts von Richard Shann, Entwickler von Denemo, welches ein eigenes xml-Format hat.
http://denemo.org/
https://de.wikipedia.org/wiki/Denemo

Bei Frescobaldi habe ich nicht nur einmal von Schwierigkeiten beim MusicXml-Ex/Import gehört, kann da selber aber nichts zu sagen da ich Frescobaldi nicht verwende.

Zitat
Ich muss sicher noch beträchtlich länger mit Scheme hantieren, bevor ich weiß, was ich wo suchen muss ...

Soweit ich das sagen kann scheints Du überhaupt keine Schwierigkeiten mit scheme zu haben.
Das Problem liegt hier eher darin, daß es kaum Doku zu Wie-schreibe-ich-engraver gibt.
In den regtests gibt es das file scheme-engraver.ly welches zumindest einen Überblick über die Möglichkeiten gibt...

Zitat
Gibt's für die Anzahl der Einzel-Notensysteme in einem Gesamtsystem evtl. auch so was Knackiges?

Ich denk mal drüber nach ...


Gruß,
  Harm
« Letzte Änderung: Mittwoch, 16. März 2016, 00:44 von harm6 »

harm6

  • Member
Re: Indexnummer eines Staff
« Antwort #8 am: Mittwoch, 16. März 2016, 23:34 »
Hallo Jost,

hier noch ein paar Ideen.
Ich bin noch nicht zufrieden damit, aber für heute abend muß es reichen, bin zu müde ...

\version "2.19.36"

#(define (format-notes note-event)
    (let* ((origin (ly:input-file-line-char-column
                    (ly:event-property note-event 'origin))))
      (string-join
        (list
          (format #f "~a" (ly:event-property note-event 'pitch))
          (format #f "point-and-click ~a ~a\n"
               (caddr origin)
               (cadr origin)))
        "\t")))

#(define (format-engr-test ctx)
  (let ((notes '()))
    (make-engraver
      (listeners
       ((note-event engraver event)
         (set! notes (cons (format-notes event) notes))))     
      ((finalize engraver)
         (let (;; name it as you like ;)
               ;; option "a" is required, though
               (port (open-file "event-listener-test-01.log" "a")))
           (newline
             ;; change to port if wanted
             (current-error-port)
             ;port
             )
           (display
             (cons
               (format #f "I'm a context of type \"~a\", my name is: \"~a\"\n"
                 (ly:context-name ctx)
                 (if (string-null? (ly:context-id ctx))
                     "unnamed"
                     (ly:context-id ctx)))
               (reverse notes))
             ;; change to port if wanted
             (current-error-port)
             ;port
             )
            (close port)
         (set! notes '()))))))
         
#(define (count-staffs-engr ctx)
  (let ((staffs '()))
    (make-engraver
      (listeners
       ((AnnounceNewContext engraver event)
          (let ((context (ly:event-property event 'context)))
            (if (eq? (ly:context-name context) 'Staff)
                (set! staffs (cons context staffs))))))     
      ((finalize engraver)
          (newline)
          (display-scheme-music (reverse staffs))
          (set! staffs '())))))

\layout {
  \context {
    \Score %% !!
    \consists #count-staffs-engr
  }
  \context {
    \Staff %% !!
    \consists #format-engr-test
  }
}

\score {
  \new Staff
    { \repeat unfold 1 <c'' e''>1 f'' }
}

\score {
  <<
    \new Staff = "first"
      \repeat unfold 17 des''1
    \new Staff = "second"
      { R1 \repeat unfold 16 d''1 << r1 \new Staff = "ossia" { fisis1 } >> }
    \new Staff = "third"
      \repeat unfold 17 eis''1
    \new Staff = "fourth"
      \repeat unfold 17 f''1
  >>
}

Gruß,
  Harm

jps

  • Member
Re: Indexnummer eines Staff
« Antwort #9 am: Donnerstag, 17. März 2016, 18:56 »
Da steckt ja wieder ein Haufen Anregungen (und sicher ziemlich viel Arbeit) drin! Ich muss mich jetzt aktuell erst mal vornehmlich ganz anderen Baustellen zuwenden; aber ich werde mir das alles bei nächster Gelegenheit auf jeden Fall mal gründlich zu Gemüte führen und bei meinen Überlegungen gerne mit einbeziehen.

Danke und herzliche Grüße
Jost