A.D.A. Amiga Demoscene Archive

  Welcome guest! Please register a new account or log in

  

  

  

log in with SceneID

  

Demos Amiga Demoscene Archive Forum / Coding / coding tutorial: adding sound

 

Author Message
z5_
Member
#1 - Posted: 7 Dec 2004 22:52 - Edited by Admin
Reply Quote
As the title suggests: how to add sound to a production, starting with the P61 replayer routine.

Some questions on that topic:
- what is the story with the packed samples? What are packed samples (is this a feature of modules in general, or a feature of some tracker?...)
- and how does one know how big the sample buffer length is?
- what is the parameter "use" (usecode) for the p61 replayer routine?
- what is the parameter "startup position"?
- what is the parameter "jump"?
- doesn't one have to enable audio dma for sound or is this turned on in the replayer routine?
- same question about the level6 interrupt (enabled in player routine)?
- what is the difference between the normal vblank version and the cia version
- what has the interrupt level 6 has to do with the replayer and how does this connect with the cia timer (is the cia timer able to generate a level 6 interrupt)? (timing the demo to sound?)
- does the module have to be loaded in chipmem?

I have read the guide included with the player, but did find it very short (too short for non-experienced coders anyway).

I have already assembled the player with the example = 1 and it works.

A last question: i have included the replayer routine (include "610.4.asm"), added the parameters just before the include takes place but i do have a strange problem occuring. I have defined a variable after this (Gfxname: dc.b "Graphics.library",0) in chipmem (section data_c) and asm-one tells me: "undefined symbol Gfxname" when compiling. If i don't include the 610.4.asm, then it compiles... It is as if my source ends after the inclusion of the 610.4.asm??
Cyf
Member
#2 - Posted: 7 Dec 2004 23:07 - Edited
Reply Quote
for the first, it's more simple to start with a normal replayer instead of CIA (I never really used cia timer with music player, shame on me ^^)
and I have problem with the startup code and old normal replays routines, so...shame! I'm just oldskool with old startup and old players 8)

is the cia timer able to generate a level 6 interrupt

yes

does the module have to be loaded in chipmem?

depend of samples packed or not (feature on some trackers), or if player support samples in fast

A last question: i have included the replayer routine (include "610.4.asm"), added the parameters just before the include takes place but i do have a strange problem occuring. I have defined a variable after this (Gfxname: dc.b "Graphics.library",0) in chipmem (section data_c) and asm-one tells me: "undefined symbol Gfxname" when compiling. If i don't include the 610.4.asm, then it compiles... It is as if my source ends after the inclusion of the 610.4.asm??

remove the "END" at the end of source. or include 610.4.asm at the end of your source

ps: v610.4 ? use v610.6 with fix by The Dark Coder and NoName :)) yes, here are such Gurus !
noname
Member
#3 - Posted: 8 Dec 2004 01:56 - Edited
Reply Quote
@z5 just answering what i can remember out of my head.

- packed samples use up less diskspace but sound worse. in p61 they use 4 bit instead of 8 bit. however, guru made a nice algorithm that uses some kind of logarithmic scaling so that in many cases the quality of the packed samples is surprisingly high. you can check every sample of a module in p61con. you usually wouldn't want to pack samples unless you have to fit into a certain size-limit. don't use it now, it complicates things.

- the usecode is a very cool and unique feature of p61. it basically tailors the replay source to the needs of the module! unused effects get kicked out during assembling. get the usecode from p61con. use this for making small executables (a.k.a. intros). although other replayers migth be more interesting when doing intros.

- vblank / cia depends on the module. most modules are timed for vbi timing. but cia timed replayer (more accurate) can play vbi timed module very well and p61 is very easy to set to cia.

- start lets you choose which pattern you want to start with.

- jump includes code to jump to specific song positions. i think that was quite well documented in the source (asmone also has a search function).

- p61 requires the samples to be in chip-ram. the song-data could stay somewhere else but this is not worth the effort since the major amount of bytes in every module goes for the samples. some other protracker replayers allow replaying modules from fastram. they do so by copying the just needed sample data to chipram. your musician will love you but your frame rate will drop. it's a cool alternative to free up some chip mem and still use big modules on 680x0 based amigas. other players again are based on ahi and can play over a soundcard (and don't need samples in chip-ram). but i never wanted to create demos that require any kind of installation.
TheDarkCoder
Member
#4 - Posted: 8 Dec 2004 09:18
Reply Quote
@z5:
in the 610.6 I also added more comment, if you read the source and the guide of 610.6 maybe you could find more info.

