事情的起因是我在制作一款歌谱生成软件,希望找找乐谱的绘图库,居然发现完全没有现成的库,不得不承认,国内外计算机水平是差着不少的。。。因为,在百度上完全找不到这方面的内容,搜索歌谱排版,歌谱转pdf等等,一直没有结果。而在google上搜英文,东西一堆一堆的,于是我就把一个个人认为非常好的软件拿过来分享一下。
Lilypond是一款GNU软件,免费而开源,可以将一篇歌谱脚本自动排版成五线谱,ps文档和midi乐,而且渲染质量非常之高,这是下面它的效果图:
而它使用的脚本则是自定义语法规则的描述类语言:
\header {
title = "LilyPond demo"
enteredby="Han-Wen Nienhuys"
maintainer="hanwen@xs4all.nl"
texidoc = "heavily mutilated Edition Peters Morgenlied by Schubert"
}
\version "2.12.0"
ignoreMelisma = \set ignoreMelismata = ##t
ignoreMelismaOff = \unset ignoreMelismata
#(set-global-staff-size 21)
\paper {
%#(set-global-staff-size (* 5.8 mm))
indent = #(* mm 4)
line-width = #(* mm 140)
interscoreline = 2.\mm
between-system-space = 15\mm
ragged-bottom = ##t
}
modernAccidentals = {
\set Staff.extraNatural = ##f
\set Staff.autoAccidentals = #'(Staff (same-octave . 1) (any-octave . 0))
\set Staff.autoCautionaries = #'()
}
melody = \relative c'' \repeat volta 2 \context Voice = "singer" {
\time 6/8
\autoBeamOff
s1*0^\markup { \larger { \hspace #-3.0 Lieblich, etwas geschwind } }
R2.
r4 r8 c4 g8 |
\acciaccatura { f16 } e4 c8
<<
\new Voice { \stemUp f8. g16 }
{ \stemDown f8.[ g16] } >> \stemNeutral a8 |
fis4 g8 c16[ b a g] f[ e] |
d4 f8
\transpose a' e' \relative c'' { a16[ g fis! g] f![ d] } |
g4. r8 gis gis |
a4 a16.[ b32] c8[( a]) fis8 |
g4.~ g8-\fermata
}
firstVerse = \lyricmode {
\set stanza = "1."
Sü -- ßes Licht! Aus
\ignoreMelisma
gol --
\ignoreMelismaOff
de -- nen Pfor -- ten brichst du __ |
sie -- gend durch __ die Nacht. Schö -- ner Tag, du __ bist er -- wacht. __
}
secondVerse = \lyricmode {
\set stanza = "2."
いろはに כיף та та ほへど ちり ぬるを
Жъл дю ля זה
いろ はに כיף та та ほへ ちり ぬる
Жъл дю ля __
}
pianoRH = \relative c''' \repeat volta 2\new Voice {
#(set-accidental-style 'modern)
\voiceOne
g16( fis a g fis g f e d c b
\oneVoice
a ) |
<g e>8( <es fis a> <d e bes'> <c e c'>\arpeggio) r8 r |
r8 c'( e,) f r a |
\once \override DynamicLineSpanner #'padding =#3
r8
<< { fis( g) } \\
<< { a4 } { s8\> s8\! } >>
>>
r8 <e c g>8[ <e c g>] |
<d c a>4. r8 \clef bass <d b f> <d b f> |
\crescTextCresc
e,16_" "\<
g c g e g d gis b gis d gis |
c, e a e c e a,-\f\! d fis d a d |
b d g d b g e16. r32\fermata
}
pianoLH = \relative c'' \repeat volta 2\new Voice {
#(set-accidental-style 'modern)
\voiceTwo
g16( fis a g fis g
f e d c b
\change Staff = down
\oneVoice
d,) |
g4.( b,8) r r
\clef treble \grace s16 r8 <bes'>8-> <bes c>8->([ <a c>)] r <f c'> |
\clef bass
r8 dis( e) r c c |
f,4. g8[ r8 g] |
<c, c,>4. <e e,>4. |
a,4. <d d,>4. |
g,8 r r g16 r16\fermata
}
\book {
\score {
<< \time 6/8
\new Staff \with {
fontSize = #-3
\override StaffSymbol #'staff-space = #(magstep -3)
} <<
\context Staff #(set-accidental-style 'modern)
\melody >>
\lyricsto "singer" \new Lyrics \firstVerse
\lyricsto "singer" \new Lyrics \secondVerse
\new PianoStaff <<
\set PianoStaff.instrumentName = \markup {
\bold
\larger\larger\larger\larger
\huge
"2."
}
\context Staff = up <<
\pianoRH
\pianoLH
>>
\context Staff = down { \clef bass \skip 1*2 }
>>
>>
\layout {
\context {
\Lyrics
\override VerticalAxisGroup #'minimum-Y-extent = #'(-0.85 . 2.2)
\override LyricText #'font-size = #-1
}
\context {
\Score
\override Beam #'thickness = #0.55
\override Beam #'auto-knee-gap = #4.0
\override SpacingSpanner #'spacing-increment = #1.0
\override Stem #'stemlet-length = #0.5
\override Slur #'height-limit = #1.5
}
}
\midi {
\context {
\Score
tempoWholesPerMinute = #(ly:make-moment 70 4)
}
}
}
}中间的部分就是描述了乐谱的旋律和符号,具体的内容规则就请看帮助文档了,另外,帮助文档大概有300兆左右。。。
这款软件可以很方便的通过命令行调用,(因为是GNU的嘛),使用方法就是
lilypond 文件名 (当然还有各种可选参数表,具体就看help吧)
我用C#写了段脚本生成代码,然后用cmd命令调用了一下,有需要的就当做参考吧:
/*
* @Author: sxf
* @Date: 2014-01-12 22:02:12
* @Last Modified by: sxf
* @Last Modified time: 2014-01-16 12:43:15
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Diagnostics;
using System.IO;
class GenerateStaff{
String title = "Demo";
public void Set(String title)
{
this.title = title;
}
StreamWriter sw;
public void Generate(String str) {
sw = new StreamWriter(str,false);
sw.WriteLine("\\header {");
sw.WriteLine("title = \"{0}\" ",title);
sw.WriteLine("}");
sw.WriteLine("\\version \"2.12.0\"");
sw.WriteLine("ignoreMelisma =\\set ignoreMelismata = ##t");
sw.WriteLine("ignoreMelismaOff = \\unset ignoreMelismata");
sw.WriteLine("#(set-global-staff-size {0})",21);
sw.WriteLine("\\paper {{\n%#(set-global-staff-size (* {0} mm))",5.8);
sw.WriteLine("indent = #(* mm {0})",4);
sw.WriteLine("line-width = #(* mm {0})",140);
sw.WriteLine("interscoreline = {0}.\\mm",2);
sw.WriteLine("between-system-space = {0}\\mm",15);
sw.WriteLine("ragged-bottom = ##t ");
sw.WriteLine("}");
sw.WriteLine("modernAccidentals = {");
sw.WriteLine("\\set Staff.extraNatural = ##f");
sw.WriteLine("\\set Staff.autoAccidentals = #\'(Staff (same-octave . 1) (any-octave . 0))");
sw.WriteLine("\\set Staff.autoCautionaries = #\'() ");
sw.WriteLine("}");
sw.Write("melody = ");
writeRelative("c\'\' ");
// writeClef("bass");
writeTime(6,8);
// sw.Write("\\repeat volta 2 \\context Voice = \"singer\" ");
sw.WriteLine("{");
// sw.WriteLine("\\autoBeamOff");
writeClef("bass");
// writeTime(6,8);
// sw.WriteLine("\\autoBeamOff");
// sw.WriteLine("s1*0^\\markup {{ \\larger {{ \\hspace #-3.0 Lieblich, etwas geschwind }} }}");
// sw.WriteLine("R2.");
writeNote(1);
writeNote(2);
for (int i = 1; i < 8; ++i)
{
writeNote(i,4);
}
for (int i = 1; i < 8; ++i)
{
writeNote(i,4);
}
Random ra = new Random();
for (int i = 1; i < 250; ++i)
{
writeNote(ra.Next(7)+1,8);
}
sw.WriteLine("}");
sw.Close();
}
int mi(int x)
{
int y = 2;
for (int i =1;i<x;++i)
{
y*= 2;
}
return y;
}
void writeRelative(String str) {
sw.Write("\\relative {0}",str);
}
void writeClef(String str){
sw.WriteLine("\\clef {0} ",str);
}
void writeTime(int p,int q) {
sw.WriteLine("\\time {0}/{1}",p,q);
}
char[] md = {'#','c','d','e','f','g','a','b'};
void writeNote(int p) {
sw.Write("{0} ",md[p]);
}
void writeNote(int p,int q) {
sw.Write("{0}{1} ",md[p],q);
}
}
class MainClass {
static void Main() {
test("sxf","hello.ly");
}
static void test(String str,String filename) {
Console.WriteLine("Hello,{0}",str);
GenerateStaff gs = new GenerateStaff();
gs.Generate(filename);
RenderPdf(filename);
}
static void RenderPdf(String str) {
//定义一个ProcessStartInfo实例
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
//设置启动进程的初始目录
info.WorkingDirectory = System.Environment.CurrentDirectory;
//设置启动进程的应用程序或文档名
info.FileName = System.Environment.CurrentDirectory+"\\usr\\bin\\lilypond";
Console.WriteLine(info.WorkingDirectory);
//设置启动进程的参数
info.Arguments = System.Environment.CurrentDirectory + "\\"+str;
//设置不显示窗口
info.CreateNoWindow = true;
//启动由包含进程启动信息的进程资源
try
{
System.Diagnostics.Process.Start(info);
}
catch (System.ComponentModel.Win32Exception we)
{
Console.WriteLine(we.Message);
return;
}
}
}
在寻找乐谱绘图库的过程中,作者发现了Lilypond这款GNU软件,它可以将歌谱脚本转化为高质量的五线谱、PS文档和MIDI乐。Lilypond使用自定义的描述语言,并支持命令行调用。文章中作者分享了如何用C#脚本调用Lilypond进行乐谱排版。
625

被折叠的 条评论
为什么被折叠?



