ftp.nice.ch/pub/next/unix/music/clm.d.tar.gz

220ins.lisp
 
ACL3.1-on-NeXT3.n
 
README.clm
 
add.ins
 
addflt.ins
 
addons.lisp
 
addsnd.ins
 
akcl-next
 
akcl-nsi
 
all.lisp
 
badd.ins
 
bag.clm
 
bell.ins
 
bigbird.ins
 
bird.clm
 
bird.ins
 
c-io.lisp
 
c56-stubs.lisp
 
canter.ins
 
cellon.ins
 
clar.ins
 
clm-example.lisp
 
clm-make
 
clm-packages.lisp
 
clm.rtf
[View clm.rtf] 
clm.txt
[View clm.txt] 

clm.wn


 
clmdsp.h
[View clmdsp.h] 
cm-example.lisp
 
cmus.c
[View cmus.c] 
cmus.h
[View cmus.h] 
cmus.lisp
 
cnv.ins
 
code56.lisp
 
cream.clm
 
dacs.lisp
 
defaults.lisp
 
defins.lisp
 
drone.ins
 
dsp56.lisp
 
env.lisp
 
files
 
fltdes.lisp
 
fltnoi.ins
 
fltsnd.ins
 
fm.rtf
[View fm.rtf] 

fm.wn


 
fmviolin.clm
 
fusion.ins
 
globals.lisp
 
headers.c
[View headers.c] 
headers.lisp
 
init.lisp
 
initmus.lisp
 
ins.lisp
 
ins56.lisp
 
insect.ins
 
io.c
[View io.c] 
io.lisp
 
jcrev.ins
 
jcvoi.ins
 
jlrev.ins
 
kcl-c56.lisp
 
kcl-clm.lisp
 
kiprev.ins
 
lbjPiano.ins
 
lib56.lisp
 
libm
 
libsgi
 
list.lisp
 
loop.lisp
 
mac.lisp
 
macintosh-io.lisp
 
makins.lisp
 
merge.c
[View merge.c] 
mlbvoi.ins
 
mus.lisp
 
ndslot.h
[View ndslot.h] 
next.c
[View next.c] 
next56.c
[View next56.c] 
next56.lisp
 
noise.ins
 
nrev.ins
 
nxtmem.lisp
 
pluck.ins
 
pqw.ins
 
pqwvox.ins
 
qp.c
[View qp.c] 
qp.lisp
 
qpins.lisp
 
qplib56.lisp
 
qpstubs.lisp
 
refs
 
resflt.ins
 
reson.ins
 
revsnd.ins
 
room.ins
 
rt.lisp
 
run.lisp
 
runpcl.cl
 
san.ins
 
sched.lisp
 
sgi-clm-make
 
sgi-walk.lisp
 
sgi.c
[View sgi.c] 
sms.lisp
 
sound.lisp
 
sound_types.h
[View sound_types.h] 
spectr.clm
 
tied.lisp
 
tl.lisp
 
trans.lisp
 
trp.ins
 
v.ins
 
vox.ins
 
walk.lisp
 
ztap-example.lisp
 

README.clm

    C O M M O N    L I S P    M U S I C

This directory contains the "common lisp music" system.
In its compressed form (for public distribution) the clm software is
called clm.tar.Z -- ftp ccrma-ftp, login as anonymous, use your email
address as the password, cd pub/Lisp, binary, get clm.tar.Z, and quit.
Back at home, uncompress clm.tar.Z, tar xf clm.tar.  This will write
out all the files that make up the clm system into the current
directory.  The current version number is in initmus.lisp, along with
news about changes.  (From outside Stanford, ftp ccrma-ftp.stanford.edu
-- I believe ccrma-ftp's address is 36.49.0.93.  I also place copies
of these files at ftp.zkm.de on the pub directory).

Basic documentation is in clm.wn (or clm.rtf or clm.txt) and ins.lisp.
makins.lisp tries out many of the instruments -- if you can load
makins, clm is probably happy.

There's a mailing list for clm news: cmdist@ccrma.stanford.edu.  To
get your address added to or removed from this list, send the request
to cmdist-request@ccrma.stanford.edu.  (Common Music and CMN use this
same mailing list).  The archive of past messages (very incomplete
before June-94) is pub/Lisp/cmdistMail.