modules which use "tempo-command" does require to be played in CIA mode.

@ all:

I have to say that I have always been unable to properly use the "setposition" function. Anyone could explain how it works?
Cyf
Member
#5 - Posted: 8 Dec 2004 14:58 - Edited
Reply Quote
z5_
Member
#6 - Posted: 8 Dec 2004 19:26
Reply Quote
I have sound too now. However, i still have some questions:

- i had to do "system =0", otherwise i don't get any sound. Why?
- nowhere did i have to enable audio dma. Why is that?
- nowhere did i have to enable interrupt 6, allthough i'm using the "lev6 = 1". Why is that?

Also, can give anyone give a short explanation or overview on what the role of the level 6 interrupt in here is?

And what about timing a demo to music? Where does one have to start looking for that? I searched the docs but didn't find anything about that.
Let's say that i have a module with just one drum playing at regular intervals and i want to do something each time the drum plays. Is this possible? Does the musician has to do something in the module or is all handled with code? How does the coder find out that the drum sound is playing? I'm not looking for code, just a general easy explanation for my curiosity... :)
Cyf
Member
#7 - Posted: 8 Dec 2004 20:21 - Edited
Reply Quote
- nowhere did i have to enable audio dma. Why is that?
- nowhere did i have to enable interrupt 6, allthough i'm using the "lev6 = 1". Why is that?


system=0 is for program that kill multitask, else multitask compliant

audio dma and interrupt 6 are set by the player during the init routine


And what about timing a demo to music? Where does one have to start looking for that? I searched the docs but didn't find anything about that.
Let's say that i have a module with just one drum playing at regular intervals and i want to do something each time the drum plays. Is this possible? Does the musician has to do something in the module or is all handled with code? How does the coder find out that the drum sound is playing? I'm not looking for code, just a general easy explanation for my curiosity... :)


already explained in Timing post.

an example is in DaJormas "Major Release" with TP3 player :
in "new line" routine of tracker, increment a position variable.
with this method, you can start an effect when tracker play a specific note.

;-------------- TP3
...
tp_play:
...
newline: ; where a new line of the pattern is read
add.l #1,sc_position ; increment timer var.
...

;--------------
sc_position ds.l 1

with p61, more difficult to find the "new line" or "next note" routine
perhaps in "P61_playtime" routine. or use a P61 variable if possible.
little test here (+ 2 rollercopper routines)
TheDarkCoder
Member
#8 - Posted: 9 Dec 2004 10:07
Reply Quote
@z5:
I add to what Cyf said that lev6 is always USED by P61. In the .guide
Guru said that a non-level 6 version was planned, but then dropped because too slow. The lev6 label inside the P61 source is in fact useless,
hence I removed it in 610.6. Answers to many of your questions are written
in the 610.6 source code.

Level 6 plays 2 distinct roles in P61:
1) in CIA mode (cia=1) is used to call P61_music, basically the same as Vblank interrupt in CIA=0 mode (or you can use copper interrupt, if you like)
2) in ALL modes, it is used to call the routine that turns ON audio DMA after a note change.

To understand #2 you have to first understand how Paula audio works, in detail. Not so short story.
Cyf
Member
#9 - Posted: 9 Dec 2004 11:34 - Edited
Reply Quote
you have to first understand how Paula audio works, in detail. Not so short story.

perhaps a full Post only for Paula "how to play a sound", and other audio effects (appart from module player)
and explain here how work a module player for example.
I have some docs and examples about Paula, amplitude (volume) and frequency (periode) modulation, filter, interruptions and registers used.
Cyf
Member
#10 - Posted: 9 Dec 2004 15:40 - Edited
Reply Quote
** from an article (c) by Philippe Rivaillon (privaillon(arobase)free.fr) in "La Voix de Paula" - Amiga News Tech issues 29-30 jan/feb 1992 (translated from french with some little summaries and omissions but not very important) :

Once upon a time,

"[...]It's Paula and incidentally Agnus for the transfers DMA which manage the sound. But its capacities arent only a simple spit of samples. Indeed, this diva is able to modulate the amplitude and the frequency of sound of one or more channels in order to produce the desired effects.[...]

A sound is a vibration, defined by two criteria: its amplitude and its frequency. The latter will determine whether a sound is low or high-pitched (the higher the frequency is, more the sound is high pitched).
The average amplitude defines the power of a sound (its volume), while the variations of this value define the sound itself. The data table transmitted to Paula will be thus a succession of instantaneous amplitudes. this table is cut out in bytes, for an amplitude from +127 to -128. Paula will of course have needs other information on the sound before playing it: its address, its length, its period (corresponding to the frequency of the signal) and its volume.

