Sod2, a player for polychannel .csf music files.
Copyright (C) 1995 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


Requirements
------------

You'll need an ANSI C compiler and a Unix box to use sod2. You should
be able to run it on MS-DOS by compiling with djgpp, but I haven't
tried this.

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. Look for
'sod2-examples.tar.gz' and 'sod2-samples.tar.gz'.


Linux-specific details
----------------------

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), 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 my 486dx2-66
running Linux 1.1.59 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.)

As for soundcard-specific details:

I'm afraid a Gravis Ultrasound isn't going to be much help in reducing
processor load, as it can be with Amiga modules. Although it's
theoretically possible to spread the virtual channels across the GUS's
channels, it would be tricky, and it isn't done at the moment. In
fact, this would improve the quality of the output only a little - as
for the CPU time needed, it would almost certainly be slightly
*greater*.

Some Soundblasters (the normal ones, not "Pro" or "16", etc.) can
playback samples at about 44kHz. You can see which version
Soundblaster you have by doing 'cat /dev/sndstat' and looking under
the 'PCM devices' line. If the version number is 2.1 or greater, you
can play 44kHz samples; otherwise, you're stuck with 22kHz as the
fastest sample rate. Note that these are not exact figures, as there's
a certain granularity to the possible playback rates - common ones you
might want to use are 8000, 14925, 21739 and 43478. Sod2 always
reports the actual playback sample rate being used when playing
through /dev/dsp.


Sun-specific details
--------------------

[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 uw - -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 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 having learned C and gained
access to reasonable computing power - flangers, various sound
generators, that kind of thing. 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. 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:

- run 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 useable, 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*." As he puts it, there are "features to
follow". This is my thinking on the matter, too. :-)

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, a support program to 'fix' slighty
out-of-tune samples, and stereo support. I expect the new tuning and
stereo are things most likely to get done.


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.

As root, do 'make install'. 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.


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
available for anon. ftp. It'd be nice if I could play something other
than my rubbish with sod2. :-)


Have fun,

- Russell Marks (mr216@gre.ac.uk)
   and
- Graham Richards (G.D.Richards@gre.ac.uk).
