[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: address@hidden Lilypond Comments!
From: |
svoboda |
Subject: |
Re: address@hidden Lilypond Comments! |
Date: |
30 Jun 2004 14:46:16 -0400 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 |
address@hidden writes:
> Hello, I have used Lilypond just last week to create a few musical
> scores (pop music with a chordline, melody line, and lyrics).
>
> Anyway I have some comments regarding usage, mainly the problems I
> encountered. I can possibly fix them given some encouragement...mainly
> I want to know if anything has been done to address these problems?
>
> (I'm using LilyPond 2.2 on both RH9 Linux and Windows XP)
>
>
> -> I use | a lot to separate measures, and am always running up
> against the "| not at a measure boundary" warning...obviously I am
> constantly having notes/measures between bars that don't add up to the
> time signature. This was a major slowdown and pain to deal with...I'd
> like to figure out some way to fix this problem.
>
> One notion I have is an addition to LilyPond's emacs mode that
> operates similar to Emacs's column-mode (which automatically displays
> the cursor's column number on the modeline). This addition would
> simply indicate on the modeline just what beat the cursor is on...or
> rather how many beats lie between the cursor and the previous | or {.
>
> With that in place, I could prevent those measure boundary warnings,
> b/c I would know how 'full' each measure was when I type it in.
>
> Has anyone attacked this problem? I could be convinced to work on a
> patch if no one else has...
<snip>
Since no one else has attacked this problem, I figured I'd take a
whack at it. My results are appended to this message. Going to try it
for a few days & see how well it works. To use it, I tweaked my .emacs
file as follows:
(load-library "lilypond-init.el") ; already there
(load "/usr0/svoboda/sw/elisp/what-beat.el") ; this file
(add-hook 'LilyPond-mode-hook (lambda () (local-set-key "\C-cb"
'what-beat)))
Hence 'C-c b' displays the current beat in the minibuffer; displayed
as a ratio. i.e. if it shows 3/8, it means there are the equivalent of
3 eighth notes between the point and the last measure indicator (|).
Comments? Buggestions?
--
David Svoboda address@hidden
Senior Research Programmer http://www.cs.cmu.edu/~svoboda
Language Technologies Institute Practice Kind Randomness and
Carnegie Mellon University Beautiful Acts of Nonsense
-----
(setq pitch-regex "\\([a-z]+[,']*\\(=[,']\\)?\\)\\|<[^>]*>")
(setq duration-regex "\\([ \t]*\\(128\\|6?4\\|3?2\\|16?\\|8\\)\\([.]*\\)\\([
\t]*[*][ \t]*\\([0-9]+\\)\\(/\\([1-9][0-9]*\\)\\)?\\)?\\)")
(defun extract-match (string match-num)
(if (null (match-beginning match-num))
nil
(substring string (match-beginning match-num) (match-end match-num))))
(defun add-fractions (f1 f2)
"Adds two fractions, both are (numerator denominator)"
(set 'result (list (+ (* (car f1) (cadr f2)) (* (car f2) (cadr f1)))
(* (cadr f1) (cadr f2))))
(set 'result (reduce-fraction result 2))
(set 'result (reduce-fraction result 3))
(set 'result (reduce-fraction result 5))
(set 'result (reduce-fraction result 7))
)
(defun reduce-fraction (f divisor)
"Eliminates divisor from fraction if present"
(while (and (= 0 (% (car result) divisor))
(= 0 (% (cadr result) divisor))
(< 1 (cadr result))
(< 0 (car result)))
(set 'result (list (/ (car result) divisor) (/ (cadr result) divisor))))
result
)
(defun parse-duration (duration)
"Returns a duration string parsed as '(numerator denominator)"
(string-match duration-regex duration)
(let ((result (list 1 (string-to-int (extract-match duration 2))))
(dots (extract-match duration 3))
(numerator (or(extract-match duration 5) "1"))
(denominator (or (extract-match duration 7) "1")))
(if (and (not (null dots)) (< 0 (string-width dots)))
(dotimes (dummy (string-width dots))
(set 'result (list (1+ (* 2 (car result))) (* 2 (cadr result))))))
(list (* (string-to-int numerator) (car result))
(* (string-to-int denominator) (cadr result)))
))
(defun walk-note-duration ()
"Returns duration of next note, moving point past note.
If point is not before a note, returns nil
If next note has no duration, returns t"
(if (not (looking-at pitch-regex))
nil
(progn
(goto-char (match-end 0))
(if (not (looking-at duration-regex))
t
(progn
(goto-char (match-end 0))
(parse-duration(match-string 0)))))))
(defun get-beat ()
(save-excursion
(save-restriction
(let* ((end (point))
(measure-start (or(re-search-backward "\|" 0 t) 0))
(last-dur (or(re-search-backward duration-regex 0 t) 0))
(duration (parse-duration(match-string 0)))
(result '(0 1))) ; 0 in fraction form
(if (= measure-start 0)
(error "No | before point")
(progn
(goto-char (1+ measure-start))
(skip-chars-forward " \t\n")
(while (< (point) end)
(set 'new-duration (walk-note-duration))
(if (null new-duration)
(if (looking-at "\\\\times[ \t]*\\([1-9]*\\)/\\([1-9]*\\)[
\t\n]*{")
(let ((numerator (string-to-int(match-string 1)))
(denominator (string-to-int(match-string 2))))
(goto-char (match-end 0))
(skip-chars-forward " \t\n")
(while (and (not (looking-at "}"))
(< (point) end))
(set 'new-duration (walk-note-duration))
(if (null new-duration)
(if (looking-at "\\\\[a-z]*[ \t]*[a-z]*")
(goto-char (match-end 0))
(error "Unknown text: %S %s"
result(buffer-substring (point) end))))
(if (not (eq new-duration t))
(set 'duration new-duration))
(set 'result (add-fractions result
(list (* numerator (car
duration))
(* denominator
(cadr duration)))))
(skip-chars-forward " \t\n"))
(if (< (point) end)
(forward-char 1))) ; skip }
(if (looking-at "\\\\[a-z]*[ \t]*[a-z]*")
(goto-char (match-end 0))
(error "Unknown text: %S %s" result(buffer-substring
(point) end))))
(if (not (eq new-duration t))
(set 'duration new-duration))
(set 'result (add-fractions result duration)))
(skip-chars-forward " \t\n"))
result
))))))
(defun what-beat ()
"Returns how much of a measure lies between last measaure '|' and point.
Recognizes chords, triples, and /clef & other context words."
(interactive)
(let ((beat (get-beat)))
(message "%d/%d" (car beat) (cadr beat)))
)
Re: address@hidden Lilypond Comments!,
svoboda <=