This software is available to anyone who is interested, free gratis
for nothing, without warranties of any kind.  Send bug reports or
suggestions to bil@ccrma.stanford.edu.



There are currently 5 possible environments for CLM: 

  a NeXT (680x0) with Franz Lisp's common lisp (OS 2.0, 2.1, 3.0, 3.1, 3.2) 
	(lisp versions 3.1.2, or 4.1)
  a NeXT (680x0) with Gnu common lisp (gcl or akcl) (OS 2.0, 2.1, 3.0, 3.1, 3.2)

    in both ACL and GCL (AKCL), Ariel's QP board for the NeXT is supported, as are the
         32K and 192K word DSP memory expansion modules, on all
         styles of NeXT hardware.  Also, get Jean Laroche's Play
         program, if you can -- it is callable via the jrdac function.

  a PC (486/Pentium) running NeXTStep 3.2, with gcl (or akcl),
         The Ariel PC56D and Ilink i56 boards are supported

  an SGI Indigo with Franz's Allegro CL 4.1 or KCL

  a Mac with MCL 2.0.1, System 7, at least 8 MBytes RAM




Contents: NeXT instructions (Allegro CL)
          NeXT instructions (GCL/AKCL)
          NS/Intel instructions (GCL/AKCL)
          SGI instructions (Allegro CL)
          SGI instructions (AKCL)
          Mac instructions (MCL)
          Defaults
          Benchmarks
          Unix File Permission Bits
          Things CLM Needs
          Other Useful Software



------------------------------------------------------------------------
NeXT:


(68000-based) NeXT with Franz Allegro CL (3.1.2 or 4.1)

To make clm, put the correct pathname for your lisp image in clm-make
and run it (i.e clm-make in a terminal). Currently clm-make dies
with

"Error (from ERROR): eof encountered on input stream #<synonym stream for *TERMINAL-IO* @ #x30ee61>
; Auto-exit"

but this is not a real error -- to run clm after clm-make has done
its job, start up lisp and load all.lisp.  (If clm-make complains
"permission denied", chmod 777 clm-make).  (I also tried using the -O2
compiler switch in clm-make, but it appears to make no difference).

If you are not running a 3.n NeXT, comment out the line in all.lisp

#+NeXT (pushnew ':NeXT-3.0 *features*)

The libraries have different names in 2.1 and 3.n, so the foreign 
function loaders need to know which system they're running under.
If you have ACL 3.1.20 that ran on NeXT 2.1, and want it to run on
NeXT 3.0 or later, follow the directions in the file ACL3.1-on-NeXT3.n.

We support Ariel's QP board -- just plug any number of them into any
available slots, follow Ariel's instructions on installing slot
drivers and so on, and the rest should be automatic.  If possible get
1Mword of DRAM; the SRAMs are less vital and can be 16K without any
loss.  If you're running a 2.1 NeXT (not 3.n), make the three changes
to qp.c to fix up differences between the 2.1 and 3.0 header file
pathnames.

To run clm on the Next without the 56000 package, comment out the
56-mus-gens feature -- in all.lisp:

;#+(and next (or (not I386) ArielPc56d)) (pushnew :56-mus-gens *features*)


On a Turbo NeXT, delete the word "inline" from the procedure declarations
for put_cpu_tx and get_cpu_rx in next56.c, before compiling next56.c

Here at CCRMA, we run ACL 3.1 on NeXT 3.2 because ACL 4.1's compiler
is impossibly slow, and later versions of ACL aren't supported.



------------------------------------------------------------------------
(68000-based) NeXT with Gnu or Kyoto Common Lisp (gcl/kcl/akcl) (NeXT 2.1 or 3.n)

AKCL: You need kcl version 1-605 or (presumably) later (I have also
used versions 615, 619, 623).  This is available free, but needs some
changes to run on the various NeXT platforms -- see akcl-next for the
original NeXT hardware, and akcl-nsi for NeXTStep/Intel.  The main
thing you need to do is to load kcl with the clm music library called
libmus.a and assumed to be on the directory that contains clm.  The
shell script libm creates this library, and the directions given in
akcl-next and akcl-nsi include the call on it -- you'll need to fix up
the -L/Local/Lisp/clm pathname to reflect your system (it is the place
where libmus.a can be found).  Once kcl is ready to go, fire it up
and:

(load "all.lisp")


