标签:
尽管GNU/Linux并非无所不能,但确实能在很多时候提供免费、开放的解决方案。这两天我想做一个简谱,在网上搜索乐谱排版软件,发现了基于GPL协议的Lilypond软件。只不过Lilypond是用来做五线谱的。幸好,又找到剑桥大学 Silas S. Brown 编写的一个 jianpu-ly.py 脚本,通过调用Lilypond能够最终生成简谱。关于它的详细介绍请看这里。
该脚本支持的简谱语法规则如下:
一个典型的简谱源文件如下:
title=标题 1=C 2/4 1 2 3 4 5 6 7 1‘
将该文件存为jianpu.txt后,先调用jianpu-ly.py生成Lilypond输入文件:
jianpu-ly.py < jianpu.txt > jianpu.ly
然后调用lilypond程序,生成指定格式的乐谱文件。令人惊喜的是,不光可以排版出PDF、PS、PNG等格式的简谱,还可以生成midi文件,直接播放试听。可以用如下方式调用lilypond:
# 生成PDF文件、midi文件 lilypond jianpu.ly # 生成png文件、midi文件 lilypond --png jianpu.ly # 生成ps文件、midi文件 lilypond --ps jianpu.ly
可以用timidity直接播放生成的midi文件,或者将其转换为RIFF wav格式,再用普通的音频播放器来听。
timidity -Ow -o jianpu.wav jianpu.midi
为了将上述几个命令自动化,方便使用,我编写了一个bash脚本make_jianpu.sh,代码如下:
#!/bin/bash script_name="make_jianpu.sh" script_usage=$(cat <<EOF make_jianpu.sh [OPTIONS] JIANPU.txt EOF ) script_function=$(cat <<EOF Batch convertion of a jianpu into Lilypond script then into pdf, png, midi and wav EOF ) script_doc=$(cat <<EOF -h Display this help. EOF ) script_examples=$(cat <<EOF EOF ) state_prefix="===" warning_prefix="***" error_prefix="!!!" function display_help() { if [ -n "$script_usage" ]; then echo -e "Usage: $script_usage" fi if [ -n "$script_function" ]; then echo -e "$script_function" fi if [ -n "$script_doc" ] ; then echo -e "\n$script_doc" fi } while getopts ":hr:" opt; do case $opt in h ) display_help exit 0 ;; \? ) display_help exit 1 ;; esac done shift $(($OPTIND - 1)) jianpu_txt="$1" # Clear old generated files if [ -e "${jianpu_txt%txt}ly" ]; then rm "${jianpu_txt%txt}ly" fi if [ -e "${jianpu_txt%txt}pdf" ]; then rm "${jianpu_txt%txt}pdf" fi if [ -e "${jianpu_txt%txt}png" ]; then rm "${jianpu_txt%txt}png" fi if [ -e "${jianpu_txt%txt}midi" ]; then rm "${jianpu_txt%txt}midi" fi if [ -e "${jianpu_txt%txt}wav" ]; then rm "${jianpu_txt%txt}wav" fi if [ -e "$jianpu_txt" ]; then jianpu-ly.py < "$jianpu_txt" > "${jianpu_txt%txt}ly" if [ -e "${jianpu_txt%txt}ly" ]; then # Generate pdf file lilypond "${jianpu_txt%txt}ly" if [ -e "${jianpu_txt%txt}pdf" ]; then echo "简谱pdf文件生成成功!" # Generate png file lilypond --png "${jianpu_txt%txt}ly" if [ -e "${jianpu_txt%txt}png" ]; then echo "简谱图片文件生成成功!" # Generate wav file from midi if [ -e "${jianpu_txt%txt}midi" ]; then echo "midi文件生成成功!" timidity -Ow -o "${jianpu_txt%txt}wav" "${jianpu_txt%txt}midi" if [ -e "${jianpu_txt%txt}wav" ]; then echo "wav文件生成成功!" else echo "无法生成wav文件,请检查简谱语法错误!" fi else echo "无法生成midi文件,请检查简谱语法错误!" fi else echo "无法生成简谱图片文件,请检查简谱语法错误!" fi else echo "无法生成PDF文件,请检查简谱语法错误!" fi else echo "无法生成ly文件,请检查简谱语法错误!" fi else echo "无法找到输入文件:$jianpu_txt!" fi
此外,我在使用的过程中发现,若使用默认的Lilypond设置,虽然能够生成正确的midi文件,但却无法排版出升、降与还原号(accidentals)。经过一番试探,发现只要在/usr/share/lilypond/2.14.2/ly/engraver-init.ly文件中第168行添加:
\consists "Accidental_engraver"
便可以解决该问题。这是因为,经jianpu-ly.py脚本转换生成的Lilypond文件基于的是RhythmicStaff context。而engraver-init.ly中的默认配置并未包括对accidentals的“雕刻”(engrave)。所以,需要手动加上。
至此,用于简谱排版的工具已经俱备。我试着编排了《博基上校进行曲》片段如下。大家可以体验一下Lilypond的效果。
源文件:
title=博基上校进行曲 1=C 2/4 q1‘ q0 q7. s6 q5 q3 q1 q3 q5 s5 s6 q5 s5 s6 5 - R{ q5 q3 0 q0 q3 q4 q5 3‘ 3‘ 1‘ - q5 q3 0 q0 q3 q4 q3 5 5 4 - q4 q2 0 } A{ q0 q2 q3 q4 q5 q3 0 q0 q3 q4 q3 q2 5 q3 q#4 2 q6 5 ( - 5 ) - | q0 q6 q7 q6 } q1‘ q5 0 q0 q5 q4 q3 q2 6 q2 q7, 5 q7, 1 ( - 1 ) q3 q3 1‘. q7 s6 s#5 q6 q5 q4 3 ( - q3 ) q3 q4 q3 6 q#5. s6 1‘ q6. s1‘ #2‘ ( - #2‘ ) 6 3‘. q2‘ s1‘ s7 q6 q#5. s6 2. q4 q6 q0 s1‘ s7 s1‘ s2‘ q3‘ q0 q7. s1‘ 6 ( - 6 ) q3 q3 1‘. q7 s6 s#5 q6 q5 q4 3 ( - q3 ) q3 q4 q3 6 q#5. s6 1‘ q6. s1‘ #2‘ ( - #2‘ ) 6 3‘. q2‘ s1‘ s7 q6 q#5. s6 2. q4 q6 q0 s1‘ s7 s1‘ s2‘ q3‘ q0 q7. s1‘ 6 ( - 6 ) 5-> \ff
简谱:
标签:
原文地址:http://www.cnblogs.com/quantumman/p/5189701.html