The Project:
Turning barks into
GOAL: Develop a sketch that responds barking over an extended period of time. For each bark, the sketch records a random shape that grows based on the duration of the bark, and provides a time stamp for that particular bark.
The user will be able to track their dogs daily barking, to find out of there is a pattern to what trigger’s the barking and/or anxiety of their pet. With this information, they can work on a way to eliminate the noise and the stress of the dog.
ADDITIONAL FEATURES: If time and technical ability allows, I would like to add on these features:
1) Record the noise attached to the shape and be able to playback when the shape is pressed
2) Have the option to export the sketch image that was drawn as a jpeg
TAKE ONE:
Using the git resources and P5 sound library, I began to get the mic to connect to drawing one shape and not erase it based on the sound. At this point, the shape is correlated to the volume.
function setup() {
createCanvas (1000, 700);
barking = new p5.AudioIn();
barking.start();
}
function draw() {
//background (50,100, 190, 109);
var vol = barking.getLevel();
fill (random (255), random (255), random (255));
stroke (0);
if (vol > 0) {
ellipse (width/2, height/2, 10+vol*2000, 10+vol*2000);
}
}
TAKE TWO:
I continue to try and find a way to get the shape to react to sound LENGTH, not volume. I have tried barking.duration, looked at FFTs and a host of other options. None of them seem to be the way.
Using FFT and waveform(); I got this crazy display (and a similar event happened when using .analyze):
function setup() {
createCanvas(1000, 700);
barking = new p5.AudioIn();
barking.start();
fft = new p5.FFT();
fft.setInput(barking);
}
function draw() {
background(0);
var barkingTime = fft.waveform();
fill(random(255), random(255), random(255));
beginShape();
stroke(255, 0, 0);
for (i = 0; i < barkingTime.length; i++) {
ellipse(random(0, width), random(0, height), barkingTime.length/100, barkingTime.length/100);
}
}
I then changed the for loop to an if statement and got this flashing series of various dots, seemingly not impacted by sound at all:
function setup() {
createCanvas(1000, 700);
barking = new p5.AudioIn();
barking.start();
fft = new p5.FFT();
fft.setInput(barking);
}
function draw() {
background(0);
var barkingTime = fft.analyze();
fill(random(255), random(255), random(255));
if (barkingTime.length > 1) {
beginShape();
stroke(0);
ellipse(random(0, width), random(0, height), barkingTime.length / 20, barkingTime.length / 20);
}
}
TAKE 3:
Playing with threshold…I had looked at this before but didn’t think it was the right process. However, I tested it out and I a getting good results. Not 100% sure yet that it is tracking the duration. And I am getting multiple shapes for one sound. This was tracking WITH ACTUAL BARKING.
function setup() {
createCanvas(1000, 700);
background(0, 100, 229);
//microph on
barking = new p5.AudioIn
barking.start();
}
function draw() {
var vol = barking.getLevel();
var threshold1 = 0.1;
var threshold2 = 0.2;
var threshhold3 = 0.3;
var threshhold4 = 0.4;
var threshhold5 = 0.5;
var threshhold6 = 0.6;
var threshhold7 = 0.7;
var threshhold8 = 0.8;
var threshhold9 = 0.9;
var threshhold10 = 1.0;
if (vol > threshold1 && vol <threshold2) {
stroke(0);
fill(random(255), random(255), random(255));
ellipse(random(1000), random(700), vol * 100, vol * 100);
}
}
TAKE 4:
Playing with FFT, I was able to get a single color to freeze for the duration of a particular sound. This was tracked with multiple dogs barking.
Unsaved QuickTime Player Document.qtpxcomposition
Getting somewhere…!
TAKE 5:
After some office hours with Jason the resident to go over my plans and a p5 Sound Library info session, it occurs to me that I might need to pull an array for the sound input and map the shape to the length of the array. However, I am still unsure how to make an array based on length of sound.
So to avoid making an array, I came up with a plan to record the sound input and map the size of the circle to the length of the recording. The first incarnation, nothing is working, except the background color.
var mic, recorder, soundFile;
var state = 0;
var threshold = 0.1
var circle
function setup() {
createCanvas(1000, 700);
background(0, 100, 229);
mic = new p5.AudioIn();
mic.start();
recorder = new p5.SoundRecorder();
recorder.setInput(mic);
soundFile = new p5.SoundFile
}
function draw() {
var vol = mic.getLevel
if (state == 0 && mic.enabled && vol > threshold) {
recorder.record(soundFile);
} else if (state === 1 && mic.enabled && vol < threshold) {
recorder.stop();
} else if (state === 3)
save(soundFile, circle)
}
function circle() {
stroke(0);
fill(random(255), random(255), random(255));
ellipse(random(1000), random(700), soundFile.length * 100, soundFile.length * 100);
}
I changed the code a bit…and then got this wild result:
var mic, recorder, soundFile;
var state = 0;
var threshold = 0.1
var circle
function setup() {
createCanvas(1000, 700);
background(0, 100, 229);
mic = new p5.AudioIn();
mic.start();
recorder = new p5.SoundRecorder();
recorder.setInput(mic);
soundFile = new p5.SoundFile();
}
function draw() {
var vol = mic.getLevel
if (state == 0 && vol > threshold) {
recorder.record(soundFile);
state++;
} else if (state === 1 && vol < threshold) {
recorder.stop();
state++;
} else if (state === 2)
soundFile.play
stroke(0);
fill(random(255), random(255), random(255));
ellipse(random(1000), random(700), soundFile.play.length * 100, soundFile.play.length * 100);
}
TAKE 6:
I also went back to another incarnation of the sketch to add on the time stamp of the noise. For some reason the time stampage is not working in my p5. I keep getting this result:
var barking;
var barkLevel = 0.3;
var threshold = 0.1;
var barkLoudest = 1.0;
var barkingNow = false;
// var month = month();
// var day = day();
var hour = hour();
var minute= minute();
function setup() {
createCanvas(1000, 700);
background(0, 100, 229);
//microph on
barking = new p5.AudioIn
barking.start();
}
function draw() {
var vol = barking.getLevel();
if (vol > threshold && !barkingNow) {
stroke(0);
fill(random(255), random(255), random(255));
ellipse(random(1000), random(700), vol * 100, vol*100);
text (“time stamp”+hour+”:”+minute,20, 20);
barkingNow = true;
} else if (barkingNow && vol < threshold) {
barkingNow = false;
}
}
TAKE 7:
I tried to play with the amplitude code that we worked on in Jason’s seminar. I had some strange results. The screen immediately gets covered in yellow circles until the background is no longer visible. A far cry from its original code and from the goals of my project. I am not quite sure why the array is generating from “ampLevelLength” and where and what is being pushed and spliced. Also, this seems to be disconnected from the mic input…or just very sensitive to sound.
var mic;
var amp;
var ampLevelLength = 200; //why is this 200?
var ampLevels = new Array(ampLevelLength);
var rectWidth;
var spacing = 0.1;
function setup() {
createCanvas(1000, 700);
rectMode(CENTER);
fill(255, 255, 19);
noStroke();
rectWidth = width / ampLevelLength * 0.9; //adds spacing
mic = new p5.AudioIn();
mic.start();
amp = new p5.Amplitude();
amp.smooth(0.40);
amp.setInput(mic);
//mic.connect(amp); <— web audio api approach
}
function draw() {
background(45, 68, 207);
//get rms level
var rms = amp.getLevel();
console.log(rms);
// var h = map(rms, 0, 0.5, height, 0);
// ellipse(width / 2, h, 50, 50);
ampLevels.push(rms);
ampLevels.splice(0, 1);
drawLevels();
}
function drawLevels() {
for (var i = 0; i < ampLevelLength; i++) {
var x = map(i, 0, ampLevelLength, random(1000), random(700));
var h = map(ampLevels[i], 0, 1, random(1000), random(700));
stroke(0);
ellipse(random(1000), random(700), h, h);
}
}
TAKE 8: PROGRESS
Returning to the time stamp & threshold model in TAKE 6…
After working with Jason and seeing that I had the variables for time in the wrong place, and that I needed to add parenthesis, I got the stamp to work! The next step was to have it mapped along with where that particular circle for that particular bark ended up. I thought I would need to create the ellipse as an object
and do a this.x and this.y bit. HOWEVER, I made a local variable in the draw loop for x & y. At this point of the sketch, this works, although in the future, I believe I will need to change it to get the results that i want.
Apparently I was doing a lot of “barking.”
PLAY WITH THE CODE HERE:
TAKE 9: Constructor Function + mouseIsPressed
I tried making the ellipses into a function and was able to call that in the sketch to draw the same thing.
var barking;
var barkLevel = 0.3;
var threshold = 0.1;
var barkLoudest = 1.0;
var barkingNow = false;
function setup() {
createCanvas(1000, 700);
background(0, 100, 229);
//microph on
barking = new p5.AudioIn
barking.start();
}
function mouseClicked() {
}
function draw() {
var vol = barking.getLevel();
if (vol > threshold && !barkingNow) {
barkMark();
barkingNow = true;
} else if (barkingNow && vol < threshold) {
barkingNow = false;
}
}
_____barkMark.js_________
function barkMark(x, y, z) {
var vol = barking.getLevel();
push();
this.x = random(1000);
this.y = random(700);
stroke(0);
fill(random(255), random(255), random(255));
ellipse(this.x, this.y, vol * 100, vol * 100);
pop();
this.clicked = function() {
text(“bark time:” + hour() + “:” + minute() + “:” + second(), this.x + (vol * 100) / 2, this.y + vol);
}
}
_________________________________________________
However, I wanted to be able to call an action to each particular ellipse that is drawn, the action being if the mouse is pressed and held on that particular ellipse, it will show the time stamp for that. I tried many many (many) different ways and was not able to. According to the p5.js video #6.7, this is best done with a for loop. However, I am not creating a for loop with these ellipses, they are all separate events happening in response to an input via the microphone. This is where I remain stuck at the moment.
Leave a Reply