AI/algorithmic music/composition theory

Hey guys.

So I am making this thread for if anyone wanted to share any concepts/theories/techniques of AI/algorithmic music and/or composition.

If you have anything you want to share, you can share it here. : )

I also wanted to share one that I came upon very recently… like within the last few days …

I call it… “Bit-by-bit circular composition”.

Basically… Let’s say you have 3 different instruments.

And each one has it’s own part… much like in a pop or rock band.

And how this technique works is by having all of those instruments “build” a piece of music, from start to finish…literally… bit by bit.

And it does it in a circular manner… like one instrument would create a “bit” of music, and then another instrument would create another “bit”… based off of the last “bit” created by the last instrument… and then another instrument would do the same in the same manner. And it would go around in a circle, with each instrument taking turns creating a “bit” of the song, based off of the “bit” that was created by the last instrument.

And it literally builds the song from the ground up… from start to finish.

A “bit” would be the smallest “block” of a piece of music. Think of a computer bit.

I see it as a democratic and intelligent way of making music between instruments… like a pop/rock music group would… with each member having equal input in the creation of the piece.

And with processing characteristics of a computer program.

Here is the basic code I wrote out for it yesterday… Each major instrument array function (ex - “~instrument_1_array_func”) is an individual instrument. And the building of a piece of music would cycle around in a circle, from instrument 1 to instrument 2 to instrument 3… and then back to 1… and so on. And I hope that you can pardon my perhaps inefficient code, if it is. : )

Also - all the way at the bottom is the “do” function which does the thing : )

Feel free to ask and comment, etc. : )

Oh… and the code below might change in the future… but I just really wanted to post the concept for you guys : )

