[comp.sys.amiga.programmer] playing samples using audio h/w

snowdond@r2.cs.man.ac.uk (D.N.Snowdon (MSc PJ)) (03/22/91)

  I'm having a problem playing sound samples by hitting the
hardware directly. The problem is that I set up the registers
for the channel I'm going to use and set audio DMA going
 using 
   move.w #(DMAF_SETCLR!DMAF_MASTER!DMAF_AUD0),dmacon(a0)
as per the h/w manual. The sound starts playing OK.
  If I then stop the sound by turning its DMA off using
  move.w #DMAF_AUD0,dmacon(a0) again as in the h/w manual, 
the sound stops. If I then reload the registers and start
DMA going the sound I get is the remains of the first sample
(assuming I stopped it before it had finished playing
completely). The h/w manual does say that if you stop and
start DMA over a short period then this can happen but there
is actually quite a long delay between turning off DMA for
the first sample and turning it on for the second.
  Can anyone shed any light on this?

             Dave   ( snowdond@uk.ac.man.cs )

dvljrt@cs.umu.se (Joakim Rosqvist) (03/25/91)

In article <2325@m1.cs.man.ac.uk> snowdond@r2.cs.man.ac.uk (D.N.Snowdon (MSc PJ)) writes:
>
>  I'm having a problem playing sound samples by hitting the
>hardware directly. The problem is that I set up the registers
>for the channel I'm going to use and set audio DMA going
> using 
>   move.w #(DMAF_SETCLR!DMAF_MASTER!DMAF_AUD0),dmacon(a0)
>as per the h/w manual. The sound starts playing OK.
>  If I then stop the sound by turning its DMA off using
>  move.w #DMAF_AUD0,dmacon(a0) again as in the h/w manual, 
>the sound stops. If I then reload the registers and start
>DMA going the sound I get is the remains of the first sample
>(assuming I stopped it before it had finished playing
>completely). The h/w manual does say that if you stop and
>start DMA over a short period then this can happen but there
>is actually quite a long delay between turning off DMA for
>the first sample and turning it on for the second.

How long is 'quite long'? The sound will only replay from where you stopped it
if the next 2 samples has not been read from memory yet.
Could you send the relevant part of the code, perhaps there is some simple
error?    /$DR.HEX$

mykes@sega0.SF-Bay.ORG (Mike Schwartz) (03/25/91)

In article <2325@m1.cs.man.ac.uk> snowdond@r2.cs.man.ac.uk (D.N.Snowdon (MSc PJ)) writes:
>
>  I'm having a problem playing sound samples by hitting the
>hardware directly. The problem is that I set up the registers
>for the channel I'm going to use and set audio DMA going
> using 
>   move.w #(DMAF_SETCLR!DMAF_MASTER!DMAF_AUD0),dmacon(a0)
>as per the h/w manual. The sound starts playing OK.
>  If I then stop the sound by turning its DMA off using
>  move.w #DMAF_AUD0,dmacon(a0) again as in the h/w manual, 
>the sound stops. If I then reload the registers and start
>DMA going the sound I get is the remains of the first sample
>(assuming I stopped it before it had finished playing
>completely). The h/w manual does say that if you stop and
>start DMA over a short period then this can happen but there
>is actually quite a long delay between turning off DMA for
>the first sample and turning it on for the second.
>  Can anyone shed any light on this?
>
>             Dave   ( snowdond@uk.ac.man.cs )

When you want to stop a sound, what you need to do is to set the volume
to 0, the period to 1, and turn off the DMA.  Setting the period to 1
causes the rest of the current sample to be played VERY fast.  You should
also store a word to the AUDxDAT register to help it flush out.  After a
couple of scan lines worth of delay, you can start a new sound fine.

--
*******************************************************
* Assembler Language separates the men from the boys. *
*******************************************************

jcs@crash.cts.com (John Schultz) (03/26/91)

In <2325@m1.cs.man.ac.uk> snowdond@r2.cs.man.ac.uk (D.N.Snowdon (MSc PJ)) writes:


>  I'm having a problem playing sound samples by hitting the
>hardware directly. The problem is that I set up the registers
>for the channel I'm going to use and set audio DMA going
> using 
>   move.w #(DMAF_SETCLR!DMAF_MASTER!DMAF_AUD0),dmacon(a0)
>as per the h/w manual. The sound starts playing OK.
>  If I then stop the sound by turning its DMA off using
>  move.w #DMAF_AUD0,dmacon(a0) again as in the h/w manual, 
>the sound stops. If I then reload the registers and start
>DMA going the sound I get is the remains of the first sample
>(assuming I stopped it before it had finished playing
>completely). The h/w manual does say that if you stop and
>start DMA over a short period then this can happen but there
>is actually quite a long delay between turning off DMA for
>the first sample and turning it on for the second.
>  Can anyone shed any light on this?

  Yeah, there's a bug in the hardware.  The best way around it (so you
don't waste cpu cycles waiting) is to set PER to 1, then write directly
to DAT and wait for the interrupt. A better (and more elaborate) scheme
is to set up an interrupt handler that handles this special case.
When the interrupt occurs, stuff the new values into all the necessary
registers. Also, before writing to DAT, turn off audio DMA (This effects
when interrupts occur).


  John

jcs@crash.cts.com (John Schultz) (03/26/91)

>>  I'm having a problem playing sound samples by hitting the
>>hardware directly. The problem is that I set up the registers
>>for the channel I'm going to use and set audio DMA going
>> using 
>>   move.w #(DMAF_SETCLR!DMAF_MASTER!DMAF_AUD0),dmacon(a0)
>>as per the h/w manual. The sound starts playing OK.
>>  If I then stop the sound by turning its DMA off using
>>  move.w #DMAF_AUD0,dmacon(a0) again as in the h/w manual, 
>>the sound stops. If I then reload the registers and start
>>DMA going the sound I get is the remains of the first sample
>>(assuming I stopped it before it had finished playing
>>completely). The h/w manual does say that if you stop and
>>start DMA over a short period then this can happen but there
>>is actually quite a long delay between turning off DMA for
>>the first sample and turning it on for the second.
>>  Can anyone shed any light on this?

Here's a quick look at how to do this:

; Brief excerpt showing how to stop DMA sound and play another.
; Although this example busy waits, it's still faster than the
; audio.device. An interrupt scheme is faster (and more elegant).

	move.w	d2,intena(a0)		; disable 7-10 (aud) interrupts
	move.w	d2,intreq(a0)		; clear any 7-10 interrupts

	move.w	d6,dmacon(a0)		; shut off dma for channel
	move.w	#0,ac_dat(a3)		; write directly to output (to stop)
	move.w	#1,ac_per(a3)		; fast period (less waiting)
	move.w	#$c000,intena(a0)	; enable
wasteloop
	move.w	intreqr(a0),d5		; wait for interrupt
	and.w	d2,d5			; test against current mask
	cmp.w	d2,d5
	bne.b	wasteloop		; not yet occurred
; Interrupt has occured, channel is stopped.
	move.w	d2,intreq(a0)		; clear 7-10 interrupt

; Write values to regs here, then turn on dma...



  John

leikvoll@newshost.hsr.no (Morten Leikvoll) (04/04/91)

In article <jcs@crash.cts.com> you write:
|> Here's a quick look at how to do this:
|> 
|> ; Brief excerpt showing how to stop DMA sound and play another.
|> ; Although this example busy waits, it's still faster than the
|> ; audio.device. An interrupt scheme is faster (and more elegant).
|> 
01|> 	move.w	d2,intena(a0)		; disable 7-10 (aud) interrupts
02|> 	move.w	d2,intreq(a0)		; clear any 7-10 interrupts
03|> 
04|> 	move.w	d6,dmacon(a0)		; shut off dma for channel
05|> 	move.w	#0,ac_dat(a3)		; write directly to output (to stop)
06|> 	move.w	#1,ac_per(a3)		; fast period (less waiting)
07|> 	move.w	#$c000,intena(a0)	; enable
08|> wasteloop
09|> 	move.w	intreqr(a0),d5		; wait for interrupt
10|> 	and.w	d2,d5			; test against current mask
11|> 	cmp.w	d2,d5
12|> 	bne.b	wasteloop		; not yet occurred
13|> ; Interrupt has occured, channel is stopped.
14|> 	move.w	d2,intreq(a0)		; clear 7-10 interrupt
|> 
|> ; Write values to regs here, then turn on dma...
|> 
|>   John

I tried to make my own music player once (gave it up), and I did almost the same you do here. I hope anybody knows the answer to some of these questions:

- Do you know if it's really necessary to have line 05? The DMA writes to this
  register and I thought it gave an interrupt just after writing the last word.
  Does the interrupt cycle take too long ?

- Do you need line 07 ? You do disable the audio interrupts (line 01)

- My routine gave frequently double interrupts. Have you got any idea what
  could be the reason for that?

-------------------------------------------------------------------------------
Morten Leikvoll              |
leikvoll@hsr.no              |               (empty space)
                             |
-------------------------------------------------------------------------------