Sharon Yang Looking Outwards 11 Computational Music Composition

The algorithmic musical project that I would like to discuss is Apparatum. Apparatum, has been created by a solo exhibition, panGenerator. With its digital interface that generates electroacoustic sounds, the device emits purely analogue sounds. The project has been inspired musically and graphically by the “Symphony – electronic music” by Boguslaw Schaeffer. Just as Schaeffer did, the apparatus makes use of the visual language of symbols that convey the audio cues. The electroacoustic generators and filters were arranged inside two steel frames, and the two types of magnetic tape samplers are used in order to base off and create basic tones. The apparatus relies on the analog way of generating sound of spinning discs with graphical patterns on them. I admire this project because it is able to make analog sounds from a purely electronic means of creating sounds. In the era where we are constantly exposed to electronic sounds, it shows that an apparatus can be used to bring back the analog sounds. Also, its relatively simple algorithm is used in this ingenious project.

APPARATUM – the installation inspired by the Polish Radio Experimental Studio from ◥ panGenerator on Vimeo.

Video Clip of the operation of Apparatum

Source: https://www.creativeapplications.net/sound/apparatum-installation-inspired-by-the-polish-radio-experimental-studio/

Joanne Lee – Project 11

Project-11

// Joanne Lee
// Section C
// joannele@andrew.cmu.edu
// Project-11

// global variables
var maze;
var character = [];
var brightnessThreshold = 10; // low threshold bc working with black background

// color variables
var redR = 255;
var redG = 96;
var redB = 95;

var pinkR = 255;
var pinkG = 184;
var pinkB = 255;

var cyanR = 2;
var cyanG = 255;
var cyanB = 255;

var orangeR = 255;
var orangeG = 184;
var orangeB = 82;

// array with color r,g,b values
var randomCol = [redR, redG, redB, pinkR, pinkG, pinkB, cyanR, cyanG, cyanB, orangeR, orangeG, orangeB]

function preload() {
    maze = loadImage("https://i.imgur.com/hGU36Hn.png") // load maze image
}

function setup() {
    createCanvas(480, 323);
    image(maze, 0, 0, 480, 323);
    maze.loadPixels();

    for (var a = 0; a < 6; a ++) { // create 6 hexagonal character in the maze
        if (a < 3) { // positions for character startion left on maze
            character[a] = makeCharacter(112, 57 + (95 * a));
        }
        else if (a >= 3) { // positions for character starting right on maze
            character[a] = makeCharacter(360, 57 + (95 * (a % 3)));
        }
        setColor(a); // randomly set colors
        character[a].setWeight(6);
        character[a].penDown(); // begin drawing
        character[a].forward(6);
        // note that it doesn't stop drawing
    }
}

function setColor(a) { // pick a random color from red, pink, cyan, orange
    var randNum = random(0,4);
    var index = floor(randNum) * 3; // take floor to make sure they're whole #'s
    character[a].setColor(color(randomCol[index], randomCol[index + 1], randomCol[index + 2]));
}

function draw() {
    for (var x = 0; x < 6; x ++) {
        chrMove(x);
        chrReset(x);
    }
}

// getPixel: fast access to pixel at location x, y from image 
function getPixel(image, x, y) {
    var i = 4 * (y * image.width + x);
    return color(image.pixels[i], image.pixels[i + 1], image.pixels[i + 2]);
}

function chrMove(x) { // update the object's position
    var theColorAtPxPy = getPixel(maze, character[x].x, character[x].y); // get color of px, py position
        
    // Fetch the brightness at PxPy, and save it.
    var theBrightnessOfTheColorAtPxPy = brightness(color(theColorAtPxPy));

    // If the brightness at PxPy is greater than the brightness threshold, move it down.
    if (theBrightnessOfTheColorAtPxPy < brightnessThreshold) {
        character[x].forward(1);
    }

    // If the brightness at PxPy is lower than darkness threshold, move up until it isn't.
    while (theBrightnessOfTheColorAtPxPy > brightnessThreshold & this.py != 0) {
        character[x].back(2);
        if (random(0,1) < 0.5) {
            character[x].right(90);
        }
        else {
            character[x].left(90);
        }
        theColorAtPxPy = getPixel(maze, character[x].x, character[x].y);
        theBrightnessOfTheColorAtPxPy = brightness(color(theColorAtPxPy));
        }
}

