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
My first ChucK
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [11 Posts]
View unread posts
View new posts in the last week
Mark the topic unread :: View previous topic :: View next topic
Author Message
Underwaterbob



Joined: Sep 03, 2008
Posts: 26
Location: Chungju, South Korea

PostPosted: Fri Sep 05, 2008 7:27 am    Post subject: My first ChucK
Subject description: help and/or comments please
Reply with quote  Mark this post and the followings unread

I found out about this forum and consequently ChucK yesterday.

ChucK seems pretty awesome so I downloaded it this afternoon. This is my first, fairly basic attempt at making something interesting.

Quote:

SinOsc s1 => dac; [ 100, 200, 300, 400, 500, 600 ] @=> int foo1[];
SinOsc s2 => dac; [ 125, 250, 375, 500, 625, 750 ] @=> int foo2[];
SinOsc s3 => dac; [ 150, 300, 450, 600, 750, 900 ] @=> int foo3[];
while ( true ) {
44100 => int time1;
44200 => int time2;
44300 => int time3;
Math.rand2f(1, 6) $ int => int note1;
.3 => s1.gain;
Math.rand2f(1, 6) $ int => int note2;
.3 => s2.gain;
Math.rand2f(1, 6) $ int => int note3;
.3 => s3.gain;
foo3[note3] => s3.freq;
time3::samp => now;
foo2[note2] => s2.freq;
time2::samp => now;
foo1[note1] => s1.freq;
time1::samp => now;
}


Three different waves slightly out of sync with each other so they change to specific random notes in three made up harmonic series. With a difference of 100 samples per duration they slowly phase in and out with each other changing pitch at regular, slightly different intervals. That was my goal anyway. It almost sounds right, but I'm not entirely clear on how the timing works yet.

It's kind of soothing except for when it hits some nasty dissonance now and again.

Any comments or hints on optimizing my code or how to make all three Ugens start on random notes at the same time?
Back to top
View user's profile Send private message
kijjaz



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

PostPosted: Fri Sep 05, 2008 8:56 am    Post subject: Reply with quote  Mark this post and the followings unread

some suggestions on something we can do to the code:

(1)
Math.rand2f(1, 6) $ int
is nice, ..
but actually we can calculate random integer the same way:

Math.rand2(1, 5)

this will generate ramdom integer in the range 1 to 5

(2)
44100 <-- you might refer to the number of sample in one second if the sample rate is 44100
but if you'd like to refer to "second" you can do this with this patch:

second => dur time1;
second + 100::samp => dur time2;
second + 200::samp => dur time3;

.. etc ..

time1 => now;
time2 => now;
time3 => now;

(3) but this can't simultenously automate 3 oscillators independently because
the control of it is in one loop.
if you want the control of each oscillator independent of each one's time,
you might wanna check out "function" and "sporking"

sporking can run a function as a new shred in ChucK virtual machine.
let me do the adjustment to your code to demonstrate.

Code:
SinOsc s1 => dac; [ 100, 200, 300, 400, 500, 600 ] @=> int foo1[];
SinOsc s2 => dac; [ 125, 250, 375, 500, 625, 750 ] @=> int foo2[];
SinOsc s3 => dac; [ 150, 300, 450, 600, 750, 900 ] @=> int foo3[];
44100 => int time1;
44200 => int time2;
44300 => int time3;

.3 => s1.gain;
.3 => s2.gain;
.3 => s3.gain;

spork ~ UpdateS1();
spork ~ UpdateS2();
spork ~ UpdateS3();

while (true) day => now; // wait forever

