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

  1.  
  2. ; Corso Asm - LEZIONE xx:  * MIXARE 2 SAMPLE *
  3.  
  4.     section    bau,code
  5.  
  6. Start:
  7.  
  8. _LVODisable    EQU    -120
  9. _LVOEnable    EQU    -126
  10.  
  11.     move.l    4.w,a6
  12.     jsr    _LVODisable(a6)
  13.     bset    #1,$bfe001        ;spegne il filtro passa-basso
  14.     lea    $dff000,a6
  15.     move.w    $2(a6),d7        ;salva DMA dell'OS
  16.  
  17.     move.l    #sample1,$a0(a6)
  18.     move.l    #sample2,$b0(a6)
  19.     move.w    #(sample1_end-sample1)/2,$a4(a6)
  20.     move.w    #(sample2_end-sample2)/2,$b4(a6)
  21. Clock    equ    3546895
  22.     move.w    #clock/21056,$a6(a6)
  23.     move.w    #clock/21056,$b6(a6)
  24.     move.w    #64,$a8(a6)
  25.     move.w    #64,$b8(a6)
  26.     move.w    #$8003,$96(a6)        ;accende AUD0-AUD1 DMA in DMACONW
  27.  
  28. WLMB:    btst    #6,$bfe001
  29.     bne.s    wlmb
  30.  
  31.     lea    sample0,a0
  32.     move.l    #sample0_end-sample0,d0
  33.     lea    sample1,a1
  34.     move.l    #sample1_end-sample1,d1
  35.     lea    sample2,a2
  36.     move.l    #sample2_end-sample2,d2
  37.     bsr.s    mixsamples
  38.     move.l    #sample0,$a0(a6)    ;verrà playato alla fine dei sample 1
  39.     move.l    #sample0,$b0(a6)    ;e 2: vi ricordate perchè ?
  40.     move.w    #(sample0_end-sample0)/2,$a4(a6)
  41.     move.w    #(sample0_end-sample0)/2,$b4(a6)
  42.  
  43. WRMB:    btst    #10,$dff016
  44.     bne.s    wrmb
  45.  
  46.     move.w    #$0003,$96(a6)        ;spegne i DMA
  47.     or.w    #$8000,d7        ;accende il bit 15 (SET/CLR)
  48.     move.w    d7,$96(a6)        ;reimposta DMA dell'OS
  49.     move.l    4.w,a6
  50.     jsr    _LVOEnable(a6)
  51.     rts
  52.  
  53.  
  54. MixSamples:    ;[a0=dst sample, a1=src sample 1, a2=soruce sample 2]
  55.         ;[d0.l=dst length.b, d1.l=src1 length.b, d2.l=src2 length.b]
  56.     movem.l    d0-d3/a0-a4,-(sp)
  57.     lea    (a1,d1.l),a3        ;a3=fine del sample 1
  58.     lea    (a2,d2.l),a4        ;a4=fine de sample 2
  59.     moveq    #0,d3            ;d3.b=0 per ADDX
  60. .Lp:    move.w    #$f00,$dff180
  61.     move.b    (a1)+,d1        ;d1.b=campione del sample 1
  62.     ext.w    d1            ;d1.w=d1.b esteso di segno a word
  63.     move.b    (a2)+,d2        ;d2.b=campione del sample 2
  64.     ext.w    d2            ;d2.w=d2.b esteso si segno a word
  65.     add.w    d1,d2            ;d2.w=somma CON SEGNO i campioni 1 e 2
  66.     asr.w    #1,d2            ;d2.w=media dei campioni (somma/2)
  67.     addx.b    d3,d2            ;d2.w=campione mixato ARROTONDATO per
  68.                     ;eccesso o per difetto in base al bit
  69.                     ;uscito con l'ASR
  70.     move.b    d2,(a0)+        ;salva il campione mixato
  71.     cmp.l    a3,a1            ;è finito il sample 1 ?
  72.     bhs.s    .quit            ;se SI: esci
  73.     cmp.l    a4,a2            ;è finito il sample 2 ?
  74.     bhs.s    .quit            ;se SI: esci
  75.     subq.l    #1,d0            ;decrementa lungh0.b fino a 0...senza
  76.                     ;DBRA perchè funziona solo a word...
  77.     bhi.s    .lp
  78. .Quit:    movem.l    (sp)+,d0-d3/a0-a4
  79.     rts
  80.  
  81.  
  82.     SECTION    Sample,DATA_C
  83.  
  84. Sample1:
  85.     incbin    "assembler2:sorgenti8/carrasco.21056"
  86. Sample1_end:
  87.  
  88. Sample2:
  89.     incbin    "assembler2:sorgenti8/lee3.21056"
  90. Sample2_end:
  91.  
  92. Sample0:blk.b    sample1_end-sample1
  93. Sample0_end:
  94.  
  95.     END
  96.  
  97.  
  98. Cosa abbiamo combinato questa volta ? Siamo riusciti a suonare 2 sample diversi
  99. sulla stessa voce ! Come ? Mixandoli via software con la CPU !
  100. Conoscete bene la struttura della forma d'onda id una sample, e sapete che
  101. ogni campione di 1 byte può variare da -128 a 127, pertanto sono BYTE CON SEGNO
  102. con i quali è possibile lavorare trattandoli secndo la loro natura di numeri
  103. ad 8 bit, il più significativo dei quali agisce da segno.
  104. Quale miglior metodo per fare in modo che date due serie di numeri se ne
  105. ottenga una che ricalchi l'andamento di entrambe ?
  106. Fare la MEDIA ARITMETICA tra ogni coppia di singoli byte/campioni: prendendo
  107. 2 campioni corrispondenti dell'uno e dell'altro sample, è sufficiente
  108. sommarli algebricamente (* TENENDO QUINDI CONTO DEL SEGNO *) e dividere il
  109. risultato per 2: MIX = (SAMP1 + SAMP2) / 2.
  110.  
  111. Quando si sommano algebricamente due byte, è possibile che il risultato sia
  112. maggiore di 127 (ad esempio, se entrambi sono 127, la somma sarà 254), e,
  113. pertanto, non esprimibile con un numero ad 8 bit con segno, per cui è
  114. necessario lavorare a word, per calcolare la media, e le word devono anch'esse
  115. rispecchiare il segno dei byte originali: per questo motivo abbiamo esteso
  116. il segno del byte alla word per fare la somma algebrica con ADD.W.
  117. Nella ruotine "MixSamples" abbiamo adottato un ulteriore particolare per
  118. incrementare la qualità e la precisione di mixing: l'ARROTONDAMENTO.
  119. Una volta fatta la somma, è necessario dividere per 2, affinchè i valori
  120. ritornino nel range di 8 bit con segno (* bisogna dividere tutti i valori per
  121. 2, non omettere quelli che sono compresi tra -128 e 127 anche solo dopo aver
  122. fatto l'ADD: i campioni NON SAREBBERO PIU' PROPORZIONALI ! *); tale divisione
  123. viene eseguita velocemente dall'ASR, che shifta a destra (di 1, in questo caso)
  124. * MANTENENDO il segno a sinistra *: l'ultimo bit che esce da destra dal
  125. registro shiftato è contenuto nel flag X (eXtend) della CPU; ora quel bit
  126. è come una sorta di "valore oltre la virgola" che sprime l'approssimazione
  127. dell'"intero" contenuto nel registro: aggiungento il contenuto del flag X
  128. all'intero si arrotondano tutti i numeri originariamente dispari al numero
  129. succesivo. Per sempio: 17 + 6 = 23, 23 / 2 = 11.5 (=%x.1) = 12 (arrotondato);
  130. od ancora: 11 + 23 = 34, 34 / 2 = 17 (%x.0) = 17 (arrotondato).
  131.  
  132. N.B.:    avete notato che il volume (inteso come livello medio dei campioni)
  133.     del sample mixato è inferiore alla resa dei 2 sample letti
  134.     contemporaneamente ? Come mai ? La risposta alla prossima puntata...
  135.