function chrReset(x) { // reset the object to the top of the screen
    if (character[x].x > width) { // bring back to left of screen if it moves off the right
        character[x].x = 0;
    }
    else if (character[x].x < 0) { // bring back to right of screen if it moves off the left
        character[x].x = width;
        character[x].back(150);
        character.right(90);
    }
}

// turtle graphic commands

function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}

function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeCharacter(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace, move: chrMove, // update the character's position
                  reset: chrReset, // reset the character to maze entrance
                  }
    return turtle;
}

I created an endless self-navigating maze inspired by Pac-Man! The colors of the lines are randomly generated from the red, cyan, pink, orange colors of the ghosts from the games. I wish I had the ability and time to add more randomness in the maze’s twists and turns as well as more smooth line as opposed to hitting the wall then moving back a step. However, I am very happy with my final product as is. I’ve included pictures of different iterations below.

The start of one iteration. You can clearly see the different paths here since it is early on in its stages.
Another iteration in a more advanced stage of completion. Lines go back the same path it took sometimes due to the slight randomness in its turns.

Christine Seo – Project 11

sketch

// Christine Seo
// Section C
// mseo1@andrew.cmu.edu
// Project-11

var turtle1;
var turtle2;
var turtle3;
var turtle4;
var turtle5;
var turtle6;

function setup() {
  createCanvas(480, 460);
  background(0);
  turtle1 = makeTurtle(160, 200);
  turtle2 = makeTurtle(210, 100);
  turtle3 = makeTurtle(370, 210);
  turtle4 = makeTurtle(480, 20);
  turtle5 = makeTurtle(150, 470);
  turtle6 = makeTurtle(8, -15);
  frameRate(10); //gradually draw
}


function draw() {
  // Draw turtle 1
  turtle1.penDown();
  turtle1.setWeight(0.25);
  turtle1.setColor("Khaki"); 
  for (var i = 0; i < 10; i++) {
    turtle1.forward(1); //go straight
    turtle1.right(55); //go right 
    turtle1.forward(38);
    turtle1.left(15); //go left 
    if (i % 9 === 0) { //angles
      turtle1.forward(13);
    }
  }

  // Draw turtle 2
  turtle2.penDown();
  turtle2.setWeight(0.25);
  turtle2.setColor("LightPink");
  for (var i = 0; i < 10; i++) {
    turtle2.forward(15);
    turtle2.left(70);
    turtle2.forward(38);
    if (i % 9 === 0) {
      turtle2.forward(13);
    }
  }

  // Draw turtle 3
  turtle3.penDown();
  turtle3.setWeight(0.25);
  turtle3.setColor("DarkSeaGreen");
  for (var i = 0; i < 10; i++) {
    turtle3.forward(15);
    turtle3.right(40);
    turtle3.forward(120);
    turtle3.right(70);
    if (i % 9 === 0) {
      turtle3.forward(13);
    }
  }

  // Draw turtle 4
  turtle4.penDown();
  turtle4.setWeight(0.25);
  turtle4.setColor("Khaki"); 
  for (var i = 0; i < 10; i++) {
    turtle4.forward(1);
    turtle4.right(55);
    turtle4.forward(38);
    turtle4.left(15);
    if (i % 9 === 0) {
      turtle4.forward(13);
    }
  }

  // Draw turtle 5
  turtle5.penDown();
  turtle5.setWeight(0.25);
  turtle5.setColor("LightPink");
  for (var i = 0; i < 10; i++) {
    turtle5.forward(15);
    turtle5.left(70);
    turtle5.forward(38);
    if (i % 9 === 0) {
      turtle5.forward(13);
    }
  }



  // Draw turtle 6
  turtle6.penDown();
  turtle6.setWeight(0.25);
  turtle6.setColor("DarkSeaGreen");
  for (var i = 0; i < 10; i++) {
    turtle6.forward(15);
    turtle6.right(40);
    turtle6.forward(120);
    turtle6.right(70);
    if (i % 9 === 0) {
      turtle6.forward(13);
    }
  }
}


function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