GCL: This is essentially the same as AKCL, except that it is all in
one file, gcl-1.0.tgz available at math.utexas.edu in pub/gcl or
ftp.cli.com (for more info, download the file "gcl.README" from
prep.ai.mit.edu:/pub/gnu). After uncompressing and untarring gcl,
you'll need to make the same sorts of changes as described for AKCL
above -- get gcl-1.0-next.gz at the zkm ftp site (once this settles
down, I'll make put a copy at ccrma-ftp), untar it in the gcl-1.0
directory (it will overwrite h/NeXT.h and various other files).  Then
change the LIBS statement in h/NeXT.defs to:

LIBS=       -u _fmod -u _log10 -u _clm_full_file_reset -u _clm_file_reset -u _c_init_sine -u _c_sin_lookup -u _c_frandom -u _c_newline -u _c_fft_window -u _c_clear_block -u _c_gcd -u _c_lcm -u _c_table_lookup -u _c_table_interp  -u _c_direct_flt  -u _c_lattice_flt  -u _c_ladder_flt  -u _c_y_or_n_p  -u _c_yes_or_no_p  -u _c_fft  -u _c_convolve  -u _c_run_block  -u _c_src -u _c_spd  -u _c_fft_filter  -u _c_base_run_block -u _jv_exp -u _mmap -u _SNDReadSoundfile -u _SNDStartPlaying -u _SNDWait -u _SNDFree -u _SNDStop -u _SNDSetHost -u _SNDAcquire -u _snddriver_get_device_parms -u _SNDRelease -u _snddriver_set_device_parms -u _snddriver_get_volume -u _snddriver_set_volume -u _snddriver_set_ramp -u _valloc -u _mutex_try_lock -u _mutex_wait_lock -u _MIDIBecomeOwner -u _MIDIClaimUnit -u _MIDISetClockMode -u _MIDISetClockQuantum -u _MIDISetSystemIgnores -u _MIDIRequestExceptions -u _MIDIGetAvailableQueueSize -u _MIDISetClockTime -u _MIDIStartClock -u _MIDIReleaseOwnership -u _MIDIStopClock -u _MIDIGetClockTime -u _MIDISendData -u _MIDIRequestData -u _MIDIHandleReply -u _MIDIClearQueue -u _cthread_detach -u _cthread_yield -u _cthread_fork -u _port_set_allocate -u _port_set_add -u _port_set_deallocate -u _name_server_port -u _mach_error_string -u _port_allocate -u _port_deallocate -u _mig_get_reply_port -u _msg_rpc -u _msg_send -u _msg_receive -u _mig_dealloc_reply_port -u _sscanf -lsys_s -lm -L/dist/lisp/kcl/clm -lmus

where "-L/dist/lisp/kcl/clm" points instead to your clm directory.
Now make the clm gcl library (i.e. in a shell execute libm). Run
add-defs for gcl, make gcl, fire it up in the clm directory,
and (load "all.lisp").


When some portion of libmus.a changes (I try to keep these changes to
an absolute minimum), you need to delete the gcl/kcl files
unixport/saved_gcl (or kcl) and unixport/raw_gcl (or kcl), then go to
the main gcl (kcl) directory and rerun make.  Once gcl (kcl) is remade
(this takes about 10 minutes), go to the clm directory, start up the
new gcl (kcl) and (load "all.lisp").


------------------------------------------------------------------------
NeXTStep running on Intel hardware with gcl/akcl:

See the file akcl-nsi for instructions on porting akcl to NS/Intel.
Then (load "all.lisp").  We use the MediaVision ProAudio Spectrum 16
board for the DAC, but it still suffers drop-outs at 44.1kHz.  If
you have an Ariel PC56D card, get David Jaffe's device driver,
and uncomment out the line that pushes arielpc56d on *features*.
Similarly for the Ilink i56 and Turtle Beach MultiSound boards.
See the directions above for the libmus.a library.  There is now
a NeXTStep driver for the i56 available from ilink -- if there's
interest among CLM users, I'll add support for it.  

For gcl, the LIBS statement in h/NeXT.defs should be:

LIBS=       -u _fmod -u _log10 -u _clm_full_file_reset -u _clm_file_reset -u _c_init_sine -u _c_sin_lookup -u _c_frandom -u _c_newline -u _c_fft_window -u _c_clear_block -u _c_gcd -u _c_lcm -u _c_table_lookup -u _c_table_interp  -u _c_direct_flt  -u _c_lattice_flt  -u _c_ladder_flt  -u _c_y_or_n_p  -u _c_yes_or_no_p  -u _c_fft  -u _c_convolve  -u _c_run_block  -u _c_src -u _c_spd  -u _c_fft_filter  -u _c_base_run_block -u _jv_exp -u _mmap -u _SNDReadSoundfile -u _SNDStartPlaying -u _SNDWait -u _SNDFree -u _SNDStop -u _SNDSetHost -u _SNDAcquire -u _snddriver_get_device_parms -u _SNDRelease -u _snddriver_set_device_parms -u _snddriver_get_volume -u _snddriver_set_volume -u _snddriver_set_ramp -u _valloc -u _mutex_try_lock -u _mutex_wait_lock -u _MIDIBecomeOwner -u _MIDIClaimUnit -u _MIDISetClockMode -u _MIDISetClockQuantum -u _MIDISetSystemIgnores -u _MIDIRequestExceptions -u _MIDIGetAvailableQueueSize -u _MIDISetClockTime -u _MIDIStartClock -u _MIDIReleaseOwnership -u _MIDIStopClock -u _MIDIGetClockTime -u _MIDISendData -u _MIDIRequestData -u _MIDIHandleReply -u _MIDIClearQueue -u _cthread_detach -u _cthread_yield -u _cthread_fork -u _port_set_allocate -u _port_set_add -u _port_set_deallocate -u _name_server_port -u _mach_error_string -u _port_allocate -u _port_deallocate -u _mig_get_reply_port -u _msg_rpc -u _msg_send -u _msg_receive -u _mig_dealloc_reply_port -u _sscanf -lsys_s -lm -L/Local/Lisp/clm -lmus


------------------------------------------------------------------------
NeXT with Clisp:

The only thing holding back CLM under Clisp is the somewhat primitive
state of the foreign function interface -- I need to pass arrays to C
functions, and call C functions with no arguments.  When these
features are added to Clisp, I'll complete the port.


------------------------------------------------------------------------
SGI:

on an SGI Iris with Franz Allegro 4.1

1) fire up a shell, cd to the clm source directory and execute the  
following six lines:

	cc io.c -c -ansi -G 0 -O
        cc headers.c -c -ansi -G 0 -O
	cc merge.c -c -ansi -G 0 -O
	cc cmus.c -c -ansi -G 0 -O
	cc sgi.c -c -ansi -G 0 -O

