Portfolio

Pcomp Creative Experiment – Audio Player Retrospective

As a creative adaptation to the fifth “tone output” lab I attempted to get a speaker to play a preloaded wav file of “The Price is Right” theme song. My hope was that I could use 3 buttons to operate as rewind, play/pause, and fast forward commands for my song. Though this project was not successful, I found the process of attempting to troubleshoot my circuit and code incredibly valuable.

This was my first attempt at assembling a circuit with an Arduino Uno, and it was a wakeup call for me to better understand C++ programming in the Arduino application. I was able to reach a point of comfort where I could test feedback from the components in my circuit. This was helpful in realizing that one of my buttons was broken, but that my other buttons worked and my SD card reader was transmitting information to my Uno.

I believe my failure came from my circuit building, and when I attempt this project again I will rectify two elements. First, I will try to build my circuit with different buttons, as I found these components hard to plug in and a source of frustration in my initial stages. Second, I was not using a “standard issue” speaker, instead, I used a cheap tweeter which I had purchased at Tinkersphere. I had checked this component, with a potentiometer, and while it “worked” I believe I should have soldered the comparatively frayed wire ends of the speaker to the more solid, easily pluggable wires.

Match Watch – Process

Our finished product!

For my final project in Comm Lab, Video & Sound, I collaborated with Youngmin Choi and Julie Lizardo to write, direct, and edit a commercial for the fictitious product, Match Watch. Match Watch would be a surveillance service for couples to keep tabs on each other to a toxic degree by utilizing contemporary surveillance technologies present in day-to-day applications.

In this sense, Match Watch is both a parody and a satire. Match Watch parodies the glib way in which technology companies present privacy-invasive technologies both for their own gain and often to the detriment of their users. Match Watch satirizes how these same technology companies facilitate toxic relationship habits, like stalking, with features like location services.

Developing Match Watch was a fascinating insight into the process of shooting a semi-professional grade video, and satisfying closure to this course. In each step of our project, we utilized skills that we have learned throughout our course, adapting these skills to fit our needs as unique issues arose. For instance, in order to shoot a scene of me walking down a hallway, we placed a tripod on a rolling chair to facilitate a stable tracking shot. Similarly, when faced with an issue where (in retrospect) one of our actors had spoken too softly, we used Adobe Audacity to raise the volume of their dialogue without distorting the clip.

ICM – Week 5 Assignment

This week, my class was expected to represent our comfort in defining our own functions and creating objects. After some practice, I felt very comfortable using these tools – and utilized some old code that I had used to make balloons float, to make a pattern of multiple bubbles floating. This was satisfying because I had initially struggled with making multiple balloons float, and I was able to overcome this obstacle and apply it in a new animation. I also learned how to add audio and gifs into my animation, I look forward to using these skills in future projects.

I ran into two interesting issues. First, for whatever reason, I could not get Adobe Photoshop to represent the color I had generated for my background in the background of my seaweed images. Second, I wanted to try and generate a realistic water ripple pattern and was not able to find any examples written in JavaScript. In the future, I’d like to see if there is a way I could interface different languages in a similar manner to p5.serialport.js (used to communicate with Arduino).

Below is a video of my final animation:

Below is the code I used:

let x;
let y;
let speedX;
let speedY;
let d ;
let gif_loadImg;
let gif_createImg;

