Alec Albright – Project 10 – Sonic Sketch

I am using one of my grace days on this assignment

sketch

// Alec Albright
// aalbrigh@andrew.cmu.edu
// Section B
// Project 10

var margin = 150;
var radius = 30;
var r = 0;
var g = 0;
var b = 0;
var rotation = 0;
var sine; // sine oscillator
var sineAmp; // sine amplitude
var sineFreq; // sine frequency
var sawtooth; // sawtooth oscillator
var sawtoothAmp; // sawtooth amplitude
var sawtoothFreq; // sawtooth frequency
var square; // square oscillator
var squareAmp; // square amplitude
var squareFreq; // square frequency

function setup(){
    createCanvas(640, 480);
    angleMode(DEGREES);
    useSound();
}

function soundSetup() { // setup for audio generation
    // making sine
    sine = new p5.Oscillator();
    sine.setType("sine");
    sine.start();

    // making sawtooth
    sawtooth = new p5.Oscillator();
    sawtooth.setType("sawtooth");
    sawtooth.start();

    // making square wave
    square = new p5.Oscillator();
    square.setType("square");
    square.freq(440);
    square.start();
}

function draw(){
    background("white");
    fill(r, g, b);

    // mapping angle of rotation to mouseY
    // as mouse moves up and down, shapes rotate
    rotation = map(mouseY, 0, height, 0, 360);

    // drawing hexagons with specified margin and rotation
    // center
    push();
    translate(width / 2, height / 2);
    rotate(rotation);
    hexagon(0, 0, radius);
    pop();
    // circle around center hexagon
    for(let i = 0; i < nvertex; i +=1){
        // finding exactly where the hexagon at hand is located
        // sin tells us where the y coordinate is
        var centerY = sin(angle) * margin;
        // cos tells us where the x coordinate is
        var centerX = cos(angle) * margin;
        // now draw the vertex at hand
        // setting up rotation for each individual hexagon
        push();
        translate(width / 2 + centerX, height / 2 + centerY);
        rotate(rotation);
        hexagon(centerX, centerY, radius);
        pop();
        // add the next portion of the angle
        angle = angle + (360 / 6)
    }
    
    // scaling mouseX to use the whole screen for size
    // as mouse moves right, shapes get bigger
    radius = map(mouseX, 0, width, 20, 70);
    
    // as mouse moves right, more red, more sine/less sawtooth
    r = map(mouseX, 0, width, 0, 255);
    // amplitude form 0 to 1
    sineAmp = map(mouseX, 0, width, 0, 1);
    sine.amp(sineAmp);
    // amplitude from .8 to 0 (bigger amplitude on left side)
    sawtoothAmp = map(mouseX, 0, width, .2, 1);
    sawtooth.amp(1 - sawtoothAmp);

    // as mouse moves down, more blue 
    b = map(mouseY, 0, height, 0, 255);
    // as mouse moves left, more green
    g = 255 - map(mouseX, 0, width, 0, 255);

    // frequency changes depending on whether we're in top half or bottom half
    if (mouseY <= height / 2) {
        // sine goes from 440 to 1760 Hz (2 octaves) if we're in the top half
        sineFreq = constrain(map(mouseY, 0, height / 2, 440, 1760), 440, 1760);
        sine.freq(sineFreq);

        // sawtooth frequency stabilizes at minumum value
        sawtooth.freq(110);
    } else {
        // sawtooth goes from 110 to 440 Hz (2 octaves) if we're in the bottom half
        sawtoothFreq = constrain(map(mouseY, height / 2, height, 110, 440), 110, 440);
        sawtooth.freq(sawtoothFreq);
     
        // sine frequency stabilizes at maximum value
        sine.freq(1760);
    }

    // if mouse is pressed, square wave can be changed
    if (mouseIsPressed) {
        // frequency mapped to the average of mouseX and mouseY, can go from 110 to 440 Hz 
        squareFreq = constrain(map((mouseX + mouseY) / 2, 0, 640, 110, 440), 110, 440);
        square.freq(squareFreq);

        // amplitude mapped to the distance from the center of x axis
        squareAmp = constrain(map(mouseX - (width / 2), -320, 320, 0, .8), 0, .8);
        square.amp(squareAmp);
    }

    // margin depends on mouseX, keeping same distance throughout
    margin = map(mouseX, 0, width, 50, 150);
}

// 6 vertices, as a hexagon has
var nvertex = 6;
// angle we're working at (when we get to TWO_PI, we're done)
var angle = 0;

function hexagon(x, y, radius){
    // draw a hexagon at (x, y) using beginShape()
    beginShape();
    // find each vertex's specific location
    for(let i = 0; i < nvertex; i += 1){
        // finding exactly where the vertex at hand is located
        // sin tells us where the y coordinate is
        var vertexY = y + sin(angle) * radius;
        // cos tells us where the x coordinate is
        var vertexX = x + cos(angle) * radius;
        // now draw the vertex at hand
        vertex(vertexX, vertexY)
        // add the next portion of the angle
        angle += (360 / 6)
    }
    // connect beginning and end points
    endShape(CLOSE)
}

For this assignment, I added sonic features to my Project 3 – Dynamic Drawing. I added a sine wave oscillator, a sawtooth wave oscillator, and a square wave oscillator. The mappings for the amplitude and frequency of these oscillators are as follows:

  1. As the mouse moves from left to right, the sine wave amplitude increases and the sawtooth wave amplitude decreases.
  2. As the mouse moves from top to bottom on the top half of the screen, the sine wave frequency gets higher (scaling up to two octaves).
  3. As the mouse moves from top to bottom on the bottom half of the screen, the sawtooth wave frequency gets higher (scaling up to two octaves).
  4. As the average of mouseX and mouseY increases, so does the frequency of the square wave.
  5. The closer to the middle of the x-axis the mouse is, the louder the square wave becomes.

Note: the square wave can only be adjusted if the mouse is pressed!!

This process was very interesting in testing harmonic balances in my dynamic drawing, as manifested by these mappings. I certainly see a lot more dimensionality in my drawing now because of the added sound layers!

Leave a Reply