I really liked how in this weeks project, it was more open ended. I was able to research and find interesting visual forms that the turtles can make. Some of the designs reminded me of flowers in some way and I wanted to portray that through my composition as well as implement the slow crawling turtles to make the designs more opaque.

Close to stage one of composition
Close to stage two of composition (gradually draws more, and gets more opaque)
Close to final stage of composition (most opaque and vibrant)

 

Connor McGaffin – Project 11

sketch

/*
Connor McGaffin
Section C
cmcgaffi@andrew.cmu.edu
Project-11
*/

var option = 1;
var b = 2;
var gold = 137.507764;

function setup() {
    createCanvas(400, 400);
}

function draw() {
    background(0); 

    //each option provides diff colors and 
    if(option == 1){
        greenHex();
    }
    if(option == 2){
        yellowTri();
    }
    if(option == 3){
        orangSq
    ();
    }
}

function greenHex () {
    var swim = mouseX / 10;
    var turtle = makeTurtle(width / 2, height / 2);
    turtle.setWeight(3);

    for(i = 0; i < 300; i++){
        if( i % 3 == 1){
            turtle.setColor("darkgreen");
        } else {
            turtle.setColor("pink");
            var swim = mouseX / 5;
        }
            turtle.penDown();
            turtle.forward(swim);
            turtle.right(60);
            turtle.forward(swim);
            turtle.right(60);
            turtle.forward(swim);
            turtle.right(60);
            turtle.forward(swim);
            turtle.right(60);
            turtle.forward(swim);
            turtle.right(60);
            turtle.forward(swim);
            turtle.right(60);
            turtle.penUp();
            turtle.right(gold);
            turtle.forward(i * 1.5);
        }
}

function yellowTri () {
    var swim = mouseX * 3;
    var turtle = makeTurtle(width / 2, height / 2);
    turtle.setWeight(3);

    for(i = 0; i < 500; i++){
        if( i % 3 == 1){
            turtle.setColor("gold");
        } else {
            turtle.setColor("indigo");
            var swim = mouseX / 5;
        }
            turtle.penDown();
            turtle.forward(swim);
            turtle.right(120);
            turtle.forward(swim);
            turtle.right(120);
            turtle.forward(swim);
            turtle.penUp();
            turtle.right(gold);
            turtle.forward(i * 1.5);
        }
}

function orangSq () {
    var swim = mouseX * 3;
    var turtle = makeTurtle(width / 2, height / 2);
    turtle.setWeight(3);

    for(i = 0; i < 500; i++){
        if( i % 3 == 1){
            turtle.setColor("navy");
        } else {
            turtle.setColor("chocolate");
            var swim = mouseX / 5;
        }
            turtle.penDown();
            turtle.forward(swim);
            turtle.right(90);
            turtle.forward(swim);
            turtle.right(90);
            turtle.forward(swim);
            turtle.right(90);
            turtle.forward(swim);
            turtle.penUp();
            turtle.right(gold);
            turtle.forward(i * 1.5);
        }
}

function mousePressed() {
    option++;
    if(option > 3) option = 1;
}


function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}



 

I approached this project as an exploration in color, shape, and the golden ratio. I created three separate interactions, which can be shuffled through via clicking on the canvas. Each of these options is an exploration in a different color palette and use of shape, each with a similar underlying turtle for loop.

In my explorations, I found a few structures that resemble organic shapes of nature. In the first interaction, Ive found a faint outline of a succulent like growth present in the green strokes when the cursor is all the way to the right. The second interaction generates a negative space at its center which resembles a seashell. Finally, the third interaction yielded a similar succulent-like growth to the first, except it is constrained by right angles on the leftmost sides, dictated so by the 90 degree angles of the squares which make up the structure.

All screenshots below were taken when the cursor was on the far right of the canvas, generating the shapes with line segments at its upper bound.

Justin Yook – Project 11

freeTurtle

// Justin Yook
// jyook@andrew.cmu.edu
// Section C
// Project 11

var blueTurtle;
var rCol = [];
var rFor;

function setup() {
    createCanvas(360, 240);
    background(0);

    for (var i = 0; i < 50; i++) {
    	rCol[i] = color(random(0, 255), random(0, 255), random(0, 255));
    }

   	blueTurtle = makeTurtle(0, height / 2);
    blueTurtle.setWeight(3);
    blueTurtle.setColor(color(255, 255, 255));

	frameRate(60);
}

