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 >
Text File  |  1992-12-07  |  10KB  |  251 lines

  1. ;Routine de restitution 8 bits pour STF.
  2. ;(C)oderight NulloS//DNT 1992
  3. ;
  4. ;
  5. ; Pour restituer le son, il faut utiliser la même fréquence que
  6. ;celle d'échantillonnage, sinon le son va être déformé.
  7. ; Par exemple,si vous utilisez un son digitalisé a 12,5Khz, il faut
  8. ;le restituer à une fréquence de 12,5Khz.
  9. ; Pour tenir cette fréquence précise, il y a deux manières de procéder:
  10. ;
  11. ;    o Faire une routine qui inclu une boucle d'attente de longueur
  12. ;    variable selon la fréquence voulue.
  13. ;    o Se servir d'un timer du MFP réglé à 12,5Khz.
  14. ;
  15. ; On va se servir ici de la 2ème méthode, à savoir la programmation du
  16. ;MFP pour utiliser un timer à 12,5Khz. Si vous avez des problèmes avec les
  17. ;interruptions, jetez un coup d'oeil à ce source, ça pourra peut-être
  18. ;vous aider.
  19. ;
  20. ; Les timers du MFP ont une fréquence de travail de 2,4576 Mhz. Celle
  21. ;ci est divisée à volonté pour obtenir la fréquence que l'on désire.
  22. ;Les diviseurs principaux sont d1=4,10,16,50,64,100 ou 200. Un deuxième
  23. ;diviseur est disponible, et possède un valeur d2=1..255 La fréquence
  24. ;obtenue est 2457600/(d1*d2)
  25. ; Pour avoir du 12,5Khz, on utilise d1=4 et d2=49 ce qui donne du 12538Hz
  26. ;à peu près. Là est la limite du MFP: on ne peut pas choisir au hertz
  27. ;près.Mais comme les logiciels de digitalisation se servent aussi d'un
  28. ;timer, les fréquences sont les mêmes entre digit et restitution.
  29. ;
  30. ; Si vous changez les valeurs du timer, la fréquence de restitution
  31. ;change, ce qui modifie la hauteur du son. Malheureusement, cela
  32. ;déforme le rendu (un son "naturel" comporte un élément appelé
  33. ;timbre qui est invariable, alors qu'un changement de fréquence le
  34. ;modifie.Par exemple, quand on digitalise une voix qui chante le LA
  35. ;d'un octave, et que l'on double sa fréquence de restitution, on
  36. ;obtient le LA de l'octave supérieur, mais le rendu est très différent
  37. ;de la même voix chantant vraiment un LA de l'octave supérieur...Ca
  38. ;permet d'ailleurs de savoir où et quand les voix des "chanteuses" de
  39. ;house-musique est trafiquée....héhé).
  40. ;
  41. ; Amusez vous bien !..
  42.  
  43.     include    a:\hard_sys.s
  44.  
  45. Start    move.l    4(sp),a6        ;récupère page de base
  46.     move.l    $c(a6),a0        ;Taille programme
  47.     adda.l    $14(a6),a0        ;   +   données
  48.     adda.l    $1c(a6),a0        ;   +   variables
  49.     lea    256+2048(a0),a0    ;   +   page de base+pile
  50.     move.l    a0,d0        ;
  51.     andi.w    #-2,d0        ;arondir à un nombre pair
  52.     move.l    d0,sp        ;nouvelle pile
  53.     adda.l    a6,sp        ;
  54.     move.l    d0,-(sp)        ;taille à conserver
  55.     move.l    a6,-(sp)        ;à partir de la page de base
  56.     move.l    #$004a0000,-(sp)    ;Mshrink. Rend le reste au
  57.     trap    #1        ;Gemdos.
  58.     lea    12(sp),sp        ;rétablit la pile
  59.     
  60.  
  61.     clr.l    -(sp)        ;passage en superviseur
  62.     move.w    #$20,-(sp)        ;
  63.     trap    #1        ;
  64.     addq.l    #6,sp        ;
  65.     move.l    d0,save_SSP    ;sauve la pile système
  66.     move.b    conterm.w,save_conterm;et les paramètres clavier
  67.     clr.b    conterm.w        ;coupe le bip clavier
  68.  
  69.     bsr    Wait_Kbd        ;attendre le clavier
  70.     move.b    #$12,KBD_data.w    ;couper la souris
  71.     
  72.     bsr    InitYamaha        ;prépare le yamaha pour la digit
  73.     lea    sample,a0        ;adresse de début du sample
  74.     lea    endsample,a1    ;adresse de fin
  75.     lea    bclsample,a2    ;adresse de bouclage
  76.     bsr    InstallDigit    ;et lance la resitution !
  77.     
  78. presskey    move.l    #$000bffff,-(sp)    ;demander l'état shift,control 
  79.     trap    #13        ;et altenrate
  80.     addq.l    #4,sp        ;
  81.     and.w    #7,d0        ;Pressée(s) ?
  82.     beq.s    presskey        ;non, attendre encore
  83.     
  84.     bsr    KillDigit        ;couper la digit
  85.     
  86.     bsr    Wait_Kbd        ;attendre clavier
  87.     move.b    #$8,KBD_data.w    ;reprendre les transferts
  88.                 ;souris
  89.     move.b    save_conterm,conterm.w;et remettre bip clavier
  90.     
  91.     move.l    save_SSP,-(sp)    ;repasse en utilisateur
  92.     move.w    #$20,-(sp)        ;
  93.     trap    #1        ;
  94.     clr.w    (sp)        ;et cassos
  95.     trap    #1        ;
  96.  
  97.  
  98. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  99. ;Routine de base. Elle se charge d'installer la digit dans le timer A
  100. ;(qui n'est pas utilisé par le système, mais pour votre usage personnel
  101. ;vous pouvez aussi vous servir d'un autre, comme le TimerB pour les
  102. ;rasters).Le sample est pointé par A0
  103. ;Je rappelle que la signification des différents bits d'interruption MFP
  104. ;sont:
  105. ;IERA/IMRA/ISRA/IPRA: 7..moniteur monochrome
  106. ;        6..sonnerie RS232
  107. ;        5..Timer A
  108. ;        4..tampon de reception plein (RS232)
  109. ;        3..erreur de reception (RS232)
  110. ;        2..tampon d'emission vide (RS232)
  111. ;        1..erreur d'émission (RS232)
  112. ;        0..Timer B
  113. ;
  114. ;IERB/IMRB/ISRB/IPRB: 7..interruption FDC/DMA
  115. ;        6..interruption clavier
  116. ;        5..Timer C
  117. ;        4..Timer D
  118. ;        3..interruption blitter
  119. ;        2..signal CTS (RS232)
  120. ;        1..detection de porteuse (RS232)
  121. ;        0..gestion Centronics
  122. ;Pour installer une de ces interruptions, il faut l'autoriser dans le
  123. ;bit correspondant de IERA ou IERB en le mettant à 1.Puis la démasquer
  124. ;avec IMRA ou IMRB (en mettant son bit à 1).A la fin de l'interruption,
  125. ;il faut mettre son bit à 0 dans le registre ISRA ou ISRB.
  126. ;Pour un timer, il faut d'abord (avant de l'autoriser) mettre son CR
  127. ;(Control Register) à 0,choisir le diviseur d2 à mettre dans TADR,TBDR
  128. ;TCDR ou TDDR (selon le timer), et mettre le diviseur d1 dans le CR
  129. ;du timer (TACR,TBCR ou TCDCR).
  130. ;On ne met pas directement d1, mais un équivalent:
  131. ;    o 1 pour choisir d1=4
  132. ;    o 2 ""     ""    d1=10
  133. ;    o 3 ""     ""    d1=16
  134. ;    o 4 ""     ""    d1=50
  135. ;          o 5 ""     ""    d1=64
  136. ;    o 6 ""     ""    d1=100
  137. ;    o 7 ""     ""    d1=200
  138. ;
  139. InstallDigit
  140.     move.l    a0,-(sp)
  141.     movem.l    a0-a2,TA_next    ;données de la digit
  142.  
  143.     move.l    #TA_replay,V_TA.w    ;installe notre routine TimerA
  144.     lea    MFP_base.w,a0    ;adresse registres MFP
  145.     clr.b    TACR(a0)        ;CR à 0
  146.     move.b    #49,TADR(a0)    ;diviseur d2=49
  147.     move.b    #1,TACR(a0)    ;diviseur d1=4
  148. ;=Fréquence 2457600/(4*49)=12538 Hz .Maintenant le timer est actif
  149.     ori.b    #%00100000,IERA(a0)    ;autorise le timer A
  150.     ori.b    #%00100000,IMRA(a0)    ;et démasque le.
  151.     movea.l    (sp)+,a0
  152.     rts
  153. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  154. ;Interruption Timer A qui restitue le son.C'est elle qui se charge du
  155. ;plus important: convertir les samples vers le yamaha.
  156. TA_next    dc.l    0
  157. TA_end    dc.l    0
  158. TA_bcl    dc.l    0
  159. TA_replay    movem.l    d0/a0,-(sp)    ;sauve les registres
  160.     moveq    #0,d0        ;annule d0
  161.     movea.l    TA_next(pc),a0    ;adresse prochain échantillon
  162.     move.b    (a0)+,d0        ;récupère le
  163.     cmpa.l    TA_end(pc),a0    ;fin atteinte ?
  164.     blt.s    TA_rsuite        ;non
  165.     movea.l    TA_bcl(pc),a0    ;si, rentre dans la boucle
  166.  
  167. TA_rsuite    move.l    a0,TA_next        ;
  168.     lsl.w    #3,d0        ;*8 pour aller dans la table
  169.     lea    yam_ctrl.w,a0    ;adresse registre yamaha
  170.     move.l    ST_REPLAY+4(pc,d0.w),(a0) ;va chercher l'équivalent du
  171.     move.l    ST_REPLAY(pc,d0.w),d0    ;sample dans la table
  172.     movep.l    d0,0(a0)        ;
  173.  
  174.     move.l    (sp)+,d0        ;
  175.     move.l    (sp)+,a0        ;remet les registres
  176.     andi.b    #%11011111,ISRA+MFP_base.w ;interruption finie
  177.     rte
  178. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  179. __SR_SIGN    equ    1
  180.     include    STREPLAY.S
  181. ;La table est organisé comme suit...les 128 lignes de 8 dc.w contiennent
  182. ;chacune 2 équivalent sample<=>yamaha.
  183. ;Chaque équivalent est comme suit:
  184. ;dc.w    $080x,$090y,$0a0a,$0z0z
  185. ;Les registres du yamaha correspondants aux volumes 0,1 et 2 sont les
  186. ;registres No 8,9 et 10 (donc $08,$09 et $0a).
  187. ;Pour accéder à un registre, il faut écrire son numéro en yam_ctrl=ff8800.w
  188. ;puis écrire sa valeur en yam_write=$ff8802. Ces deux adresses contiennent
  189. ;un octet, donc.Mais les adresses $ff8804 et $ff8806 ont exactement les
  190. ;mêmes rôles (dans l'ordre), ce sont en quelque sorte des images de yam_ctrl
  191. ;et yam_write (en fait, les adresses $ff8800+4*n et $ff8802+4*n sont
  192. ;toutes équivalentes 2 à 2).
  193. ;Bref.Un fois chargé en D0 la valeur 080x090y, on fait un movep.l à l'adresse
  194. ;ffff8800. Or movep écrit les 4 octets du registre D0 aux adresses 0(a0),2(a0)
  195. ;4(a0) et 6(a0), donc $ff8800,$ff8802,$ff8804 et $ff8806...Donc il écrit
  196. ;8 en $ff8800, ce qui sélectionne le volume 0,puis la valeur x en $ff8802,
  197. ;donc dans le registre de volume.Ensuite 9 et y en $ff8804 et $ff8806, ce
  198. ;qui place y dans le volume 1 !!.Deux volumes ont donc été placés.
  199. ;Il reste le troisième. le move.l ST_REPLAY(pc,d0.w),(a0) place la
  200. ;valeur $0a0a0z0z en $ff8800...Les adresses $ff8801 et $ff8803 n'existent
  201. ;pas, mais la manoeuvre ne provoque pas de bombes. Donc on écrit 10=$a
  202. ;en $ff8800 (et $ff8801,mais cela n'a aucun effet), puis z en $ff8802 (et
  203. ;$ff8803).
  204. ;En fin de compte, nous avons placé x,y et z dans les volumes 0,1 et 2
  205. ;selon la valeur de l'échantillon. La somme des volumes 4 bits va ainsi
  206. ;émuler un convertisseur 8 bits, la table permettant de trouver l'équivalent
  207. ;8 bits=>3 fois 4 bits...
  208. ;
  209. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  210. KillDigit    move.l    a0,-(sp)
  211.     lea    MFP_base.w,a0    ;adresse registres MFP
  212.     clr.b    TACR(a0)        ;coupe d'abord le timer A
  213.     clr.b    TADR(a0)        ;annule son diviseur
  214.     andi.b    #%11011111,IERA(a0)    ;interdit le timer A
  215.     andi.b    #%11011111,IMRA(a0)    ;masque le
  216.     move.l    (sp)+,a0        ;le timer est maintenant
  217.     rts            ;totallement enlevé
  218. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  219. Wait_Kbd    btst    #1,KBD_stat.w    ;clavier près à recevoir ?
  220.     beq.s    Wait_Kbd        ;non, attendre
  221.     rts            ;c'est bon !
  222. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  223. ;Coupe les oscillateurs ainsi que les enveloppes du processeur sonore
  224. ;afin de pouvoir se servir du volume de chaque voix comme d'un
  225. ;convertisseur 4 bits.
  226. ;
  227. InitYamaha
  228.     movem.l    d0/a0-a1,-(sp)    ;
  229.     lea    yam_ctrl.w,a1    ;adresse du registre yamaha
  230.     lea    yaminit_data+1(pc),a0    ;données à envoyer
  231.     moveq    #14,d0        ;15 registres
  232. yami_0    move.b    d0,(a1)        ;selectionne le registre No D0
  233.     move.b    (a0)+,2(a1)    ;donne lui la bonne valeur
  234.     dbf    d0,yami_0        ;registre suivant
  235.     movem.l    (sp)+,d0/a0-a1    ;
  236.     rts            ;
  237. yaminit_data
  238.     dc.b    $00,$27,$00,$00,$00,$00,$00,$00
  239.     dc.b    $ff,$00,$ff,$ff,$ff,$ff,$ff,$ff
  240.     
  241.     SECTION    DATA
  242.  
  243. sample    incbin    flut_pan.spl    ;sample à restituer
  244. endsample    equ    *        ;son adresse fin
  245. bclsample    equ    sample+40962    ;bouclage
  246.  
  247.     SECTION    BSS
  248. save_SSP    ds.l    1
  249. save_conterm
  250.     ds.w    1