home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / MISC / AUDIO.ZIP / PITCH.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-12-11  |  11.8 KB  |  365 lines

  1. *
  2. *
  3. *   PITCH.ASM - pitch change effect for TI DSK module.
  4. *
  5. *
  6.  
  7. *
  8. *   Knobs - adjust these values within suggested range for
  9. *           variations on the effect.
  10. *
  11. *   SWEEP_STEP and UP are set according to the following tables:
  12. *
  13. *   Semitones   Up (UP=1)   Down (UP=0)
  14. *       1       1948        -1839
  15. *       2       4012        -3575
  16. *       3       6199        -5213
  17. *       4       8517        -6760
  18. *       5       10972       -8219
  19. *       6       13572       -9597
  20. *       7       16328       -10897
  21. *       8       19247       -12125
  22. *       9       22340       -13284
  23. *       10      25617       -14377
  24. *       11      29089       -15409
  25. *       12      32767       -16384
  26. *
  27. *     Cents     Up (UP=1)   Down (UP=0)
  28. *       2       37          -37
  29. *       4       75          -75
  30. *       6       113         -113
  31. *       8       151         -151
  32. *       10      189         -188
  33. *       12      227         -226
  34. *       14      266         -263
  35. *       16      304         -301
  36. *       18      342         -338
  37. *       20      380         -376
  38. *
  39. SWEEP_STEP      .set    16328   ; (sets amnt of pitch change, see above tables)
  40. UP              .set    1       ; (0 = down, 1 = up)
  41. MIX             .set    1       ; (0 = no dry, 1 = mix dry signal in)
  42.  
  43. *
  44. *   Misc. defines
  45. *
  46. BUF             .set    0420h   ; main circular buffer start, middle, and end
  47. BUF+1           .set    0421h
  48. BUFMID          .set    0500h
  49. BUFMID+1        .set    0501h
  50. BUFEND          .set    0800h
  51. BSZ             .set    03e0h   ; total buffer size
  52. XFADE           .set    508     ; # of samples in crossfade zone
  53. XMAJOR          .set    91      ; fast part of crossfade
  54. XMINOR          .set    38      ; slow part of crossfade
  55. *
  56. * Another faster crossfade option, sounds better for certain things
  57. * XFADE         .set    128     ; # of samples in crossfade zone
  58. * XMAJOR        .set    362     ; fast part of crossfade
  59. * XMINOR        .set    150     ; slow part of crossfade
  60. *
  61.  
  62. *
  63. *   Data storage
  64. *
  65. SWEEPCNT        .set    00h ; primary interp factor
  66. SWEEPCOMP       .set    01h ; complement of interp factor
  67. STEP            .set    02h ; inc/dec value for sweepcnt
  68. TMP             .set    03h ; temporary storage reg
  69. INPVAL          .set    04h ; input value
  70. OUTVAL          .set    05h ; output value
  71. BLENDA          .set    06h ; blend for delay A
  72. BLENDB          .set    07h ; blend for delay B
  73. BL_STEPA        .set    08h ; blend step A
  74. BL_STEPB        .set    09h ; blend step B
  75. ACTIVE_FLG      .set    0ah ; active delay channel, 0=delay A, 1=delay B
  76. SWEEP           .set    0bh ; active sweep length
  77.  
  78.         .include "setup.asm"
  79.         
  80. *
  81. *                               main
  82. *
  83. main:
  84.         ssxm                    ; set sign extension mode
  85.         spm     1               ; set P shift for Q15 (1 bit left shift
  86.                                 ; from P => accum)
  87.         ldpk    8
  88.         lrlk    AR0,BUFEND      ; permanently point to end of mem buf
  89.         lrlk    AR1,BUF         ; write ptr, point to start of mem buf
  90.         lrlk    AR2,BUF+1       ; delay A 1st read ptr
  91.         lrlk    AR3,BUF         ; delay A 2nd read ptr
  92.         lrlk    AR4,BUFMID+1    ; delay B 1st read ptr
  93.         lrlk    AR5,BUFMID      ; delay B 2nd read ptr
  94.         lalk    04000h          ; half most positive value
  95.         sacl    SWEEPCNT        ; set initial fractional sweep to midrange val
  96.         lalk    07fffh          ; initial blend value for A
  97.         sacl    BLENDA
  98.         lack    0               ; initial blend value for B
  99.         sacl    BLENDB
  100.         lalk    XMINOR          ; initial xfade rate for A
  101.         sacl    BL_STEPA
  102.         lalk    XMAJOR          ; initial xfade rate for B
  103.         neg
  104.         sacl    BL_STEPB
  105.         ; set amount of pitch change
  106.         lalk    SWEEP_STEP      ; install sweep rate
  107.         sacl    STEP
  108.         abs
  109.         sacl    TMP
  110.         ;  usable portion of sweep before crossfade
  111.         lt      TMP             ; |step| * xfade
  112.         mpyk    XFADE
  113.         pac
  114.         neg
  115.         sach    TMP
  116.         lalk    BSZ             ; subtract from buffer size
  117.         add     TMP
  118.         subk    2               ; just to be sure
  119.         sacl    SWEEP           ; this is main sweep length counter value
  120.         lar     AR6,SWEEP       ; load xfade trigger counter
  121.         lark    AR7,0           ; this counter is inactive until loaded
  122.         lack    0
  123.         sacl    ACTIVE_FLG      ; show delay A active first
  124.         lack    014h            ; enable AIC recv interrupts
  125.         ldpk    0
  126.         sacl    IMR
  127.         ldpk    8
  128.  
  129.         ; loop here forever processing interrupts
  130. loop:   idle
  131.         b       loop
  132.  
  133. *
  134. *                               rint
  135. *
  136. *   Recv interrupt handler performs all the work. Since there is
  137. *   no main thread, there is no need to save or restore regs.
  138. *   We can assume:
  139. *
  140. *   AR0 - points to end of buffer
  141. *   AR1 - current write ptr
  142. *   AR2 - delay A 1st read ptr
  143. *   AR3 - delay A 2nd read ptr
  144. *   AR4 - delay B 1st read ptr
  145. *   AR5 - delay B 2nd read ptr
  146. *   AR6 - sign counter (indicates when to swap blend signs and reload)
  147. *   AR7 - size counter (indicates when to swap blend step sizes)
  148. *
  149. rint:
  150.         ; note: no need to save/restore processor state since
  151.         ; main thread does absolutely nothing
  152.  
  153.         sovm                    ; set clipping overflow mode for the
  154.                                 ; "analog" processing
  155.         ldpk    0                                       
  156.         lac     DRR             ; read in new input value
  157.         ldpk    8
  158.         sfr                     ; dump 1 junk bit
  159.  .if    MIX
  160.         sacl    INPVAL          ; temporary storage
  161.  .endif
  162.         larp    AR1             ; use store ptr AR1
  163.         sacl    *+              ; store to circular buffer
  164.         cmpr    0
  165.         bbz     nowrap1,*,AR2
  166.         lrlk    AR1,BUF
  167. nowrap1:
  168.  
  169.         ; interpolate A ouput value from the delay A read ptrs
  170.         lalk    32767           ; develop complement of fractional
  171.         sub     SWEEPCNT        ; sweep position
  172.         sacl    SWEEPCOMP
  173.         lt      SWEEPCNT        ; get fractional sweep position
  174.         mpy     *,AR3           ; scale 1st read value
  175.         ltp     SWEEPCOMP
  176.         mpy     *,AR4           ; scale 2nd read value
  177.         apac
  178.         sach    TMP
  179.         ; apply crossfade factor to A
  180.         lt      BLENDA
  181.         mpy     TMP
  182.         sph     TMP             ; keep xfaded A val handy
  183.         
  184.         ; interpolate B output value from the delay B read ptrs
  185.         lt      SWEEPCNT
  186.         mpy     *,AR5           ; scale 1st read value
  187.         ltp     SWEEPCOMP
  188.         mpy     *,AR2           ; scale 2nd read value
  189.         apac
  190.         sach    OUTVAL
  191.         ; apply crossfade factor to B
  192.         lt      BLENDB
  193.         mpy     OUTVAL
  194.         pac
  195.         addh    TMP             ; bring in A value
  196.  .if    MIX
  197.         addh    INPVAL
  198.  .endif
  199.         sach    OUTVAL          ; this will be our "wet" output value
  200.         lac     OUTVAL          ; prepare final output for AIC
  201.         andk    0fffch          ; clear lowest 2 bits
  202.         ldpk    0
  203.         sacl    DXR             ; do output
  204.         ldpk    8
  205.                         
  206.         ; adjust crossfade blend
  207.         zac
  208.         addh    BLENDA          ; adjust A crossfade blend
  209.         addh    BL_STEPA
  210.         bgez    not_neg1        ; clamp at zero
  211.         zac
  212. not_neg1:
  213.         sach    BLENDA
  214.         zac
  215.         addh    BLENDB          ; adjust B crossface blend
  216.         addh    BL_STEPB
  217.         bgez    not_neg2,*,AR7  ; clamp at zero
  218.         zac
  219. not_neg2:
  220.         sach    BLENDB
  221.         ; see if size of crossfade steps need changing
  222.         banz    chk_ar7,*       ; if AR7 == 0, don't decrement (idle)
  223.         b       do_sweep,*
  224. chk_ar7:
  225.         mar     *-              ; dec AR7
  226.         banz    do_sweep,*
  227.         lac     BL_STEPA        ; simply exchange A and B
  228.         sacl    TMP
  229.         lac     BL_STEPB
  230.         neg                     ; but swapping signs to preserve direction
  231.         sacl    BL_STEPA
  232.         lac     TMP
  233.         neg
  234.         sacl    BL_STEPB
  235.         
  236.         ;
  237.         ; now update our sweep stuff
  238.         ;
  239. do_sweep:
  240.         rovm                    ; normal overflow operation for arithmetic
  241.         bv      next,*,AR2
  242. next:
  243.         
  244.  .if UP     
  245.         ;
  246.         ; UPWARD SWEEP (delay decreasing, pitch goes up)
  247.         ;
  248.         ; always move forward at least one notch
  249.         call    inc_delay_ptrs
  250.         
  251.         ; now update fractional delay
  252.         zac                     ; clear accum
  253.         addh    SWEEPCNT        ; use high accum for calc
  254.         addh    STEP
  255.         sach    SWEEPCNT
  256.         bnv     done,*,AR2      ; fractional part didn't overflow,
  257.                                 ; no need to advance sweep further
  258.                                     
  259.         ; fractional portion overflowed, adjust sweeps A & B forward
  260.         call    inc_delay_ptrs
  261.         lac     SWEEPCNT        ; mask off sign stuff from overflow
  262.         andk    07fffh
  263.         sacl    SWEEPCNT
  264.         
  265.  .else
  266.         ;
  267.         ; DOWNWARD SWEEP (delay increasing, pitch goes down)
  268.         ;
  269.         ; see if we need to update pointers
  270.         lac     SWEEPCNT
  271.         add     STEP            ; step is negative here so we're actually
  272.         sacl    SWEEPCNT        ; subtracting
  273.         blz     underflow,*,AR2 ; cnt went less than zero, skip ptr advance
  274.         
  275.         ; no underflow, advance ptrs but skip rest of sweep updates
  276.         call    inc_delay_ptrs
  277.         b       done,*
  278.         
  279.         ; fractional portion underflowed, update sweep stuff
  280. underflow:
  281.         lac     SWEEPCNT        ; mask off sign stuff from underflow
  282.         andk    07fffh
  283.         sacl    SWEEPCNT
  284.  .endif
  285.         
  286.         ; see if signs of crossfade steps need changing
  287.         larp    AR6
  288.         mar     *-              ; dec AR6
  289.         banz    done,*
  290.         lar     AR6,SWEEP       ; counter expired, reload
  291.         lac     BL_STEPA        ; swap signs
  292.         neg
  293.         sacl    BL_STEPA
  294.         lac     BL_STEPB
  295.         neg
  296.         sacl    BL_STEPB
  297.         ; load halfway crossfade counter
  298.         lalk    XFADE
  299.         sfr
  300.         sacl    TMP
  301.         lrlk    AR7,TMP
  302.         ; reset idle delay channel to beginning of sweep by grabbing store ptr
  303.         sar     AR1,TMP         ; stash store ptr in TMP
  304.         lac     ACTIVE_FLG      ; see which channel needs restart
  305.         bz      reset_B         ; A has been active, go reload B
  306.         ; reload delay channel A
  307.         lar     AR2,TMP
  308.         lack    0
  309.         sacl    ACTIVE_FLG      ; indicate A going active
  310.         b       done,*
  311. reset_B:
  312.         ; reload delay channel B
  313.         lar     AR4,TMP
  314.         lack    1
  315.         sacl    ACTIVE_FLG      ; indicate B going active
  316.  
  317.         ;
  318.         ; DONE
  319.         ;
  320. done:
  321.         eint
  322.         ret
  323.  
  324.  
  325. *
  326. *                               inc_delay_ptrs
  327. *
  328. *   Increment the both read ptrs for both delays A and B.
  329. *   Must always be called with arp=>AR2.
  330. *
  331. inc_delay_ptrs:
  332.         sar     AR2,TMP         ; copy AR2 to AR3
  333.         lar     AR3,TMP
  334.         mar     *+              ; inc AR2
  335.         cmpr    0               ; end of buffer?
  336.         bbz     nowrap2,*,AR4
  337.         lrlk    AR2,BUF         ; reload AR2
  338. nowrap2:
  339.         sar     AR4,TMP         ; copy AR4 to AR5
  340.         lar     AR5,TMP
  341.         mar     *+              ; inc AR4
  342.         cmpr    0               ; end of buffer?
  343.         bbz     nowrap3,*
  344.         lrlk    AR4,BUF         ; reload AR4
  345. nowrap3:
  346.         ret     
  347.  
  348. *
  349. *                               tint
  350. *
  351. *   Timer interrupt - not used.
  352. *
  353. tint:
  354.         eint
  355.         ret
  356.  
  357. *
  358. *                               xint
  359. *
  360. *   AIC xmit interrupt - not used.
  361. *       
  362. xint:
  363.         eint
  364.         ret
  365.