t t t t looper sketch
parent
4e57ebe4f3
commit
856937ddb1
@ -0,0 +1,95 @@
|
||||
// The surface where to tap
|
||||
const ttt = document.querySelector("#ttt")
|
||||
|
||||
// The input to store a sequence
|
||||
const s = document.querySelector("#s")
|
||||
|
||||
|
||||
let series = []
|
||||
let initial = null
|
||||
|
||||
// The function of a tap
|
||||
const tap = () => {
|
||||
if (initial == null) {
|
||||
initial = new Date()
|
||||
series.push(0)
|
||||
} else {
|
||||
series.push((new Date() - initial))
|
||||
}
|
||||
|
||||
ttt.innerHTML = series
|
||||
}
|
||||
|
||||
|
||||
const stap = () => {
|
||||
if (initial == null) return
|
||||
|
||||
// insert the final value
|
||||
series.push((new Date() - initial))
|
||||
|
||||
// copy the series
|
||||
let sequence = series
|
||||
|
||||
// reset series and initial date
|
||||
series = []
|
||||
initial = null
|
||||
|
||||
return sequence
|
||||
}
|
||||
|
||||
const audioContext = new AudioContext()
|
||||
const gain = new GainNode(audioContext, {
|
||||
value: 0.05
|
||||
})
|
||||
|
||||
|
||||
const playNoise = (bandHz=1000, time=0) => {
|
||||
|
||||
let noiseDuration = 0.05
|
||||
|
||||
const bufferSize = audioContext.sampleRate * noiseDuration
|
||||
const noiseBuffer = new AudioBuffer({
|
||||
length: bufferSize,
|
||||
sampleRate: audioContext.sampleRate
|
||||
})
|
||||
|
||||
const data = noiseBuffer.getChannelData(0)
|
||||
for (let i=0; i<bufferSize; i++){
|
||||
data[i] = Math.random() * 2 - 1;
|
||||
}
|
||||
|
||||
|
||||
const noise = new AudioBufferSourceNode(audioContext, {
|
||||
buffer: noiseBuffer
|
||||
})
|
||||
|
||||
const bandpass = new BiquadFilterNode(audioContext, {
|
||||
type: "bandpass",
|
||||
frequency: bandHz
|
||||
})
|
||||
|
||||
noise.connect(bandpass).connect(gain).connect(audioContext.destination);
|
||||
noise.start(time)
|
||||
}
|
||||
|
||||
const promiSeq = (sequence) => {
|
||||
return new Promise((resolve)=>{
|
||||
const seq = (sequence = []) => {
|
||||
if (!sequence.length) resolve()
|
||||
setTimeout( ()=> playNoise(), sequence[0])
|
||||
sequence.shift()
|
||||
seq(sequence)
|
||||
}
|
||||
seq(sequence)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
ttt.addEventListener("click", () => tap())
|
||||
|
||||
s.addEventListener("click", () => {
|
||||
let sequence = stap();
|
||||
promiSeq([...sequence])
|
||||
})
|
||||
|
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>t t t</title>
|
||||
<script src="ttt.js" defer></script>
|
||||
<style>
|
||||
#ttt {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#s {
|
||||
position: absolute;
|
||||
top: 100px;
|
||||
left: 100px;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<button id="s">Send</button>
|
||||
<div id="ttt"></div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,107 @@
|
||||
// The surface where to tap
|
||||
const ttt = document.querySelector("#ttt")
|
||||
|
||||
// The input to store a sequence
|
||||
const s = document.querySelector("#s")
|
||||
|
||||
|
||||
let series = []
|
||||
let initial = null
|
||||
|
||||
// The function of a tap
|
||||
const tap = () => {
|
||||
if (initial == null) {
|
||||
initial = new Date()
|
||||
series.push(0)
|
||||
} else {
|
||||
series.push((new Date() - initial))
|
||||
}
|
||||
|
||||
ttt.innerHTML = series
|
||||
}
|
||||
|
||||
|
||||
const stap = () => {
|
||||
if (initial == null) return
|
||||
|
||||
// insert the final value
|
||||
series.push((new Date() - initial))
|
||||
|
||||
// copy the series
|
||||
let sequence = series
|
||||
|
||||
// reset series and initial date
|
||||
series = []
|
||||
initial = null
|
||||
|
||||
return sequence
|
||||
}
|
||||
|
||||
const audioContext = new AudioContext()
|
||||
const gain = new GainNode(audioContext, {
|
||||
value: 0.05
|
||||
})
|
||||
|
||||
|
||||
const playNoise = (bandHz=1000, time=0) => {
|
||||
|
||||
let noiseDuration = 0.05
|
||||
|
||||
const bufferSize = audioContext.sampleRate * noiseDuration
|
||||
const noiseBuffer = new AudioBuffer({
|
||||
length: bufferSize,
|
||||
sampleRate: audioContext.sampleRate
|
||||
})
|
||||
|
||||
const data = noiseBuffer.getChannelData(0)
|
||||
for (let i=0; i<bufferSize; i++){
|
||||
data[i] = Math.random() * 2 - 1;
|
||||
}
|
||||
|
||||
|
||||
const noise = new AudioBufferSourceNode(audioContext, {
|
||||
buffer: noiseBuffer
|
||||
})
|
||||
|
||||
|
||||
const bandpass = new BiquadFilterNode(audioContext, {
|
||||
type: "bandpass",
|
||||
frequency: bandHz
|
||||
})
|
||||
|
||||
noise.connect(bandpass).connect(gain).connect(audioContext.destination);
|
||||
noise.start(time)
|
||||
}
|
||||
|
||||
const playOsc = (freq=440) => {
|
||||
const osc = new OscillatorNode(audioContext, {
|
||||
type: "sine",
|
||||
frequency: freq
|
||||
})
|
||||
osc.connect(gain).connect(audioContext.destination);
|
||||
osc.start()
|
||||
osc.stop(audioContext.currentTime + 0.1)
|
||||
}
|
||||
|
||||
const seq = (sequence, fn) => {
|
||||
if (!sequence.length) return
|
||||
setTimeout(fn, sequence[0])
|
||||
let copy = [...sequence]
|
||||
copy.shift()
|
||||
seq(copy,fn)
|
||||
}
|
||||
|
||||
|
||||
ttt.addEventListener("click", () => tap())
|
||||
|
||||
|
||||
s.addEventListener("click", () => {
|
||||
let sequence = stap();
|
||||
let period = sequence.pop()
|
||||
let freq = Math.random() * 1000
|
||||
seq(sequence, ()=> playOsc(freq))
|
||||
setInterval(seq, period, sequence, ()=>playOsc(freq))
|
||||
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue