* Sod2, a player for polychannel .csf music files.	-*- outline -*-
Copyright (C) 1995, 1996 Russell Marks.

Based on `sodman' by Graham Richards.


This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


* Requirements

You'll need an ANSI C compiler and a Unix box to use sod2. You can
also run it on MS-DOS by compiling with djgpp, but there are some
difficulties using sod2 in that environment; see the MS-DOS section
below.

Real-time playback is only currently supported on Linux. On all
systems other than Linux, output goes to a file called `output' by
default (this can be changed with the `-o' option), and you'll need to
work out some way of playing this file for yourself.


* Example files

You may also want to get the example files I wrote to try out the
player before writing some of your own - in addition, the samples may
be useful when writing your own csf files (as well as being needed to
play the example files). Look for `sod2-examples.tar.gz',
`sod2-samples.tar.gz', and `sod2-samp-new.tar.gz'. Also, be sure to
get and read `sod2-samples.README', which explains how to install the
samples (and why they come in two separate files).


* Installation

Edit both `Makefile' and `config.h' as necessary. The current setup
should be right for a Linux system, since that's what my home machine
is.

Do `make', then (as root) `make install'. (You may see a warning
regarding `ioctl' if compiling on Linux - don't worry about it, it's
harmless.) Then look at the man pages for sod2 and csf. Reading the
csf man page and looking at the example csf files should give you some
idea how to write your own csf files, if you're interested.

If you've installed the program and samples and want to try out the
example csf files, the easiest way is to use one of the example `mlt'
files bundled with them (these are used with csfmulti, and are a
simple way of playing multiple files), with `csfmulti solipsism.mlt'.
Be sure to edit `solipsism.mlt' first though, as at least the `*dir'
line will need changing. The same applies to `stargate.mlt'.


* OS-specific details and hints

** Linux

On Linux, sod2 will output to the file /dev/dsp which should be a
soundcard or a PC speaker-style sound device.

With PC speaker output (you need the `pcsndrv' kernel patch at the
time of writing), there's no point varying the output sample rate as
even the default 8kHz can't be output perfectly - you may want to try
using `-O' for oversampling, but I doubt it'll improve matters much
given the high quality of the average PC speaker. :-)

All the example tracks can play in real-time at 15kHz on a 486dx2-66
with a Soundblaster v2, and most can also play at 22kHz. (All can play
at 22kHz with the `-b' option; see the man page for details of that.)

With an SB16 (which is my current soundcard), all can play in 16-bit
stereo at 16kHz on the same machine, with the `-p' option (though only
just, in some cases...). A high-end Pentium could probably play CD
quality (16-bit stereo at about 44kHz) in real-time.

Having used Soundblasters for a few years now, I've come across
various (admittedly minor) problems with them. See `SB_NOTES' here for
details.


** SunOS/Solaris

[These details assume all Suns have an 8kHz-only U-law /dev/audio
device. I presume some Suns have better sound hardware, but all the
Sparcstations I've used have had only that.]

You should be able to play the music in real-time by using the `sox'
program to convert the unsigned 8-bit values to U-law format with a
command something like this:

	sod2 -O -o - filename.csf | sox -t ub - -t ul /dev/audio

You will almost certainly want 2x oversampling, as shown above with
the `-O' option.

Since (if I remember rightly) U-law's 8-bit logarithmic values are
meant to be equivalent to 12-bit linear values, you may get better
results by using:

	sod2 -Ow -o - filename.csf | sox -x -t sw - -t ul /dev/audio

i.e. getting sod2 to generate 16-bit output and converting *that* to
U-law, thus preserving as much per-sample resolution as possible. The
inclusion of `-x' is necessary on big-endian processors like the 68000
and SPARC as sod2 always produces little-endian samples in 16-bit
mode.

This isn't quite as far as you can go - the `-i' option uses
interpolation when resampling to (usually) give better results. This
slows sod2 down by about 30%, but it's probably worth it at low sample
rates:

	sod2 -Owi -o - filename.csf | sox -x -t sw - -t ul /dev/audio

I believe the /dev/audio device actually plays at 8012Hz, not 8000.
The difference would be very slight, but adding `-s 8012' to the sod2
command line would provide for this if you're bothered by it.


** MS-DOS

This is a bit involved, and a bit tangential to the main point of
sod2, which is to run on Unix. So the details for dos are in the file
`MSDOS' rather than here. A good summary would be that it's awkward
running it on dos, but it can be made to work.


* The history of `sod2' and what it does

Graham Richards asked me some time in late 1993 what I could use in
terms of music playing software. He was really getting into writing
sound-related programs of various kinds - flangers, various sound
generators, that kind of thing - having learned C and gained access to
reasonable computing power. I, on the other hand, had recently bought
a Soundblaster and was writing Amiga-style modules with the aid of a
program called `makemod' I'd written to make modules from text files
describing the samples, notes etc.

Amiga modules were great compared to the previous sequencing stuff I'd
been using - a Spectrum +3, with a simple three-channel sound chip,
and a low-end Yamaha keyboard (and not with one driving the other, I
hasten to add... sigh...). That said, after a while it got annoying
that a note played after another on the same channel would stop the
previous one. Also, the size of samples allowed was a bit limited.

After talking about what I wanted and what he could do, the following
spec for the new music player I wanted emerged. It would:

- play in real time. He didn't much like this requirement. :-)

- use the technique of playing samples at different speeds, like
   modules do, to play different notes.

- combine a number of channels together and generate a single sample
   that could be played on a simple sound card.

- allow you to put an volume `envelope' over the sound generated above
   after resampling. This means with a sufficiently long sample you
   can elimate (well, hide) the `low notes are long, high notes are
   short' problem.

- allow as many notes playing simultaneously as you like.

- allow as many notes on one virtual channel to play simultaneously
   as you like, so a new note doesn't stop an old one unless you say
   it should.

- write its output directly to the sound card on Linux, and possibly
   on Suns too.

- read a simple file format designed to be computer-generated. I would
   then write a preprocessor for a modified version of my `.mdf'
   format I was using to write modules, to output these `.sod' files.

- allow you to define `patterns' which would be equivalent to one
   channel from a block in a module - that is, 64 notes-or-gaps.

- allow the output sample to be of any sample rate.

- allow input samples (those used to generate the notes) to be of any
   sample rate.

About a month or so after this, and after a week of hacking, Graham
managed to get the player he named `sodman' working, despite having no
real way to test it except getting me to run it on my machine. It
worked well, and still does, but it has one big problem; it uses
floating-point maths while playing. This makes it a fair bit slower
than it really needs to be.

After a couple of failed attempts to optimise Graham's code, I decided
to just write a clone of sodman, using Graham's algorithm as a
guide. Although there's none of Graham's code in the resulting program
`sod2', it plays the music in much the same way as sodman.

Sod2 uses fixed-point maths, using 32-bit integers and 10-bit
bit-shifts, which seems to result in no noticeable difference in
output quality, and a fair speed increase over floating-point. On my
486dx2-66 running Linux for example, sod2 runs about 40% faster than
sodman. On a machine without hardware FP support such as a 386 or
486sx w/o copro, sod2 will be usable, and sodman will not - since
software FP is very slow, sodman will hardly run at all.

Sod2 also uses .csf files, which are the altered .mdf files I
mentioned earlier, simply because I use them and already had the .csf
file reader handy. This eliminates the need for the preprocessing
step.

Graham's view of this is: "There are quite a few new features I would
like to add to sod2. As sod2 is faster than sodman, it seems a waste
of time to carry on with upgrades to sodman. I have *loads* of things
I want to change about sod*."

(Graham wrote that in early '95. Last I heard, he's been using a
different system for his own music, where you sample N bars then
glue/mix these samples together - so he probably isn't likely to do
much (if any) more work on sod2 or anything similar.)

Current ideas being mulled over include repitching the notes better
(probably using FFTs), using `better' tuning (not mathematically
generated), a different kind of enveloping which goes
attack/looped-centre/decay, and a support program to `fix' slightly
out-of-tune samples (`tunesam' can help a bit in this direction).
Don't hold your breath, though. :-)


* The End

As usual, bug reports and suggestions for improvements are welcome,
and accompanying patches are even more welcome. :-)

Also, if you write any reasonable csf files, consider making them
publicly available. It'd be nice if we could play something other than
my rubbish with sod2. :-)


** Contacting me

No email address at the moment I'm afraid. :-(

Postal address:
		Russell Marks,
		3 Rapley Close,
		Camberley,
		Surrey,
		GU15 4ER,
		United Kingdom.

If you insist on abbreviating my name, please use "R. J. Marks".


Have fun,
-Rus.