~instrument_1_array_func = {

("instrument_1_array_part_"++(~part_num)).asSymbol.envirPut(
	("instrument_1_array_part_"++(~part_num)).asSymbol.envirGet.add(

		case
		{~instrument_1 == "bass"}{
			([
				(~instrument_1_freq = ~instrument_3_freq
					*[(~ratio_array.at(~bass_numerology.wrapAt(y=y+1))), (~ratio_array.at(~bass_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_1_freq > 1396.9129257322}{~instrument_1_freq = ~instrument_1_freq/2}
				{~instrument_1_freq < 233.08188075905}{~instrument_1_freq = ~instrument_1_freq*2}
				{(~instrument_1_freq >= 233.08188075905) and: (~instrument_1_freq <= 1396.9129257322)}{~instrument_1_freq = ~instrument_1_freq};
				/*(x = Routine({inf.do({if(~instrument_1_freq > 1396.9129257322, {~instrument_1_freq = ~instrument_1_freq/2}, {x.stop;})})}); x.play; ~instrument_1_freq.value;)*/,
				(y=y+1; ~instrument_1_freq = ~instrument_1_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])}
		{~instrument_1 == "keys"}{
			([
				(~instrument_1_freq = ~instrument_3_freq
					*[(~ratio_array.at(~keys_numerology.wrapAt(y=y+1))), (~ratio_array.at(~keys_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_1_freq > 1396.9129257322}{~instrument_1_freq = ~instrument_1_freq/2}
				{~instrument_1_freq < 233.08188075905}{~instrument_1_freq = ~instrument_1_freq*2}
				{(~instrument_1_freq >= 233.08188075905) and: (~instrument_1_freq <= 1396.9129257322)}{~instrument_1_freq = ~instrument_1_freq};
				/*(x = Routine({inf.do({if(~instrument_1_freq > 1396.9129257322, {~instrument_1_freq = ~instrument_1_freq/2}, {x.stop;})})}); x.play; ~instrument_1_freq.value;)*/,
				(y=y+1; ~instrument_1_freq = ~instrument_1_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])}
		{~instrument_1 == "vocal"}{
			([
				(~instrument_1_freq = ~instrument_3_freq
					*[(~ratio_array.at(~vocal_numerology.wrapAt(y=y+1))), (~ratio_array.at(~vocal_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_1_freq > 1396.9129257322}{~instrument_1_freq = ~instrument_1_freq/2}
				{~instrument_1_freq < 233.08188075905}{~instrument_1_freq = ~instrument_1_freq*2}
				{(~instrument_1_freq >= 233.08188075905) and: (~instrument_1_freq <= 1396.9129257322)}{~instrument_1_freq = ~instrument_1_freq};
				/*(x = Routine({inf.do({if(~instrument_1_freq > 1396.9129257322, {~instrument_1_freq = ~instrument_1_freq/2}, {x.stop;})})}); x.play; ~instrument_1_freq.value;)*/,
				(y=y+1; ~instrument_1_freq = ~instrument_1_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])};
));

};

~instrument_2_array_func = {

("instrument_2_array_part_"++(~part_num)).asSymbol.envirPut(
	("instrument_2_array_part_"++(~part_num)).asSymbol.envirGet.add(

		case
		{~instrument_2 == "bass"}{
			([
				(~instrument_2_freq = ~instrument_1_freq
					*[(~ratio_array.at(~bass_numerology.wrapAt(y=y+1))), (~ratio_array.at(~bass_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_2_freq > 1396.9129257322}{~instrument_2_freq = ~instrument_2_freq/2}
				{~instrument_2_freq < 233.08188075905}{~instrument_2_freq = ~instrument_2_freq*2}
				{(~instrument_2_freq >= 233.08188075905) and: (~instrument_2_freq <= 1396.9129257322)}{~instrument_2_freq = ~instrument_2_freq};
				/*(x = Routine({inf.do({if(~instrument_2_freq > 1396.9129257322, {~instrument_2_freq = ~instrument_2_freq/2}, {x.stop;})})}); x.play; ~instrument_2_freq.value;)*/,
				(y=y+1; ~instrument_2_freq = ~instrument_2_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])}
		{~instrument_2 == "keys"}{
			([
				(~instrument_2_freq = ~instrument_1_freq
					*[(~ratio_array.at(~keys_numerology.wrapAt(y=y+1))), (~ratio_array.at(~keys_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_2_freq > 1396.9129257322}{~instrument_2_freq = ~instrument_2_freq/2}
				{~instrument_2_freq < 233.08188075905}{~instrument_2_freq = ~instrument_2_freq*2}
				{(~instrument_2_freq >= 233.08188075905) and: (~instrument_2_freq <= 1396.9129257322)}{~instrument_2_freq = ~instrument_2_freq};
				/*(x = Routine({inf.do({if(~instrument_2_freq > 1396.9129257322, {~instrument_2_freq = ~instrument_2_freq/2}, {x.stop;})})}); x.play; ~instrument_2_freq.value;)*/,
				(y=y+1; ~instrument_2_freq = ~instrument_2_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])}
		{~instrument_2 == "vocal"}{
			([
				(~instrument_2_freq = ~instrument_1_freq
					*[(~ratio_array.at(~vocal_numerology.wrapAt(y=y+1))), (~ratio_array.at(~vocal_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_2_freq > 1396.9129257322}{~instrument_2_freq = ~instrument_2_freq/2}
				{~instrument_2_freq < 233.08188075905}{~instrument_2_freq = ~instrument_2_freq*2}
				{(~instrument_2_freq >= 233.08188075905) and: (~instrument_2_freq <= 1396.9129257322)}{~instrument_2_freq = ~instrument_2_freq};
				/*(x = Routine({inf.do({if(~instrument_2_freq > 1396.9129257322, {~instrument_2_freq = ~instrument_2_freq/2}, {x.stop;})})}); x.play; ~instrument_2_freq.value;)*/,
				(y=y+1; ~instrument_2_freq = ~instrument_2_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])};
));

};

~instrument_3_array_func = {

("instrument_3_array_part_"++(~part_num)).asSymbol.envirPut(
	("instrument_3_array_part_"++(~part_num)).asSymbol.envirGet.add(

		case
		{~instrument_3 == "bass"}{
			([
				(~instrument_3_freq = ~instrument_2_freq
					*[(~ratio_array.at(~bass_numerology.wrapAt(y=y+1))), (~ratio_array.at(~bass_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_3_freq > 1396.9129257322}{~instrument_3_freq = ~instrument_3_freq/2}
				{~instrument_3_freq < 233.08188075905}{~instrument_3_freq = ~instrument_3_freq*2}
				{(~instrument_3_freq >= 233.08188075905) and: (~instrument_3_freq <= 1396.9129257322)}{~instrument_3_freq = ~instrument_3_freq};
				/*(x = Routine({inf.do({if(~instrument_3_freq > 1396.9129257322, {~instrument_3_freq = ~instrument_3_freq/2}, {x.stop;})})}); x.play; ~instrument_3_freq.value;)*/,
				(y=y+1; ~instrument_3_freq = ~instrument_3_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])}
		{~instrument_3 == "keys"}{
			([
				(~instrument_3_freq = ~instrument_2_freq
					*[(~ratio_array.at(~keys_numerology.wrapAt(y=y+1))), (~ratio_array.at(~keys_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_3_freq > 1396.9129257322}{~instrument_3_freq = ~instrument_3_freq/2}
				{~instrument_3_freq < 233.08188075905}{~instrument_3_freq = ~instrument_3_freq*2}
				{(~instrument_3_freq >= 233.08188075905) and: (~instrument_3_freq <= 1396.9129257322)}{~instrument_3_freq = ~instrument_3_freq};
				/*(x = Routine({inf.do({if(~instrument_3_freq > 1396.9129257322, {~instrument_3_freq = ~instrument_3_freq/2}, {x.stop;})})}); x.play; ~instrument_3_freq.value;)*/,
				(y=y+1; ~instrument_3_freq = ~instrument_3_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])}
		{~instrument_3 == "vocal"}{
			([
				(~instrument_3_freq = ~instrument_2_freq
					*[(~ratio_array.at(~vocal_numerology.wrapAt(y=y+1))), (~ratio_array.at(~vocal_numerology.wrapAt(y=y+1))).reciprocal].choose);
				case
				{~instrument_3_freq > 1396.9129257322}{~instrument_3_freq = ~instrument_3_freq/2}
				{~instrument_3_freq < 233.08188075905}{~instrument_3_freq = ~instrument_3_freq*2}
				{(~instrument_3_freq >= 233.08188075905) and: (~instrument_3_freq <= 1396.9129257322)}{~instrument_3_freq = ~instrument_3_freq};
				/*(x = Routine({inf.do({if(~instrument_3_freq > 1396.9129257322, {~instrument_3_freq = ~instrument_3_freq/2}, {x.stop;})})}); x.play; ~instrument_3_freq.value;)*/,
				(y=y+1; ~instrument_3_freq = ~instrument_3_freq;),
				(y=y+1; 0;)
		]).wchoose([0.7,0.2,0.1])};
));

};

//Do function

~part_1 = 1.do({~part_num = 1;

1.do({

	~instrument_1_array_starting_func.value;

	~instrument_2_array_func.value;

	~instrument_3_array_func.value;

});

63.do({

	~instrument_1_array_func.value;

	~instrument_2_array_func.value;

	~instrument_3_array_func.value;

});

});

1 Like

Oh… and that code wouldn’t really do much on it’s own : ) Just saying : )

I also don’t have anything to demonstrate as of right now : P

Sorry :)… It was really just the technique I wanted to share.

Thanks for sharing! I always enjoy very much seeing other people’s compositional strategies. I’m about to (finally!) get back to coding some music again soon, looking forward to studying what you’ve done :slight_smile: