[comp.sys.amiga.programmer] Audio state machine

bevis@en.ecn.purdue.edu (Jeff Bevis) (04/01/91)

A few days ago I posted a plea for help with my audio software.  "Simple,"
thought I, "the Amiga audio programming will be."  Ho ho hooo!  Was I ever
wrong.  I was completely dumbfounded by the behavior of the interrupts. 
Sometimes I'd get sound, other times not.  Sometimes the right sound, other
times the previous sound again.  Frequently the interrupts would hack off
the sound early.  I was about to go bonkers.  BUT, I re-discovered the
'Audio State Diagram' on page 162 of the Hardware Manual.  Lord, how could
I have overlooked this before??  (blinded by my confusion, I suppose.)

Well, how many of you have really taken a *good* look at that page?  Until
now, not me.  But it seems, upon careful inspection, that the machine is
flawed.  That's because there's no *easy* way to force the machine into
a known state rapidly.

Ok, let's suppose you're doing DMA-driven audio (like me), and you were
initially in the 000 state (idle), and you set things in motion with
AUDxON.  You'll soon end up in states 010/011, cycling back and forth
pumping out audio bytes.  If you want to stop this, the only path out 
of the loop requires the period counter to be finished decrementing, the
DMA must be turned off, and there must be an interrupt pending for the
audio channel (in intreq).  Of these three conditions, only the second
(DMA turned off) can be controlled directly.  To satisfy the first
(perfin, in the diagram) the period counter *must* count down completely
-- so, if you've chosen a period of, say, 3000 previously, then you'll
have to WAIT up to 3000/3579552 seconds (838 milliseconds!!) to get the
channel back... no way out.  For higher periods, it gets still worse.

What we need here is one new control bit for each channel... AUDxHLT - an
audio 'halt' bit.  This bit should take the state machine from state 011
to idle (000) by making the transition condition

	(perfin)(/AUDxON)(AUDxIP)+AUDxHLT

(note that DeMorgan's law was applied to the equation in the diagram to
 get an equivalent equation, then the AUDxHLT was added.)

A similar equation should get us out of state 010 and directly to 000. 

Once back in idle, we're not going to be guaranteed to stay now unless
we put AUDxHLT into the two exit-path equations, as a negated product term.
going to state 010, we get:

	(AUDxDAT)(/AUDxON)(/AUDxIP)(/AUDxHLT)

And going to state 001 we get:

	(AUDxON)(/AUDxHLT)

There.  Once the CPU hits AUDxHLT, we abort anything within only a few
ticks of the clock.  When we get there, we'll stay until the CPU lets us
go.  So, we can initialize everything and let it begin.  Isn't that a
lot cleaner?

Is this an old idea?  Is there any compatibility problem for such an 
implementation?  Is what I have said really stupid?

Feel free to bombard me with criticism, additional ideas, etc...


-- 
-------------------------------------------------------------------------------
    "Three is never equal to four, except for very large values of three."
-------------------------------------------------------------------------------
Jeff Bevis		     Purdue Univeristy School of Electrical Engineering