2) next, (re)build lisp with the audio library linked in. cd to Franz  
Lisp's build directory and execute the following statement, with /CLM  
replaced by the appropriate directory for clm sources on your  
machine:

	sh config /CLM/sgi.o /CLM/headers.o /CLM/io.o /usr/lib/libaudio.a

3) boot the newly rebuilt lisp image and:

	:ld all.lisp

this will compile and load all the sources.


------------------------------------------------------------------------

on an SGI with AKCL, run the script libsgi rather than libm and load akcl 
following the NeXT instructions.


------------------------------------------------------------------------
MAC:

The Macintosh version of CLM has gone through a variety of changes over
the years, and is still awkward.  Since the MCL/MPW connection (ff-load)
insists on having the entire context present on each call, the current
version assumes you call MCL to compile an instrument file, quit MCL,
fire up MPW, compile the c side of the instrument created by the MCL
compilation, fire up MCL, add the c.o name to the list in all.lisp,
and reload clm -- this is incredibly tedious!!  If anyone can figure
out the "right" way to load a C object file in MCL, let me know.

Also in defaults.lisp is the constant *clm-mac-array-size-limit*.
It determines how much information can be passed down to the 
instrument from MCL.  If you overflow this number (by using very
large delay lines, for example), clm may crash.


To uncompress clm.tar.Z you can use the MacCompress program.  Similarly,
there's a version of tar for the Mac to expand clm.tar.  Both are
available at ccrma-ftp, along with documentation, in the file
pub/Lisp/macunix.sit.hqx.

Microsoft Word can read clm.rtf, the main documentation file.  You'll
need at least 8 MBytes of RAM, system 7, Sound Manager 3.0, MPW 3.3,
etc.  MPW 3.2 is probably ok too.