registers used :
*=# of channel (0-3)
+=channels 0=$A, 1=$B, 2=$C, 3=$D

AUD*LCH $dff0+0 Address of data in Chip
AUD*LCL $dff0+2

AUD*LEN $dff0+4 lenght of sample in words (16 bits) . max=128 kb

AUD*VOL $dff0+8 volume. 0-63. in words (16 bits)
only the 6 lower bits used.

AUD*PER $dff0+6 periode. speed of sample play. in cycle (16 bits)
frequency in bytes : Periode=1/(Freq)/279,365.10^-9 (for a 68000)

moreover than the audio circuit has limits because of its synchronization with the screen: knowing that it load a data word per rasterline, we obtains a maximum theoretical frequency of: 2 bytes*262.5 lines/screen * 59.94 screen/sec) = 31469 bytes/s
but the real max freq is 28867 bytes/s = periode 124 cycles.

If you put a value lower than 124 in this register, Agnus will not inevitably have time to charge the audio data and it's the old one which will be used, then a deformation of the sound.

First: simple transmission in automatic mode with Paula

summary:
- setup the registers above for each channel.
- to start the sound, enable DMA channels. (bit 9 and 0-3)
- Paula loop the sample automatically : after having read the number of words indicated in AUD*LEN, Paula will replace itself automatically at the beginning of the data.
- to stop the sound, disable DMA channels. if you give these channels DMA on the way, Paula will start again the sound from the beginning, with an exception : if the interval of time passed between the cut and the re-starting is lower than 2 times the period, then the reading will continue where Paula had left it.[...]

a quick example 1 :
start:
lea custom,a6
move.l #data,aud0lch(a6) ; $dff0a0
move.w #1,aud0len(a6) ; len in word - $dff0a4
move.w #5000,aud0per(a6) ; periode - $dff0a6
move.w #50,aud0vol(a6) ; volume - $dff0a8
move.w #D_setclr|D_Master|D_aud0,dmacon(a6) ; start dma channel 0
wait: btst #6,$bfe001
bne.s wait
move.w #D_aud0,dmacon(a6) ; stop
rts
data: dc.b 120,-120 ; square signal (in chipram)

my Example : 4 channels - 4 diff. period
lea custom+aud0lch,a0
move.w #3000,d0 ;period
lea Sample,a1
moveq #3,d1
loop:
move.l a1,(a0)+ ad
move.w #13,(a0)+ len
move.w d0,(a0)+ per
move.w #64,(a0) vol
addq.w #4,d0 ; incr period
addq.l #8,a0 ; next channel
dbf d1,loop
move.w #D_setclr|D_Master|D_aud,custom+dmacon
mouse: btst #6,$bfe001
bne mouse
move.w #D_aud,custom+dmacon
rts

Sample
dc.w $808a,$949e,$a8d2,$bcd0,$daea,$eef8,$d20c,$1c20,$2a34,$3e48,525c,$6670 ,$7a40 ; in chip"

to be continued...
Cyf
Member
#11 - Posted: 9 Dec 2004 15:42 - Edited
Reply Quote
"Second: effects.

there are two kinds of possible modulations: amplitude modulation (volume) and frequency modulation (period).
The first could be used to make effects of vibrato or tremolo type, imitation of distance of a sound...
The second allows simulating chords.
Moreover, it's possible to combine the two modulations.
one problem: to modulate a voice, it's needed to use two consecutive channels.
the first (low) is used for the envelope and the second (high) is used for the basic sound.
the registers are initialized normally (except volume of the modulation channel, not played).
for the modulation channel, the data table is not made up of bytes but of words either a volume (0-64) or a period.

if you want to make an amplitude and frequency modulation at the same time, the table must alternatively contain a volume and a period, in this order. In this last case, there will be two readings instead of one so that the modulations are done simultaneously and not one after the other. Not need to touch at the period to compensate.

Then it's necessary to link the two channels for the modulation with register ADKCON (!! it is also used for the disk drives !!).

ADKCON/R: $dff09e/10
15 set/clr
07 ATPER3 if 1, cut voice 3
06 ATPER2 if 1, voice 2 module voice 3
05 ATPER1 if 1, voice 1 module voice 2
04 ATPER0 if 1, voide 0 module voice 1
03 ATVOL3 idem
02 ATVOL2 ...
01 ATVOL1 ...
00 ATVOL0 ...

