2010-12-07 18 views
6

Utilizo LilyPond para crear notas de práctica y etudes. He descubierto cómo permitir la entrada de notas en la notación de solfeo Moveable Do y tengo una plantilla (ver a continuación) que permite mostrar los símbolos de solfeo como letras debajo de las notas. En este momento, tengo que extraer manualmente la letra de la notación más el marcado que genera la música. He podido automatizar parcialmente esto con algún código python y vim (no se muestra aquí), pero aún así es algo insatisfactorio.LilyPond: extracción de nombres de tono de la música

Me parece que la mejor solución sería utilizar el intérprete Scheme integrado de LilyPond para extraer los nombres de tono mientras se procesa el archivo. Intenté utilizar el mapa con ly: note-pitchname, pero hasta ahora no he tenido éxito. Probablemente porque sé squat sobre Scheme, especialmente como se usa en los scripts de 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"     

Respuesta

3

que recibieron información útil a partir de Valentin Villenave en el Foro de Usuarios de LilyPond que llevó a la siguiente solución viable:

LilyPond proporciona un grabador NoteNames que imprimirá automáticamente los nombres de tono, por ejemplo. "c d e" como letras debajo de las notas, pero existe un error de larga data que hace que NoteNames revierte a los nombres de tono holandeses. La solución alternativa de Valentin es crear una matriz asociativa y usarla como una búsqueda en una función lambda que se llama cuando cada tono está a punto de imprimirse. Al sustituir las entradas de la matriz, se imprimen los nombres de tono deseados.

Para que la solución sea completamente funcional, también tuve que agregar un segundo bloque de puntuación para separar la generación de salida midi de la impresión de puntaje. Esto es necesario para evitar que el grabador NoteNames produzca salida midi.

He probado esta solución con un archivo mucho más grande utilizando el conjunto completo de nombres de solfeo cromático. Funciona muy bien. El único problema restante es que sería bueno poder ajustar las propiedades de la fuente en el resultado NoteNames para hacer que el solfeo sea distinto de las letras normales. Hasta ahora no he podido hacer que eso suceda.

% 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" 

ACTUALIZACIÓN: Resulta que las propiedades de fuente pueden ser controlados con el markup function, por ejemplo, cambiando

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

a

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

Hay, probablemente, otras formas de lograr lo mismo, pero esto es simple y hace lo que necesito. En este punto, considero respondida esta pregunta. Tenga en cuenta que una versión futura de LilyPond puede corregir el error de NoteNames y eliminar la necesidad de utilizar Scheme para este fin.

0

La respuesta ayudó muy cerca de mi necesidad. Solo echo de menos cómo conseguir un punto por encima o por debajo del número para mi práctica de armónica y violín.

I restructed las cosas por lo que es más como un futuro incluye la escritura y también para la generación de número, Inglés y no OP do-re-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 { 

    }  
} 
Cuestiones relacionadas