2010-12-07 28 views
6

J'utilise LilyPond pour créer des partitions de pratique et des études. J'ai trouvé comment autoriser la saisie de notes dans la notation de solfège Moveable Do et avoir un modèle (voir ci-dessous) qui supporte l'affichage des symboles de solfège sous forme de paroles sous les notes. Actuellement, je dois extraire manuellement les paroles de la notation plus le balisage qui génère la musique. J'ai été capable d'automatiser partiellement ceci avec du code python et vim (non montré ici), mais il est encore un peu insatisfaisant.LilyPond: Extraire des noms de chansons de la musique

Il me semble que la meilleure solution serait d'utiliser l'interpréteur Scheme intégré de LilyPond pour extraire les noms de hauteur pendant le traitement du fichier. J'ai fait quelques tentatives pour utiliser map avec ly: note-pitchname, mais jusqu'ici aucun succès. Probablement parce que je connais squat sur Scheme, surtout comme utilisé dans les scripts LilyPond.

% Moveable Do as lyrics example 

% define some solfege pitchnames 
% (in practice, the full set goes into "english.ly") 
pitchnames = #`(
    (do . ,(ly:make-pitch -1 0 NATURAL)) 
    (re . ,(ly:make-pitch -1 1 NATURAL)) 
    (mi . ,(ly:make-pitch -1 2 NATURAL)) 
    ) 

#(ly:parser-set-note-names parser pitchnames) 

% compose as though in C major 
mynotes = \relative do' {\key do \major do2 re4(mi4) } 

% transpose to desired key 
melody = \transpose do mi { \mynotes } 

% I WANT TO AUTOMATICALLY CREATE THE 
% THE PITCHNAMES IN THIS BLOCK 
% FROM THE CONTENTS OF \mynotes 
solfa = \lyricmode { 
    \set ignoreMelismata = ##t % one syllable per note 
    do re mi 
    \unset ignoreMelismata % allow normal placement of other lyrics 
    } 

% Produce score with solfege names as lyrics 
\score { 
    << 
    \new Voice = "myVoice" { 
     \melody 
    } 
    \new Lyrics \lyricsto "myVoice" \solfa 
    >> 
    } 
\version "2.12.3"     

Répondre

3

J'ai reçu des informations utiles de Valentin Villenave sur les utilisateurs LilyPond Forum qui a conduit à la solution réalisable suivante:

LilyPond fournit un graveur de NoteNames qui imprimera automatiquement les noms de pas, par exemple. "c d e" en tant que paroles sous les notes, mais il existe un bug de longue date qui fait que NoteNames revient aux noms des hauteurs hollandais. La solution de Valentin consiste à créer un tableau associatif et à l'utiliser comme une recherche dans une fonction lambda qui est appelée au fur et à mesure que chaque pas est sur le point d'être imprimé. En substituant les entrées du tableau, les noms de hauteur souhaités sont imprimés. Pour rendre la solution complètement opérationnelle, j'ai également dû ajouter un deuxième bloc de partition pour séparer la génération de sortie MIDI de l'impression de partition. Ceci est nécessaire pour empêcher le graveur NoteNames de produire une sortie midi.

J'ai testé cette solution avec un fichier beaucoup plus volumineux en utilisant l'ensemble complet des noms de solfège chromatique. Il fonctionne très bien. Le seul problème restant est que ce serait bien de pouvoir ajuster les propriétés de la police sur la sortie NoteNames pour que le solfege soit distinct des paroles normales. Jusqu'à présent, je n'ai pas été en mesure d'y arriver.

% Moveable Do as lyrics example 

% define solfege pitchnames 
pitchnames = #`(
    (do . ,(ly:make-pitch -1 0 NATURAL)) 
    (re . ,(ly:make-pitch -1 1 NATURAL)) 
    (mi . ,(ly:make-pitch -1 2 NATURAL)) 
    ) 

#(ly:parser-set-note-names parser pitchnames) 

% Apparently, LilyPond reverts to dutch names when 
% using the NoteNames context. The following 
% workaround was posted by V. Villenave at 
% http://lists.gnu.org/archive/html/lilypond-user/2010-10/msg00687.html 

