.module SNYTH; {------------------------------------------------------------------------ SNYTH v1.0 by Xjn (Christian Oncken) www.urbanjazznaturals.com/xjn www.mp3.com/xjn www.booyaka.com/~oncken Snyth is a wierd synth dreamed up by me. It uses 2 short delay lines. A pulse is injected into each delay line at CP1 or CP2, and the lines loop when they reach the length needed for the target frequency. CP3 is a feedback tap into both the delay lines, and their outputs cross into one another at that tap. The filter is Noah's SVF with my Q and band modifications. ----------------------------------------------------------------------- My own request: Please credit the EZKITDEV collective if you release music or write software based on this code... ----------------------------------------------------------------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License long with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------} .include <..\template\system.k>; .include <..\template\midi.k>; .include <..\template\setup.dsp>; .global handle_MIDI_controller; .global newsound; .global killsound; { signal processing variables here } .var K2,K3,K4; .init K2:0x3fff; .init K3:0x1000; .init K4:0x1000; .var low,band,high,notch; .init low:0; .init band:0; .init high:0; .init notch:0; .var input; .var outputs[4]; .var outband; .init outband: 1; { internal variables } .var last_input; .var last_outputL; .var last_outputR; .init last_outputL:0; .init last_outputR:0; { parameters here } .var/dm CP1; {Control point 1} .var/dm CP2; {Control point 2} .var/dm CP3; {Control point 3} .var/dm CP4; {uhhhh... } .var/dm CP5; {uhhhh... } .var/dm CP6; {uhhhh... } .var/dm CP7; {uhhhh... } .var/dm/circ tube1[2000]; {buffer 1} .var/dm/circ tube2[2000]; {buffer 2} .var/dm freq; .var/dm freqTab[84]; { do any dynamic memory/variable initializing you need to here } init_params: .init freqTab:; i0 = ^freqTab; L0 = 0; m0 = 0; i2 = ^tube1; L2 = %tube1; m2 = 1; i3 = ^tube2; L3 = %tube2; m3 = 1; ax0 = 200; dm(CP1) = ax0; ax0 = 100; dm(CP2) = ax0; ax0 = 500; dm(CP3) = ax0; ax0 = 0x8000; dm(CP4) = ax0; ax0 = 0x8000; dm(CP5) = ax0; ax0 = 0x8000; dm(CP6) = ax0; ax0 = 0x8000; dm(CP7) = ax0; nop; nop; nop; rts; { command loop - check for incoming data on serial port } main_loop: ar = dm (CHAR_WAITING_FLAG); { check serial port for MIDI data } none = pass ar; if ne jump main_loop; call process_midi; { if MIDI byte received } jump main_loop; { SPORT0 interrupt handler -- this is called at 44.1KHz } input_samples: ena sec_reg; { use shadow register bank } my0 = dm(rx_buf +1); { read a/d converters } my1 = dm(rx_buf +2); { leave left/right values in my0,my1 } {----------------------SNYTH------------------------} {-------generate periodic impulses} m0 = 0; {TUBE1---------------------------------------} ax0 = i2; ay0 = ^tube1; ar = ax0 - ay0; {subtract current i2 from start of tube1} ax0 = ar; {to get the current index into the buffer??} ay0 = dm(freq); af = ax0 - ay0; if ne jump loop1; {start over if index > freq} i2 = ^tube1; loop1: ay0 = dm(CP1); {get control points} af = ax0 - ay0; if ne jump nope1; {if its equal to the current value of the} {buffer index, then generate a pulse here} ax0 = dm(CP6); {0x8000;} dm(i2, m0) = ax0; nope1: {TUBE2-----------------------------------} ax0 = i3; ay0 = ^tube2; ar = ax0 - ay0; {subtract current i3 from start of tube2} ax0 = ar; {to get current index into tube2??} ay0 = dm(freq); af = ax0 - ay0; if ne jump loop2; {start over if index > freq} i3 = ^tube2; loop2: ay0 = dm(CP2); af = ax0 - ay0; if ne jump nope2; {if its equal to the current value of the} {buffer index, then generate a pulse here} ax0 = dm(CP7); {0x8000;} dm(i3, m0) = ax0; nope2: {-------FEEDBACK TAP AT CP3} mx0 = dm(i2, m0); {read buffer} my0 = dm(CP4);{0x8000; } mr = mx0 * my0 (rnd); {attenuate} ax0 = dm(CP3); {set up to skip forward} ay1 = 0; {and back} ar = ay1 - ax0; m0 = ar; modify(i3, m0); {skip ahead by CP3} m0 = ax0; dm(i3, m0) = mr1; {write and skip back} mx0 = dm(i3, m0); {read buffer} my0 = dm(CP5);{0x8000; } mr = mx0 * my0 (rnd); {attenuate} ax0 = dm(CP3); {set up to skip forward} ay1 = 0; {and back} ar = ay1 - ax0; m0 = ar; modify(i2, m0); {skip ahead by CP3} m0 = ax0; dm(i2, m0) = mr1; {write and skip back} m0 = 1; {reset increment} ax0 = dm(i2, m0); ay0 = dm(i3, m0); ar = ax0 + ay0; {mix} my0 = ar; {output} dm(input)=my0; call filter; i1 = ^outputs; m1 = dm(outband); mx0 = dm(i1, m1); mx0 = dm(i1, m1); my0 = mx0; my1 = mx0; {--------------------------------END------------------------------------} dm(tx_buf+ 1)=my0; { write d/a converters } dm(tx_buf+ 2)=my1; { write left/right values from my0, my1 } { save output value (for possible feedback) } dm(last_outputL)=mr0; dm(last_outputR)=mr1; thatwasfun: rti; filter: { $H=$input - $K2*$B + $L; } { dm(high)=dm(input) - dm(K2) * dm(band) + dm(low); } mr = 0; mr1 = dm(input); { input } mx0 = dm(K2); my0 = dm(band); mr = mr - mx0*my0(ss); { + K2 * band } if mv sat mr; mx0 = 0x7fff; my0 = dm(low); mr = mr + mx0*my0(ss); { + low } if mv sat mr; dm(high) = mr1; dm(outputs) = mr1; { $B= $B + $K3*$H; } { dm(band)= dm(band) + dm(K3*dm(high); } mr = 0; mr1 = dm(band); { band } mx0 = dm(K3); my0 = dm(high); mr = mr + mx0*my0(ss); { + K3 * high } if mv sat mr; dm(band) = mr1; dm(outputs +2) = mr1; { $L= $L - $K4*$B; } { dm(low)= dm(low) - dm(K4)*dm(band); } mr = 0; mx0 = dm(K4); mr1 = dm(low); { low } my0 = dm(band); mr = mr - mx0*my0(ss); if mv sat mr; dm(low) = mr1; dm(outputs +1) = mr1; { $N=($H+$L)/2; } { dm(notch)=(dm(high)+dm(low))/2; } my0 = dm(high); my1 = dm(low); mx0 = 0x3fff; mr = mx0*my0(ss); mr = mr + mx0*my1(ss); dm(notch) = mr1; dm(outputs +3) = mr1; rts; { Use MIDI note number.....euh ---------------------------- } newsound: ax1 = dm(midi_ch); i0 = ^freqTab; {ok... get the frequency of the note } L0 = 0; ay0 = 83; m0 = ay0; ar = ay0 - ax0; if lt jump toohigh; m0 = ax0; toohigh: modify(i0, m0); m0 = 0; ax1 = dm(i0, m0); dm(freq) = ax1; {store it in freq} {zero out the buffers} {naaaaahh...} m1 = 1; cntr = L2; do zero1 until ce; zero1: dm(i2, m1) = 0; cntr = L3; do zero2 until ce; zero2: dm(i3, m1) = 0; rts; { remove a sound from the sound queue ---------------------------------- } killsound: rts; { Here is where MIDI messages are used to set variables in your Effect! } handle_MIDI_controller: ax1 = dm(midi_cont); ar = dm(midi_val); ay1 = 1;none = ax1-ay1;if eq jump set_CP1; ay1 = 2;none = ax1-ay1;if eq jump set_CP2; ay1 = 3;none = ax1-ay1;if eq jump set_CP3; ay1 = 4;none = ax1-ay1;if eq jump set_freq; ay1 = 5;none = ax1-ay1;if eq jump set_res; ay1 = 6;none = ax1-ay1;if eq jump set_band; { ay1 = 7;none = ax1-ay1;if eq jump set_CP7; } rts; set_CP1: ar = dm(midi_val); dm(CP1) = ar; rts; set_CP2: ar = dm(midi_val); dm(CP2) = ar; rts; set_CP3: ar = dm(midi_val); sr = lshift ar by 3 (hi); dm(CP3) = ar; rts; set_CP4: ax0 = dm(midi_val); ay0 = 64; ar = ax0 -ay0; mx1 = 0x0200; my1 = ar; mr = mx1 * my1 (RND); dm(CP4) = mr1; rts; set_CP5: ax0 = dm(midi_val); ay0 = 64; ar = ax0 -ay0; mx1 = 0x0200; my1 = ar; mr = mx1 * my1 (RND); dm(CP5) = mr1; rts; set_CP6: ax0 = dm(midi_val); ay0 = 64; ar = ax0 -ay0; mx1 = 0x0200; my1 = ar; mr = mx1 * my1 (RND); dm(CP6) = mr1; rts; set_CP7: ax0 = dm(midi_val); ay0 = 64; ar = ax0 -ay0; mx1 = 0x0200; my1 = ar; mr = mx1 * my1 (RND); dm(CP7) = mr1; rts; set_freq: ar = dm(midi_val); sr = lshift ar by 8(lo); ar = sr0 or ay1; dm(K3) = ar; dm(K4) = ar; rts; set_res: ar = dm(midi_val); sr = lshift ar by 7(lo); ar = sr0 or ay1; dm(K2) = ar; rts; set_band: ar = dm(midi_val); sr = lshift ar by -5(lo); dm(outband) = sr0; rts; .endmod;