2010-12-07 6 views
6

私はLilyPondを使って練習問題と練習問題を作成します。私は、Moveable Do solfege表記法でノート入力を許可する方法と、ノートの下にソルフェージ記号を歌詞として表示するテンプレート(下記参照)を用意しました。現在、音楽を生成するマークアップとマークアップから手作業で歌詞を抽出する必要があります。私は部分的にこれをいくつかのpythonとvimコード(ここには表示されていません)で自動化することができましたが、やや不満足です。LilyPond:音楽から音名を抽出する

ファイルの処理中にLilyPondの組み込みSchemeインタプリタを使って音名を抽出するのが最善の解決策だと思います。私はly:note-pitchnameで地図を使う試みをいくつか行いましたが、これまでのところ成功していません。おそらく、私はSchemeについてスクワットを知っているから、特にLilyPondスクリプトで使われているように。

のLilyPondが自動的例えば、音名を表示しますNoteNames彫刻を提供しています。

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

答えて

3

は、私は次のような解決策につながったLilyPondのユーザーフォーラムにバレンティンVillenaveから有益な情報を受け取りました。ノートの下に歌詞として "c d e"が付いていますが、ノートネームがオランダのピアノの名前に戻ってしまう原因となる長年のバグがあります。 Valentinの回避策は、連想配列を作成し、各ピッチが印刷される直前に呼び出されるラムダ関数のルックアップとして使用することです。アレイからのエントリを置換することによって、所望のピッチ名が印刷される。

解決策を完全に実行可能にするために、私はスコア出力からmidi出力生成を分離するために2番目のスコアブロックを追加する必要がありました。これは、NoteNamesの彫刻家がmidi出力を生成しないようにするために必要です。

私は、このソリューションを、クロマティックソルフェージ名の完全なセットを使ってはるかに大きなファイルでテストしました。それはとてもうまくいく。唯一残っている問題は、Solfegeを通常の歌詞と区別させるために、NoteNamesの出力でフォントのプロパティを調整できることがうれしいことです。これまで私はそれを実現させることができませんでした。

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

UPDATE: それはフォントプロパティは

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

を変更することで、例えば、markup functionで制御することができることが判明し

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

、おそらく、他の方法にはあります。同じことを達成するが、これは簡単で、私が必要とするものを行う。この時点で、私はこの質問に答えました。 LilyPondの将来のバージョンではNoteNamesのバグが修正され、この目的のためにSchemeを使う必要がなくなることに注意してください。

0

私の必要性に非常に近い回答でした。私のハーモニカとヴァイオリンの練習のために、数字の上または下のドットを取得する方法を忘れてしまった。

それはより多くの将来のようなスクリプトを含めてもOPが行う-RE-MI番号、英語を生成しないためのものですので、私は物事をrestructed:

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

    }  
} 
関連する問題