fun void UpdateS1()
{
    int note1;
    while(true)
    {
        Math.rand2f(1, 6) $ int => note1;
        foo1[note1] => s1.freq;
        time1::samp => now;
    }
}   
fun void UpdateS2()
{
    int note2;
    while(true)
    {       
        Math.rand2f(1, 6) $ int => note2;
        foo2[note2] => s2.freq;
        time2::samp => now;
    }
}   
fun void UpdateS3()
{
    int note3;
    while(true)
    {       
        Math.rand2f(1, 6) $ int => note3;
        foo3[note3] => s3.freq;
        time3::samp => now;
    }


but you see there're some duplications in code,
we can make those update functions better by making it more flexible for all cases.

Code:
SinOsc s1 => dac; [ 100, 200, 300, 400, 500, 600 ] @=> int foo1[];
SinOsc s2 => dac; [ 125, 250, 375, 500, 625, 750 ] @=> int foo2[];
SinOsc s3 => dac; [ 150, 300, 450, 600, 750, 900 ] @=> int foo3[];
44100 => int time1;
44200 => int time2;
44300 => int time3;

.3 => s1.gain;
.3 => s2.gain;
.3 => s3.gain;

spork ~ Update(foo1, s1, time1::samp);
spork ~ Update(foo2, s2, time2::samp);
spork ~ Update(foo3, s3, time3::samp);

while (true) day => now; // wait forever

fun void Update(int NoteList[], SinOsc s, dur d)
{
    int note;
    while(true)
    {
        Math.rand2f(1, 6) $ int => note;
        NoteList[note] => s.freq;
        d => now;
    }
}   


so those are my suggestions on adjusting the code for being able to play more.
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: Fri Sep 05, 2008 12:44 pm    Post subject: Reply with quote  Mark this post and the followings unread

Great notes by Kijjaz. I'd add that everything becomes easier if you use some tabs and the occasional extra line of white. Once your programs grow larger this will help you a LOT so it's best to get used to this as soon as possible.
_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Underwaterbob



Joined: Sep 03, 2008
Posts: 26
Location: Chungju, South Korea

PostPosted: Fri Sep 05, 2008 5:02 pm    Post subject: Reply with quote  Mark this post and the followings unread

Awesome! Thanks!

A couple comments to see if I understand:

Spork lets me run separate functions simultaneously. So, for example, in the end of the larry, moe and curly tutorial where you are supposed to use command line ChucK to run the separate files simultaneously you would use spork and define larry, moe and curly as separate functions in one file.

In your second reduction. Spork used multiple times acting on the same function with different parameters will make the function run more than once at the same time using each set of parameters. Even when each occurrence of this function is updating at a different time.

Initially I had random, similar times for each SinOsc, but since I had them all in one loop it wasn't doing what I wanted it to do, I moved the goalpost. Very Happy

I'm coming at this from a Csound perspective where I'm used to manipulating different "instruments" simultaneously.

Yeah, my code badly needs cleaning up.

One more thing:

Is there an output to wave option in miniAudicle or when using command line ChucK, or do I have to record it using some other software?
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


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

PostPosted: Fri Sep 05, 2008 9:26 pm    Post subject: Reply with quote  Mark this post and the followings unread

I could tell :¬), for some reason Csound has a tradition of code without tabs and minimal white space. I respect Csound a lot for it's history but I strongly feel that if you are going to use loops and other more high-level structures you owe it to yourself to use some more formatting. Csound tends towards more straightforward and linear code structures then ChucK. I don't want to tell anybody what to do but I would predict you might thank me in a while if you'd try this; I know I would get lost without those very quickly indeed in larger files :¬).

Also; your summary of sporking seems spot on to me.

In /examples/basic/ you'll find "rec.ck" and "rec-auto.ck". Those will get you started in recording wave files. If you have specific needs and/or get stuck do shout.

_________________
Kassen
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Underwaterbob



Joined: Sep 03, 2008
Posts: 26
Location: Chungju, South Korea

PostPosted: Fri Sep 05, 2008 11:13 pm    Post subject: Reply with quote  Mark this post and the followings unread

Csound code has been around for decades, but due to the disparate nature of the community and the nature of music creation itself, it seems no two coders do it the same. I've been doing it for ten years and I still come across code that makes me go "huh" because of the way people choose to format it. Some of it my own.

I redid my ChucK in the format kijjaz suggested and easily implemented the random durations I initially wanted, even making the code quite a bit shorter:

Code:

SinOsc s1 => dac; [ 100, 200, 300, 400, 500, 600 ] @=> int foo1[];
SinOsc s2 => dac; [ 125, 250, 375, 500, 625, 750 ] @=> int foo2[];
SinOsc s3 => dac; [ 150, 300, 450, 600, 750, 900 ] @=> int foo3[];

.3 => s1.gain => s2.gain => s3.gain;

spork ~ Update(foo1, s1);
spork ~ Update(foo2, s2);
spork ~ Update(foo3, s3);

while (true) day => now; // wait forever

fun void Update(int NoteList[], SinOsc s)
{
    int note;
    while(true)
    {
        Math.rand2f(800, 1000) $ int => int d;
        Math.rand2f(1, 6) $ int => note;
        NoteList[note] => s.freq;
        d::ms => now;
    }
}


ChucK's proving itself pretty awesome. There goes my spare time.
Back to top
View user's profile Send private message
Kassen
Janitor
Janitor


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

