| Author |
Message |
Low Note

Joined: Jul 20, 2007 Posts: 146 Location: New Jersey
Audio files: 2
|
Posted: Sat Aug 02, 2008 7:48 pm Post subject:
Re-diving into chuck Subject description: and causing multiple crashes |
 |
|
I jumped back into chuck this week. I reread all the basic documentation and fooled around with some of the tutorials.
I think I found the answer to my question when I first went into chuck, but I can't find it now.
I wanted to add Amplitude Modulation to a SinOsc. I found the answer to that pretty easily. I also wanted to feed that SinOsc a repeating pattern of pitches.
Now, both of these were set up in tutorials using infinite time loops. When I put the two back to back, it never got to the second loop because it was still computing the first one (infinitely).
I've been trying to nest the two, but I keep crashing MiniAudicle, so I don't get an opportunity to see the error message. Can someone show me how to sort out the code so that it'll work?
| Code: | SinOsc a => dac;
1=> float x;
[8, 0, 1, 4, 5, 9, 7, 13, 0, 6] @=> int mel[]; //creates the pattern of pitches
for (0=> int i; ; i++) //sets up the AM
{
Std.mtof (60+ mel[i%mel.cap()] ) => a.freq;
Std.rand2f (0.2, 1.5)::second => dur t;
t=> now;
while (true) //sets up the looped pitch sequence and random note lengths
{Mat.sin (x) => a.gain;
x+.04 => x;
1::ms => now;
}
} |
|
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Sat Aug 02, 2008 9:04 pm Post subject:
|
 |
|
Here's one modified version:
The main loop keeps doing the frequency adjustment for a.
But another function is created for updating a's gain.
We can do this easily to run another process, but as a shred.
| Code: | SinOsc a => dac;
1=> float x;
[8, 0, 1, 4, 5, 9, 7, 13, 0, 6] @=> int mel[]; //creates the pattern of pitches
// run Gain Adjust as a shred for updating a's gain
spork ~ GainAdjust();
for (0=> int i; ; i++) //sets up the AM
{
Std.mtof (60+ mel[i%mel.cap()] ) => a.freq;
Std.rand2f (0.2, 1.5)::second => dur t;
t => now;
}
fun void GainAdjust()
{
while(true)
{
Math.sin (x) => a.gain;
x+.04 => x;
1::ms => now;
}
} |
|
|
|
Back to top
|
|
 |
Low Note

Joined: Jul 20, 2007 Posts: 146 Location: New Jersey
Audio files: 2
|
Posted: Sun Aug 03, 2008 5:26 am Post subject:
|
 |
|
Is generally the best way feed multiple variables to a Unit Generator through different Shreds?
Right after I posted the question that idea popped into my head, but that was something I didn't do a whole lot of when I was first using chuck.
Edit:
Why can't I make both the melodic pattern and the AM functions and still have it run?
| Code: | SinOsc a => dac;
1=> float x;
[8, 0, 1, 4, 5, 9, 7, 13, 0, 6] @=> int mel[]; //creates the pattern of pitches
// run Gain Adjust as a shred for updating a's gain
spork ~ GainAdjust();
spork ~ Melody();
fun void Melody()
{
for (0=> int i; ; i++) //sets up the AM
{
Std.mtof (60+ mel[i%mel.cap()] ) => a.freq;
Std.rand2f (0.2, 1.5)::second => dur t;
t => now;
}
}
fun void GainAdjust()
{
while(true)
{
Math.sin (x) => a.gain;
x+.04 => x;
1::ms => now;
}
} |
|
|
|
Back to top
|
|
 |
Antimon
Joined: Jan 18, 2005 Posts: 4145 Location: Sweden
Audio files: 371
G2 patch files: 100
|
Posted: Sun Aug 03, 2008 9:31 am Post subject:
|
 |
|
As soon as the "main shred" is finished, i.e. the code in your ChucK program that isn't part of function or class definitions, the program ends regardless if you have sporked any shreds in your code. In your last example the finishing line is this:
To keep the program running, a common solution is to add an infinite loop with a wait inside at the end of the program, like this:
| Code: | while (true) {
1::week => now;
} |
In your case, you need to spork a separate shred for the Melody since that uses a different timing than GainAdjust (random intervals rather than a constant 1 millisecond). You could bring them together in the same shred (by having 1 ms intervals for the melody or doing some messy math with the wait intervals), but having separate shreds in this case is preferable, I think.
/Stefan _________________ Antimon's Window
@soundcloud @Flattr home - you can't explain music |
|
|
Back to top
|
|
 |
Low Note

Joined: Jul 20, 2007 Posts: 146 Location: New Jersey
Audio files: 2
|
Posted: Sun Aug 03, 2008 10:25 am Post subject:
|
 |
|
| A ha! Makes sense. Thank you. |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sun Aug 03, 2008 2:03 pm Post subject:
|
 |
|
| Antimon wrote: | | As soon as the "main shred" is finished, i.e. the code in your ChucK program that isn't part of function or class definitions, the program ends regardless if you have sporked any shreds in your code. |
Exactly. And not only that; if a shred exits for any reason then any other shreds sporked by it will exit as well.
I tend to simply use "day => now;" because "day" is quite short as a word so that's easy to write and I never run stuff for more then a day anyway. _________________ Kassen |
|
|
Back to top
|
|
 |
blue hell
Site Admin

