;*************************************************************** ; ; Stereo chorus for the DSP56001 signal processor. ; Developed by Quinn Jensen ; ; This program fragment implements a stereo "chorus" effect ; on a DSP56001 processor. Chorus adds depth and warmth to ; sound by creating the illusion that more instruments ; are involved in the sound than really are. It does this by ; mixing together a delayed version of the input with the input ; itself. This program uses the following signal flow. ; ; ; Left in ------+------- "dry" gain -----------> sum -----> Left out ; | ^ ; v | ; sum --> delay ---> "wet" gain -----+ ; ^ | ; | v - ; Right in -----+------- "dry" gain -----------> sum -----> Right out ; ; ; Note that the delay line output is negated before summing with the ; right input signal. This throws in 180 degrees of phase shift ; making for interesting results even with mono inputs ; (i.e. Left in == Right in). ; ; Chorus uses a delay time of between about 10 and 50ms in some commercial ; units. This program can be configured for longer delays. ; In the chorus effect, the delay time is slowly varied, adding a very ; subtle pitch shift. The depth and speed of the delay-time modulation ; are adjustable to taste. The greater the depth or speed, the greater ; the coloration of the signal. ; ; Variations in this algorithm are possible and encouraged. I came ; up with this code after studying the impulse response and characteristics ; of a commercial stereo chorus pedal and reading various articles in magazines ; and on usenet over the years. My somewhat dry TX81 synthesizer sounds pretty ; good with this and other effects I run on the 56001. ; ; A recent article with a pretty good not-too-technical overview of chorus ; and other effects: Gary Hall, "From the Top: Effects, the Essential Musical ; Spice," _Electronic Musician_, August 1991, pp. 62-68. ; ; I would enjoy seeing any improvements to the code. ; include "tdsg.a56" ;hardware specific initialization code ;*************************************************************** ; ; Data and constants ; ;*************************************************************** P:0076 dot ;remember where we were in P-space X:0020 org x:$20 ;put runtime variables in on-chip X-space ; A spreadsheet was used to calculate the following numbers ; Sample rate 32.5500 kc ; ; Delay time (4-52) 28.0000 ms delay time knob ; Depth (1-10) 10.0000 depth knob (I like it deep) ; Speed (1-10) 0.0000 speed knob (I like it slow) ; ; max depth +/- 24.0000 ms ; min delay 4.0000 ms ; max delay 52.0000 ms ; 1/2 cycle period 5.0000 s ; samples per 1/2 cyc 162750.0000 ; time delta/samp 0.2949 us ; offset samp/samp 0.0096 ; FFFF7E doff_i equ -130 ;initial delay offset (tap) 0.0096 ddeltaf equ 0.0096 ;delta-delay, per sample 027BBE dspeed_i equ 162750 ;number of samples per ;half cycle of triangle wave ;delay-time modulator ; ; Delay time (ms) tap tap delay ; ; 1 32.5500 1 0.03 ; 2 65.1000 2 0.06 ; 4 130.2000 4 0.12 ; 5 162.7500 8 0.25 ; 8 260.4000 16 0.49 ; 10 325.5000 32 0.98 ; 20 651.0000 64 1.97 ; 25 813.7500 128 3.93 ; 40 1302.0000 256 7.86 ; 50 1627.5000 512 15.73 ; 60 1953.0000 1024 31.46 ; 70 2278.5000 2048 62.92 ; 80 2604.0000 4096 125.84 ; 90 2929.5000 8192 251.67 ; 100 3255.0000 16384 503.35 ; ; The delay line is in off-chip X memory ; 002000 delay equ $2000 001000 dmax equ 4096 ;125 ms (probably way too long) ; ; doff and ddelta are 48-bit quantities ; X:0020 FFFF7E doff dc doff_i ;current delay distance Y:0020 org y:doff Y:0020 000000 dc 0 X:0021 org x:doff+1 X:0021 000000 ddelta dc 0 ;delta delay per sample Y:0021 org y:ddelta Y:0021 013A93 dc ddeltaf X:0022 org x:ddelta+1 X:0022 027BBE dspeed dc dspeed_i ;samples per half cycle of triangle modulator X:0023 000000 dtoggle dc 0 ;current sample count X:0024 delayout X:0024 000000 dc 0 ;current delay-line output Y:0000 org y:$0 P:0076 org p:dot ;go back to P-space ;*************************************************************** ; ; Initialization code ; ;*************************************************************** P:0076 hf_init P:0076 61F400 move #delay,r1 ;delay line input P:0077 002000 P:0078 05F421 movec #dmax-1,m1 ; P:0079 000FFF P:007A 71F400 move #doff_i,n1 ;distance to output P:007B FFFF7E P:007C 00000C rts ; ;*************************************************************** ; ; Sample-rate computations. Call chorus_compute at ; interrupt time when both left and right inputs are ; ready. ; ; fs = 32.552083 kHz ; ; x:1,x0 P:00AA 000001 P:00AB 200044 sub x0,a P:00AC 562300 move a,x: