/* | |
Copy this into the console of any web page that is interactive and doesn't | |
do hard reloads. You will hear your DOM changes as different pitches of | |
audio. | |
I have found this interesting for debugging, but also fun to hear web pages | |
render like UIs do in movies. | |
*/ | |
const audioCtx = new (window.AudioContext || window.webkitAudioContext)() | |
const observer = new MutationObserver(function(mutationsList) { | |
const oscillator = audioCtx.createOscillator() | |
oscillator.connect(audioCtx.destination) | |
oscillator.type = "sine" | |
oscillator.frequency.setValueAtTime( | |
Math.log(mutationsList.length + 5) * 880, | |
audioCtx.currentTime, | |
) | |
oscillator.start() | |
oscillator.stop(audioCtx.currentTime + 0.01) | |
}) | |
observer.observe(document, { | |
attributes: true, | |
childList: true, | |
subtree: true, | |
characterData: true, | |
}) |
This comment has been minimized.
This comment has been minimized.
Great idea |
This comment has been minimized.
This comment has been minimized.
This hilarious! thanks! |
This comment has been minimized.
This comment has been minimized.
This is cool stuff, thank you for sharing! |
This comment has been minimized.
This comment has been minimized.
I can never hear my websites the same way again. I need to release these souls from their agony. |
This comment has been minimized.
This comment has been minimized.
Sounds beautiful, love it |
This comment has been minimized.
This comment has been minimized.
wow! I like it |
This comment has been minimized.
This comment has been minimized.
Make a browser extensions before somebody else does. Take the credit! cool stuff! |
This comment has been minimized.
This comment has been minimized.
True that! |
This comment has been minimized.
This comment has been minimized.
Brilliant! |
This comment has been minimized.
This comment has been minimized.
very smart !!! |
This comment has been minimized.
This comment has been minimized.
And add a sound output for network activity! |
This comment has been minimized.
This comment has been minimized.
Now this! |
This comment has been minimized.
This comment has been minimized.
Awesome! |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This is absolutely brilliant. And useful. |
This comment has been minimized.
This comment has been minimized.
Here's a funny variation that speaks out the counts in different pitches/rates const speechSynthesis = window.speechSynthesis
const min = 0
const max = 100
const bad = 15 // just a random max to enable 'bad developer' mode
const observer = new MutationObserver(function(mutationsList) {
const msg = new SpeechSynthesisUtterance()
const len = mutationsList.length
if (len > bad) {
msg.text = 'Bad Developer'
} else {
const n = len > max ? max : len
const pitch = ((n - min) / (100 - min)) * 2
msg.text = len
msg.rate = 4 - pitch * 4
msg.pitch = 2 - (pitch * 1.6 * 1.2)
}
speechSynthesis.speak(msg)
})
observer.observe(document, {
attributes: true,
childList: true,
subtree: true,
characterData: true,
}) |
This comment has been minimized.
This comment has been minimized.
Can anyone upload what they hear on some sites? |
This comment has been minimized.
This comment has been minimized.
Hahaha, great work! |
This comment has been minimized.
This comment has been minimized.
You'll just hear a Chewbacca Jr. talking |
This comment has been minimized.
This comment has been minimized.
Hahaha great idea! |
This comment has been minimized.
This comment has been minimized.
I honestly didn't like it at first, then I realized how useful it can actually be :) . So I turned it into a basic Chrome extension: https://github.com/R4meau/plink-plonk I'll be working on it every Sunday (very slow for now) and I'm open for any contributions at any time. Thanks for the head start @tomhicks. |
This comment has been minimized.
This comment has been minimized.
I have moved out the constants into variables, to be able to play with the settings more easily. // origin: https://gist.github.com/tomhicks/6cb5e827723c4eaef638bf9f7686d2d8 , tomhicks/plink-plonk.js
const audioCtx = new (window.AudioContext || window.webkitAudioContext)()
var delay = 0.03
var freqbase = 600
var freqrnd = 400
const observer = new MutationObserver(function(mutationsList) {
const oscillator = audioCtx.createOscillator()
oscillator.connect(audioCtx.destination)
oscillator.type = "sine"
oscillator.frequency.setValueAtTime(
Math.log(mutationsList.length + 5) * (Math.random()*freqrnd + freqbase),
audioCtx.currentTime,
)
oscillator.start()
oscillator.stop(audioCtx.currentTime + delay)
})
observer.observe(document, {
attributes: true,
childList: true,
subtree: true,
characterData: true,
}) Then you can play with delay and freq on the fly. |
This comment has been minimized.
This comment has been minimized.
Love this! |
This comment has been minimized.
This comment has been minimized.
This one randomly decreases/increases tone until it reaches a threshold. Makes it a bit more harmonious: // origin: https://gist.github.com/tomhicks/6cb5e827723c4eaef638bf9f7686d2d8 , tomhicks/plink-plonk.js
const audioCtx = new (window.AudioContext || window.webkitAudioContext)()
var delay = 0.03
// parameters of the random increment/decrement
var freqstart = 600
var freqlow = 400
var freqhigh = 900
var freqspeed = 50
// initial values
var freqinc = 25
var freq = 600
const observer = new MutationObserver(function(mutationsList) {
const oscillator = audioCtx.createOscillator()
oscillator.connect(audioCtx.destination)
oscillator.type = "sine"
oscillator.frequency.setValueAtTime(
Math.log(mutationsList.length + 5) * freq,
audioCtx.currentTime,
)
freq += freqinc
if (freq > freqhigh || freq<freqlow) {
// reset if we have reached the high or low bound
freq = freqstart
freqinc = (Math.random()-0.5)*freqspeed
}
oscillator.start()
oscillator.stop(audioCtx.currentTime + delay)
})
observer.observe(document, {
attributes: true,
childList: true,
subtree: true,
characterData: true,
}) |
This comment has been minimized.
This comment has been minimized.
Genius! |
This comment has been minimized.
This comment has been minimized.
Nice work! Check this out https://soundcode.now.sh too |
This comment has been minimized.
This comment has been minimized.
Absolutely wonderful! |
This comment has been minimized.
This comment has been minimized.
awesome! My computer now sounds like one from a '70s TV serial |
This comment has been minimized.
This comment has been minimized.
Could replace the pulses with Rice Krispies sounds. Now, web == tasty breakfast! |
This comment has been minimized.
This comment has been minimized.
try this on a typing test website. very enjoyable lol |
This comment has been minimized.
This comment has been minimized.
Added quantization and randomness + delay for a cuter effect https://gist.github.com/MarkArts/3d4217f957df8a30802a8cbf962fa204 // origin: https://gist.github.com/tomhicks/6cb5e827723c4eaef638bf9f7686d2d8 , tomhicks/plink-plonk.js
/*
Copy this into the console of any web page that is interactive and doesn't
do hard reloads. You will hear your DOM changes as different pitches of
audio.
I have found this interesting for debugging, but also fun to hear web pages
render like UIs do in movies.
*/
// dorian (-) C E F G- A B-
let scale = [
264, 330, 352, 391.1, 440, 488.9
]
scale = scale.concat(scale.map(x=>x*2))
console.log(scale)
function quantize(scale, freq) {
return scale.reduce(function(prev, curr){
return (Math.abs(curr - freq) < Math.abs(prev - freq) ? curr : prev);
});
}
const audioCtx = new (window.AudioContext || window.webkitAudioContext)()
const observer = new MutationObserver(observe)
function observe(mutationsList) {
// with delay
delayNote(gain => playNote(mutationsList, gain), 300, 0.2)
// without
// playNote(mutationsList)
}
// Compressor as final stage to prevent clipping
const compressor = audioCtx.createDynamicsCompressor()
compressor.threshold.setValueAtTime(-40, audioCtx.currentTime);
compressor.knee.setValueAtTime(40, audioCtx.currentTime);
compressor.ratio.setValueAtTime(12, audioCtx.currentTime);
compressor.attack.setValueAtTime(0, audioCtx.currentTime);
compressor.release.setValueAtTime(0.25, audioCtx.currentTime);
compressor.connect(audioCtx.destination)
async function playNote(mutationsList, gain = 1) {
audioCtx.resume()
const oscillator = audioCtx.createOscillator()
oscillator.type = "triangle"
const biquadFilter = audioCtx.createBiquadFilter();
biquadFilter.type = "lowpass";
const gainNode = audioCtx.createGain();
const panNode = audioCtx.createStereoPanner();
// Setup audio chain
oscillator.connect(biquadFilter);
biquadFilter.connect(gainNode);
gainNode.connect(panNode);
panNode.connect(compressor)
let freq = quantize(scale, 440 * (Math.random() * 3))
oscillator.frequency.setValueAtTime(
quantize(scale, freq),
audioCtx.currentTime,
)
// Low pass gate
biquadFilter.frequency.setValueAtTime(
quantize(scale, freq * 4),
audioCtx.currentTime
);
biquadFilter.frequency.setTargetAtTime(
freq,
audioCtx.currentTime,
0.09,
);
// accend the low pass gate with normal attenuatiob
gainNode.gain.setValueAtTime(
gain,
audioCtx.currentTime
);
gainNode.gain.setTargetAtTime(
0,
audioCtx.currentTime,
0.1,
);
// random stereo pan
panNode.pan.setValueAtTime(
Math.random() * 2 - 1,
audioCtx.currentTime
);
oscillator.start()
oscillator.stop(audioCtx.currentTime + 1)
}
async function delayNote(f, time, decay, gain = 1){
if (gain <= 0) {
return // stop repeats when they become inaudible
}
f(gain)
setTimeout( _ => delayNote(f, time, decay, gain - decay), time);
}
observer.observe(document, {
attributes: true,
childList: true,
subtree: true,
characterData: true,
}) |
This comment has been minimized.
This comment has been minimized.
Deploy this on production but use an Arnold Schwarzenegger sound bank which plays a random line at each DOM mutation. |
This comment has been minimized.
This comment has been minimized.
Wow this is probably the best gist I've ever seen |
This comment has been minimized.
This comment has been minimized.
love this |
This comment has been minimized.
This comment has been minimized.
This one's great~ |
This comment has been minimized.
This comment has been minimized.
Awesome idea! It would be nice to create some debugging library with sounds for Ajax Requests, Ajax failures, console errors etc. |
This comment has been minimized.
This comment has been minimized.
@everaldo I'm working on it at the moment: https://github.com/r4meau/plink-plonk Also, great idea about the console errors. Added this to the list of features in the README :). For the requests, it's already in the list. |
This comment has been minimized.
This comment has been minimized.
@R4meau, that's awesome! |
This comment has been minimized.
This comment has been minimized.
Maybe someone makes some chrome extension? |
This comment has been minimized.
This comment has been minimized.
And the bookmarklet version:
|
This comment has been minimized.
This comment has been minimized.
Yeah, let's do it... (adding to backlog) |
This comment has been minimized.
This comment has been minimized.
@aibolik Already in the making: https://github.com/r4meau/plink-plonk Feel free to fork and contribute... or start your own. I'm gonna go slow on it for now (Sunday only), but I'll accept useful PRs at anytime. |
This comment has been minimized.
This comment has been minimized.
Could anyone add reload support? This is so wonderful |
This comment has been minimized.
This comment has been minimized.
Its so helpful to find out the DOM manipulations happening behind the eyes!!. Good job @R4meau |
This comment has been minimized.
Haha, I wonder what kind of debugging you're into. XD