Hello All.
My name is Edward. I'm a synthesis buff from Melbourne.
I've been using Chuck for about a week now, and I'm really loving it. I haven't really learnt to use a sporking language before. I used to program in Borland Turbo C 2.0 back in the early 90s, and also did a lot of QuickBasic, but, I never really caught up to the modern age so to speak. I'm only 29, so I thought, there's no time to learn like now! I think I've got this all sporked off in a reasonably sensible way, but, I could probably do more. I am totally open to people sending me suggestions (on or off list). I'm not "precious" about my program in any way.
 
 I hope some of you get some use from this example. I don't think it is by any means "distro example" quality, but, I hope that with some work, and the addition of some more features not present in examples currently in distro, that one day it might be!
 
 I have tried looking around for a model for sympathetic strings, and have had no luck. If anyone has any advice, please advise.
 
best wishes to all;
-Edward r Jones
 
 
// Tambura-with-sporking.ck
//
// Tambura with Sporking
//
// by Edward r Jones (loscha@gmail.com)
//
// This is my emulation of an electronic tambura device.
// By Tambura, I mean the Indian classical instrument.
// A Tambura has 4 to 6 strings, which are plucked in a repeating pattern to accompany Indian classical music
// It has a resonating cavity, and resonant sympathetic strings, like a Sitar, but, no frets.
// Please Help! This Model Needs!
//
// = Sympathetic Strings. I've tried setting up a series of 8 delay lines
// tuned to the resonant frequencies I desire), but, they didn't give me the results I wanted at all.
// I am new to coding Physical Modelling, and if anyone has some advice on this matter I'd love to hear from you.
//
//   A Resonant Cavity.
//   I've goen with using LPF and HPF to limit the output frequency range to give the sort of timbre I want, but,
//   I know that this could be better acheived.
//
//   At the moment, it sounds more like a Koto.
//   I found the stk Sitar instrument to sound nothing like a Sitar or a Tambura,
//   Buuut, this is because of the reasons I listed above -- Sympathetic Strings & real Resonant Cavity.
//
// In closing, I want to thank:
// The ChucK community, I love this language (and you all!) so much,
// and I hope to be able to contribute to it's development in the future
// My wonderful partner, Michelle, who doesn't mind me staying up until 3am working on this stuff!
// All my local friends in synthesis; Bill Harrison aka James Earthenware, Paul Perry, Robin Whittle & Jaymz
//  \=> Clae, All the Melbourne Dorkbot community, and all the other hardcore synthesists in Melbourne, Victoria, Australia!
// All my online friends, Matrixsynth, Sealed, SynthDiy and all my LiveJournal Buddies.
// The Founding Fathers of this craft that I love so much. John Chowning, Max V Matthews, Steve Reich, Paul Lansky & Stockhausen,
//
// Enuff! On to the Code!



[  1,  0,  0,  1,  1,  0] @=> int beats[];  // 1 means play, 0 means skip
[ 00, 00, 00, 12, 09, 04] @=> int notes[];  // Note pitch, relative to noteoffset
30 => int noteoffset;     // this is the transpose, to make scales easier
float variance[beats.cap()];        // this is for randomization of string pitches to achieve "thickness"
                                    // They are calculated once at startup, to simulate real string tuning
.05  => float waver;                // range for variance in NOTES
72   => float tempo;

float click;
30000 / tempo => click;
<<<"Click length", click,"">>>;
int numsteps;
beats.cap() => numsteps;
LPF lpf;
HPF hpf;
JCRev jcrev;

2550 => lpf.freq;
300 => hpf.freq;
.05 => jcrev.mix;

StifKarp tambura[numsteps];
lpf => hpf => jcrev => dac;

        //------- Hook up all tamburas to the chain & set them up the way we want them.
        
        //    .pickupPosition - ( float , READ/WRITE ) - pickup position [0.0 - 1.0]
        //    .sustain - ( float , READ/WRITE ) - string sustain [ 0.0 - 1.0]
        //    .stretch - ( float , READ/WRITE ) - string stretch [0.0 - 1.0]
        //    .pluck - ( float , WRITE only ) - pluck string [0.0 - 1.0]
        //    .baseLoopGain - ( float , READ/WRITE ) - ?? [ 0.0 - 1.0]
        //    .clear - ( ) - reset instrument
        for (0 => int stab; stab < numsteps; stab++)
        {
            tambura[stab] => lpf;
            .03 => tambura[stab].pickupPosition;
            1 => tambura[stab].sustain;
            1 => tambura[stab].stretch;
            .99 => tambura[stab].baseLoopGain;
            Std.rand2f(1-waver, waver) => variance[stab];
            <<<"tambura #",stab,"hooked up","">>>;
        }
        //------ Hookups done.


<<<"pre-comparison","">>>;
if (beats.cap() == notes.cap())
    {
        
        
        <<<"Steps in our sequence", numsteps,"">>>;
        
        //------------------------------------ The Sequence Plays! ----------------------
        while (true)
            {
                for (0 => int stab; stab < numsteps; stab++)
                    {
                        if (beats[stab] == 1)
                        {
                            <<<"Stab",stab,"">>>;
                            tampluck (stab);
                            
                        }
                      click * 1::ms => now;
                    }
            }
        //------------------------------------ The Sequence (never) Ends! ----------------------

        <<<"End of Playing!","">>>;
    }
//------------------------------------------------------------------------
// Error, stop the program
else
    {
       <<<"ERROR IN SEQUENCER DATA", "";>>>;
       <<<"Item count mismatch","">>>;
    }
    
//-------------------------------------------------------------------------
//  This is the sporkage for our note playing.
fun void tampluck (int step)
{
    float npitch;
    variance[step] + noteoffset + notes[step] => Std.mtof => npitch;
    npitch => tambura[step].freq;
    <<<"Pitch",npitch,"">>>;
    1 => tambura[step].pluck;    
}

--
www.loscha.com/chuck