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
algorithmic composition
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
fraukefroehlich



Joined: May 11, 2007
Posts: 22
Location: home
Audio files: 1

PostPosted: Sat Jun 14, 2008 12:16 am    Post subject: algorithmic composition
Subject description: wolfram cellular automata determining the notes to be played with length specified by a markov chain
Reply with quote  Mark this post and the followings unread

hi there,

the deadline has passed now and i'm here to show you my code.
i hope it is understandable and you may give me some advice on how to improve my style with chuck.

maybe it could have been done with fewer lines of code or using less resources. but all in all i'm happy with the result.

so here comes:
Code:
//-----------------------------------------------------------------------------------//
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//-----------------------------------------------------------------------------------//

140 => float bpm;
1::minute / bpm     => dur viertel;     //fourth
1::minute / bpm / 2 => dur achtel;      //eighth

"v" => string v; //fourth
"a" => string a; //eighth
"pa" => string pa; //eighth pause
"pv" => string pv; //fourth pause

//this is the array holding the not durations as base for the markov chain calculations
[
a,a,pa,a,pa,a,v,v,pv,v,
pv,v,a,pv,v,a,v,v,a,v,
v,v,v,v,a,a,pa,v,a,a,v,
v,a,pv,v,a,v,v,a,v,v,v,
v,a,a,pa,v,a,a,v,pv,a,
a,a,v,a,pa,a,a,a,pa,a,
a,a,pv,a,a,a,v,a,pa,v,a] @=> string durations[];

//the array holding the "pyramid" generetad by the cellular automata
int wolfram[150][9];
int band[150][7]; //to cut out just a 7 bit wide segment of the pyramid
int rule[2][2][2]; //array for the rule used in calculating the cellular automata

//current and next line of the pyramid
int line[9];
int newLine[9];

//instruments
Shakers m[7];
HevyMetl mandolin[7];

//mix
Gain mix => dac;
mix.gain(.17);

//tones
Std.mtof(30) => mandolin[0].freq;
Std.mtof(42) => mandolin[1].freq;
Std.mtof(54) => mandolin[2].freq;
Std.mtof(66) => mandolin[3].freq;
Std.mtof(78) => mandolin[4].freq;
Std.mtof(90) => mandolin[5].freq;
Std.mtof(102) => mandolin[6].freq;

Std.mtof(50) => m[0].freq;
Std.mtof(62) => m[1].freq;
Std.mtof(74) => m[2].freq;
Std.mtof(86) => m[3].freq;
Std.mtof(98) => m[4].freq;
Std.mtof(110) => m[5].freq;
Std.mtof(122) => m[6].freq;

//connect to dac
for(0 => int i; i < m.cap(); i++){
    m[i] => mix;
    mandolin[i] => mix;
}

//starting position - first line of the pyramid (the peek)
1 @=> line[4];

//rules for cellular automata. first is rule 30, following are
//other rules, slightly modified by me
[
[0,1,1,1,1,0,0,0],
[0,1,1,1,1,0,0,0],
[0,1,1,1,0,1,1,0],
[1,0,0,1,1,0,0,0],
[1,0,1,1,1,0,0,1]] @=> int ruleValues[][];

//ruleCounter to switch to a random rule when changing
-1 => int ruleCounter;

//after 12 iterations change rule to avoid repeating patterns
12 => int iterations;

//please stop this somewhen... ;)
1::minute + now => time later;

//set first rule
setRule(ruleValues);

//calculate the pyramid of the cellular automata
for(0 => int i; i < wolfram.cap(); i++){
    for(0 => int j; j < line.cap(); j++){
        line[j] => wolfram[i][j];
    }
    getNewLine(line, rule) @=> newLine;
    newLine @=> line;
    //change rule
    if(iterations % 12 == 0){
        setRule(ruleValues);
       
    }
}

