jank-client-fork/webpage/audio.js

83 lines
2.2 KiB
JavaScript

class voice{
constructor(wave,freq){
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
this.info={wave:wave,freq:freq}
this.playing=false;
this.myArrayBuffer=this.audioCtx.createBuffer(
1,
this.audioCtx.sampleRate,
this.audioCtx.sampleRate,
);
this.buffer=this.myArrayBuffer.getChannelData(0);
this.source = this.audioCtx.createBufferSource();
this.source.buffer = this.myArrayBuffer;
this.source.loop=true;
this.source.start();
this.updateWave(freq);
}
get wave(){
return this.info.wave;
}
get freq(){
return this.info.freq;
}
set wave(wave){
this.info.wave=wave;
this.updateWave()
}
set freq(freq){
this.info.freq=freq;
this.updateWave()
}
updateWave(){
const func=this.waveFucnion();
for (let i = 0; i < this.buffer.length; i++) {
this.buffer[i]=func(i/this.audioCtx.sampleRate,this.freq);
}
}
waveFucnion(){
switch(this.wave){
case "sin":
return (t,freq)=>{
return Math.sin(t*Math.PI*2*freq);
}
case "triangle":
return (t,freq)=>{
return Math.abs((4*t*freq)%4-2)-1;
}
case "sawtooth":
return (t,freq)=>{
return ((t*freq)%1)*2-1;
}
case "square":
return (t,freq)=>{
return (t*freq)%2<1?1:-1;
}
case "white":
return (t,freq)=>{
return Math.random()*2-1;
}
case "noise":
return (t,freq)=>{
return 0;
}
}
}
play(){
if(this.playing){
return;
}
this.source.connect(this.audioCtx.destination);
this.playing=true;
}
stop(){
if(this.playing){
this.source.disconnect();
this.playing=false;
}
}
}
const audio=new voice("triangle",101);
//audio.play();