[comp.sys.acorn] Sun audio file update

gtoal@tardis.computer-science.edinburgh.ac.uk (05/13/91)

Some time back I asked about playing sun audio files on the Archie;
here's a reply I got from Mark Taunton at Acorn;  I've finally gotten
round to passing it on to the net...

Hi Graham,

sorry there has been a little delay, but I thought I'd write anyway.
I have previously looked into this, and after some difficulty with
getting the Sun audio format *exactly* right, I was able to play back
Sun files OK under RISC iX.  The primary details of the Sun audio
format you need are:

Sample frequency is 8000 Hz (fixed), mono only.  Sample format is 8
bits/sample: bit 7 = sign, bits 0..6 are BITWISE COMPLEMENT of mu255
(pseudo-exponential) representation of magnitude.

You probably know that VIDC's audio data format is bit 0 = sign, 
bits 1..7 are the mu255 magnitude (not complemented).

The fact that the magnitude is complemented is what caused me grief
for a while: it renders the sound totally unrecognisable (i.e. it
sounds like just noise).  If you think about the signal transformation
you can see why.

As a little extra, feel free to use the following in any way you like.
It's a simple UNIX filter, so it's up to you to adapt for RISC OS...

Cheers.

Mark.

P.S. I haven't thought hard about it, but if you *really* cared about
speed it might be minutely quicker to just complement the whole word
(*including* the sign bits) before (or after) doing the byte-wise
rotate, since not even Golden Eared people should be able to detect
the reversed polarity with this quality of signal!  On the other hand,
it might not be.

P.P.S.  A quick tip on improving the perceived sound quality: if you
double, triple or quadruple the playback frequency and repeat each
input sample 2, 3 or 4 times (as appropriate!) you cut down on the
amount of audible locally-generated mush considerably, allowing the
crystal-clear beauty of the original signal to shine through. ;-)


/*
 * stov.c: convert SparcStation audio data on stdin 
 *         to Archimedes (VIDC) format on stdout.
 *
 * Mark Taunton, January 1991.
 */

void *malloc();

#define BSZ 4096
main (int argc, char **argv)
{
    unsigned char *buff = (unsigned char *)malloc (BSZ);
    unsigned int xm1 = 0x01010101;
    unsigned int xm2 = ~xm1;		/* help compiler along */
    int n;
    /*
     * In the following loop we convert 4 bytes at once because it's
     * all pure bit twiddling: there is no arithmetic to cause
     * overflow/underflow or other such nasty effects.  Each byte is
     * converted using the algorithm:
     *
     *   output = (input >> 7) | (~(input << 1) & 0xFE)
     *
     * i.e. we rotate the byte left by 1 and bitwise complement the
     * 7-bit magnitude part.  On ARM the actual conversion works out
     * to take all of 4 S-cycles (it could be 3 but the (RISC iX 1.21)
     * compiler misses a trick), and since we are doing 4 bytes at once
     * this really ain't bad!  Note that we don't worry about alignment
     * on any odd bytes at the end of the buffer (unlikely anyway) - we
     * just convert all 4 bytes.  The right number still get written.
     */
    while ((n = read (0, buff, BSZ)) > 0)
    {
	unsigned int *wp = (unsigned int *)buff;
	unsigned int *lim = (unsigned int *)(buff + ((n + 3) & ~3));
	do
	{
	    unsigned int ss = *wp;
	    *wp++ = ((ss >> 7) & xm1) | (xm2 & ~(ss << 1));
	} while (wp != lim);
	write (1, buff, n);
    }
}