Language Lilypond
Date: | 12/15/06 |
Author: | Nate Eldredge |
URL: | http://www.math.ucsd.edu/~neldredg/ |
Comments: | 1 |
Info: | http://lilypond.org |
Score: | (3.01 in 158 votes) |
% Lilypond is a music engraving system with an % embedded Scheme interpreter. % http://lilypond.org % Output of this program is at % http://www.math.ucsd.edu/~neldredg/personal/99-lilypond.pdf \include "english.ly" % Necessary because we use deep recursion #(debug-set! stack 0) \header{ title = "Ninety-Nine Bottles of Beer" composer = "Traditional" arranger = \markup{ "Nate Eldredge" } } \version "2.8.7" totalbottles = #99 startmelody = { \time 6/8 \clef treble \key c \major \autoBeamOff } endmelody = { \bar "|." } % text = \lyricmode { % Nine -- ty nine bot -- tles of beer on the wall % Nine -- ty nine bot -- tles of beer __ % Take one down and pass it a -- round % Nine -- ty eight bot -- tles of beer on the wall % } zerosyl = { } onesyl = \relative c''{ c4. } twosyl = \relative c''{ c4 c8 } threesyl = \relative c''{ c8 c8 c8 } foursyl = \relative c''{ c16 c16 c8 c8 } fivesyl = \relative c''{ c16 c16 c8 c16 c16 } #(define (count-syllables L) (if (null? (ly:music-property L 'text)) (apply + (map count-syllables (ly:music-property L 'elements))) 1)) % FIXME - check the syllabication zero = \lyricmode { } % because "seventy" will become { \seventy \zero } one = \lyricmode { one } two = \lyricmode { two } three = \lyricmode { three } four = \lyricmode { four } five = \lyricmode { five } six = \lyricmode { six } seven = \lyricmode { se -- ven } eight = \lyricmode { eight } nine = \lyricmode { nine } ten = \lyricmode { ten } eleven = \lyricmode { e -- le -- ven } twelve = \lyricmode { twelve } thirteen = \lyricmode { thir -- teen } fourteen = \lyricmode { four -- teen } fifteen = \lyricmode { fif -- teen } sixteen = \lyricmode { six -- teen } seventeen = \lyricmode { se -- ven -- teen } eighteen = \lyricmode { eigh -- teen } nineteen = \lyricmode { nine -- teen } twenty = \lyricmode { twen -- ty } thirty = \lyricmode { thir -- ty } forty = \lyricmode { for -- ty } fifty = \lyricmode { fif -- ty } sixty = \lyricmode { six -- ty } seventy = \lyricmode { se -- ven -- ty } eighty = \lyricmode { eigh -- ty } ninety = \lyricmode { nine -- ty } nomore = \lyricmode { no more } error = \lyricmode { oh shit } #(define (speak-small n) (cond ((= n 0) zero) ((= n 1) one) ((= n 2) two) ((= n 3) three) ((= n 4) four) ((= n 5) five) ((= n 6) six) ((= n 7) seven) ((= n 8) eight) ((= n 9) nine) ((= n 10) ten) ((= n 11) eleven) ((= n 12) twelve) ((= n 13) thirteen) ((= n 14) fourteen) ((= n 15) fifteen) ((= n 16) sixteen) ((= n 17) seventeen) ((= n 18) eighteen) ((= n 19) nineteen) (else error))) #(define (speak-tens n) (cond ((= n 1) ten) ((= n 2) twenty) ((= n 3) thirty) ((= n 4) forty) ((= n 5) fifty) ((= n 6) sixty) ((= n 7) seventy) ((= n 8) eighty) ((= n 9) ninety) (else error))) #(define (speak-number n) (cond ((= n 0) nomore) ((< n 20) (speak-small n)) (else (make-sequential-music (list (speak-tens (quotient n 10)) (speak-small (modulo n 10))))))) #(define (sing-syllables k) (cond ((= k 0) zerosyl) ((= k 1) onesyl) ((= k 2) twosyl) ((= k 3) threesyl) ((= k 4) foursyl) ((= k 5) fivesyl))) #(define (sing-number n) (sing-syllables (count-syllables (speak-number n)))) SingNumber = #(define-music-function (parser location n) (integer?) (ly:music-deep-copy (sing-number n))) SpeakNumber = #(define-music-function (parser location n) (integer?) (ly:music-deep-copy (speak-number n)) ) #(define (capitalize! s) (string-set! s 0 (char-upcase (string-ref s 0)))) #(define (capitalize s) (let ((l (string->list s))) (list->string (cons (char-upcase (car l)) (cdr l))))) % takes a list of music objects #(define (capitalize-lyric-list L) (cond ((null? L)) ((not (null? (ly:music-property (car L) 'text))) (ly:music-set-property! (car L) 'text (capitalize (ly:music-property (car L) 'text)))) (else (capitalize-lyric-list (append (ly:music-property (car L) 'elements) (cdr L)))))) CapitalizeLyric = #(define-music-function (parser location lyr) (ly:music?) (let ((newlyr (ly:music-deep-copy lyr))) (capitalize-lyric-list (list newlyr)) newlyr)) melodyone = \relative c''{ g8 g g | c c c c4 r8 | } melodytwo = \relative c''{ a8 a a | d4.~ d8 r8 r8 | b4 b8 b4 b8 | b8 b b b4 r8 | } melodytwofinal = \relative c''{ a8 a a | d4.~ d8 r4 | b8 b8 b8 b4 b8 | b4 b8 b4 r8 | } melodythree = \relative c''{ a8 a b | c c c c4 r8 |} lyricsone = \lyricmode{ of beer on the wall, } lyricstwo = \lyricmode{ of beer. Take one down and pass it a -- round, } lyricstwofinal = \lyricmode{ of beer. Go to the store and buy some more, } lyricsthree = \lyricmode { of beer on the wall. } bottle = \lyricmode{ bot -- tle } bottles = \lyricmode{ bot -- tles } PluralBottle = #(define-music-function (parser location n) (integer?) (if (= n 1) bottle bottles)) SingVerse = #(define-music-function (parser location n) (integer?) (let ((nn (if (> n 0) (- n 1) totalbottles)) (meltwo (if (> n 0) melodytwo melodytwofinal))) #{ { { \SingNumber #$n }} \melodyone { \transpose c d { \SingNumber #$n }} $meltwo { \transpose c' g { \SingNumber #$nn }} \melodythree #})) SpeakVerse = #(define-music-function (parser location n) (integer?) (let ((nn (if (> n 0) (- n 1) totalbottles)) (lyrtwo (if (> n 0) lyricstwo lyricstwofinal))) #{ \CapitalizeLyric \SpeakNumber #$n \PluralBottle #$n \lyricsone \SpeakNumber #$n \PluralBottle #$n $lyrtwo \SpeakNumber #$nn \PluralBottle #$nn \lyricsthree #})) SingVerses = #(define-music-function (parser location nstart nend) (integer? integer?) (if (>= nstart nend) (let ((nextverse (- nstart 1))) #{ \SingVerse #$nstart \SingVerses #$nextverse #$nend #}) #{ #} )) SpeakVerses = #(define-music-function (parser location nstart nend) (integer? integer?) (if (>= nstart nend) (let ((nextverse (- nstart 1))) #{ \SpeakVerse #$nstart \SpeakVerses #$nextverse #$nend #}) #{ #} )) \score{ { << \new Voice = "one" { \transpose c' g { \startmelody \SingVerses #totalbottles #0 \endmelody } } \new Lyrics \lyricsto "one" { \SpeakVerses #totalbottles #0 } >> } \layout { } \midi { } }
Download Source | Write Comment
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments
plams said on 05/11/09 21:58:33
Wow! This is fucking great. People, this is the output:
http://www.math.ucsd.edu/~neldredg/personal/99-lilypond.pdf
!!!
It even takes the different number of syllables in the numbers into account in the music. Genius. Next step must be to sing it in csound or ChucK :D