Before starting the compilation process, give the lisp image more heap
space: select the lisp image, hit APPLE-i (i.e. FILE menu option "Get
Info"), type in 8000 in the little field in the lower right hand
corner of the pop-up window (the one labelled "preferred size" on my
Mac).  Then fire up MPW and compile headers.c and merge.c
all with the -d MAC switch.  Then compile cmus.c with C -d
MAC -s CMUS cmus.c, and io.c with -d MAC -s CLIO. The result should be 
files in the clm directory with names like io.c.o.  Then fire up MCL, 
fix up the clm pathnames in all.lisp, and load "all.lisp".






------------------------------------------------------------------------
DEFAULTS

The default sound file names are set in defaults.lisp.  You can either
reset these names to your own favorites, or in your init file:

    (setf default-sound-file-name "test.snd")
    (setf default-reverb-file-name "reverb.snd")

or whatever.

Similarly, the following variables (all set in defaults.lisp)
have the following default values:

  sampling-rate  	   22050 (8012 and 44100 are also playable on the NeXT)
  default-sound-file-type  NeXT or AIFF (the latter on the Mac)
  *clm-array-print-length* 10    (affects print-out of IO structures)
  *available-IO-channels*  16    (how many sound files can be open at once)
  default-table-size       512   (for table-lookup generator)
  *clm-max-delay-lines*    256   (how many delay lines can be running at once)
  *ignore-header-errors*   nil   (should CLM ignore bogus header info)
  *fix-header-errors*      t     (should CLM try to fix bogus header info)
  *clm-verbose*            nil   (affects print-out during with-sound, mostly)
  *clm-safety*		   0     (if not 0, enables various error checks)
  *clm-speed*              1     (not used yet)
  *sound-player*           nil   (for user's own DAC funtion -- e.g. quad playback)
  *grab-dac*               t     (should CLM interrupt the DAC when the dac function is called)
  *clm-init*               nil   (override "clm-init.lisp" as init file name)
  *clm-mac-array-size-limit* 1024 


------------------------------------------------------------------------
BENCHMARKS

Stephen Pope is publishing some benchmarks comparing csound, cmix, and
cmusic, and I ran the same tests in clm.  Here are the numbers
(execution time in seconds) (data applies only to NeXT).

Test              clm    csound    cmix    cmusic  clm with 2 QP's  MusicKit

fm short note:     0.6     2.6        6        6        0.75            1.7
fm long note:      32      64        76      274         35             32
fm many notes:    190     344       893     1235         81             60
fm long notes:    271     477       588     1685        110
mix many files:   414    1161      3033     1807
mix long files:    24      71        82      404

Both instruments were extremely simple, so in clm's case it's really
just testing the I/O speeds -- in the numbers given above, I used a
normal clm instrument for the fm case and fasmix for the file
envelope/mix case.  Since fasmix runs on the main processor, the QP's
made no difference.


Within CLM, I tried out the following tests on various systems:

1. (with-sound (:statistics t) (expsrc 0 1 "/user/bil/cl/oboe.snd" 3 .5 .1))
2. (with-sound (:statistics t :reverb jc-reverb) (fm-violin 0 2 440 .1))
3. (with-sound (:statistics t) (fm-violin 0 2 440 .1))
4. (with-sound (:statistics t) (loop for i from 0 to 9 do (fasmix "/user/bil/cl/oboe.snd" :duration 1 :amplitude .1)))
5. (with-sound (:statistics t) (loop for i from 0 to 99 do (fm-violin (* i .1) 1 440 .01)))
6. (load "i.clm")
7. (with-sound (:statistics t) (pins 0 1 "/user/bil/cl/oboe.snd" 1.0 :max-peaks 8))


1. sample rate conversion and "granular synthesis"
2. reverberated fm note
3. just the single fm note
4. a few short sound file fragments mixed
5. a bunch of fm notes
6. a portion of the piece "idyll" (fm+reverb)
7. spectral analysis followed by additive synthesis


        machine                              1.     2.     3.     4.     5.       6.        7.

68040 NeXT 16 mbytes standard dsp memory:   4.9    9.5    2.4    1.2    116.6    399 482   10.3
68040 NeXT 32 mbytes with 32k memory:       4.4    6.1    2.4     .9    113.7    394 435    9.4
68040 NeXT 16 mbytes with qp:               4.6    6.9    2.4    1.1     29.3    156 199    9.5
68040 NeXT 16 mbytes with 2 qps:                                                  73 117
68040 NeXT C ugs (acl 3.1):                 5.4    4.5    2.0    1.0     91.7    275 298    8.0

66 Mhz Pentium AKCL 32 MBytes Ariel PC56D:  2.8    5.7    2.0     .5     95.1        369    6.9
66 Mhz Pentium AKCL C ugs:                  [5.6]  1.5    0.6     .6     25.5     77  84    1.8

660av Mac 16 MBytes Lisp ugs:              82.3  539.6   67.0   33.2   3481.3  10585 15249 164.4
same with C ugs:                                         28.8          1393.1

The 56000's ran at 25-27 MHz; the 68040's at 25 MHz.  Timings appear to be basically the same
on the Ilink i56 board. 
     


------------------------------------------------------------------------
UNIX FILE PERMISSION BITS

CLM creates the sound files with the permission 666 (in io.c) but each
user has a "umask", often set to 022, which changes the final
permission bits.  This can cause trouble if more than one user is
using a machine because files left in the /zap directory (the default
location as set in defaults.lisp) cannot be overwritten by the next
user.  Strictly speaking, this isn't CLM's fault, but since it's come
up many times, I'll append here the logout hook we use here at ccrma:


The file below, CCRMA.Logout.Hook, describes the dwrite to make it work.

******************************************************************

#!/bin/sh
#
# All machines in cm-next-* have their logouthook set to execute this
# script.  Important: if you modify this file, be VERY CAREFUL.
# Use only absolute pathnames.  [grd & davem 9/8/90]
#
# This file is enabled by doing, as root,
#       dwrite loginwindow LogoutHook /LocalApps/CCRMA.Logout.Hook
#
# clear all the crud in /zap (which is for login session storage only)
if test -d /zap
        then /bin/rm -rf /zap/*
fi
# write "nodbody" into the loggedIn file
host=${host-`/bin/hostname`}
if test -w /dist/People/loggedIn/$host -a -x /dist/adm/writeName
        then /dist/adm/writeName nobody /dist/People/loggedIn/$host
fi
#
# Darken the screen
#
/dist/bin/VidLev -b -p /tmp/VidLev.pid



------------------------------------------------------------------------
THINGS CLM NEEDS

There are a variety of things that would improve CLM, many of which
are relatively straightforward, but my queue of things-to-do doesn't
seem to be getting any shorter; so, on the optimistic theory that
someone might be looking for something to do, here's a list of 
possibilities:

  NeXT Dac routine needs to be able to play non-NeXT files,
                         to accept an "end" argument (like the "start" arg)
                         to provide on-the-fly srate conversions -- use Jean Laroche's play program
  SGI Dac needs srate conversion

  LPC instrument (Celso Aguiar has a first pass at this)
  Some good examples using the fusion instrument (JC's bell->voice?)
  Reverb instrument that uses convolution  
  More flexible reverb instrument
  Noise modelling in the Spectral Modelling instrument (san.ins)
  Perry Cook's Singer as a CLM instrument
  FOF soprano instrument

  Better locsig (Fernando Lopez-Lezcano is doing this)
  Arbitrary room shapes in roomsig

  A purge list in mix
  Some tie into recording possibilities and CD-ROM libraries
    (I have the C code for the Apple CD300 and the Toshiba 3410, 
     but haven't incorporated it into clm yet)
  Fill out filter design stuff in fltdes.lisp
  Get the "real-time" controls working (rt.lisp)
  A graphics-oriented sound editor or instrument designer


------------------------------------------------------------------------
OTHER USEFUL SOFTWARE

A Better DAC on the NeXT:
  Jean LaRoche has written a DAC routine for the NeXT that is well
  worth getting -- it can be tied into CLM via jrdac.  Look for
  Play.tar.Z in /pub/next/submissions on nova.cc.purdue.edu (128.210.7.22)

Audio CD data direct to sound file:
  on the Mac:
    I use the Disc-to-disk program available from Optical Media for
    $200.  Their number is (800) 347 2664.
  on the NeXT:
    Carl Edman's play3401 program reads the raw CD data, but at least
    in the version I have, it doesn't create a sound file.  Presumably
    this would not be a hard thing to add.

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.