newnames = 
#`(("c" . "do") 
    ("d" . "re") 
    ("e" . "mi")) 

myNoteNames = 
#(lambda (grob) 
    (let* (
      ;; bindings 
      (default-name (ly:grob-property grob 'text)) 
      (new-name (assoc-get default-name newnames)) 
     ) 
      ;; body 
     (ly:grob-set-property! grob 'text new-name) 
     (ly:text-interface::print grob) 
     ) 
    ) 

% compose as though in C major 
mynotes = \relative do' {\key do \major do2 re4(mi4) } 

% transpose to desired key 
melody = \transpose do mi { \mynotes } 

% Produce score with solfege names as lyrics 
\score { 
    << 
    \new Voice = "myVoice" { 
     \melody 
    } 
    \context NoteNames \with { 
     \override NoteName #'stencil = #myNoteNames 
    } { \mynotes } 

    >> 
} 
% Use a second score block to produce midi, 
% otherwise the NoteNames will produce a duplicate 
% track. 
\score { 
    \new Voice = "myVoice" { 
     \melody 
    } 
     %% This generates the midi file 
    \midi { 

    }   
}  
\version "2.12.3" 

MISE À JOUR: Il se trouve que les propriétés de police peuvent être contrôlées avec le markup function, par exemple, en changeant

(ly:grob-set-property! grob 'text new-name) 

à

(ly:grob-set-property! grob 'text (markup #:italiC#:smaller new-name)) 

Il y a, sans doute, d'autres façons de accomplir la même chose mais c'est simple et fait ce dont j'ai besoin. À ce stade, je considère que cette question a été répondue. Notez qu'une future version de LilyPond peut corriger le bug NoteNames et éliminer le besoin d'utiliser Scheme à cette fin.

0

La réponse a aidé très proche de mon besoin. Manque juste comment obtenir un certain point au-dessus ou au-dessous du nombre pour ma pratique d'harmonica et de violon.

Je restructed les choses il est donc plus comme un avenir inclus scénario et aussi pour générer le numéro, l'anglais et non OP do-ré-mi:

% LilyBin == template with 馬槽歌 Away in a Manger lilypond ... === 

% LilyBin 

\version "2.18.2" 

\include "english.ly"  

%% === melody ============================== 

mynotesC =  

\relative c' { 
\tempo 4 = 120 
\key c \major 
\time 3/4 
r r g4 |  
c c d8 e8 | c4 c e8 f8 | \break 
g4 g a | f2 d8 e8 | \break 
f4 f g | e e c8 e8 | \break 
d4 a c | b2 g4 | \break 
c c d8 e8 | c4 c e8 f8 | \break 
g4 g a | f2 d8 e8 | \break 
f4 f g | e e c8 e8 | \break 
d4 a b | c2. | \break } 


mymelodyC = \transpose c c  { \mynotesC } 

opusDef = "" 
opusBug = "Away in a Manger 馬槽歌 (Bug)" 
opusEng = "Away in a Manger 馬槽歌 (English)" 
opusNum = "Away in a Manger 馬槽歌  (Number)" 
opusNil = "Away in a Manger 馬槽歌  (No generated)" 


%% === default header ============================= 

\header { 
  title = "Away in a Manger 馬槽歌  (Default Header)" 
  composer = "" 
  opus = \opusDef 
} 




%% still problem 
%% based on http://stackoverflow.com/questions/4378228/lilypond-extracting-pitch-names-from-music 

%% === engnames ====================================== 

engnames = 
#`(
   ("c" . "D") 
   ("d" . "D") 
   ("e" . "E") 
   ("f" . "F") 
   ("g" . "G") 
   ("a" . "A") 
   ("b" . "B")   
   
   ("ces" . "Cb") 
   ("des" . "Db") 
   ("ees" . "Eb") 
   ("fes" . "Fb") 
   ("ges" . "Gb") 
   ("aes" . "Ab") 
   ("bes" . "Bb")   
    
   ("cis" . "C#") 
   ("dis" . "D#") 
   ("eis" . "E#") 
   ("fis" . "F#") 
   ("gis" . "G#") 
   ("ais" . "A#") 
   ("bis" . "B#")   
 ) 

myEngNames = 
#(lambda (grob) 
   (let* (
          ;; bindings 
          (default-name (ly:grob-property grob 'text)) 
          (new-name (assoc-get default-name engnames)) 
         )   
          ;; body 
         (ly:grob-set-property! grob 'text new-name) 
         (ly:text-interface::print grob) 
         ) 
   ) 
    
%% === numnames ===================================== 

numnames = 
#`(
   ("c" . "1") 
   ("d" . "2") 
   ("e" . "3") 
   ("f" . "4") 
   ("g" . "5") 
   ("a" . "6") 
   ("b" . "7")   
   
   ("ces" . "1b") 
   ("des" . "2b") 
   ("ees" . "3b") 
   ("fes" . "4b") 
   ("ges" . "5b") 
   ("aes" . "6b") 
   ("bes" . "7b")   
    
   ("cis" . "1#") 
   ("dis" . "2#") 
   ("eis" . "3#") 
   ("fis" . "4#") 
   ("gis" . "5#") 
   ("ais" . "6#") 
   ("bis" . "7#")   
 ) 

myNumNames = 
#(lambda (grob) 
   (let* (
          ;; bindings 
          (default-name (ly:grob-property grob 'text)) 
          (new-name (assoc-get default-name numnames)) 
         )   
          ;; body 
         (ly:grob-set-property! grob 'text new-name) 
         (ly:text-interface::print grob) 
         ) 
   ) 


%% === no generated "lyrics" ================= 


\score { 

   << 
    \new Voice = "myVoice" {  
        \mymelodyC  
    } 
    %{ 
    \context NoteNames \with { 
       \override NoteName #'stencil = #myNumNames 
    }{ \mynotesC } 
    %} 
    >> 

  \layout{ 
  \context { 
      \Score 
      proportionalNotationDuration = #(ly:make-moment 1/16) 
    } 


  #(layout-set-staff-size 30) 
    indent = #0 
    line-width = #180 
    ragged-last = ##f} %% ##t} 
  %%  \midi{} 

  \header { 

  opus = \opusNil 
} 

} 


%% === Produce score with buggy non-English names as lyrics ====== 

\pageBreak 

\score { 


    << 
    \new Voice = "myVoice" {  
        \mymelodyC  
    } 
    \context NoteNames { \mynotesC } 

    >> 

\header { 
  opus = \opusBug 
} 


      \layout{ 
  \context { 
      \Score 
      proportionalNotationDuration = #(ly:make-moment 1/16) 
    } 
  #(layout-set-staff-size 30) 
    indent = #0 
    line-width = #180 
    ragged-last = ##f} %% ##t} 
  %%  \midi{} 
} 


%% ===  Produce score with English names as lyrics ============ 

\pageBreak 

\score { 


    << 
    \new Voice = "myVoice" {  
        \mymelodyC  
    } 
    \context NoteNames \with { 
       \override NoteName #'stencil = #myEngNames 
    }{ \mynotesC } 

    >> 
\header { 

  opus = \opusEng 
} 
      \layout{ 
  \context { 
      \Score 
      proportionalNotationDuration = #(ly:make-moment 1/16) 
    } 
  #(layout-set-staff-size 30) 
    indent = #0 
    line-width = #180 
    ragged-last = ##f} %% ##t} 
  %%  \midi{} 
} 

%% === Page with numNames ============================ 

\pageBreak 

\score { 

   << 
    \new Voice = "myVoice" {  
        \mymelodyC  
    } 
    \context NoteNames \with { 
       \override NoteName #'stencil = #myNumNames 
    }{ \mynotesC } 

    >> 

  \layout{ 
  \context { 
      \Score 
      proportionalNotationDuration = #(ly:make-moment 1/16) 
    } 


  #(layout-set-staff-size 30) 
    indent = #0 
    line-width = #180 
    ragged-last = ##f} %% ##t} 
  %%  \midi{} 

  \header { 

  opus = \opusNum 
} 

} 





%% === MIDI ============================================ 

% Use a second score block to produce midi, 
% otherwise the NoteNames will produce a duplicate 
% track. 

\score { 
    \new Voice = "myVoice" {  
        \mymelodyC  
    }  
      %% This generates the midi file 
    \midi { 

    }  
}