<br><br><div class="gmail_quote">2008/5/22 AlgoMantra &lt;<a href="mailto:algomantra@gmail.com">algomantra@gmail.com</a>&gt;:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="Ih2E3d"><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">I&#39;m not 100% sure I understand the concept of<br>

granular synthesis, and I can&#39;t afford a book right now, so I&#39;m asking<br>
if you guys got an example/demo of the technique which I could study<br>
(preferably in ChucK)?<br>
</blockquote></div><br></div>I would lurrrv an example in Chuck too! <br></blockquote><div><br>Ok, pasted below is a small ChucktudE in grains and blitsaw. First it synthesises a theme, then it uses grains to manipulate the theme..... Well, that was the plan. The result is more like &quot;first it synthesises a theme, then does stuff with it and a ending is bolted on because I got a bit bored with it and grains are hard to use on themes&quot;. :¬)<br>
<br>Still, it demonstrates a few nice tricks with grains and it&#39;s a start for exploration, I hope. I also strongly suspect that requesting and using voices from LiSa too quickly (a few hundred per second) will crash the whole VM. Badly. These crashes may also have been caused by some other factor, there are quite a few variables flying around, after all. Uses some tricks with time and timing which could be eductational and/or confusing.<br>
<br>==================================<br>//&quot;A night with LiSa&quot;, composed by Kassen<br>//permision granted to copy for fun and educational value<br></div></div>//No waranties, no refunds; mind your speakers and CPU<br>
//remixing and extending strongly encouraged<br>&lt;&lt;&lt;&quot;let&#39;s pretend we&#39;re Bach and base the theme on a name!&quot;, &quot;&quot;&gt;&gt;&gt;;
<br>float G, E;
<br>&nbsp;<br>43 =&gt; Std.mtof =&gt; G;
<br>52 =&gt; Std.mtof =&gt; E;
<br>&nbsp;<br>BlitSaw s =&gt; Gain amp =&gt; dac;
<br>.8=&gt; s.gain;
<br>&nbsp;<br>dac =&gt; LiSa l =&gt; dac;
<br>4::second =&gt; l.duration;
<br>1 =&gt; l.record;
<br>&nbsp;<br>3=&gt; s.harmonics;
<br>3 =&gt; amp.op;
<br>SinOsc lfo =&gt; amp;
<br>second =&gt; lfo.period;
<br>&nbsp;<br>&nbsp;<br>G =&gt; s.freq;
<br>second =&gt; now;
<br>&nbsp;<br>//use the LFO to cover up clicks in the sound
<br>.25::second =&gt; lfo.period;
<br>repeat(8)
<br>&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; s.harmonics() + 2 =&gt; s.harmonics;
<br>&nbsp;&nbsp;&nbsp; .125::second&nbsp; =&gt; now;
<br>&nbsp;&nbsp;&nbsp; }
<br>&nbsp;<br>&nbsp;<br>.5::second =&gt; lfo.period;
<br>&nbsp;<br>for (0 =&gt; int n; n&lt; 4; n++)
<br>&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; s.harmonics() -3&nbsp; =&gt; s.harmonics;
<br>&nbsp;&nbsp;&nbsp; if (n%2) G =&gt; s.freq;
<br>&nbsp;&nbsp;&nbsp; else E =&gt; s.freq;
<br>&nbsp;&nbsp;&nbsp; .25::second&nbsp; =&gt; now;
<br>&nbsp;&nbsp;&nbsp; }
<br>5 =&gt; s.harmonics;
<br>2::second =&gt; lfo.period;
<br>1::second =&gt; now;
<br>&nbsp;<br>//stop recording, disconect blitsaw
<br>0 =&gt; l.record;
<br>amp =&lt; dac;
<br>&nbsp;<br>&nbsp;<br>&nbsp;<br>&lt;&lt;&lt;&quot;Now we use simple granualtion to repeat the theme a octave down&quot;, &quot;&quot;&gt;&gt;&gt;;
<br>100 =&gt; int slices;
<br>(l.duration() / slices) / 2 =&gt; dur ramprate;
<br>l.rate(0, .5);
<br>l.rate(1, .5);
<br>for (0 =&gt; int n; n&lt;slices*2; n++)
<br>&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; //as one voice ramps up...
<br>&nbsp;&nbsp;&nbsp; l.rampUp(n%2, ramprate);
<br>&nbsp;&nbsp;&nbsp; l.playPos(n%2, 0.005 * n * l.duration() );
<br>&nbsp;&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp; //...the other goes down
<br>&nbsp;&nbsp;&nbsp; l.rampDown(!(n%2), ramprate);
<br>&nbsp;&nbsp;&nbsp; ramprate =&gt; now;
<br>&nbsp;&nbsp;&nbsp; }
<br>&nbsp;<br>&lt;&lt;&lt;&quot;again, a octave up&quot;, &quot;&quot;&gt;&gt;&gt;;
<br>&nbsp;<br>l.rate(0, 2);
<br>l.rate(1, 2);
<br>for (0 =&gt; int n; n&lt;slices*2; n++)
<br>&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; l.rampUp(n%2, ramprate);
<br>&nbsp;&nbsp;&nbsp; l.playPos(n%2, 0.005 * n * l.duration() );
<br>&nbsp;&nbsp;&nbsp; l.rampDown(!(n%2), ramprate);
<br>&nbsp;&nbsp;&nbsp; ramprate =&gt; now;
<br>&nbsp;&nbsp;&nbsp; }
<br>l.rampDown(!(slices%2), 20::ms);
<br>&nbsp;<br>&lt;&lt;&lt;&quot;random grains, decreasing density&quot;, &quot;&quot;&gt;&gt;&gt;;
<br>&nbsp;<br>now + 4::second =&gt; time later;
<br>l.rate(0, 1);
<br>l.rate(1, 1);
<br>&nbsp;<br>int free_voice;
<br>float time_past_ratio;
<br>second / G =&gt; dur loop_length;
<br>while (now &lt; later)
<br>&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; (later-now) / 4::second =&gt; time_past_ratio;
<br>&nbsp;&nbsp;&nbsp; //this goes from a chance of &quot;1&quot; to no chance at all over the cource of the note
<br>&nbsp;&nbsp;&nbsp; if ( Std.rand2f(0,1) &lt; time_past_ratio)&nbsp;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.getVoice() =&gt; free_voice;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.loopStart(free_voice, Std.rand2f(0, 1) * (l.duration() - loop_length));
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.playPos(free_voice, l.loopStart(free_voice) );
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.loopEnd(free_voice, l.loopStart(free_voice) + loop_length);&nbsp;&nbsp;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.rate(free_voice, Std.rand2(1, 2)/ Std.rand2(1, 2));
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.rampUp(free_voice, loop_length);
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop_length =&gt; now;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.rampDown(free_voice, 75::ms);
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop_length =&gt; now;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp; else 2::loop_length =&gt; now;
<br>&nbsp;&nbsp;&nbsp; }
<br>&nbsp;<br>//never mind this bit
<br>//it&#39;s just here to end &quot;properly&quot;
<br>l.getVoice() =&gt; free_voice;
<br>l.rate(free_voice, .5);
<br>l.loop(free_voice, 0);
<br>l.playPos(free_voice, 0::ms);
<br>l.play(free_voice, 1);
<br>&nbsp;<br>&lt;&lt;&lt;&quot;increase it again&quot;,&quot;&quot;&gt;&gt;&gt;;
<br>2::second / E =&gt; loop_length;
<br>now + 4::second =&gt; later;
<br>while (now &lt; later)
<br>&nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; (later-now) / 4::second =&gt; time_past_ratio;
<br>&nbsp;&nbsp;&nbsp; if ( Std.rand2f(0,1) &lt; 1-time_past_ratio)&nbsp;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.getVoice() =&gt; free_voice;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.loopStart(free_voice, Std.rand2f(0, 1) * (l.duration() - loop_length));
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.playPos(free_voice, l.loopStart(free_voice) );
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.loopEnd(free_voice, l.loopStart(free_voice) + loop_length);&nbsp;&nbsp;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.rate(free_voice, Std.rand2(1, 4)/ Std.rand2(1, 4));
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.rampUp(free_voice, loop_length);
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop_length =&gt; now;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; l.rampDown(free_voice, 75::ms);
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop_length =&gt; now;
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }
<br>&nbsp;&nbsp;&nbsp; else 2::loop_length =&gt; now;
<br>&nbsp;&nbsp;&nbsp; }
<br>&nbsp;<br>&lt;&lt;&lt;&quot;cheat because endings are hard&quot;, &quot;&quot;&gt;&gt;&gt;;
<br>&nbsp;<br>&nbsp;5::second =&gt; now;<br>====================================<br><br>Cheers,<br>Kas.<br>