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

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)

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