//cut the segment out of the pyramid to use it as "music sheet"
cutBand(wolfram);

    //----------------------------------------------------------//
    // MAIN LOOP
    //----------------------------------------------------------//
    while (now < later){
        play(band);
        1::samp => now;
    }
    //----------------------------------------------------------//
    // SET RULE
    //----------------------------------------------------------//
    fun void setRule(int ruleValues[][]){
        //get and set random rule
        Std.rand() % 5 => ruleCounter;
        ruleValues[ruleCounter][0] @=> rule[0][0][0];
        ruleValues[ruleCounter][1] @=> rule[0][0][1];
        ruleValues[ruleCounter][2] @=> rule[0][1][0];
        ruleValues[ruleCounter][3] @=> rule[0][1][1];
        ruleValues[ruleCounter][4] @=> rule[1][0][0];
        ruleValues[ruleCounter][5] @=> rule[1][0][1];
        ruleValues[ruleCounter][6] @=> rule[1][1][0];
        ruleValues[ruleCounter][7] @=> rule[1][1][1];
    }
    //----------------------------------------------------------//
    // GET NEW LINE
    //----------------------------------------------------------//
    fun int[] getNewLine(int oldLine[], int rule[][][]){
        int temp[9];
        //look at the values of i-1, i and i+1 of the previous line. use the
        //code (i.e. 101) as index for the array holding the rule. then copy
        //the value of the array at index 101 to the newLine[i]. after completion
        //return the whole line.
        for(1 => int i; i < (oldLine.cap()-1); i++){
            if(rule[oldLine[i-1]][oldLine[i]][oldLine[i+1]] == 1){
                1 => temp[i];
            }else{
                0 => temp[i];
            }
        }
        return temp;
    }
    //----------------------------------------------------------//
    // CUT BAND
    //----------------------------------------------------------//
    //cut off first and last column
    fun void cutBand(int wolfram[][]){
        for(0 => int i; i < wolfram.cap(); i++){
            for(1 => int j; j < wolfram[i].cap()-1; j++){
                wolfram[i][j] @=> band[i][j-1];
                <<<band[i][j-1]>>>;
            }
            <<<"-----------">>>;
        }
    }
    //----------------------------------------------------------//
    // PLAY SOUND
    //----------------------------------------------------------//
    fun void play(int band[][]){
        //go through the columns of the segment
        for(0 => int i; i < band.cap(); i++){
            //go through rows of segment
            for(0 => int j; j < band[i].cap(); j++){
                if(band[i][j] == 0){
                    m[j] =< mix; //value 0 -> unchuck instrument
                }else{
                    m[j] => mix; //value 1 -> chuck instrument
                }
                m[j].noteOn(1); //play note
            }
            //same for second instrument
            (i + 1) % 150 => int vorsprung;   
            for(0 => int j; j < band[i].cap(); j++){
                if(band[vorsprung][j] == 0){
                    mandolin[j] =< mix; //value 0 -> unchuck instrument
                }else{
                    mandolin[j] => mix; //value 1 -> chuck instrument
                }
                mandolin[j].noteOn(1); //play note
            }
            combo(i) => dur note; //get note from markov chain
            note => now;
        }
    }
    //----------------------------------------------------------//
    // GET NEXT DURATION
    //----------------------------------------------------------//
    fun dur combo(int b){
        //post[] counts how often a specific note length emerges after a given
        //combination of the two previous note lengths.
        float post[4];
        //b represents the index of the current note length combination. has
        //to be calculated mod 72 as durations[] does not have more elements
        b % 72 => int c;
        //copy current length combination to c1
        durations[c] + durations[c+1] => string c1;
        //go through all durations
        for(0 => int i; i < durations.cap() - 2; i++){
            if(durations[i] + durations[i+1] == c1){
                //count the lengths following to the c1 combination
                if(durations[i+2] == "v") post[0] + 1 => post[0];
                if(durations[i+2] == "a") post[1] + 1 => post[1];       
                if(durations[i+2] == "pa") post[2] + 1 => post[2];
                if(durations[i+2] == "pv") post[3] + 1 => post[3];
            }
        }
        //total count of combination c1
        post[0] + post[1] + post[2] + post[3] => float sum;

        float thresholds[post.cap()];
        for(0 => int i; i < thresholds.cap(); i++){
            post[i] / sum => float tmp; //probability of length i
            if(i == 0){
                //just copy first probability value
                tmp @=> thresholds[i];
            }else{
                //then add the following probabilities to the previous in order
                //to get intervals between 0 and 1
                thresholds[i-1] + tmp @=> thresholds[i];
            }
        }
        //give me a random value and check out to which interval it corresponds
        getRandVal(thresholds) => int interval;
       
        //check interval and return the note length duration
        //if pause, unchuck instruments
        if(interval == 2){
            for(0 => int i; i < m.cap(); i++){
                m[i] =< mix;
                mandolin[i] =< mix;
            }
            <<<"-----------">>>;
            <<< "pauseLength: achtel" >>>;
            <<<"-----------">>>;
            return achtel;
        }
        if(interval == 3){
            for(0 => int i; i < m.cap(); i++){
                m[i] =< mix;
                mandolin[i] =< mix;
            }
            <<<"-----------">>>;
            <<< "pauseLength: viertel" >>>;
            <<<"-----------">>>;
            return viertel;
        }
        if(interval == 0){
            <<< "noteLength: viertel" >>>;
            return viertel;
        }
        if(interval == 1){
            <<< "noteLength: achtel" >>>;
            return achtel;
        }
    }
    //----------------------------------------------------------//
    // GET RANDOM VALUE
    //----------------------------------------------------------//
    fun int getRandVal(float threshold[]){
        Std.rand2f(0, 1) => float rand;
        for(0 => int z; z < threshold.cap(); z++){
            //if true, return index which corresponds to interval
            if(rand <= threshold[z]) return z;
       
        }
    }

what do you think about it?

edit: thx 4 the advice, kassen!

_________________
u said it man... nobody chucks with the jesus...

Last edited by fraukefroehlich on Tue Jun 17, 2008 11:57 pm; edited 1 time in total
Back to top
View user's profile Send private message
chuckles



Joined: Apr 02, 2007
Posts: 72
Location: San Diego, California

PostPosted: Mon Jun 16, 2008 12:29 pm    Post subject:  Re: algorithmic composition
Subject description: wolfram cellular automata
Reply with quote  Mark this post and the followings unread

fraukefroehlich wrote:
hi there,

the deadline has passed now and i'm here to show you my code.
i hope it is understandable and you may give me some advice on how to improve my style with chuck.

maybe it could have been done with fewer lines of code or using less resources. but all in all i'm happy with the result.
...
what do you think about it?


I think it's extremely cool and I'm all ready to steal your code!

Congratulations, very creative use of ChucK and interesting sound (I like the way you make the Mandolin become a heavy metal guitar too)

.c.
Back to top
View user's profile Send private message
fraukefroehlich



Joined: May 11, 2007
Posts: 22
Location: home
Audio files: 1

PostPosted: Mon Jun 16, 2008 11:19 pm    Post subject: Re: algorithmic composition
Subject description: wolfram cellular automata
Reply with quote  Mark this post and the followings unread

chuckles wrote:


I think it's extremely cool and I'm all ready to steal your code!
thank you very much! yeah, no problem - steal every little character... but don't make money with it! Wink
Quote:

Congratulations, very creative use of ChucK and interesting sound (I like the way you make the Mandolin become a heavy metal guitar too)

.c.

lol... it first was a mandolin, then i added a second instrument and finally tried to find two more or less harmonic instruments... i haven't had the patience to change the var names all over again... Wink

_________________
u said it man... nobody chucks with the jesus...
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: Tue Jun 17, 2008 5:55 pm    Post subject: Re: algorithmic composition
Subject description: wolfram cellular automata
Reply with quote  Mark this post and the followings unread

fraukefroehlich wrote:
yeah, no problem - steal every little character... but don't make money with it! Wink


