last modified Time-stamp: "07/05/21 17:01:01 nik"

What is CM-ETF? /

CM-ETF is a subsystem for Common Music (CM) that generates
music notation files in Enigma Transportable File (ETF)
format. These files can be used by the popular notation
software Finale, or Sibelius.

CM-ETF is released under the terms of the GNU Software
License. See the file LICENSE.txt for details.

To report bugs or make comments, contact the author:
Niklas Kambeitz <>

Requirements /

Common Lisp and Common Music (version 2.8 or later).

Finale (2003 or later) or Sibelius is required to open the
generated files.

Works on these platforms:
Windows --> CLISP, SBCL
Linux ----> CMUCL, SBCL, CLISP

Installation /

Download the source tarball (CVS snapshot):
Then unpack it and put the CM-ETF folder in
the same directory as CM.

Older packaged releases and instructions for CVS access
are available at the sourceforge project pages:

Loading /

First load CM into lisp, then evaluate (use-system :cm-etf).

How to use it /

CM-ETF adds functions to CM, so first (in-package :cm)

SEQ->ETF translates a SEQ object and writes it to
"cm-etf_OUTPUT.ETF" in the CM-ETF directory.
Each channel is written to a separate staff.
e.g. (seq->etf (new seq :subobjects
(list (new midi :time 0 :duration 3 :keynum 61)
(new midi :time 3 :duration 1 :keynum 62)
(new midi :time 3 :duration 1 :keynum 63)
(new midi :time 0 :duration 4 :keynum 64 :channel 1))))

OPEN-FINALE opens "cm-etf_OUTPUT.ETF" with the default
application for ETF's (only on Windows or Mac).
e.g. (open-finale)

SPELL tries to correctly spell a list of midi pitch numbers.
e.g. (spell '(60 61 63 66))

SCORE->ETF writes lists of events to ETF.
The format of each event is: (time duration (pitches))
e.g. (score->etf '((0 2 (60 64 67)) (2 2 (60 64 67))))
writes two C-major half notes.
Each event list supplied as an argument is written
to a separate staff.

MAKE-ETF writes an ETF based on a rhythm tree
and a list of chords. This allows the user to bypass
the CM-ETF quantization and spelling algorithms.
e.g. (make-etf '(? (((4 4) (1 (2 (1 -1 1)) 1.0))))
'((60) (cs4 ef4) nil (60 61) (60 61)))

Notes /

Both SEQ->ETF and SCORE->ETF accept the keyword argument :time-sigs,
which is either a single time signature in the format of (numerator
denominator), or a list of time-signatures.

The page layout and music spacing must be redone in Finale.

The spelling algorithm only works vertically, so that chords
are spelled correctly, disregarding pitches in other
staves. Horizontal melodic motion is not taken into account

Some code from OpenMusic is used to convert the times and
durations of midi events into a rhythm "tree".

To customize the template, use Finale 2003 to save a new file
called "template.ETF" with the desired document options and
replace the old template with the new one.

Sequences are quantized according to the parameter
*allowed-subdivisions* which controls the permitted subdivisions of
the quarter note. The default value is '(8 12 10)

Links /

CM-ETF webpage -->
at SourceForge -->
Niklas Kambeitz ->

Common Music ---->
FOMUS ----------->
OpenMusic ------->

Files /

README.txt ............ this file
LICENSE.txt ........... legal stuff

template.ETF .......... new ETF's are based on this file

cm-etf.asd ............ system definition (ASDF)

load.lisp ............. to load CM-ETF if USE-SYSTEM doesn't work
packages.lisp ......... package definitions: "CM-ETF" and "OM"
text-io.lisp .......... portably handle newlines in unicode text
file-io.lisp .......... parse from and insert data to ETF strings
etf-data.lisp ......... generate data to insert into an ETF file
rhythm-analysis.lisp .. analyze event lists and SEQ objects
combinations.lisp ..... finding all subsets of a list, for spelling
spelling.lisp ......... pitch spelling
om-bits.lisp .......... bits of OpenMusic needed by simpleTree
simpleTree.lisp ....... turn duration lists into rhythm trees
conversion.lisp ....... converting among objects types

To do list /

- fix (score->etf '((3 16/5 (60))) :time-sigs '((3 2)))
- let tuplets span durations greater than time signature denominator
- rework the method for assigning the displayed numbers on tuplets
- fix stem displacement bug
- fix extra final bar bug
- fix page layout
- fix pitch bends of score->seq
- rewrite spelling algorithm to use stored data for each set class
- hide accidentals on repeated notes
- automatically split scores with wide pitch fields or too many pitches into multiple voices

- allow tuplets to span more than one quarter note
- there are no beat charts yet (worth it?)
- each entry should state its distance from the barline to facilitate beat-charts
- different spelling algorithms for melodic lines?
- generate instrument lists?

- export more functions to cm? (packages.lisp)
- make a method for "events"?
- make CM-ETF work without Common Music?
- what CM functions are used?
- rhythm, note-name, note-accidental, octave-number

Changelog /

Jul/07/2006 - first CVS import
Aug/01/2006 - conversion.lisp: fixed bugs in process-tree and tupletize
Aug/01/2006 - conversion.lisp: added meta->etf and make-etf, rewrote score->etf
May/21/2007 - added support for note-attached text expressions Logo