electro-music.com   Dedicated to experimental electro-acoustic
and electronic music
 
    Front Page  |  Radio
 |  Media  |  Forum  |  Wiki  |  Links
Forum with support of Syndicator RSS
 FAQFAQ   CalendarCalendar   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   LinksLinks
 RegisterRegister   ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in  Chat RoomChat Room 
 Forum index » DIY Hardware and Software » ChucK programming language
Re-diving into chuck
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [12 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
Low Note



Joined: Jul 20, 2007
Posts: 146
Location: New Jersey
Audio files: 2

PostPosted: Sat Aug 02, 2008 7:48 pm    Post subject: Re-diving into chuck
Subject description: and causing multiple crashes
Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Visit poster's website
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Sat Aug 02, 2008 9:04 pm    Post subject: Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Low Note



Joined: Jul 20, 2007
Posts: 146
Location: New Jersey
Audio files: 2

PostPosted: Sun Aug 03, 2008 5:26 am    Post subject: Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Visit poster's website
Antimon



Joined: Jan 18, 2005
Posts: 4145
Location: Sweden
Audio files: 371
G2 patch files: 100

PostPosted: Sun Aug 03, 2008 9:31 am    Post subject: Reply with quote  Mark this post and the followings unread

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:

Code:
spork ~ Melody();


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
View user's profile Send private message Visit poster's website
Low Note



Joined: Jul 20, 2007
Posts: 146
Location: New Jersey
Audio files: 2

PostPosted: Sun Aug 03, 2008 10:25 am    Post subject: Reply with quote  Mark this post and the followings unread

A ha! Makes sense. Thank you.
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Sun Aug 03, 2008 2:03 pm    Post subject: Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Send e-mail Visit poster's website
blue hell
Site Admin


Joined: Apr 03, 2004
Posts: 24119
Location: The Netherlands, Enschede
Audio files: 279
G2 patch files: 320

PostPosted: Sun Aug 03, 2008 2:07 pm    Post subject: Reply with quote  Mark this post and the followings unread

You cant use "eon => now" ? Wink
_________________
Jan
also .. could someone please turn down the thermostat a bit.
Posted Image, might have been reduced in size. Click Image to view fullscreen.
Back to top
View user's profile Send private message Visit poster's website
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Sun Aug 03, 2008 11:30 pm    Post subject: Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Send e-mail Visit poster's website
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Tue Aug 05, 2008 3:25 am    Post subject: Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Low Note



Joined: Jul 20, 2007
Posts: 146
Location: New Jersey
Audio files: 2

PostPosted: Tue Aug 05, 2008 6:51 am    Post subject: Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Visit poster's website
kijjaz



Joined: Sep 20, 2004
Posts: 765
Location: bangkok, thailand
Audio files: 4

PostPosted: Tue Aug 05, 2008 12:44 pm    Post subject: Reply with quote  Mark this post and the followings unread

(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
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Kassen
Janitor
Janitor


Joined: Jul 06, 2004
Posts: 7678
Location: The Hague, NL
G2 patch files: 3

PostPosted: Tue Aug 05, 2008 1:45 pm    Post subject: Reply with quote  Mark this post and the followings unread

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
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [12 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
 Forum index » DIY Hardware and Software » ChucK programming language
Jump to:  

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Forum with support of Syndicator RSS
Powered by phpBB © 2001, 2005 phpBB Group
Copyright © 2003 through 2009 by electro-music.com - Conditions Of Use