PostPosted: Sat Sep 06, 2008 3:33 am    Post subject: Reply with quote  Mark this post and the followings unread

Yeah, I know. Actually I kinda like that feeling and puzzling it out :¬).

I think, BTW, that I started with Csound not that long after you did but I didn't stick with it for long. Still like The Book as a reference, there's so much in there, and it's nice to be able to read Csound, even if I don't write it.

Your new version looks nice and clean to me.

_________________
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: Sat Sep 06, 2008 7:39 am    Post subject: Reply with quote  Mark this post and the followings unread

I have some suggestions for more adjustments:

(1) the size of an array can be read by its .cap() function.
so you can design the function to be more adaptable to arrays with any size:

original:
Math.rand2f(1, 6) $ int => note;
NoteList[note] => s.freq;

note will be an int in the range 1-5
but i suggest using Math.rand2(0, NoteList.cap() - 1) => note;

NoteList.cap() is the size of the refered array,
for example, if there are 6 members, we can refer to each member as member number 0 to 5
so it's actually 0 to TheArraySize - 1

with this you can initialize each foo array with any size of array you'd like.

(2) something I usually do is to create a master mix gain for overall volumn adjustment.
for example:

SinOsc s1 => Gain master => dac;
SinOsc s2 => master;
SinOsc s3 => master;
.3 => master.gain;

with this it's nice that s1, s2, s3's gain are all 1
(so we can think of the value as the weight of each oscillator's volumn)
and just lower the volumn at the master gain.

hmm that's all for today ^_^.
i'll look forward to seeing more of your patchs ^_^.
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Underwaterbob



Joined: Sep 03, 2008
Posts: 26
Location: Chungju, South Korea

PostPosted: Sat Sep 06, 2008 9:36 am    Post subject: Reply with quote  Mark this post and the followings unread

kijjaz wrote:

original:
Math.rand2f(1, 6) $ int => note;
NoteList[note] => s.freq;

note will be an int in the range 1-5


Thanks for that, I didn't realize my random function wasn't hitting every value in the array. Confused

How is the situation in Thailand? I heard things were getting a bit scary for a while.
Back to top
View user's profile Send private message
kijjaz



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

PostPosted: Sat Sep 06, 2008 2:47 pm    Post subject: Reply with quote  Mark this post and the followings unread

Hmm.. In Thailand? Usually Thais were always peaceful, even in this kind of situation, they behave okay.
Sometimes these people can be very angry,
but actually they don't mean it deeply.
I see it as fashion lol.
Back to top
View user's profile Send private message Send e-mail Visit poster's website Yahoo Messenger MSN Messenger
Underwaterbob



Joined: Sep 03, 2008
Posts: 26
Location: Chungju, South Korea

PostPosted: Mon Sep 08, 2008 6:13 pm    Post subject: Reply with quote  Mark this post and the followings unread

I'm glad things are OK there. Great country.

I hadn't touched ChucK for a few days but then all of my classes were canceled, so I'm at work and not working and downloaded ChucK on my office machine, luckily it looks like work. Very Happy

In about ten minutes I turned what's left of my first ChucK into a "Steve Reich Arpeggio Generator". Each of the harmonic series now cycles up and down through each value and the durations are 1::ms apart so it takes around 1:40 for the three arpeggios to phase 360 degrees.

Code:

SinOsc s1 => Gain master => dac;
SinOsc s2 => master;
SinOsc s3 => master;

.3 => master.gain;

[ 100, 200, 300, 400, 500, 600, 500, 400, 300, 200 ] @=> int n1[];
[ 125, 250, 375, 500, 625, 750, 625, 500, 375, 250 ] @=> int n2[];
[ 150, 300, 450, 600, 750, 900, 750, 600, 450, 300 ] @=> int n3[];

100 => int t1;
99 => int t2;
98 => int t3;

spork ~ Update(n1, s1, t1::ms);
spork ~ Update(n2, s2, t2::ms);
spork ~ Update(n3, s3, t3::ms);

while (true) day => now; // wait forever

fun void Update(int NoteList[], SinOsc s, dur d)
{
    int note;
    while(true)
    {
        NoteList[note] => s.freq;
        d => now;
        note + 1 => note;
        if ( note == 10 ) { 0 => note; }
    }
}   


Since they're letting me go home early today maybe I'll try something new later, but then I can't call it my first ChucK anymore.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic Moderators: Kassen
Page 1 of 1 [11 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