jank-client-fork/webpage/audio.ts
2024-09-02 15:59:56 -05:00

164 lines
3.4 KiB
TypeScript

import{getBulkInfo}from"./login.js";
class Voice{
audioCtx:AudioContext;
info:{wave:string|Function,freq:number};
playing:boolean;
myArrayBuffer:AudioBuffer;
gainNode:GainNode;
buffer:Float32Array;
source:AudioBufferSourceNode;
constructor(wave:string|Function,freq:number,volume=1){
this.audioCtx = new (window.AudioContext)();
this.info={wave,freq};
this.playing=false;
this.myArrayBuffer=this.audioCtx.createBuffer(
1,
this.audioCtx.sampleRate,
this.audioCtx.sampleRate,
);
this.gainNode = this.audioCtx.createGain();
this.gainNode.gain.value=volume;
this.gainNode.connect(this.audioCtx.destination);
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();
}
get wave():string|Function{
return this.info.wave;
}
get freq():number{
return this.info.freq;
}
set wave(wave:string|Function){
this.info.wave=wave;
this.updateWave();
}
set freq(freq:number){
this.info.freq=freq;
this.updateWave();
}
updateWave():void{
const func=this.waveFunction();
for(let i = 0; i < this.buffer.length; i++){
this.buffer[i]=func(i/this.audioCtx.sampleRate,this.freq);
}
}
waveFunction():Function{
if(typeof this.wave === "function"){
return this.wave;
}
switch(this.wave){
case"sin":
return(t:number,freq:number)=>{
return Math.sin(t*Math.PI*2*freq);
};
case"triangle":
return(t:number,freq:number)=>{
return Math.abs((4*t*freq)%4-2)-1;
};
case"sawtooth":
return(t:number,freq:number)=>{
return((t*freq)%1)*2-1;
};
case"square":
return(t:number,freq:number)=>{
return(t*freq)%2<1?1:-1;
};
case"white":
return(_t:number,_freq:number)=>{
return Math.random()*2-1;
};
case"noise":
return(_t:number,_freq:number)=>{
return 0;
};
}
return new Function();
}
play():void{
if(this.playing){
return;
}
this.source.connect(this.gainNode);
this.playing=true;
}
stop():void{
if(this.playing){
this.source.disconnect();
this.playing=false;
}
}
static noises(noise:string):void{
switch(noise){
case"three":{
const voicy=new Voice("sin",800);
voicy.play();
setTimeout(_=>{
voicy.freq=1000;
},50);
setTimeout(_=>{
voicy.freq=1300;
},100);
setTimeout(_=>{
voicy.stop();
},150);
break;
}
case"zip":{
const voicy=new Voice((t:number,freq:number)=>{
return Math.sin(((t+2)**(Math.cos(t*4)))*Math.PI*2*freq);
},700);
voicy.play();
setTimeout(_=>{
voicy.stop();
},150);
break;
}
case"square":{
const voicy=new Voice("square",600,0.4);
voicy.play();
setTimeout(_=>{
voicy.freq=800;
},50);
setTimeout(_=>{
voicy.freq=1000;
},100);
setTimeout(_=>{
voicy.stop();
},150);
break;
}
case"beep":{
const voicy=new Voice("sin",800);
voicy.play();
setTimeout(_=>{
voicy.stop();
},50);
setTimeout(_=>{
voicy.play();
},100);
setTimeout(_=>{
voicy.stop();
},150);
break;
}
}
}
static get sounds(){
return["three","zip","square","beep"];
}
static setNotificationSound(sound:string){
const userinfos=getBulkInfo();
userinfos.preferences.notisound=sound;
localStorage.setItem("userinfos",JSON.stringify(userinfos));
}
static getNotificationSound(){
const userinfos=getBulkInfo();
return userinfos.preferences.notisound;
}
}
export{Voice};