Umwandlung Pausen in Spaces; Entfernung des Schlüssels [GELÖST]

Begonnen von ingmar, Samstag, 11. Mai 2019, 10:21

« vorheriges - nächstes »

ingmar

Liebe unermüdliche Helfer, : - )

heute hab ich ein wenig mehr vor! Ich habe ein Stück Musik, das (anfangs) einen Schlüssel enthält, oder auch nicht, und anschließend nur Spaces oder nur Pausen, die aber auch durch Noten mit \rest ausgedrückt sein können. Jedenfalls keine Tonhöhen oder weitere Elemente. Es wird auch nicht leer sein - Beispiele:

   { \clef "bass" s1 *2 s2 }
   { s\breve }
   { \clef "alto" R1 *3 }
   { r2 }
   { \clef "violin" d'4\rest }
   { a1\rest a2\rest }

Nun möchte ich aus meinem Stück Musik

  • Erfahren, ob es einen Schlüssel enthält
  • Den Namen des Schlüssels erfahren (als String)
  • Die Angabe zum Schlüssel entfernen
  • Erfahren, ob es nur aus Spaces besteht (alternativ, falls leichter: ob das erste Element ein Space ist)
  • Alle Pausen in Spaces umwandeln

Tja, viel auf einmal! - Sorry. Leider hab ich in der Doku nichts gefunden, was mir wirklich weitergeholfen hätte. Ich glaube, Kollege Harms hatte irgendwo mal die Funktion extract-named-music musi 'TimeSignatureMusic verwendet, um die Taktvorzeichnung aus einem Stück Musik herauszufischen, aber das Gegenstück für den Schlüssel hab ich auch nicht herausgefunden...

Und leider kann ich natürlich kein echtes Minimalbeispiel liefern; vielleicht aber hilft das Folgende zumindest, Tipparbeit zu vermeiden:


\version "2.19.83"

musi = { \clef "violin" s1 *2 s2 }
% musi = { s\breve }
% musi = { \clef "alto" R1 *3 }
% musi = { r2. }
% musi = { \clef "violin" d'4\rest }
% musi = { a1\rest a2\rest }


% 1, 2:
get-clef = #(define-scheme-function (my-music) (ly:music?)
;;; returns string or empty string
(
)

\markup { \get-clef \musi }


% 3:
remove-clef = #(define-music-function (my-music) (ly:music?)
;;; returns music
(
)

\score { \remove-clef \musi }


% 4:
has-spaces = #(define-scheme-function (my-music) (ly:music?)
;;; returns boolean
(
)

\markup { #(if (eq? #t \has-spaces \musi ) #{ \markup "ja." #} #{ \markup "nein." #}) }


% 5:
convert-to-spaces = #(define-void-function (my-music) (ly:music?)
;;; returns music
(
)
\score { \convert-to-spaces \musi }



Sehr herzliche Dank für Eure Hilfe! : - )

--ingmar

harm6

Hallo ingmar,

schau mal, ob Du damit klar kommst:


\version "2.19.82"

#(define-public (make-clef-unset mus)
  "Reset the clef settings."
  (map-some-music
   (lambda (m)
     (and (eq? (ly:music-property m 'name) 'PropertySet)
          (member (ly:music-property m 'symbol)
                  '(clefGlyph
                    middleCClefPosition
                    clefPosition
                    clefTransposition
                    clefTranspositionStyle))
          (make-music 'PropertyUnset
                      'symbol (ly:music-property m 'symbol))))
   mus))
   
clefUnset =
#(define-music-function (m) (ly:music?)
  (_i "Unset the current cue clef.")
  (make-clef-unset m))
 
allSpacer =
#(define-scheme-function (m)(ly:music?)
  (let ((rhythmic-elts (extract-typed-music m 'rhythmic-event))
  )
  (if (every (lambda (elt) (music-is-of-type? elt 'skip-event)) rhythmic-elts)
      "All rhythmic elements of my arg are of type skip-event"
      "Not all rhythmic elements of my arg are of type skip-event")))
     
allRestsToSkips =
#(define-music-function (mus)(ly:music?)
  (music-map
    (lambda (m)
      (if (or (music-is-of-type? m 'rest-event)
              (eq? (ly:music-property m 'name) 'MultiMeasureRestMusic))
          (make-music 'SkipEvent 'duration (ly:music-property m 'duration))
          m))
    mus))
   
getClef =
#(define-scheme-function (mus)(ly:music?)
"LIMITATION:
  No warranty the input-string is displayed exactly. Too many aliases.
  Does not work, if more than one clef is set."
  (let* ((prop-sets (extract-named-music mus 'PropertySet))
         (rel-props
           (filter
             (lambda (p)
               (member (ly:music-property p 'symbol)
                       '(clefGlyph
                         ;middleCClefPosition
                         clefPosition
                         clefTransposition
                         ;clefTranspositionStyle
                         )))
              prop-sets))
         (rel-props-vals
           (map (lambda (p) (ly:music-property p 'value)) rel-props))
         (find-clef-entry
           (find
             (lambda (e)
               (equal? (cdr e) rel-props-vals))
             supported-clefs)))
    (if find-clef-entry
        (format #f "Clef is of type ~a" (car find-clef-entry))
        "No clef found")))
     
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\paper { indent = 35 }
 
mus =
{
\compressFullBarRests
%\displayMusic
\clef "bass"
b2 s s1*2
r2 b\rest
R1*2
}

\new Staff \with { instrumentName = "Unchanged example " }
  \mus
 
%% 1/2: 
%% Get clef (if any), print it's name (for limitation see above)
\markup
  \override #'(box-padding . 2)
  \box \column { \getClef \mus \score { \mus } }

%% 3:
%% Unset clef, return music
\new Staff \with { instrumentName = "Unset clef " }
  \clefUnset \mus

%% 4:
%% All spacer in music? Return string for use in \markup
\markup
  \override #'(box-padding . 2)
  \box \column { "check for spacers:" \allSpacer \mus \score { \mus } }

%% 5: Convert rest/pitched-rest/multi-measure-rest to skip-event
\new Staff \with { instrumentName = "Rests to spacers  " }
  \allRestsToSkips \mus


Gruß,
  Harm

ingmar

Vielen Dank!


Ja, es hilft sehr gut weiter.

in deinem Code, Harm, hattest du an einigen Stellen auf Limitierungen hingewiesen. Ich habe aber gut unter Kontrolle, wie ich den Code aufrufen, daher ist das kein echtes Problem.

Ich habe einige Zeit gebraucht, bis ich dazu gekommen bin, aber nun habe ich fast alles aus deiner Antwort umgesetzt, und das funktioniert so, wie es soll. Danke für dir Unterstützung!


--ingmar