Csound Csound-dev Csound-tekno Search About

a hardware question....

Date1997-04-25 19:00
Fromjwilder
Subjecta hardware question....
I wanted to post this question to the group to see if there are any soundcard pros out there..

For my Masters of Science in Engineering thesis at the University of Alabama, I've been working on building a quad-output
soundcard for the PC that will work with Csound.  Basically, the idea is that it will take any digital sound file that
contains 16 bit samples and convert that to analog information ==> sound.  The thesis idea came from a music prof. here
that's been wanting to have electronic music quad output for a long time and suggested that if I wanted to do a thesis
project for the music dept., that I build one for him.  I know there are some devices out there that will do quad, but I
haven't been able to find anything that's specifically used just for quad output.  Anyway, enough background info. and
on to my question.

I'm using a hardware interrupt to signal an interrupt software routine to port out 4 samples to my card, where each of the
samples is loaded into a different digital-to-analog converter.  My hardware interrupt is a clock that equals 44.1kHz, so 
in theory, within one clock cycle of 44.1kHz (about 22 micro-secs.), the interrupt software routine (ISR) should access
the digital sound file(which is dang large as we all know) four times within 22usec.  The problem is that hard drive access
time isn't quick enough to keep up with my 44.1kHz clock; hence, within 22usec I could never hope to make 4 reads to the
hard drive, and the samples to the DACs aren't making it there fast enough!  I thought about loading my samples first into 
RAM, but that wouldn't be very efficient and would place a severe limit on the size of the sound file(100 secs of quad
music takes around 35 Megabytes).  Does anyone know how a sound card achieves its output?  Surely it uses some kind of
buffering (maybe with DMA?) that will keep on filling up a buffer with the samples, and then the samples are just 
ported out from the buffer, thus allowing the critical 22usec time frame to be achieved so that all DACs are filled and
outputed according to the 44.1kHz clock before the next set of samples comes in.

Any knowlege on sound card output would be appreciated...

Thanks in advance,
Joel Wilder

Date1997-04-29 17:37
FromRichard Dobson
SubjectRe: a hardware question....
> 
> I wanted to post this question to the group to see if there are any soundcard pros out there..
> 
> For my Masters of Science in Engineering thesis at the University of Alabama, I've been working on building a quad-output
> soundcard for the PC that will work with Csound.  Basically, the idea is that it will take any digital sound file that
> contains 16 bit samples and convert that to analog information ==> sound.  The thesis idea came from a music prof. here
> that's been wanting to have electronic music quad output for a long time and suggested that if I wanted to do a thesis
> project for the music dept., that I build one for him.  I know there are some devices out there that will do quad, but I
> haven't been able to find anything that's specifically used just for quad output.  Anyway, enough background info. and
> on to my question.
> 
> I'm using a hardware interrupt to signal an interrupt software routine to port out 4 samples to my card, where each of the
> samples is loaded into a different digital-to-analog converter.  My hardware interrupt is a clock that equals 44.1kHz, so 
> in theory, within one clock cycle of 44.1kHz (about 22 micro-secs.), the interrupt software routine (ISR) should access
> the digital sound file(which is dang large as we all know) four times within 22usec.  The problem is that hard drive access
> time isn't quick enough to keep up with my 44.1kHz clock; hence, within 22usec I could never hope to make 4 reads to the
> hard drive, and the samples to the DACs aren't making it there fast enough!  I thought about loading my samples first into 
> RAM, but that wouldn't be very efficient and would place a severe limit on the size of the sound file(100 secs of quad
> music takes around 35 Megabytes).  Does anyone know how a sound card achieves its output?  Surely it uses some kind of
> buffering (maybe with DMA?) that will keep on filling up a buffer with the samples, and then the samples are just 
> ported out from the buffer, thus allowing the critical 22usec time frame to be achieved so that all DACs are filled and
> outputed according to the 44.1kHz clock before the next set of samples comes in.
> 
> Any knowlege on sound card output would be appreciated...
> 
> Thanks in advance,
> Joel Wilder
> 
> 

There are several general issues here:
Firstly, are you designing for DOS, for Windows 3.1, or Windows95 (or even NT)?
For DOS you can access a hardware device such as a soundcard directly, and
use either or both of interrrupts (you could use more than one), and DMA.
However, old DOS dma is pretty slow, and brobably cannot handle four-channel
stuff too well. These days, you reaaly want to use the full facilities of
Windows 3.1 at least, which means writing a device driver (HORRIBLY difficult!)
which can then also be used under Windows95.

Secondly, yes absolutely use buffering. There are two levels of buffering when
playing a sound from disk. The first in handled by the disk driver/operating system,
which deals in blocks of data - you can ask the system to get four samples from
the disk, but in fact it HAS to get at least one sectors-worth - say 512 bytes.
Often the minimum amount is much more ( the 'cluster size' - perhaps 8K. Windows
will add a further layer of buffering to this. Then you write a block (say 32K)
to the card, which then streams it out at the required rate. The trick is to do
so-called 'double-buffering', where you send one block of data while the card is
still busy playing out the previous one. This is because, though disk access for
bytes is horribly inefficient, access for large blocks is wonderfully efficient.

It is quite possible, with a good card design, to transfer data simply by
polling, and not using interrupts or dma at all. I have a Motorola DSP56K
development board, which has three blocks of 3k words of fast memory. One of
these blocks is used to buffer data being sent to the card, and the clock to
write the data to the output port comes (in my case) from a SONY PCM. The main
loop on the card receives samples from the PC and stores them in a circular buffer,
and the DSP interrupt arrives each 44100Hz cycle to write from that buffer.

On the PC end, I have a simple loop which asks if the card is ready to receive
data (this is the 'poling' part), by reading a bit in a control register.
(the card appears to the PC as eight bytes of memory starting at Port address
$340). When the card say 'yes' I send the card a block of data, 32KB each.
Beacause my first machinw was so slow, I coded the PC end in assembler, but
on a faster modern machine coding in C will be fine.


So long as the disk is fast enough, this works fine.My first machine was a 386
with a very slow drive, and I could not get data of it fast enough. Once I had
upgraded to a 486 and a more modern drive, 44100Hz stereo played back easily.

This enable you to do the job without handling any interrupts or dma, or even
writing a device driver. This is viable up to and incluing Windows95 (if you
have a compiler which allows you to use 'outp()' calls - Visual C++ 32bit 
doesn't!); for Windows NT you HAVE to use a device driver, as it does not 
permit any direct access to the hardware, for security reasons.

The advantage of a device driver is that it separates the hardware from the
computer to a degree. If you improve the card, you only have to supply a new
driver, not a whole new application. Also, you can publish the driver functions
to third parties (the 'public interface'), without having to expose all your
clever low-level code if you choose to keep it to yourself.

I hope this helps. good luck with the design.

Richard Dobson.

Date1997-04-29 19:31
FromKent Williams
SubjectRe: a hardware question....
There is a card from Frontier designs (Wavecenter) that has two stereo
outputs, that can handle 4 signals at once.

Without putting intelligence on the card itself, you're pretty much limited
to using DMA to send data out the port. If you're doing hardware engineering,
you should be up on how DMA works.  If it was me, I'd set up the
card to use one DMA channel, have the driver software interleave the
samples, and use a counter to select which DAC to load.

DMA programming is a little weird but not bad once you get used to it.
You can (I believe) set up the DMA to transfer synchronized to your
digital world clock.  To transfer 4 16 bit samples every 1/44100 of a second
the clock will just run at 176.4 kilohertz.

On the PC side you simply fill a buffer from disk, initiate the transfer,
then fill a second buffer during the transfer of the first transfer.  When
you get an I/O Complete interrupt, you set up a transfer for the second
buffer, and fill the first.

How big you make each buffer depends on a latency/CPU usage tradeoff.
If your buffers are too small you will have very low latency, but
will have to spend more time handling interrupts and setting up DMA
requests.  If your buffers are too large, then you will spend less time
servicing interrupts, but the time quantum of each transfer is larger,
introducing a time lag between when some other real time event (like a 
midi note) can affect the output.

These are great days though -- modern processors are fast enough to
do lots of work besides pumping out audio. Back in the old day, you had
to do things in assembly language and cross your fingers in order to
keep up with the demands of high bandwidth devices.

It also gets a lot easier if you don't mind putting a DSP or
a microcontroller on the card, and implementing a shared memory window.
Then you can just blast data off the hard disk directly into the dual
port buffer.  This is what the Turtle Beach Hurricane architecture does,
and they were getting a reliable 4 tracks of 44khz sound off of hard disk
back in the dark days of 25mhz 386's.

---------------------------------------------------------------------
Kent Williams kent@inav.net -- http://soli.inav.net/~kent