bits 7 and 3 are same effect : stop the voice 3, the higher and so cant modulate an other. But even if no sound, datas continues to be loaded by Agnus. these 2 bits are useless. we can make use of it to create a break up of the audio in voice 3, but there are other less constraining methods to do that (amplitude modulation with a table made of only 2 values: 0 and 64).
After that, enable DMA channels : the basic sound will be played on the highest voice of both. It will use as volume or frequency (or both) the words loaded at each period with the channel of modulation. These words are loaded at the address of volume or frequency of the modulated channel. if you stop the modulation, dont forget to reset the volume or the frequency of the modified channels and disable DMA of the modulated channels.
It's possible to use only one channel, by modifying the volume or the frequency "in one's hand", but no syncro and cpu fully used!

example2:
lea custom,a6
; freq modulation
move.l #datamod,aud0lch(a6) ; datamod2 for amplitude modul. / datamod3 for both
move.w #8,aud0len(a6) ; 16 for both mod
move.w #40000,aud0per(a6) ; periode
; basic sound
move.l #data,aud1lch(a6)
move.w #1,aud1len(a6)
move.w #5000,aud1per(a6)
move.w #50,aud1vol(a6)

move.w #$8010,adkcon(a6) ; adkcon = 0 + 1 / 8001 for amplitude / 8011 for both

move.w #$8203,dmacon(a6) ; start
mouse: btst #6,$bfe001
bne.s mouse
move.w #$11,adkcon(a6) ; end of modulation
move.w #3,dmacon(a6)
rts
data: dc.b 120,-120 ; square signal
datamod:
dc.w 1000,2000,3000,4000,5000,6000,7000,8000 ; freq modulation
datamod2:
dc.w 2,8,10,20,30,40,50,60 ; amplitude modulation
datamod3:
dc.w 2,1000,8,2000,10,3000,20,4000 ; both
dc.w 30,5000,40,6000,50,7000,60,8000"

to be continued...
Cyf
Member
#12 - Posted: 9 Dec 2004 22:08 - Edited
Reply Quote
"Third: interruption mode

[...]Amiga has 4 audio circuits, one for each voice. Agnus uses 4 DMA channels to transfer datas.[... ]

After the authorization of DMA transfers, Paula transfer address and length of the sound in its own registers. Afterwards, it generates an interruption of level 4 to inform the 68000 that it finished the operation.
The processor can then change the contents of the address and volume registers without that influencing the audio in progress. During this time Agnus load a word both periodes in register AUD*DAT $dff0+A

A cut of DMA channel is without effect if it lasts less time than twice the period of the played sound, because the state of DMA channel is checked only before each transfer of data, time between two transfers is the double of the period of the sound since the data are loaded word by word.

When the end of the sample reached, Paula reload audio registers and causes an interruption, until DMA stopped.
first problem: for example, we want to launch at the same time the same sound on the 4 channels. if the channels are not synchronized between them, that will produce a cacophony. But that will occur however only in one precise case: if the computer played already a sound on one or several of the voices. In this case, Paula will take account of the new sound only after having finished that which it was playing, from where a shift compared to the sound which began immediately.

Before any work with Paula, make sure that previous DMA transfers are finished. For that, it's necessary to wait time that the longest period lasts twice, 65535 cycles, or 20 ms with a CIA timer, more compatible with all amiga .

second problem: how to join 2 samples too long to play in one time ?
launch the first piece normally. After having loaded the contents of the registers, Paula causes an interruption of level 4. It's there that the interruption should be grabed, re-init address and length of the second piece without modifying DMACON.
During the second reading, these are the lately initialized registers that Paula will load, and it will be thus the new piece which will be played. If you have more than two pieces, the system is the same.

[skip note about interruptions in general]

example:
; save values
;...
; init
lea custom,a6
move.w #$7fff,intena(a6)
move.l #intlev4,$70.w
move.w #$c080,intena(a6) ; channel 0
; first sample
move.w #500,aud0per(a6)
move.w #50,aud0vol(a6)
move.l #data1,aud0lch(a6)
move.w #50000,aud0len(a6)
move.w #$8201,dmacon(a6)
mouse: btst #6,$bfe001
bne.s mouse
move.w #1,dmacon(a6)
; restore
;...
rts
intlev4: movem.l d0/a0/a6,-(sp)
lea custom,a6
move.w intreqr(a6),d0
btst #7,d0
beq .no
move.l pt,a0
move.l (a0)+,aud0lch(a6)
move.w (a0)+,aud0len(a6)
cmp.l #endtable,a0
bne .skip
lea table,a0
.skip:
move.l a0,pt
move.w #$80,intreq(a6)
.no:
movem.l (sp)+,d0/a0/a6
rte

