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.
//
// 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", "";>>>;