function draw() {
	// CREATE THE ZIG ZAG PATTERN
	blueTurtle.forward(1);

	if (blueTurtle.x >= 45 & blueTurtle.x < 90) {
		blueTurtle.face(300);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 90 & blueTurtle.x < 135) {
		blueTurtle.face(70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 135 & blueTurtle.x < 180) {
		blueTurtle.face(-70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 180 & blueTurtle.x < 225) {
		blueTurtle.face(70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 225 & blueTurtle.x < 270) {
		blueTurtle.face(-70);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 270 & blueTurtle.x < 315) {
		blueTurtle.face(-300);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= 315 & blueTurtle.x < width) {
		blueTurtle.face(0);
		blueTurtle.forward(1);
	}

	if (blueTurtle.x >= width) {
		blueTurtle.x = 0;
		blueTurtle.y = random(0, 240);
		blueTurtle.setColor(random(rCol));
	}
}

// Implement Turtle 
function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

I was inspired by how heartbeats and sound were represented on monitors, and created a zig-zag pattern similar to them. To add something interesting, I made an array with length 50, where each element is a random color. In addition, the y-coordinate of each pattern drawn after the first is random.

One variation of random colors and y-coordinates

Justin Yook – Looking Outwards 11

Design of Application

Prélude in ACGT by Pierry Jaquillard is a project that converts personal DNA data into into sounds. Jaquillard used his own DNA sequence to convert it into music. I admire this project because it combines biology and music together, two topics that can seem unrelated. It is a new way of expressing something through music, and it can open doors to creative and innovative ideas. Jacquillard used a midi Library for JavaScript to generate the midi signals in the main computer. Then he sent those signals to Ableton Live to play the sounds from webapps on iPads and iPhones. Even other musical elements such as tempo can be controlled on the application. There is no mention of a specific algorithm used with JavaScript. The creator’s artistic sensibilities show in his simple and intuitive design of the app.

Source: https://www.creativeapplications.net/js/prelude-in-acgt-sonification-of-personal-dna-data/

Christine Seo – Looking Outwards 11

Caption: A video documentation, filmed in Montreal, Québec, of Mesa Musical Shadows (2016), an interactive musical pavement.

Mesa Musical Shadows is an interactive art related to computational music by Daily Tous Les Jours studio, an interaction design studio with a focus on work in public spaces. This project was inspired by a mix of performance, musical instruments, and digital arts, using contemporary tools such as sensors and real-time data. The artists wanted passing crowds to be invited to play a critical role in the transformation of their environment and their relationships. The creator’s artistic sensibilities manifest in the final form by using bright geometrically tiled surfaces that make the piece more inviting for the audience. The piece allows shadows to cast with the sensor, where sounds and melodies are projected by speakers. The sensors are controlled by a MaxMSP patch linking Arduino Mega boards via OSC and are constantly recalibrate themselves in order to define new threshold values to determine what is a shadow and what is not.

The shadows cast on different tiles, which trigger different voices, all singing in harmony. Additionally, the music dependent on the weather and the time of the day (due to variations of the lengths of the shadows). I thought that this project was very intriguing because the artists let the audience compose the music and are welcomed by a moment of surprise and an invitation to engage with the piece, as well as interact with other visitors and passersby. I believe that music is a language that is universal, and it is really exciting to see art and music collaborate in order for the community to come together as well.

https://www.creativeapplications.net/maxmsp/playin-the-pavement-daily-tous-les-jours-mesa-musical-shadows/

Hannah Cai—Looking Outwards—11

For this week’s Looking Outwards, I chose this sample of music, which was generated by David Cope’s “Experiments in Musical Intelligence” computer program. It’s termed as a “Bach-style chorale” in the title, which, based on the comments, confused and angered a lot of the audience, who said it sounded nothing like Bach. One commenter clarified this distinction: ” A “Bach Chorale” refers to a style, not a composer – pretty much any SATB vocal piece utilizing the rules of counterpoint. That’s why a computer can do it — once you lay in one of the voices, you really can fill in the rest “by the numbers”. But don’t confuse that with actually composing or creating. And no offense but any real lover of Bach can tell that this sounds nothing like him — it has none of his intrigue or quirkiness (some of which has to do with his deliberate breaking of said rules). It sounds incredibly bland and boring to me. Which is exactly what I’d expect from computer-generated music.” ”

I found the reactions to this experiment more interesting than the audio itself, which I enjoyed, but didn’t find really special. I guess that personally, I feel like music needs some kind of human creativity or spontaneity/randomness to truly be “art.” Because this piece only “fills in” harmonies based on preset rules, it is less interesting/valuable to me, and apparently to quite a few other people as well. I still find the experiment impressive though, and I’d love to experiment with some kind of generative music in the future, if I can manage to learn how to.

Sophia Kim – Looking Outwards 11 – Sec C

I am taking the option of using my Looking Outwards 04, focusing on the sound design of the project. “Apparatum” was created by two different teams. The “Symphony – electronic music” was composed by Boguslaw Schaeffer, and the produced analogue sounds were created by the panGenerator team.

Compared to regular music, which is prerecorded and planned, sound art uses various beats that gives texture to art, specifically installations,  conceptual art, and exhibits. Like I said in Looking Outwards 04, I really liked how they fused communication, product, and sound design all together. With the sound design, the aesthetic design of the entire project is very well done. The designers of this project used various linear tape samplers as primary mediums. Also, to obtain noise and basic tones, spinning discs with graphic patterns were used, which are installed in the radio.

I really admire how different sound designs can be fused together by the user. Also, I admire how user customization is a big part of this project. The sound patterns the user picks are recorded, played out loud, and then printed on a receipt to document the patterns.

Robert Oh- Project 10- Landscape

version2

//Robert Oh
//Section C
//rhoh@andrew.cmu.edu
//Project-10-Landscape

var fish = [];
var terrainSpeed = 0.0005;
var terrainDetail = 0.0005;

function setup() {
    createCanvas(480, 480);
    frameRate(30);
    noStroke();
    fish.push(makeFish(width));
}
 
function draw() {
    background(130, 255, 246);

    //creating the river
    push();
    beginShape(); 
    fill(96, 149, 255);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, height / 6, height / 4);
        vertex(x, y); 
    }
    vertex(width, height);
    endShape();
    pop();
    
    //updating the fish locations 
    updateFish();

    //adding new fish 
    if (fish.length > 0){
        lastFish = fish[fish.length - 1]
        if (lastFish.x + lastFish.length < width - 50){
            addFish();
        }
    }

    // removing fish out of view
    removeFish();
}

function updateFish(){
    for (var i = 0; i < fish.length; i++){
        fish[i].move();
        fish[i].display();
    }
}

function fishMove() {
    this.x += this.speed;
}

function removeFish() {
    var keep = [];
    for (var i = 0; i < fish.length; i++){
        if (fish[i].x + fish[i].length * 3/2 > 0) {
            keep.push(fish[i]);
        }
    }
    fish = keep;
}

// drawing each fish
function fishDisplay() {
    //tail
    fill(this.r, 0, 0);
    triangle(this.x + this.length * (4 / 5), this.y, this.x + this.length * (3 / 2), this.y + 20, 
        this.x + this.length * (3 / 2), this.y - 20);

    //body
    fill(this.r, this.g, this.b);
    ellipse(this.x + this.length / 2, this.y, this.length, this.h);

    //eye
    fill(0);
    ellipse(this.x + this.length / 5, this.y - this.h / 8, 7, 7);

}

//adding a new fish on the right side of screen
function addFish() {
        fish.push(makeFish(width));
}

//fish object
function makeFish(startX) {
    var fsh = {x: startX,
                y : random(width / 3, width - 30),
                h : random(50, 70),
                length: random(50, 80),
                speed: random(-4, -2),
                r : random(255),
                g : random(255),
                b : random(255),
                move: fishMove,
                display: fishDisplay}
    return fsh;
}

I had a lot of fun making this project! While looking around for inspiration, I was looking at our old assignments we had completed. Then I remembered how much fun I had making the fish design for our first lab exam, and I decided to make this project off of that! (You’ll notice that I used similar code to create the fish). I wanted to give off a river design, where the fish in my landscape are swimming with the current down the river. Overall, I had a lot of fun designing the landscape, and I enjoyed being able to create my own object type 🙂 .