data1: dcb.b 384000,0
table:
dc.l data1
dc.w 50000
dc.l data1+100000
dc.w 50000
dc.l data1+200000
dc.w 50000
dc.l data1+300000
dc.w 42000
fin:

pt: dc.l table+6

note: if the following piece doesnt have the same frequency or if you want to change his volume, you will have to wait the beginning of this piece (loading of the registers) to carry out the changes because volume and frequency arent safeguarded by Paula, who works directly on.

Fourth: manual mode

no more need to use audlch, audlen, nor to authorize the DMA.
it's necessary to indicate volume and period.
then you transfer the first data word in auddat, which will start the process: the word will be read at the frequency indicated and an interruption of level 4 will be generated indicating that you can send the following word. if you dont grab it, the sound transmission will end, and you will be forced to restart the process.

advantages (summary):
1. makes it possible to use samples of which the length depends only on the memory size.
2. amplitude and frequency modulation by using only one channel.
3. easy realization of many effects (inversion of sound, scratching...)
4. mix in real time several signals: fake 4+ channels!
to mix 2 sounds, it's enough to add the current amplitudes of the two signals by taking the differences of volume and frequency into account.
5. data dont need more to be in CHIP since the DMA is not used.

this mode is needed for the sampling.

last, the filter:
it cuts all the high frequencies, no more risks of aliasing.[...]
it's on bit 1 of port A of the CIA-A ($$bfe001). On old Amiga, it on/off the power-led.

ex.: eor.w #2,$bfe001

advices:
try echo effect by desynchronizing slightly two voices playing the same sound (and it's better if on the same stereo channel)
for good quality: use all the band of amplitude (+127 to -128), frequency not too low (min 7000), and for the loop, same value for the beginning and the end of the sample."

The End
credits: (c) Philippe Rivaillon in "La Voix de Paula" - ANT issues 29/30 jan/feb 1992


ps: possible to make a cool "fading" effect of the power-led but only on old amiga (see "Demon Download"/Silents boot)
Cyf
Member
#13 - Posted: 9 Dec 2004 22:54
Reply Quote
and sorry for these looooong posts !
TheDarkCoder
Member
#14 - Posted: 11 Dec 2004 10:36
Reply Quote
Great tutorial Cyf!!!!
almost everything explained.

In particular I congratulate because of :

A cut of DMA channel is without effect if it lasts less time than twice the period of the played sound, because the state of DMA channel is checked only before each transfer of data, time between two transfers is the double of the period of the sound since the data are loaded word by word.

Before any work with Paula, make sure that previous DMA transfers are finished. For that, it's necessary to wait time that the longest period lasts twice, 65535 cycles, or 20 ms with a CIA timer for example.


this fact is VERY IMPORTANT,but not very well explained on the HRM, and on other references.

I had to discover it by myself, after very carefull reading/interpreting/many experiments.
Many time wasted!!

Well done, thanks to your help,many inexperienced coders will learn it more quickly and will avoid productions that starts producing rubbish from the sound!!

:-)
Cyf
Member
#15 - Posted: 11 Dec 2004 12:32 - Edited
Reply Quote
thanks.
But you must thank Philippe Rivaillon for these great tutos in the french mag ANT "Amiga News Tech", where I found all infos at the time of demo coding, and translated them.
these mags are rare and "collector", and nowhere on the net.

ps: hmm, he's the founder of Hidden Floor development studio, and before at Kalisto
(french interview here)

ps2: I just had the authorization from Philippe Rivaillon himself. thanks a lot ! (so I completed with some adds from original article)
Cyf
Member
#16 - Posted: 11 Dec 2004 16:21
Reply Quote
another thread about sample playback, with an example by Photon (ex.scoopex/phenomena ^^) from Protracker with Cia interruption :
http://eab.abime.net/showthread.php?t=16265
TheDarkCoder
Member
#17 - Posted: 16 Dec 2004 19:53
Reply Quote
@Cyf: anyway, I think what you wrote is a very good tutorial about sound. After some nice formatting, it could be a very good atutorial for the ADA's coder corner!!! ;-)

 

  Please register a new account or log in to comment

  

  

  

 

A.D.A. Amiga Demoscene Archive, Version 3.0