Current File : /home/jeshor13/11bsouth.com/HonkBoard0.6/sketch.js |
// Jesse Horwitz Nov 5 2015
// how do I make using the admin interface clear --- what is the user flow???
// enable people to figure out what it is -- QR codes???
// Project the honk sign !!!!
// output data in a meaningful way
// the way sounds effect our hearing
// Questions: Draw spectrograph faster? , Save and recall JSON, Tips for sound isolation, Any other UI, data or sound recognition tips? sound Filters?
var honkSample1 = [73];
var honkSample2 = [0]
var honkSoundLevels = [honkSample1, honkSample2 /*, honkSample3, honkSample4, honkSample5*/ ]
var honkCount = 0
var honkCount0 = 0
var headlineText = "Your Honks"
var midlineText = "Today's Conditions:"
var bottomlineText = "Total Honks This Week:"
var modeSelector;
var mode = 'Sign';
var micCheckbox;
var micMode = true;
var honkSoundsCheckbox;
var honkSoundsMode = false;
var fft;
var mic;
var p_spectrum = []
var p_spectrumMax = [0]
var p_spectrumAvg = []
var spectrum = [];
var backgroundHonkTimer = 0
var trailingAvgTimer = 0
var spectrographDrawTimer = 1000
var leastSq = 0
var mousePressTimer = 0;
var spectrograph = []
var honkStoreTimer = 0
var analysies = 0
var fftSpectrumLength = 350
var adjSpectrum = [0]
//var adjHonkSoundLevels = []
var leastSqHonk = []
var leastSqAvg = 0
var leastSqZero = 0
var honkJson = {}
var honkData = []
var analysiesPerTime = 0
var filterTop
var filterBottom
var peakDetect;
var pauseMode = false;
var globalArray = []
var spectsTime = 0
var soundRecCount = 0
var displayHonkCount = 0
var displayHonkCount0 = 0
var displayHonkCountTimer = 0
var honkCount1 = 0
var whileHonks = 0
var notHonkCeiling = 0
var honkFloor = 0
var nonHonkFeather = 0
var honkFeather = 0
var minHonkPeaks = 0
var minNonHonkValleys = 0
var notHonkCeilingInput
var honkFloorInput
var nonHonkFeatherInput
var honkFeatherInput
var minHonkPeaksInput
var minNonHonkValleysInput
var notHonkCeilingLable
var honkFloorLable
var nonHonkFeatherLable
var honkFeatherLable
var minHonkPeaksLable
var minNonHonkValleysLable
var theSign
var panicMode = false
var panicNotches = 0
var panicTimer = 0
var streetSoundsCheckBox
function preload() {
externalMedia() // see media.js for external files
}
function setup() {
theSign = createCanvas(windowWidth, windowHeight * 0.90) // create canvas using full display width and 90% of
//
// micCheckbox = createCheckbox('Mic?', true);
// micCheckbox.changed(micCheckedEvent);
//
honkSoundsCheckbox = createCheckbox('Honk Sounds?', false);
honkSoundsCheckbox.changed(honkSoundsCheckedEvent);
//
button = createButton('Save Honk Data [Broken]');
button.mousePressed(saveOut);
//
button2 = createButton('Pause');
button2.mousePressed(pause);
//
selector = createSelect();
selector.option('Sign');
selector.option('Data');
selector.option('Settings');
selector.changed(selectorEvent);
//
//
//filterTop = new p5.LowPass()
//filterTop.setType("highpass")
// //filterBottom = new p5.HighShelf
//filterTop.freq(500)
// //filterBottom.freq(350)
// mic = new p5.AudioIn();
// //mic.connect(filterTop)
// mic.start();
fft = new p5.FFT();
fft.setInput();
carHorns = [carHornsLong, carHornsShort, carHornsShort2,
carHornsLong2, carHornsLong3, carHornOne, streetSound1/*, streetSound2*/
];
carHorns[6].loop()
//
loadJSON('Honks.json', dataLoader)
//
// domInputs = [notHonkCeilingInput, honkFloorInput, nonHonkFeatherInput, honkFeatherInput, minHonkPeaksInput, minNonHonkValleysInput]
notHonkCeilingInput = createInput();
notHonkCeilingInput.size(25)
notHonkCeilingInput.position(windowWidth * 0.23, windowHeight * 0.33);
notHonkCeilingInput.attribute("value", 12.5)
notHonkCeilingInput.input(notHonkCeilingInputChanged)
notHonkCeilingLable = createP('"Low" amplitude ceiling - This value helps determine which frequencies are unusually loud')
notHonkCeilingLable.position((windowWidth * 0.23) + 35, (windowHeight * 0.33) - 15);
notHonkCeilingLable.style("color", "#ffffff")
honkFloorInput = createInput();
honkFloorInput.size(25)
honkFloorInput.position(windowWidth * 0.23, (windowHeight * 0.33) + 45);
honkFloorInput.attribute("value", 35)
honkFloorInput.input(honkFloorInputChanged)
honkFloorLable = createP('"High" amplitude floor - This value helps determine which frequencies are very loud')
honkFloorLable.position((windowWidth * 0.23) + 35, (windowHeight * 0.33) + 30);
honkFloorLable.style("color", "#ffffff")
nonHonkFeatherInput = createInput();
nonHonkFeatherInput.size(25)
nonHonkFeatherInput.position(windowWidth * 0.23, (windowHeight * 0.33) + 90);
nonHonkFeatherInput.attribute("value", 12.5)
nonHonkFeatherInput.input(nonHonkFeatherInputChanged)
nonHonkFeatherLable = createP('Low-sound foward tolerance - Helps to identify continous low or average sounds')
nonHonkFeatherLable.position((windowWidth * 0.23) + 35, (windowHeight * 0.33) + 75);
nonHonkFeatherLable.style("color", "#ffffff")
honkFeatherInput = createInput();
honkFeatherInput.size(25)
honkFeatherInput.position(windowWidth * 0.23, (windowHeight * 0.33) + 135);
honkFeatherInput.attribute("value", 1.5)
honkFeatherInput.input(honkFeatherInputChanged)
honkFeatherLable = createP('High-sound foward tolerance - Helps to identify continuous loud sounds')
honkFeatherLable.position((windowWidth * 0.23) + 35, (windowHeight * 0.33) + 120);
honkFeatherLable.style("color", "#ffffff")
minHonkPeaksInput = createInput();
minHonkPeaksInput.size(25)
minHonkPeaksInput.position(windowWidth * 0.23, (windowHeight * 0.33) + 180);
minHonkPeaksInput.attribute("value", 3)
minHonkPeaksInput.input(minHonkPeaksInputChanged)
minHonkPeaksLable = createP('Minimum peaks per honk - The number of continuous loud sounds lasting longer than 1/8th of a second')
minHonkPeaksLable.position((windowWidth * 0.23) + 35, (windowHeight * 0.33) + 165);
minHonkPeaksLable.style("color", "#ffffff")
minNonHonkValleysInput = createInput();
minNonHonkValleysInput.size(25)
minNonHonkValleysInput.position(windowWidth * 0.23, (windowHeight * 0.33) + 225);
minNonHonkValleysInput.attribute("value", int(fftSpectrumLength / 3))
minNonHonkValleysInput.input(minNonHonkValleysInputChanged)
minNonHonkValleysLable = createP('Minimum valleys per honk - The number of continuous low or average sounds lasting longer than 1/8th of a second')
minNonHonkValleysLable.position((windowWidth * 0.23) + 35, (windowHeight * 0.33) + 210);
minNonHonkValleysLable.style("color", "#ffffff")
notHonkCeilingInput.hide()
honkFloorInput.hide()
nonHonkFeatherInput.hide()
honkFeatherInput.hide()
minHonkPeaksInput.hide()
minNonHonkValleysInput.hide()
notHonkCeilingLable.hide()
honkFloorLable.hide()
nonHonkFeatherLable.hide()
honkFeatherLable.hide()
minHonkPeaksLable.hide()
minNonHonkValleysLable.hide()
notHonkCeiling = 12.5
honkFloor = 35
nonHonkFeather = 12.5
honkFeather = 1.5
minHonkPeaks = 3
minNonHonkValleys = int(fftSpectrumLength / 3)
}
function draw() {
p_soundStorage()
trailingAverage()
honkDisplayNumber()
soundRecCount++
if (millis() > 2000) {
spectsTime = int(analysiesPerTime / 8)
soundRecognition2()
}
if (honkSoundsMode == true) {
playHonkSound()
}
if (mode == 'Sign') {
basicSign()
}
if (mode == 'Data') {
consoleData()
drawSpectrograph()
}
if (mode == 'Settings') {
consoleData()
consoleSettings()
}
//
if (honkCount0 != honkCount) {
honkData[honkData.length++] = {
"seshID": honkCount,
"honk": true,
//"fft": spectrum,
"time": [year(), month(), day(), hour(), minute(), second()]
}
}
//
honkCount0 = honkCount
displayHonkCount0 = displayHonkCount
}
// function micCheckedEvent() {
// if (this.checked()) {
// micMode = true;
// print("true");
// } else {
// micMode = false;
// print("false");
// }
// }
function honkSoundsCheckedEvent() {
if (this.checked()) {
honkSoundsMode = true;
} else {
honkSoundsMode = false
}
}
function mousePressed() {
if (millis() - mousePressTimer > 1000 && mouseX <= width * 0.99 && mouseY <= height * 0.20) {
carHornOne.setVolume(0.3);
carHornOne.play();
mousePressTimer = millis()
}
}
function selectorEvent() {
mode = selector.value()
if (mode == 'Sign') {
background(0)
}
if (mode == 'Data') {
background(230)
}
if (mode == 'Settings') {
background(1)
}
if (mode != 'Settings') {
notHonkCeilingInput.hide()
honkFloorInput.hide()
nonHonkFeatherInput.hide()
honkFeatherInput.hide()
minHonkPeaksInput.hide()
minNonHonkValleysInput.hide()
notHonkCeilingLable.hide()
honkFloorLable.hide()
nonHonkFeatherLable.hide()
honkFeatherLable.hide()
minHonkPeaksLable.hide()
minNonHonkValleysLable.hide()
}
}
function playHonkSound() {
if (millis() - backgroundHonkTimer > 10000) {
var i = int(random(0, 4))
carHorns[i].setVolume(0.3);
carHorns[i].play();
backgroundHonkTimer = millis()
}
}
function trailingAverage() { // consider adjusting this so that you only update the average whith new numbers
if (millis() - trailingAvgTimer >= 500) {
for (var i = 0; i < p_spectrum[0].length; i++) {
var frequency = i;
var sumAmplitude = 0;
for (var j = 0; j < p_spectrum.length; j++) {
var currentSpectrum = p_spectrum[j];
var amplitude = currentSpectrum[frequency];
sumAmplitude += amplitude;
}
var averageAmplitude = sumAmplitude / p_spectrum.length;
p_spectrumAvg[frequency] = averageAmplitude;
}
trailingAvgTimer = millis()
}
}
function drawSpectrograph() {
if (millis() - spectrographDrawTimer > 5000) {
var xMap = []
var yMap = []
var fillFreq = []
var p_i = 0
var p_j = 0
// each rectangle is 1/4rd of a second and ?? Hz
for (var i = 0; i < 160; i++) {
for (var j = 0; j < 160; j++) {
xMap.push(int(map(i, 0, 160, width * 0.22, width * 0.99)))
yMap.push(int(map(-j, -160, 0, 0, height * 0.99)))
var ii = ceil(map(i, 0, 160, 0, p_spectrum.length))
var jj = ceil(map(j, 0, 160, 0, p_spectrum[i].length))
var kk = p_spectrum[ii]
fillFreq.push(kk[jj])
}
}
colorMode(HSB)
noStroke()
var cc = ceil((((width * 0.99) - (width * 0.22)) / (sqrt(xMap.length))))
var gg = ceil((height * 0.98) / (sqrt(xMap.length)))
for (var k = 0; k < (xMap.length); k++) {
fill(fillFreq[k], 225, 255)
rect(xMap[k], (yMap[k]), cc, gg)
}
colorMode(RGB)
spectrographDrawTimer = millis()
}
}
function p_soundStorage() {
spectrum = fft.analyze();
for (var zz = 0; zz < (((1024) - (fftSpectrumLength))); zz++) {
spectrum.pop()
}
for (var i = 0; i < honkSoundLevels.length; i++) {
for (var iii = 0; iii < (((honkSoundLevels[i].length) - (fftSpectrumLength))); iii++) {
honkSoundLevels[i].pop()
}
}
p_spectrum.push(spectrum)
analysies++
if (millis() - honkStoreTimer > 1000) {
analysiesPerTime = analysies
analysies = 0
honkStoreTimer = millis()
}
while (p_spectrum.length >= 30 * analysiesPerTime && p_spectrum.length >= 100) {
p_spectrum.shift()
}
}
// function soundRecognition1() {
// leastSqHonk = []
// leastSqHonk.length = honkSoundLevels.length
// leastSqAvg = 0
// leastSqZero = 0
// for (ii = 0; ii < honkSoundLevels.length; ii++) {
// var kk = honkSoundLevels[ii]
// for (var jj = 0; jj < spectrum.length; jj++) {
// leastSqHonk[ii] = int(leastSqHonk[ii] + ((kk[jj] - spectrum[jj]) * (kk[jj] - spectrum[jj])))
// leastSqAvg = int(leastSqAvg + (p_spectrumAvg[jj] - spectrum[jj]) * (p_spectrumAvg[jj] - spectrum[jj]))
// leastSqZero = int(leastSqZero + (0 - spectrum[jj]) * (0 - spectrum[jj]))
// }
// }
// var honkMatch = 0
// for (pp = 0; pp < honkSoundLevels.length; pp++) {
// if ((leastSqHonk[pp] / (honkSoundLevels[pp].length)) <= (leastSqAvg / p_spectrumAvg.length) && ((leastSqZero / p_spectrumAvg.length) >= leastSqAvg / p_spectrumAvg.length)) {
// honkMatch++
// }
// }
// if (honkMatch >= 1) {
// honkCount++
// }
// }
function soundRecognition2() {
// First determine if a single spectrum has
var possibleHonks = []
var noiseLen = 1
var nonHonks = []
var avgLen = 1
spectsTime = int(analysiesPerTime / 8)
for (j = p_spectrum.length - spectsTime; j < p_spectrum.length; j++) {
for (i = 0; i < fftSpectrumLength; i++) {
if (p_spectrum[j][i] < int(p_spectrumAvg[i] + notHonkCeiling /*+ (0.0005 * i)*/ )) {
avgLen = 1
for (v = avgLen; v < spectsTime; v++) {
if (p_spectrum.length > j + v) {
if (p_spectrum[j + v][i] > (p_spectrum[j][i] - nonHonkFeather)) {
if (p_spectrum[j + v][i] < (p_spectrum[j][i] + nonHonkFeather)) {
avgLen++
}
}
}
}
if (avgLen > spectsTime - 2) {
nonHonks.push(avgLen)
}
}
if (p_spectrum[j][i] > int(p_spectrumAvg[i] + honkFloor)) {
noiseLen = 1
for (k = noiseLen; k < spectsTime; k++) {
if (p_spectrum.length > j + k) {
if (p_spectrum[j + k][i] > (p_spectrum[j][i] - honkFeather)) {
if (p_spectrum[j + k][i] < (p_spectrum[j][i] + honkFeather)) {
noiseLen++
}
}
}
}
if (noiseLen > spectsTime - 2) {
possibleHonks.push(noiseLen)
}
}
}
}
var honkMatch = 0
if ((possibleHonks.length > minHonkPeaks) && (nonHonks.length > minNonHonkValleys)) {
honkMatch++
}
if (honkMatch >= 1) {
honkCount++
whileHonks++
}
}
function dataLoader(jsonHonk) {
honkData = [jsonHonk]
}
function saveOut() { //NOT YET WORKING
if (honkCount0 == honkCount) {
print(honkData)
saveJSON(honkData, 'Honks.json');
//{ "seshID": 0, "honk": false, "fft": [0], "time": [ 0, 0, 0, 0, 0,0 ]}
}
}
function pause() {
pauseMode = !pauseMode
if (pauseMode == true) {
noLoop()
} else {
loop()
}
}
// domInputs = [notHonkCeilingInput, honkFloorInput, nonHonkFeatherInput, honkFeatherInput, minHonkPeaksInput, minNonHonkValleysInput]
function notHonkCeilingInputChanged() {
if (notHonkCeilingInput.value() > 0 && notHonkCeilingInput.value() < 255) {
notHonkCeiling = int(notHonkCeilingInput.value())
print(notHonkCeiling)
}
}
function honkFloorInputChanged() {
if (honkFloorInput.value() > 0 && honkFloorInput.value() < 255) {
honkFloor = int(honkFloorInput.value())
print(honkFloor)
}
}
function nonHonkFeatherInputChanged() {
if (nonHonkFeatherInput.value() > 0 && nonHonkFeatherInput.value() < 255) {
nonHonkFeather = int(nonHonkFeatherInput.value())
print(nonHonkFeather)
}
}
function honkFeatherInputChanged() {
if (honkFeatherInput.value() > 0 && honkFeatherInput.value() < 255) {
honkFeather = int(honkFeatherInput.value())
print(honkFeather)
}
}
function minHonkPeaksInputChanged() {
if (minHonkPeaksInput.value() > 0 && minHonkPeaksInput.value() < fftSpectrumLength) {
minHonkPeaks = int(minHonkPeaksInput.value())
print(minHonkPeaks)
}
}
function minNonHonkValleysInputChanged() {
if (minNonHonkValleysInput.value() > 0 && minNonHonkValleysInput.value() < fftSpectrumLength) {
minNonHonkValleys = int(minNonHonkValleysInput.value())
print(minNonHonkValleys)
}
}