home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / software / testi / corsoasm / sorgenti8 / lezione14-8b.s < prev    next >
Text File  |  1995-09-29  |  6KB  |  158 lines

  1.  
  2. ; Corso Asm - LEZIONE xx:  * MIXARE 2 SAMPLE E BOOSTARE IL VOLUME *
  3.  
  4. Start:
  5.  
  6. _LVODisable    EQU    -120
  7. _LVOEnable    EQU    -126
  8.  
  9.     move.l    4.w,a6
  10.     jsr    _LVODisable(a6)
  11.     bset    #1,$bfe001        ;spegne il filtro passa-basso
  12.     lea    $dff000,a6
  13.     move.w    $2(a6),d7        ;salva DMA dell'OS
  14.  
  15.  
  16.     move.l    #sample1,$a0(a6)
  17.     move.l    #sample2,$b0(a6)
  18.     move.w    #(sample1_end-sample1)/2,$a4(a6)
  19.     move.w    #(sample2_end-sample2)/2,$b4(a6)
  20. Clock    equ    3546895
  21.     move.w    #clock/21056,$a6(a6)
  22.     move.w    #clock/21056,$b6(a6)
  23.     move.w    #64,$a8(a6)
  24.     move.w    #64,$b8(a6)
  25.     move.w    #$8003,$96(a6)        ;accende AUD0-AUD1 DMA in DMACONW
  26.  
  27. WLMB:    btst    #6,$bfe001
  28.     bne.s    wlmb
  29.  
  30.     lea    sample0,a0
  31.     move.l    #sample0_end-sample0,d0
  32.     lea    sample1,a1
  33.     move.l    #sample1_end-sample1,d1
  34.     lea    sample2,a2
  35.     move.l    #sample2_end-sample2,d2
  36.     bsr.s    boost_mixsamples
  37.  
  38.     lea    $dff000,a6
  39.     move.l    #sample0,$a0(a6)
  40.     move.l    #sample0,$b0(a6)
  41.     move.w    #(sample0_end-sample0)/2,$a4(a6)
  42.     move.w    #(sample0_end-sample0)/2,$b4(a6)
  43.     move.w    #$8003,$96(a6)
  44.  
  45. WRMB:    btst    #10,$dff016
  46.     bne.s    wrmb
  47.  
  48.     move.w    #$0003,$96(a6)        ;spegne i DMA
  49.     or.w    #$8000,d7        ;accende il bit 15 (SET/CLR)
  50.     move.w    d7,$96(a6)        ;reimposta DMA dell'OS
  51.     move.l    4.w,a6
  52.     jsr    _LVOEnable(a6)
  53.     rts
  54.  
  55.  
  56. Boost_MixSamples:
  57.         ;[a0=dst sample, a1=src sample 1, a2=soruce sample 2]
  58.         ;[d0.l=dst length.b, d1.l=src1 length.b, d2.l=src2 length.b]
  59.     movem.l    d0-d3/a0-a4,-(sp)
  60.     lea    (a1,d1.l),a3        ;a3=fine del sample 1
  61.     lea    (a2,d2.l),a4        ;a4=fine de sample 2
  62.     moveq    #0,d3            ;d3.w=0=MAX campione di partenza
  63. .Lp1:    move.w    #$f00,$dff180
  64.     move.b    (a1)+,d1        ;d1.b=campione del sample 1
  65.     ext.w    d1            ;d1.w=d1.b esteso di segno a word
  66.     move.b    (a2)+,d2        ;d2.b=campione del sample 2
  67.     ext.w    d2            ;d2.w=d2.b esteso si segno a word
  68.     add.w    d1,d2            ;d2.w=somma CON SEGNO i campioni 1 e 2
  69.     bpl.s    .noabs
  70.     neg.w    d2
  71. .NoAbs:    cmp.w    d3,d2            ;d2.w=valore assoluto di d2
  72.     bls.s    .nomax
  73.     move.w    d2,d3            ;se d2>d3: d3(MAX)=d2
  74. .NoMax:    cmp.l    a3,a1            ;è finito il sample 1 ?
  75.     bhs.s    .quit1            ;se SI: esci
  76.     cmp.l    a4,a2            ;è finito il sample 2 ?
  77.     bhs.s    .quit1            ;se SI: esci
  78.     subq.l    #1,d0
  79.     bhi.s    .lp1
  80. .Quit1:    move.l    (sp),d0            ;ripristina d0
  81.     movem.l    5*4(sp),a1-a2        ;ripristina a1 ed a2
  82.     move.w    d3,$7ff0000
  83.                     ;d3.w=MAX raggiunto dalle somme
  84. .Lp2:    move.w    #$00f,$dff180
  85.     move.b    (a1)+,d1        ;d1.b=campione del sample 1
  86.     ext.w    d1            ;d1.w=d1.b esteso di segno a word
  87.     move.b    (a2)+,d2        ;d2.b=campione del sample 2
  88.     ext.w    d2            ;d2.w=d2.b esteso si segno a word
  89.     add.w    d1,d2            ;d2.w=somma CON SEGNO i campioni 1 e 2
  90.  
  91.     muls.w    #127,d2            ;PROPORZIONE: d3(MAX)/127=d2/x
  92.     divs.w    d3,d2
  93.     move.b    d2,(a0)+
  94.  
  95.     cmp.l    a3,a1            ;è finito il sample 1 ?
  96.     bhs.s    .quit2            ;se SI: esci
  97.     cmp.l    a4,a2            ;è finito il sample 2 ?
  98.     bhs.s    .quit2            ;se SI: esci
  99.     subq.l    #1,d0            ;decrementa lungh0.b fino a 0...senza
  100.     bhi.s    .lp2
  101. .Quit2:    movem.l    (sp)+,d0-d3/a0-a4
  102.     rts
  103.  
  104.  
  105.     SECTION    Sample,DATA_C
  106.  
  107. Sample1:
  108.     incbin    "assembler2:sorgenti8/carrasco.21056"
  109. Sample1_end:
  110.  
  111. Sample2:
  112.     incbin    "assembler2:sorgenti8/lee3.21056"
  113. Sample2_end:
  114.  
  115. Sample0:blk.b    sample1_end-sample1
  116. Sample0_end:
  117.     END
  118.  
  119.  
  120. In teoria, il vero mixing si dovrebbe fare solo sommando algebricamente i
  121. campioni, tuttavia, per ovvi omtivi, spesso si fuoriesce dal range di 8 bit con
  122. segno, e, per deamplificare direttamente la forma d'onda in maniera equa, si
  123. divide sempre per 2. Risultato: la resa d'intensità finale è minore di
  124. quella dei 2 sample suonati indipendentemente su due canali diversi.
  125. Per poter utilizzare il normale algoritmo di mixing, sarebbe necessario che
  126. la somma non sorpassi mai 127 o -128, che non esca mai dai limiti del range.
  127. Visto che non conviene campionare sample bassi perchè l'audio ad 8 bit non
  128. possiede una grande precisione, siamo costretti a boostare il volume del
  129. sample mixato fino al limite: si considera il più alto volume raggiunto dalle
  130. somme, e lo si usa come range massimo proporzionale a 127 (valore assoluto
  131. massimo raggiungibile: NON 128, poichè solo la parte negativa arriva a -128,
  132. ed amplificando troppo la positiva - oltre 127 - saremmo al punto di prima).
  133. Le proporzioni - che, personalmente, sono solito definire « gli "zoom" della
  134. matematica » - sono utili, in questo caso, per restringere il campo/range
  135. entro i limiti in modo appunto proporzionale ed equo per tutti i sample.
  136. *** In sostanza, abbiamo deamplificato fino a che il valore più alto delle
  137. somme non fosse pari a 127 (o -127), e tutto il resto proporzionalmente ***.
  138.  
  139.  
  140. N.B.:    anche se sarebbe forse stato opportuno, non è stato applicato alcun
  141.     arrotondamento: si sarebbe dovuto usare un sorta di approssimazione
  142.     oltre la virgola di più bit, che, pur incrementando - anche se non
  143.     effettivamente percepibilmente - la qualità del mixing, avrebbe
  144.     causato non pochi problemi di comprensione del sorgente e, soprattutto,
  145.     di velocità: dopo la moltiplicazione per 127 avremmo potuto shiftare
  146.     il tutto a destra di 16 bit (moltiplicando il numero di molto per 
  147.     simulare la virgola con numeri molto grandi da dividere, poi),
  148.     ottenendo così un valore a 32 bit; valore che doveva essere diviso
  149.     per MAX e poi risfhiftato a sinistra di 16 bit ed arrotondato con
  150.     il bit più significativo della parte shiftata per essere riportato alla
  151.     grandezza originale. Tutto ciò, però, comporterebbe un problema dovuto
  152.     ad una limitazione del 68000: dividendo il valore a 32 bit per MAX,
  153.     il risultato - se MAX è vicino al valore somma corrente - potrebbe
  154.     essere ancora a 32, e l'istruzione DIVS - purtroppo - restituisce il
  155.     risultato a 16 bit nella parte bassa del registro ed il resto nella
  156.     parte alta, cancellando la word a noi tanto utile. Il problema si
  157.     sarebbe potuto presentare per qualsiasi altra approssimazione...
  158.