home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
No Fragments Archive 10: Diskmags
/
nf_archive_10.iso
/
MAGS
/
DNTPAPER
/
DNT_04.MSA
/
ARCHIVES.DNT
/
SOURCES.ZIP
/
SAMPLING
/
SON_STF.S
< prev
next >
Wrap
Text File
|
1992-12-07
|
10KB
|
251 lines
;Routine de restitution 8 bits pour STF.
;(C)oderight NulloS//DNT 1992
;
;
; Pour restituer le son, il faut utiliser la même fréquence que
;celle d'échantillonnage, sinon le son va être déformé.
; Par exemple,si vous utilisez un son digitalisé a 12,5Khz, il faut
;le restituer à une fréquence de 12,5Khz.
; Pour tenir cette fréquence précise, il y a deux manières de procéder:
;
; o Faire une routine qui inclu une boucle d'attente de longueur
; variable selon la fréquence voulue.
; o Se servir d'un timer du MFP réglé à 12,5Khz.
;
; On va se servir ici de la 2ème méthode, à savoir la programmation du
;MFP pour utiliser un timer à 12,5Khz. Si vous avez des problèmes avec les
;interruptions, jetez un coup d'oeil à ce source, ça pourra peut-être
;vous aider.
;
; Les timers du MFP ont une fréquence de travail de 2,4576 Mhz. Celle
;ci est divisée à volonté pour obtenir la fréquence que l'on désire.
;Les diviseurs principaux sont d1=4,10,16,50,64,100 ou 200. Un deuxième
;diviseur est disponible, et possède un valeur d2=1..255 La fréquence
;obtenue est 2457600/(d1*d2)
; Pour avoir du 12,5Khz, on utilise d1=4 et d2=49 ce qui donne du 12538Hz
;à peu près. Là est la limite du MFP: on ne peut pas choisir au hertz
;près.Mais comme les logiciels de digitalisation se servent aussi d'un
;timer, les fréquences sont les mêmes entre digit et restitution.
;
; Si vous changez les valeurs du timer, la fréquence de restitution
;change, ce qui modifie la hauteur du son. Malheureusement, cela
;déforme le rendu (un son "naturel" comporte un élément appelé
;timbre qui est invariable, alors qu'un changement de fréquence le
;modifie.Par exemple, quand on digitalise une voix qui chante le LA
;d'un octave, et que l'on double sa fréquence de restitution, on
;obtient le LA de l'octave supérieur, mais le rendu est très différent
;de la même voix chantant vraiment un LA de l'octave supérieur...Ca
;permet d'ailleurs de savoir où et quand les voix des "chanteuses" de
;house-musique est trafiquée....héhé).
;
; Amusez vous bien !..
;
include a:\hard_sys.s
Start move.l 4(sp),a6 ;récupère page de base
move.l $c(a6),a0 ;Taille programme
adda.l $14(a6),a0 ; + données
adda.l $1c(a6),a0 ; + variables
lea 256+2048(a0),a0 ; + page de base+pile
move.l a0,d0 ;
andi.w #-2,d0 ;arondir à un nombre pair
move.l d0,sp ;nouvelle pile
adda.l a6,sp ;
move.l d0,-(sp) ;taille à conserver
move.l a6,-(sp) ;à partir de la page de base
move.l #$004a0000,-(sp) ;Mshrink. Rend le reste au
trap #1 ;Gemdos.
lea 12(sp),sp ;rétablit la pile
clr.l -(sp) ;passage en superviseur
move.w #$20,-(sp) ;
trap #1 ;
addq.l #6,sp ;
move.l d0,save_SSP ;sauve la pile système
move.b conterm.w,save_conterm;et les paramètres clavier
clr.b conterm.w ;coupe le bip clavier
bsr Wait_Kbd ;attendre le clavier
move.b #$12,KBD_data.w ;couper la souris
bsr InitYamaha ;prépare le yamaha pour la digit
lea sample,a0 ;adresse de début du sample
lea endsample,a1 ;adresse de fin
lea bclsample,a2 ;adresse de bouclage
bsr InstallDigit ;et lance la resitution !
presskey move.l #$000bffff,-(sp) ;demander l'état shift,control
trap #13 ;et altenrate
addq.l #4,sp ;
and.w #7,d0 ;Pressée(s) ?
beq.s presskey ;non, attendre encore
bsr KillDigit ;couper la digit
bsr Wait_Kbd ;attendre clavier
move.b #$8,KBD_data.w ;reprendre les transferts
;souris
move.b save_conterm,conterm.w;et remettre bip clavier
move.l save_SSP,-(sp) ;repasse en utilisateur
move.w #$20,-(sp) ;
trap #1 ;
clr.w (sp) ;et cassos
trap #1 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Routine de base. Elle se charge d'installer la digit dans le timer A
;(qui n'est pas utilisé par le système, mais pour votre usage personnel
;vous pouvez aussi vous servir d'un autre, comme le TimerB pour les
;rasters).Le sample est pointé par A0
;Je rappelle que la signification des différents bits d'interruption MFP
;sont:
;IERA/IMRA/ISRA/IPRA: 7..moniteur monochrome
; 6..sonnerie RS232
; 5..Timer A
; 4..tampon de reception plein (RS232)
; 3..erreur de reception (RS232)
; 2..tampon d'emission vide (RS232)
; 1..erreur d'émission (RS232)
; 0..Timer B
;
;IERB/IMRB/ISRB/IPRB: 7..interruption FDC/DMA
; 6..interruption clavier
; 5..Timer C
; 4..Timer D
; 3..interruption blitter
; 2..signal CTS (RS232)
; 1..detection de porteuse (RS232)
; 0..gestion Centronics
;Pour installer une de ces interruptions, il faut l'autoriser dans le
;bit correspondant de IERA ou IERB en le mettant à 1.Puis la démasquer
;avec IMRA ou IMRB (en mettant son bit à 1).A la fin de l'interruption,
;il faut mettre son bit à 0 dans le registre ISRA ou ISRB.
;Pour un timer, il faut d'abord (avant de l'autoriser) mettre son CR
;(Control Register) à 0,choisir le diviseur d2 à mettre dans TADR,TBDR
;TCDR ou TDDR (selon le timer), et mettre le diviseur d1 dans le CR
;du timer (TACR,TBCR ou TCDCR).
;On ne met pas directement d1, mais un équivalent:
; o 1 pour choisir d1=4
; o 2 "" "" d1=10
; o 3 "" "" d1=16
; o 4 "" "" d1=50
; o 5 "" "" d1=64
; o 6 "" "" d1=100
; o 7 "" "" d1=200
;
InstallDigit
move.l a0,-(sp)
movem.l a0-a2,TA_next ;données de la digit
move.l #TA_replay,V_TA.w ;installe notre routine TimerA
lea MFP_base.w,a0 ;adresse registres MFP
clr.b TACR(a0) ;CR à 0
move.b #49,TADR(a0) ;diviseur d2=49
move.b #1,TACR(a0) ;diviseur d1=4
;=Fréquence 2457600/(4*49)=12538 Hz .Maintenant le timer est actif
ori.b #%00100000,IERA(a0) ;autorise le timer A
ori.b #%00100000,IMRA(a0) ;et démasque le.
movea.l (sp)+,a0
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Interruption Timer A qui restitue le son.C'est elle qui se charge du
;plus important: convertir les samples vers le yamaha.
TA_next dc.l 0
TA_end dc.l 0
TA_bcl dc.l 0
TA_replay movem.l d0/a0,-(sp) ;sauve les registres
moveq #0,d0 ;annule d0
movea.l TA_next(pc),a0 ;adresse prochain échantillon
move.b (a0)+,d0 ;récupère le
cmpa.l TA_end(pc),a0 ;fin atteinte ?
blt.s TA_rsuite ;non
movea.l TA_bcl(pc),a0 ;si, rentre dans la boucle
TA_rsuite move.l a0,TA_next ;
lsl.w #3,d0 ;*8 pour aller dans la table
lea yam_ctrl.w,a0 ;adresse registre yamaha
move.l ST_REPLAY+4(pc,d0.w),(a0) ;va chercher l'équivalent du
move.l ST_REPLAY(pc,d0.w),d0 ;sample dans la table
movep.l d0,0(a0) ;
move.l (sp)+,d0 ;
move.l (sp)+,a0 ;remet les registres
andi.b #%11011111,ISRA+MFP_base.w ;interruption finie
rte
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
__SR_SIGN equ 1
include STREPLAY.S
;La table est organisé comme suit...les 128 lignes de 8 dc.w contiennent
;chacune 2 équivalent sample<=>yamaha.
;Chaque équivalent est comme suit:
;dc.w $080x,$090y,$0a0a,$0z0z
;Les registres du yamaha correspondants aux volumes 0,1 et 2 sont les
;registres No 8,9 et 10 (donc $08,$09 et $0a).
;Pour accéder à un registre, il faut écrire son numéro en yam_ctrl=ff8800.w
;puis écrire sa valeur en yam_write=$ff8802. Ces deux adresses contiennent
;un octet, donc.Mais les adresses $ff8804 et $ff8806 ont exactement les
;mêmes rôles (dans l'ordre), ce sont en quelque sorte des images de yam_ctrl
;et yam_write (en fait, les adresses $ff8800+4*n et $ff8802+4*n sont
;toutes équivalentes 2 à 2).
;Bref.Un fois chargé en D0 la valeur 080x090y, on fait un movep.l à l'adresse
;ffff8800. Or movep écrit les 4 octets du registre D0 aux adresses 0(a0),2(a0)
;4(a0) et 6(a0), donc $ff8800,$ff8802,$ff8804 et $ff8806...Donc il écrit
;8 en $ff8800, ce qui sélectionne le volume 0,puis la valeur x en $ff8802,
;donc dans le registre de volume.Ensuite 9 et y en $ff8804 et $ff8806, ce
;qui place y dans le volume 1 !!.Deux volumes ont donc été placés.
;Il reste le troisième. le move.l ST_REPLAY(pc,d0.w),(a0) place la
;valeur $0a0a0z0z en $ff8800...Les adresses $ff8801 et $ff8803 n'existent
;pas, mais la manoeuvre ne provoque pas de bombes. Donc on écrit 10=$a
;en $ff8800 (et $ff8801,mais cela n'a aucun effet), puis z en $ff8802 (et
;$ff8803).
;En fin de compte, nous avons placé x,y et z dans les volumes 0,1 et 2
;selon la valeur de l'échantillon. La somme des volumes 4 bits va ainsi
;émuler un convertisseur 8 bits, la table permettant de trouver l'équivalent
;8 bits=>3 fois 4 bits...
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KillDigit move.l a0,-(sp)
lea MFP_base.w,a0 ;adresse registres MFP
clr.b TACR(a0) ;coupe d'abord le timer A
clr.b TADR(a0) ;annule son diviseur
andi.b #%11011111,IERA(a0) ;interdit le timer A
andi.b #%11011111,IMRA(a0) ;masque le
move.l (sp)+,a0 ;le timer est maintenant
rts ;totallement enlevé
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Wait_Kbd btst #1,KBD_stat.w ;clavier près à recevoir ?
beq.s Wait_Kbd ;non, attendre
rts ;c'est bon !
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Coupe les oscillateurs ainsi que les enveloppes du processeur sonore
;afin de pouvoir se servir du volume de chaque voix comme d'un
;convertisseur 4 bits.
;
InitYamaha
movem.l d0/a0-a1,-(sp) ;
lea yam_ctrl.w,a1 ;adresse du registre yamaha
lea yaminit_data+1(pc),a0 ;données à envoyer
moveq #14,d0 ;15 registres
yami_0 move.b d0,(a1) ;selectionne le registre No D0
move.b (a0)+,2(a1) ;donne lui la bonne valeur
dbf d0,yami_0 ;registre suivant
movem.l (sp)+,d0/a0-a1 ;
rts ;
yaminit_data
dc.b $00,$27,$00,$00,$00,$00,$00,$00
dc.b $ff,$00,$ff,$ff,$ff,$ff,$ff,$ff
SECTION DATA
sample incbin flut_pan.spl ;sample à restituer
endsample equ * ;son adresse fin
bclsample equ sample+40962 ;bouclage
SECTION BSS
save_SSP ds.l 1
save_conterm
ds.w 1