[stella] music compression

Subject: [stella] music compression
From: Schwerin <schwerin@xxxxxxxx>
Date: Fri, 19 Mar 1999 13:25:02 -0500
Hi all, here's my lastest puzzle:  I'm working on a four channel music
engine, and I'm trying to work out some of the internal memory management
for a composition program on the atari.  I'm limiting myself to 4K ROM and
128 bytes RAM on this initial version just to see what is possible for a
non Supercharger version.

My sound engine is working well.  I can give more details later when it is
finalized.  For now, understand that it is designed to take %50 to %100 of
the processor time, so it is not practical to do any drawing while music
is playing.  This version is really a demo of the audio hardware, but
future versions may be designed to be incorporated into a game with
concurrent graphics.

Here is the setup as I see it so far:  There are four oscillators, so you have
four voices available for musical use.  To simplify the situation, assume that
all four voices must be playing at the same time (you cannot turn any of them
off, and thus, there is no concept of a musical "rest"), however you can
create the illusion of a disappearing voice if you set one voice to the
same note
as another voice.

If middle C is called C3, the system has a range of 32 pitches from
0 = B2 up to 31 = F#4, which covers most of a grand staff.

The four voices from low to high I call "Bass" "Tenor" "Alto" and "Soprano".

In most composition programs, a wide range of duration values are available,
from a 32nd or 64th note to a whole or a double whole note.  Also triplets
and other grouped notes are allowed.

For my program, this range needs to be severely constricted.  The model for
my program is that you define the smallest interval needed up front, which
is most likely a quarter note or an eighth note.  From that point on, every
interval is counted in multiples of that smallest interval.

Here is an example of what I'm talking about.  Let's say that you have
a melody line that changes every quarter note.  The smallest interval you
need is a quarter note.  The smallest interval is called a "beat", and in this
case there are 4 beats per measure:

4/4 time.....4 beats per measure (mX is measure counter, bX is beats)

m1              m2              m3              m4  ...
b0  b1  b2  b3  b4  b5  b6  b7  b8  b9  b10 b11 b12 ...

C   D   E   F   G   A   G   A   G   F   E   D   C

If you need some eighth notes, you set the beat to eighth notes.  To generate
quarter notes, just leave pitch the same for two beats.  Note that there is
no way to articulate the same notes in sequence because there are no rests,
so you can't go "C!" "C!" "C!" "C!" it would sound like "C.........."

4/4 time w/ eighth notes means 8 beats per measure

m1                              m2                              m3
b0  b1  b2  b3  b4  b5  b6  b7  b8  b9  b10 b11 b12 b13 b14 b15 b16

C   C   D   D   E   E   F   F   G   G   A   G   A   G   A   G   F

|___|___ quarter note                   |___eighth note

Still with me?  I hope so.  The bottom line is, forget about tempo,
forget about 3/4 or 4/4 time and just remember "beats".  The "beat" is
the smallest time interval needed by the composer, and the fundamental
time interval for a composition.  Everything else is just how fast you play it
and where you draw the bar lines for measures.

There's one more topic before we can get to the fun stuff...Pitches.
The overall pitch range of the system is 32 values (5 bits).  Instead of
allowing free movement of the four voices, you can constrict them to save
memory.  You can limit each individual voice to it's own range of 16 values
(4 bits).  So the Bass might roam from 0 to 15, Tenor from 8 to 23...
something like that.  Or limit to 8 values (3 bits):
Bass: 0 - 7  Tenor: 8 - 15  Alto: 16 - 23 Soprano: 24 - 31

I really like the 3 bit system when it comes to saving memory space, but it
is much more constrictive that the 4 bit system for creative options.

Another option is to describe pitches by relative motion, but I've
discounted that because it turns out to take the same amount of space and
limit the intervals each voice can jump per beat.

Now we get to the juicy bit of my problem.  How do we store all this stuff in
memory.  Let's assume we have 64 bytes allocated to our program's system needs
and 64 free for memory space.  That is to say, as a composer, the user of the
program has 64 bytes in which to create and modify his/her own composition.
(Other composition programs would run home to mamma crying "Out of Memory"
at this point, but not us.)

I'd like to set an example of the size of song I *want* to be able to edit.
I'm using as my baseline the Ameri-centrist example of the National Anthem.
I'm sure my atari loving associates from other nations will bear with me.
The reason I picked it was that it was relatively familar *AND* it lends
itself quite well to voicing in four parts.

By my count it is 33 measures long
Each measure is 6 beats long (3/4 time with eighth notes)
That's 198 beats!!

If we use a *least compressed* system, each beat costs us 16 bits
     4 bits per voice for range of 16 pitches per voice (more than 1 octave)
     4 voices
     16 bits per beat, or 2 bytes.

So uncompressed, 198 beats = 3168 bits, or 396 bytes.

The unintrepid may discontinue reading now.

Yes, we need to fit 396 bytes into 64 bytes.  6.1:1 compression

Here are my compression ideas, starting with no compression.
We have 512 bits to work with.
For each method I list the bits needed and the number of beats we
get for 64 bytes.
Our goal for beats is 198.

Uncompressed:  16 bits             32 beats

               xxxx xxxx xxxx xxxx voices  4 bits each

3 bit with duration:  14 bits      36 beats

               xxx xxx xxx xxx xx  voices 3 bits each, 2 bit "duration"

               "duration" is how many beats before any voice changes.

3 bit:         12 bits             42 changes

                xxx xxx xxx xxx    voices 3 bits each

This is all I have at the moment.  I *really* welcome your thoughts on
this.  The goal would be a method which can compress beats to an
average size of 2.5 bits.

This good news is, this may be more than you thought possible.  You can get
an atari composer with 4 voices and 42 beats to work with.
This is a perfect size for game "jingles" or even music loops.

-Andrew Schwerin
Just Another Bit Counter

Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/

Current Thread