Joined: Apr 03, 2004 Posts: 24119 Location: The Netherlands, Enschede
Audio files: 279
G2 patch files: 320
|
Posted: Sun Aug 03, 2008 2:07 pm Post subject:
|
 |
|
You cant use "eon => now" ?  _________________ Jan
also .. could someone please turn down the thermostat a bit.
 |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sun Aug 03, 2008 11:30 pm Post subject:
|
 |
|
No :¬)
ChucK only uses values for time and duration that can be exactly defined. A day (if we ignore leap-seconds) always has the same length. Months on the other hand vary and years can have 365 or 366 days.
If you want to get dramatic you can go;
| Code: | Event the_end;
the_end => now; |
This defines a event, then tells the shred to wait for it to be broadcasted or signalled but it never happens. Programming languages aren't that good at implementing spiritual concepts.... _________________ Kassen |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Tue Aug 05, 2008 3:25 am Post subject:
|
 |
|
Maybe we'll propose a new duration syntax: forever
forever => now; // hahhahahahahhah
- - -
The way we split another control system into another function for sporking,
is because we intend to apply a different timing for each one.
If we want to use only one timing for the control,
we can apply that altogether in the same loop.
example:
| Code: | SawOsc s => dac;
while(true)
{
if (maybe) Std.rand2(0, 24) + 40 => Std.mtof => s.freq;
if (maybe) Std.rand2f(0, 1) => s.gain;
Std.rand2(1, 40)::ms => now;
} |
but what we do is that each value we're controlling are controlled at a different timing mechanism,
so we split them and let them run together in paralel.
| Code: | SawOsc s => dac;
spork ~ UpdateFreq();
while(true)
{
if (maybe) Std.rand2f(0, 1) => s.gain;
Std.rand2(1, 40)::ms => now;
}
fun void UpdateFreq()
{
while(true)
{
if (maybe) Std.rand2(0, 24) + 40 => Std.mtof => s.freq;
100::ms => now;
}
} |
This recent one is similar to your example with our modifications.
| Code: | SawOsc s => dac;
spork ~ UpdateFreq();
while(true)
{
if (maybe) Std.rand2f(0, 1) => s.gain;
0 => s.phase;
Std.rand2(1, 40)::ms => now;
}
fun void UpdateFreq()
{
while(true)
{
if (maybe) Std.rand2(0, 24) + 40 => Std.mtof => s.freq;
100::ms => now;
}
} |
Here, notice that I wanted to reset s's phase to 0 everytime the amplitude is set,
so, I add it to the same loop as the one controlling the amplitude because I wanted to use a similar timing mechanism to it.
| Code: | SawOsc s => dac;
SinOsc lfo => blackhole;
2 => lfo.freq;
spork ~ Update();
while(true)
{
if (maybe) Std.rand2f(0, 1) => s.gain;
Std.rand2(1, 40)::ms => now;
}
fun void Update()
{
int i;
int NoteNumber;
while(true)
{
if (i % 200 == 0) Std.rand2(0, 24) + 40 => NoteNumber;
NoteNumber + lfo.last() => Std.mtof => s.freq;
1::ms => now;
i++;
}
} |
Now, this Update thing does update some more features,
It updates a new random NoteNumber every 200::ms (by counting i every 1::ms and do the frequency update every time i % 200 == 0).
But every 1::ms, it also perform the update of the frequency by adding lfo's last value to note number before assigning to s's freq also.
With this kind of thing, you can update many things altogether in one update function. |
|
|
Back to top
|
|
 |
Low Note

Joined: Jul 20, 2007 Posts: 146 Location: New Jersey
Audio files: 2
|
Posted: Tue Aug 05, 2008 6:51 am Post subject:
|
 |
|
It seems like If statements could be used to update/reset a variety of variables if they're all within some sort of infinity loop.
This is unrelated, but in your last example does the LFO's last sample get treated as MIDI or a Frequency? |
|
|
Back to top
|
|
 |
kijjaz

Joined: Sep 20, 2004 Posts: 765 Location: bangkok, thailand
Audio files: 4
|
Posted: Tue Aug 05, 2008 12:44 pm Post subject:
|
 |
|
(1) integer + float produces a float result.
(2) NoteNumber is an int, Any UGen's .last() returns a float, so NoteNumber + lfo.last() in the above example produces float.
(3) Std.mtof converts midi value to frequency but... one thing is that we can use float value as Std.mtof's argument.
for example, 60.5 is a note exactly between middle C and Db
so.. that lfo.last() is added to the note value,
and it will make the note swing from -1 semitone to +1 semitone of the selected note.
so if I say, that lfo.last() is treated as midi note value.
(added to the selected note to create a vibrato-like effect). |
|
|
Back to top
|
|
 |
Kassen
Janitor


Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Tue Aug 05, 2008 1:45 pm Post subject:
|
 |
|
| kijjaz wrote: | Maybe we'll propose a new duration syntax: forever
forever => now; // hahhahahahahhah
|
I think I'd stick to
day => now;
for my own ChucKing that amounts to the same thing and it's shorter.
What we could do is take the Towers of Hanoi thing with 64 disks and make a estimate of how long it would take the monks to move a granite disk, advancing time by that amount for every step (perhaps as a function of the disk's size).
According to the legend the world will end when they are done. Even for a single second per disk movement this amounts to "really long indeed". _________________ Kassen |
|
|
Back to top
|
|
 |
|