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); } }