If this is a issue to you; know that you can always attach a license (for example some form of Creative Commons or GPL) to your code. Of course under most copyright laws you automatically have rights over anything you create but it can't hurt to be clear.

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



Joined: May 26, 2008
Posts: 29
Location: Asheville NC

New postPosted: Wed Jun 18, 2008 9:17 am    Post subject: Reply with quote  Mark this post and the followings unread

Very nice!

I've been reading a lot about cellular automata lately, so this program intrigued me.
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

New postPosted: Wed Jun 18, 2008 10:20 am    Post subject: Reply with quote  Mark this post and the followings unread

chuckbeginner wrote:
Very nice!

I've been reading a lot about cellular automata lately, so this program intrigued me.


Welcome on board!

I hope we'll be making fun of your login-name in a few years.
;¬)

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



Joined: May 26, 2008
Posts: 29
Location: Asheville NC

New postPosted: Wed Jun 18, 2008 9:43 pm    Post subject: Reply with quote  Mark this post and the followings unread

Well, I've been working with this wonderful language for about a month. It's great to find a group of people of whom I can ask questions.
Back to top
View user's profile Send private message
fraukefroehlich



Joined: May 11, 2007
Posts: 22
Location: home
Audio files: 1

New postPosted: Wed Jun 18, 2008 10:31 pm    Post subject: Reply with quote  Mark this post and the followings unread

chuckbeginner wrote:
Well, I've been working with this wonderful language for about a month. It's great to find a group of people of whom I can ask questions.
wonderful language, eh? well i think it's cool, yes but a bit unintuitive too tough... and it turns my mind upside down... Smile the reverse var assignment is easy to get into, but a pain in the a** when you get back to a normal language Smile

but hey - it really is fun.

_________________
u said it man... nobody chucks with the jesus...
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

New postPosted: Thu Jun 19, 2008 5:48 am    Post subject: Reply with quote  Mark this post and the followings unread

chuckbeginner wrote:
It's great to find a group of people of whom I can ask questions.


We shouldn't be that hard to find? Links to the forum, mailing-list and WiKi are on the ChucK homepage.

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



Joined: May 26, 2008
Posts: 29
Location: Asheville NC

New postPosted: Thu Jun 19, 2008 9:12 am    Post subject: Reply with quote  Mark this post and the followings unread

fraukefroehlich wrote:
chuckbeginner wrote:
Well, I've been working with this wonderful language for about a month. It's great to find a group of people of whom I can ask questions.
wonderful language, eh? well i think it's cool, yes but a bit unintuitive too tough... and it turns my mind upside down... Smile the reverse var assignment is easy to get into, but a pain in the a** when you get back to a normal language Smile

but hey - it really is fun.


I am, shall we say, not encumbered by experience with other languages. Smile
Back to top
View user's profile Send private message
Inventor
Stream Operator


Joined: Oct 13, 2007
Posts: 6221
Location: near Austin, Tx, USA
Audio files: 267

New postPosted: Thu Jun 26, 2008 10:21 am    Post subject: Re: algorithmic composition
Subject description: wolfram cellular automata
Reply with quote  Mark this post and the followings unread

fraukefroehlich wrote:
chuckles wrote:


I think it's extremely cool and I'm all ready to steal your code!
thank you very much! yeah, no problem - steal every little character... but don't make money with it! Wink


I'm not very clear on the details of the GNU GPL, but I don't believe it prohibits the user from making money on your code. The following quote:

Quote:
Free software does not mean non-commercial. A free program must be available for commercial use, commercial development, and commercial distribution. Commercial development of free software is no longer unusual; such free commercial software is very important.


is from this page:

http://www.gnu.org/philosophy/free-sw.html

Though it is thorough, I find the GNU GPL FAQ a bit confusing actually. Perhaps someone could explain it more clearly.

_________________
"Let's make noise for peace." - Kijjaz
Back to top
View user's profile Send private message Send e-mail
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