Introduction: GNU Denemo is a graphical music notation program written in C with gtk+. It is an official part of the GNU project (http://www.gnu.org/), and its homepages are http://www.gnu.org/software/denemo/denemo.html and http://denemo.sourceforge.net/ Denemo is intended to be used in conjunction with GNU Lilypond (http://www.cs.uu.nl/hanwen/lilypond/), but is adaptable to other computer-music-related purposes as well. (In fact, one of the reasons Adam Tee is involved in the project is his desire to extend Denemo for use in music analysis.) On the design of Denemo: please consult the DESIGN file in the distribution for all the details. Do so especially before you make suggestions that change the way the interface works - much deliberation went into many of the features and approaches that you see. Credit to others where it's due: The pixmaps that Denemo uses are taken from Lilypond, as produced by the mf-to-xpms script. Many thanks to Jan Nieuwenhuizen for helping me produce these correctly. Note: the metafont sources that were used to create these pixmaps are _not_, in fact, included with the Denemo; you'll find them in the mf/ directory of the lilypond-1.2.10 distribution, available at ftp://ftp.cs.uu.nl/pub/GNU/LilyPond/v1.2/ System requirements: * gtk+ and glib versions 1.2.0 or better, including the development libraries * a C compiler Recommended: * GNU Lilypond (for typesetting and for MIDI playback) * an external MIDI player (for MIDI playback) * flex (for hacking the lexers) * bison (for hacking the parsers) (note that this program has only been tested on one or more of the following systems: i386 Red Hat Linux 6.2, i386 Mandrake Linux 6.1, and i386 Debian GNU/Linux 2.1 with updated gtk+ and glib. I'd imagine it should work under other UN*X OSes as well; no guarantees on Win32, though you're welcome to hack my code to get it running.) Actually using the darn program: The primary way to interact with Denemo is with the keyboard (and eventually with a MIDI keyboard as well.) Though there are plans to add better mouse support to the program, this concern will still remain secondary when it comes to the process of note entry. Though it can be useful to beginners, point-and-click note entry would be too inefficient for seasoned users of the program. As supporting beginners will be important down the road, there are plans to introduce point-and-click note entry eventually, but right now it's low on the priority list. New in version 0.5.3, Denemo has the ability to sound your chords through /dev/sequencer as you enter them. It accomplishes this by opening /dev/sequencer and holding it open as long as your still entering notes; if you pause, a timeout will elapse and /dev/sequencer will be closed down until you start note-entry again. This is intentional; it is there to facilitate the use of an external midi player for full-score playback or to have multiple instances of Denemo running at once. Sometimes, though (particularly if you have a fast machine), Denemo may hold open /dev/sequencer for long enough that it interferes with an invocation of playmidi. If this happens, simply be patient and try again. The keys you should use to control Denemo: Navigation: h, left arrow: move the cursor to the left. If at the beginning of a measure, move the cursor to the end of the preceding measure (if there is a preceding measure). l, right arrow: move the cursor to the right. If at the end of a measure, move the cursor to the beginning of the next measure (if there is a next measure. If there isn't a next measure, you may want to hit m to create one.) j, down arrow: move the cursor down to the next line or space on the score. k, up arrow: move the cursor up to the next line or space on the score. Control-up arrow, Control-k: move the cursor to the previous staff Control-down arrow, Control-j: move the cursor to the next staff Control-left arrow, Control-h: move the cursor to the beginning of the measure or (if there) the beginning of the preceding measure. Control-right arrow, Control-l: move the cursor to the beginning of the next measure. a-g: move the cursor up or down to the nearest note of that pitch. ': move the cursor up one octave ,: move the cursor down one octave Beginning the entry of a chord: 0, `: insert a whole note at the current cursor position. 1: insert a half note. 2, SPACE BAR: insert a quarter note. 3: insert an eighth note. 4-6: you can figure it out. Alt in combination with any of those keys will produce a rest instead of a note. That is, if your windowmanager isn't set to trap that key combination. If this is the case, you can probably disable it for Denemo. For example, with WindowMaker one would right-click on Denemo's title bar and navigate to the Window Attributes->Advanced Options->Don't Bind Keyboard Shortcuts option. Alternately, to enter rests one can use: ESC: put the cursor into rest mode. This will cause the cursor to turn gray; the next note entry command will be interpreted as a request to insert a rest. Note that entering a chord when you are already at the end of the measure (the cursor turns red when this happens) may cause your next note to be added to the _beginning_ of the next measure, or even implicitly create a next measure if one didn't already exist. Fleshing out a chord: Enter: Add a tone to the chord presently "at the cursor"*. The tone to be added reflects the current cursor position. This will also convert a rest to a note. Shift-Enter: Removes the chord tone presently "at the cursor". If there is only one tone in the chord presently at the cursor, this will convert the note to a rest. +: Sharpen the note "at the cursor" by one half-step. -: Flatten the note "at the cursor" by one half-step. Adding Tuplets: Control-0, Control-1, or Control-2 to bring up a dialog that allows you to specify what coefficient you want to use for your tuplets. (e.g., "Times 2/3"). Control-3 through Control-7: Inserts a tuplet group with a common coefficient. Display Commands: Control-Shift-left: Decrease the minimum display width of all measures by 10 pixels Control-Shift-right: Increase the same by 10 pixels Control-Shift-up: Decrease vertical space alloted to each staff by 10 pixels Control-Shift-down: Increase vertical space alloted to each staff by 10 pixels Selection: Control-Space: set a markpoint at the cursor Control-C: Copy the area between the markpoint and the current cursor location to the paste buffer. Control-X: The same as above, but clear the selection after doing this. Control-V: Paste the buffer at the current cursor position. Note that the behavior of cut-and-paste is a little bit idiosyncratic. Play around with it a little bit to get the hang of it. The intention is for it to behave in a manner that's reasonable, and easy to correct if that isn't exactly what you would have liked Denemo to do. For example, paste will not add new measures to the score unless the paste operation conflicts with music that has already been entered; cut will delete measures if every staff is in the selection, but otherwise it will simply clear them, and so on. Stemming Directives: S: insert a stemboth directive +: stemdown->stemboth, or stemboth->stemup -: stemup->stemboth, or stemboth->stemdown Other Commands: .: Add a dot to the current chord. shift-. (>): Remove a dot from the current chord, if possible. =: Toggle whether the current chord is tied to the next or not. DEL, x: delete the note at the current cursor position with Control - delete the whole measure, if possible. with Control and Shift - delete the whole staff. BackSpace, X: delete the note just before the current cursor position. Has no effect at the beginning of a measure. m: add a new measure to each staff at the current cursor position. M: add a new measure to each staff at the end of the score. Home: move cursor to first measure of piece End: move cursor to last measure of piece There are long-term plans to make these keybindings fully customizable, but this default arrangement should be relatively usable. And even familiar to vi users; don't get the wrong idea, though, for coding I'm an emacs man through and through. :) Users of Lilypond will probably note that this mimics Lilypond's relative entry mode. Yes; this is intentional. Known issues that there's no pressing need to fix: The ways that accidentals persist is somewhat peculiar (though not overly so). It's hard to explain - it's easiest if you just experiment with Denemo to see how that works. The shift-numeral system described above works only with a US-style keyboard layout. As far as I can tell, though, this will only be fixable when the keyboard customization interface is in place. Why is this written in C?: Mainly because my C is better than my C++; I have only passing familiarity with the latter. Besides that, I've had my hands full learning the relatively well documented C interfaces to gtk+. As I'd never worked with gtk+ before starting this program, learning a less-well-documented language binding would have made things much more difficult for me. Apart from that - the C makes it run reasonably fast even on older machines (there'd be a performance hit with, say, Python/gtk+), and I have my doubts on whether C++ would actually make the program more readable, maintainable, more impervious to memory problems, or whatever. Contributing and contacting me: My e-mail address is mhiller@pacbell.net Your input and suggestions on how to make this program better is very much encouraged, though be sure to read DESIGN before you make a suggestion that deliberately runs counter to the ideas behind this program. And if you have patches to contribute (better still!), here are some guidelines on submitting them: * Denemo is evolving very quickly towards compliance with the GNU Coding Standards; your code should do formatted accordingly. Refer to http://www.gnu.org/prep/standards_toc.html if you're uncertain how to do this. Also note that GNU indent can format your source code appropriately (indeed, its default behavior is to do so.) * Feel free to submit a ChangeLog entry as part of your patch; the easiest way to do this is probably with M-x add-change-log-entry in GNU Emacs when the source file you've altered is in the foreground. * Make your patch with the diff command; unidiff format is best. The command line that you use for making your patch should look something like this, 'cause it makes it easy for me to integrate it: diff -urN ../denemo-x.y.z . that is, the original source tree for the version of denemo that you're patching can be found in ../denemo-x.y.z, and the source tree where you've changed files is . Another option, providing you have checked the latest Denemo code out of CVS (which, in turn, ensures that it will be useful to us), is to use the CVS diff command. From within your copy of the repository, for example, cvs diff -uN > mydiff.diff should do the trick. *Commands that affect the note or chord "at the cursor" do not always require the cursor to be positioned precisely. If the cursor is in "appending mode" (at the end of a measure), these commands will affect the chord preceding the cursor. Also, the commands that modify or remove an existing chord tone do not require exact vertical positioning of the cursor - the vertically-closest note in the chord will be affected. If the cursor is halfway between two chord tones, the command will affect the higher of the two tones.