let b1 = {
  x: 0,
  y: 25,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b2 = {
  x: 50,
  y: 40,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b3 = {
  x: 100,
  y: 60,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b4 = {
  x: 125,
  y: 91,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b5 = {
  x: 150,
  y: 84,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b6 = {
  x: 400,
  y: 93,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b7 = {
  x: 450,
  y: 101,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b8 = {
  x: 500,
  y: 30,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b9 = {
  x: 3700,
  y: 74,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b10 = {
  x: 420,
  y: 24,
  speedX: 3,
  speedY: 5,
  d: 5
};
let b11 = {
  x: 400,
  y: 300,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b12 = {
  x: 450,
  y: 250,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b13 = {
  x: 500,
  y: 275,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b14 = {
  x: 370,
  y: 274,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b15 = {
  x: 420,
  y: 244,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b16 = {
  x: 42,
  y: 24,
  speedX: 3,
  speedY: 5,
  d: 5
};
let b17 = {
  x: 24,
  y: 300,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b18 = {
  x: 45,
  y: 250,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b19 = {
  x: 65,
  y: 275,
  speedX: 3,
  speedY: 5,
  d: 5
};

let b20 = {
  x: 37,
  y: 274,
  speedX: 3,
  speedY: 5,
  d: 5
}

let b21 = {
  x: 90,
  y: 244,
  speedX: 3,
  speedY: 5,
  d: 5
};

let bg = {
  r: 62,
  g: 96,
  b: 167
}

function clearCanvas(r, g, b) {
  background(r, g, b);
}

function drawBubble(x, y, d, bubbleColor) {
  fill(bubbleColor);
  circle(x, y, d);
}

function initializeBubble(b1) {
  b1.x = width / 18;
  b1.y = height / 2;
  b1.speedX = b1.speedX + random(-1, 1);
  b1.speedY = -1;
  b1.d = 5;
}

function updateBubble(b1) {
  b1.x = b1.x + random(-1, 1);
  b1.y = b1.y - 1;
  if (b1.y < 0) 
  b1.y = height; 
}
  
// drew gif insertion concept from https://editor.p5js.org/kjhollen/sketches/S1bVzeF8Z
function preload() {
  gif_loadImg = loadImage("fishes.gif");
  gif_createImg = createImg("fishes.gif");
  song = loadSound('dive.mp3');
  img1 = loadImage('seaweed.png');
  img2 = loadImage('seaweed3.png');
}

function setup() {
  createCanvas(550, 390);
    initializeBubble(b1);
}

function mousePressed() {
  if (song.isPlaying()) {
    // .isPlaying() returns a boolean
    song.stop();
  } else {
    song.play();
  }
}
function draw() {
  clearCanvas(bg.r, bg.g, bg.b);
  gif_createImg.position(155, 0);
  image(img1, 0, 200);
  image(img2, 350, 200);

//b1
drawBubble(b1.x, b1.y, b1.d, 255);
  updateBubble(b1);
  
//b2
drawBubble(b2.x, b2.y, b2.d, 255);
  updateBubble(b2);  

//b3
drawBubble(b3.x, b3.y, b3.d, 255);
  updateBubble(b3);    

//b4
drawBubble(b4.x, b4.y, b4.d, 255);
  updateBubble(b4);    
  
//b5
drawBubble(b5.x, b5.y, b5.d, 255);
  updateBubble(b5);    
  
//b6
drawBubble(b6.x, b6.y, b6.d, 255);
  updateBubble(b6);    
  
//b7
drawBubble(b7.x, b7.y, b7.d, 255);
  updateBubble(b7);    
  
//b8
drawBubble(b8.x, b8.y, b8.d, 255);
  updateBubble(b8);    
  
//b9
drawBubble(b9.x, b9.y, b9.d, 255);
  updateBubble(b9);    
  
//b10
drawBubble(b10.x, b10.y, b10.d, 255);
  updateBubble(b10);  

//b11
drawBubble(b11.x, b11.y, b11.d, 255);
  updateBubble(b11);    
  
//b12
drawBubble(b12.x, b12.y, b12.d, 255);
  updateBubble(b12);    
  
//b13
drawBubble(b13.x, b13.y, b13.d, 255);
  updateBubble(b13);    
  
//b14
drawBubble(b14.x, b14.y, b14.d, 255);
  updateBubble(b14);

//b15
drawBubble(b15.x, b15.y, b15.d, 255);
  updateBubble(b15);

//b16
drawBubble(b16.x, b16.y, b16.d, 255);
  updateBubble(b16);    
  
//b17
drawBubble(b17.x, b17.y, b17.d, 255);
  updateBubble(b17);    
  
//b18
drawBubble(b18.x, b18.y, b18.d, 255);
  updateBubble(b18);    
  
//b19
drawBubble(b19.x, b19.y, b19.d, 255);
  updateBubble(b19);

//b20
drawBubble(b20.x, b20.y, b20.d, 255);
  updateBubble(b20);

//b21
drawBubble(b21.x, b21.y, b21.d, 255);
  updateBubble(b21);   
}

ICM – Week 4 Assignment

This week, my assignment was to present my competence using for loops. While thinking of projects I often came up with ideas that relied on more advanced concepts – specifically arrays and objects. Initially, I tried to create a yahtzee-esque game, which I intend to complete once I have a mastery of arrays, and particularly, the shuffle function. However, I ended up creating a grid of multiple faces to represent the range of emotions I could be feeling on a given day. As a cute added feature, I included a mouseIspressed function that printed “Lol don’t worry about me, life’s great rn”.

In the future, I believe I could use an array, and the shuffle function, to display a randomized grid of a greater variety of emotions – and would like to do so. Creating the for loops, and aligning these three images in the grid were relatively time-intensive, though creating this project has definitely given me greater insight into how to troubleshoot positioning issues in for loop generated grids.

This is a picture of my screen, which shows the code and preview that I described above

Below is my code

const GRID_SIZE = 3;
let confused;
// function preload() {
//   img = loadImage('confused.png');}
let frustrated;
// function preload() {
//   img = loadImage('frustrated.png');}
let sleepy;
// function preload() {
//   img = loadImage('sleepy.png');}

function setup() {
  createCanvas(400, 400);
  confused = loadImage('confused.png', img => {
    image(img, 0, 0);
  });
  frustrated = loadImage('frustrated.png', img => {
    image(img, 0, 0);
  });
  sleepy = loadImage('sleepy.png', img => {
    image(img, 2, 2);
  });
}

function draw() {
  background(220);
  textSize(16);
  let rectSide = width / GRID_SIZE;
  for (let x = 0; x < GRID_SIZE; x += 1) {
    for (let y = 0; y < GRID_SIZE; y += 1) {
      let xPos = x * rectSide;
      let yPos = y * rectSide;
      rect(xPos, yPos, rectSide, rectSide);
      let circleSize = width / 3;
      for (let i = 0; i < width; i += GRID_SIZE) {
        image(confused, xPos + 35, height / 2.4, 80, 80);
      }
      for (let i = 0; i < width; i += GRID_SIZE) {
        image(frustrated, xPos + 35, height / 9.7, 80, 80);
      }
      for (let i = 0; i < width; i += GRID_SIZE) {
        image(sleepy, xPos + 38, height / 1.35, 83, 83);
      }
    }
    if (mouseIsPressed){print ("Lol don't worry about me, life's great rn")}
  }
}

ICM – Week 3 Assignment

This week my partner, Ashwita, and I expanded on my initial balloon popping game concept. We wanted to expand the concept by being able to generate multiple balloons, have those balloons change colors in a non-monochromatic range, have the balloons be pressable buttons (instead of relying on a general mouseClick function), and to incorporate a popping sound and pop counter.

We ran into the following problems. First, we could not figure out how to make a circular moving button (the balloon). We tried doing so by using the distance function and not having the balloons pop when clicked, but when the mouse hovered over the balloons instead. We also struggled with making each balloon, as individual objects, separate clickable entities.

Pending feedback we look forward to making different levels, turning this exercise into a game. Below is a video of our animation, with a final and test iteration of code.

let balloonColor;
let balloonPositionX;
let balloonPositionY;
let s = 'POP lol';
let r,g,b;
let imga, imgb;
    
function setup() {
  createCanvas(800, 600);
  balloonColor = random(255);
  balloonPositionX = random(0,200);
  balloonPositionY = 400;
}


function preload() {
  // sound = loadSound('balloon-pop.mp3'); // balloon pop sound
  imga = loadImage('balloon.png');
  imgb = loadImage('balloon.png');
}

function draw() {
  background(220);
  image(imgb, balloonPositionX, balloonPositionY, 200, 200);
  push();
  pop();
  fill(0);

  // pin 
  ellipse(mouseX, mouseY, 5, 5);
  line(mouseX, mouseY, mouseX + 20, mouseY - 10);
  
  //floating balloon waver
  balloonPositionX = balloonPositionX ;
  balloonPositionY = balloonPositionY - 4;
  if (balloonPositionY === 0) {
    balloonPositionY = 600;
    balloonPositionX = random(0,400);
    balloonColor = random(255,0,0);
  }
  if (mouseIsPressed) {
    // text(s, balloonPositionX , balloonPositionY, 80, 80)
    balloonPositionY = 600;
    balloonPositionX = random(0,800);
    balloonColor = random(255);
  }
}

Below is the code for one of our test iterations

let counter1 = 400; // counter for balloon 1 
let counter2 = 600; // counter for balloon 2
let xpos1, xpos2; // the horizontal positions for the balloon 1 and 2
// let speed = 1;
let position;
let ypos;
var sound;
var imga, imgb;
let bx1, by1, bx2, by2;

function setup() {
  createCanvas(400, 400);
  xpos1 = random(0, 400); // setting a random position for balloon 1
  xpos2 = random(0, 400); // setting a random position for balloon 2
  ypos = random(0, 400); // setting up horizontal pos. differences between Balloon 1&2.
  bx1 = random(0, 600);
  bx2 = random(0, 600);
  by1 = random(0, 400);
  by2 = random(0, 400);
}

function preload() {
  // sound = loadSound('balloon-pop.mp3'); // balloon pop sound
  imga = loadImage('balloon.png');
  imgb = loadImage('balloon.png');
}


function draw() {
  background(255);
  strokeWeight(1);
  image(imga, xpos1, counter1, 200, 200);
  // let ball1 = rect(xpos1,counter1,50, 50) // balloon 1 represented by a square

  // to make the balloon float one after the other in a loop
  if (counter1 <= -50 && counter2 <= -50) {
    counter1 = 400;
    counter2 = 600;
    xpos1 = random(0, 400);
    fill(255); // resets the color every loop 

    if (dist(mouseX, mouseY, xpos1, counter1) < 200 / 2 ||
      dist(mouseX, mouseY, xpos2, counter2) < 200 / 2) {
      background(0);
    } else {
      background(255);
    }
    
    // ellipse(bx1, by1, d, d);
    // ellipse(bx2, by2, d, d);
  }
  image(imgb, xpos2, counter2, 200, 200);
  // let ball2 = rect(xpos2,counter2,50, 50); // balloon 2 represented by a square
  counter1 -= 1;
  counter2 -= 1;


  ellipse(mouseX, mouseY, 5, 5);
  line(mouseX, mouseY, mouseX, mouseY - 15);

  // // making the balloon pop sound
  // if (mouseIsPressed) {
  //   // sound.play();
  //  fill(0,0,255);
  // }


}

Match Watch – Storyboard and Synopsis

This is a gif of our storyboard for Match Watch, a romantic partner surveillance app. It's a series of static black and white images of mannequins.

Our project is an infomercial for a product called Match Watch. Match Watch is an application and digital service designed to help partners keep track of their significant others through questionable surveillance means. Our infomercial will depict a scenario where the application would be necessary, a description of the product, testimonies pertinent to the success of the product (facetiously), and a demonstration of a limited-edition service offering.

Public Technology Observation – LinkNYC

In observing how consumers utilize LinkNYC, my cynicism and disdain for this public technology have been affirmed. On the surface, LinkNYC is benign, if not handy; built so that its buttons and touch screen sit at a height that is accessible to all, adults and children alike. As LinkNYC is a New York City initiative, Link booths are presumably ADA compliant. However, LinkNYC is a private piece of surveillance technology, and like all surveillance technology, it has a disparate impact on who is “targeted” by its true purpose. LinkNYC booths and their private parent company have been at the center of many lawsuits surrounding data privacy violations. The ease and inviting aesthetic of LinkNYC obfuscates its nefarious, similarly opaque practices of data collection and sale.

In my observation of how this technology is used, the majority of peoples who gave “links” more than a passing glance were individuals who appeared unconventionally housed. Were LinkNYC a public good, with no perverse incentive to collect and monetize the data of its users, I would take no issue with this dynamic. However, the fact that LinkNYC (in my observation) almost exclusively appeals to vulnerable peoples in our society, one must consider how features that may seem convenient at first glance, are ultimately predatory. For instance, LinkNYC has phone charging ports that, in keeping with the interaction trends I witnessed, unconventionally housed peoples utilized the most, and longest. Bear in mind, these are individuals who may not be able to charge their phones at home, at work, or even in a private business due to stigma – convenient design features for the more privileged can be lifelines for these individuals. 

The majority of people I witnessed using LinkNYC used these booths to charge their phones – these transactions took the longest, almost definitely contingent on the user’s battery charge.  I did not witness anyone use LinkNYC to place a phone call, perhaps this speaks to how little people place phone calls in general.

Sound Guide Reflection

Creating a sound guide gave me perspective into how mindlessly I ingest subtle audio cues in my environment. I got to know the history of 370 Jay Street through our sound guide.  By searching the history of each sound Sylvan and I recorded through our initial walk in the basement; I inverted my usual approach for understating a space, and am grateful for having experienced this process differently. I would not take any element of this process back, though, I might have wanted to do some research about the space before entering the basement so that we could better select the sounds we warped into abstraction. Furthermore (though there was equal input throughout), I might have delegated the load of sound editing and pamphlet making more evenly, though we were both versed in these practices. Overall, I am pleased with our ability to guide without direct guidance, as the excess of guidance in the sound guide, I attempted leading up to this project frustrated me greatly.

ICM – Week 2 Assignment

For this week I was tasked with animating a scenario where elements acted automatically and were interactive. I knew I wanted to animate a poppable balloon, however, my initial approach (which I, unfortunately, scrapped before I could document) left me more confused than inspired. After an insightful help session with my professor, I was put on the right track, and was able to animate the following work. Partly my issue stemmed from not knowing the material well enough, though I would say a larger issue I ran into was conceptualizing how best to plan and approach my design in individual steps.

Balloon Popping!

Below is the code I wrote to generate my project.

let balloonColor;
let balloonPositionX;
let balloonPositionY;
let s = 'POP lol';
    
function setup() {
  createCanvas(400, 600);
  balloonColor = random(255)
  balloonPositionX = 200
  balloonPositionY = 400
}

function draw() {
  background(220);

  fill(balloonColor);
  ellipse(balloonPositionX, balloonPositionY, 100, 140);
  push();
  noFill();
  bezier(balloonPositionX, balloonPositionY + 70, balloonPositionX + 20, balloonPositionY + 100, balloonPositionX - 20, balloonPositionY + 150, balloonPositionX, balloonPositionY + 200);
  pop();
  fill(0);
  ellipse(mouseX, mouseY, 5, 5);
  line(mouseX, mouseY, mouseX + 20, mouseY - 10);
  balloonPositionX = balloonPositionX + random (-1,1);
  balloonPositionY = balloonPositionY - 4;
  if (balloonPositionY === 0) {
    balloonPositionY = 600;
    balloonColor = random(255);
  }
  if (mouseIsPressed) {
    text(s, balloonPositionX - 20, balloonPositionY, 80, 80)
    balloonPositionY = 400;
    balloonColor = random(255);
  }
}

Moving forward with this project, I’d like to be able to have the balloons generate in multi-color (non-monochrome). Furthermore, I would like to add a pop counter, and have multiple balloons generate, to turn this small project into a full game.

Creative Switch

For this assignment, I knew that I wanted to use a material that was readily accessible, unconventional, and conductive. Gatorade was a natural choice as a medium, as the same chemicals that imbue the beverage with electrolytic properties are what make it so beneficial for biological replenishment. The circuit sits atop the Gatorade bottle top, with the ground and live wires sitting inside the Gatorade bottle. The switch occurs when the Gatorade vessel tips and the Gatorade liquid completes the circuit between the two live wires.

In order to create this circuit, I learned how to solder. This was essential not only to connect my LED (circuit success indicator) to my resistor and power source. One of the greatest frustrations I ran into in this process was that I could not find a sufficiently small heat wrap to sufficiently waterproof my ground wires, in order to prevent my circuit from shorting. To mitigate this issue, I soldered the ground wires together and wrapped the soldered connection in electrical tape; passable, but not preferable.

I created two versions, the second more aesthetically pleasing. Below are videos documenting the first test of my circuit, the completion of my first design, and the completion of my final design.

Circuit Test
Switch Test Version 1
Switch Test Final Version