thetascape-sound-engine
Version:
A sound engine by Jason Snell
2 lines (1 loc) • 8.98 kB
JavaScript
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const T=require("tone"),H=require("react"),V=require("react-p5");function B(n){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const i in n)if(i!=="default"){const e=Object.getOwnPropertyDescriptor(n,i);Object.defineProperty(t,i,e.get?e:{enumerable:!0,get:()=>n[i]})}}return t.default=n,Object.freeze(t)}const m=B(T),h=Object.freeze({INTRO:0,DELTA:1,THETA:2,ALPHA:3,BETA:4,GAMMA:5}),W=Object.freeze([2.5,2.5,5,10,20,40]);class q{constructor(t,i,e,r){console.log("VisualizerBar: constructor",t,i,e,r),this.brainwaveID=t,this.barWidth=i,this.containerHeight=e,this.colors=r,this.carrierValue=0,this.carrierAmp=1,this.modulatorValue=.5,this.currentHeight=e,this.currentOffset=0,this.gradient=null,this.lastGradientHeight=null,this._configureBrainwave(t)}_configureBrainwave(t){switch(t){case 1:this.carrierAmp=1.1,this.animSmoothing=5,this.minWaveHeight=this.containerHeight*.8,this.maxWaveHeight=this.containerHeight*1.1,this.modulationStrength=.12;break;case 2:this.carrierAmp=1.1,this.animSmoothing=4,this.minWaveHeight=this.containerHeight*.85,this.maxWaveHeight=this.containerHeight*1.1,this.modulationStrength=.05;break;case 3:this.carrierAmp=1.45,this.animSmoothing=2,this.minWaveHeight=this.containerHeight*1.25,this.maxWaveHeight=this.containerHeight*1.55,this.modulationStrength=.075;break;case 4:this.carrierAmp=1.2,this.animSmoothing=3,this.minWaveHeight=this.containerHeight*1.55,this.maxWaveHeight=this.containerHeight*4,this.modulationStrength=.2;break;case 5:this.carrierAmp=1.2,this.animSmoothing=1,this.minWaveHeight=this.containerHeight*1.1,this.maxWaveHeight=this.containerHeight*2.75,this.modulationStrength=.115;break;default:this.carrierAmp=1,this.animSmoothing=1,this.minWaveHeight=this.containerHeight,this.maxWaveHeight=this.containerHeight,this.modulationStrength=0;break}}reset(t,i,e){this.brainwaveID=t,this.containerHeight=i,this.colors=e,this.carrierValue=0,this.modulatorValue=.5,this.currentHeight=i,this.currentOffset=0,this.gradient=null,this.lastGradientHeight=null,this._configureBrainwave(t)}setValues(t,i){this.carrierValue=t*this.carrierAmp,this.modulatorValue=i}updateColors(t){this.colors=t,this.gradient=null}update(t){const i=1/this.animSmoothing,e=this.maxWaveHeight-this.carrierValue*(this.maxWaveHeight-this.minWaveHeight);this.currentHeight+=(e-this.currentHeight)*i;const r=this.modulatorValue-.5,a=this.containerHeight*this.modulationStrength,u=r*2*a;this.currentOffset+=(u-this.currentOffset)*i}draw(t,i,e){if(this.currentHeight<1)return;t.push(),t.translate(i,e+this.currentOffset);const r=Math.abs(this.currentHeight-this.lastGradientHeight);(!this.gradient||r>5)&&(this.gradient=t.drawingContext.createLinearGradient(0,-this.currentHeight/2,0,this.currentHeight/2),this.gradient.addColorStop(0,this.colors[0]),this.gradient.addColorStop(.25,this.colors[1]),this.gradient.addColorStop(.5,this.colors[2]),this.gradient.addColorStop(.75,this.colors[3]),this.gradient.addColorStop(1,this.colors[4]),this.lastGradientHeight=this.currentHeight),t.drawingContext.fillStyle=this.gradient,t.noStroke(),t.rect(-this.barWidth/2,-this.currentHeight/2,this.barWidth,this.currentHeight),t.pop()}}class E{constructor(t,i,e,r,a,u,M){this.p5=t,this.bars=[];const f=e*(r+a),g=(t.width-f)/2+a/2;for(let s=0;s<e;s++){const d=g+s*(r+a),l=new q(i,r,u,M);this.bars.push({bar:l,x:d})}}resetAllBars(t,i,e){for(const{bar:r}of this.bars)r.reset(t,i,e)}updateColors(t){for(const{bar:i}of this.bars)i.updateColors?.(t)}updateAndDraw(t,i){if(t.length!==i.length)return;const{p5:e}=this;for(let r=0;r<this.bars.length;r++){const{bar:a,x:u}=this.bars[r];a.setValues(t[r]||0,i[r]||.5),a.update(e),a.draw(e,u,e.height/2)}}}const P={getColors(n){switch(n){case h.DELTA:return{barColors:["#1d262d","#0468b8","#bbd0e0","#43b3d3","#202025"],bgColors:["#1d262d","#15445d","#202025"]};case h.THETA:return{barColors:["#22242f","#7d82a6","#f8f8fa","#5d6393","#1f1f24"],bgColors:["#22242f","#373e73","#1f1f24"]};case h.ALPHA:return{barColors:["#01a2cb","#45bbd9","#ffffff","#038ecf","#0398cf"],bgColors:["#01a2cb","#e1eff3","#0398cf"]};case h.BETA:return{barColors:["#0072CE","#127cd1","#ffffff","#00a2cb","#022d97"],bgColors:["#0072CE","#a9cfee","#022d97"]};case h.GAMMA:return{barColors:["#168cb9","#168cb9","#ffffff","#5e6ac9","#5e6ac9"],bgColors:["#168cb9","#ffffff","#5e6ac9"]};default:return{barColors:["#8A8FB6","#aab5bf","#D7E4F0","#aab5bf","#8A8FB6"],bgColors:["#8A8FB6","#D7E4F0","#8A8FB6"]}}}},k={processMeters:(n,t,i=[0,16],e=!1)=>{const r=n(),a=Object.values(r),[u,M]=i,f=a.slice(u,M),g=[],s=f.length-1,d=-135,l=-80,w=o=>Math.max(0,Math.min(1,o)),c=o=>w((o-d)/(l-d));if(e){const o=Math.ceil(t/2);for(let p=0;p<o;p++){const b=p/(o-1||1)*s,A=Math.floor(b),C=Math.min(A+1,s),x=b-A,z=f[A]*(1-x)+f[C]*x,v=c(z);g[p]=v,g[t-1-p]=v}return g}else{for(let o=0;o<t;o++){const S=o/(t-1||1)*s,b=Math.floor(S),A=Math.min(b+1,s),C=S-b,x=f[b]*(1-C)+f[A]*C,z=c(x);g.push(z)}return g}}};class O{constructor(t){this.barTotal=t,this.phase=0,this.freqModPhase=0,this.ampModPhase=0,this.widthModPhase=0,this.freqModSpeed=0,this.ampModSpeed=0,this.widthModSpeed=0,this.ampMultiplier=1,this.widthMultiplier=1,this.minHz=1,this.maxHz=1,this.speed=0,this._ampModValue=1,this._widthModValue=1,this.active=!1,this._idleArray=new Array(this.barTotal).fill(.5)}setBrainwave(t){const e={[h.DELTA]:{minHz:.075,maxHz:.175,amp:.8,width:.04,freq:.003,ampS:.004,widthS:.003},[h.THETA]:{minHz:.175,maxHz:.3,amp:1.2,width:.05,freq:.004,ampS:.005,widthS:.004},[h.ALPHA]:{minHz:.2,maxHz:.4,amp:1.5,width:.05,freq:.005,ampS:.001,widthS:.0025},[h.BETA]:{minHz:2.2,maxHz:3.3,amp:1.5,width:1.5,freq:.001,ampS:0,widthS:.001},[h.GAMMA]:{minHz:1.1,maxHz:1.6,amp:1.025,width:.75,freq:.001,ampS:.001,widthS:0}}[t];if(!e){console.warn("Unknown brainwave ID:",t);return}this.minHz=e.minHz,this.maxHz=e.maxHz,this.ampMultiplier=e.amp,this.widthMultiplier=e.width,this.freqModSpeed=e.freq,this.ampModSpeed=e.ampS,this.widthModSpeed=e.widthS,this.active=!0}_computeSpeed(t){const i=8/t;return 2*Math.PI/i}update(){if(!this.active)return;this.freqModPhase+=this.freqModSpeed,this.ampModPhase+=this.ampModSpeed,this.widthModPhase+=this.widthModSpeed,this.freqModPhase>Math.PI*2&&(this.freqModPhase-=Math.PI*2),this.ampModPhase>Math.PI*2&&(this.ampModPhase-=Math.PI*2),this.widthModPhase>Math.PI*2&&(this.widthModPhase-=Math.PI*2);const t=Math.sin(this.freqModPhase)*.5+.5,i=Math.sin(this.ampModPhase)*.5+.5,e=Math.sin(this.widthModPhase)*.5+.5,r=this.minHz+t*(this.maxHz-this.minHz);this.speed=this._computeSpeed(r),this._ampModValue=i*this.ampMultiplier,this._widthModValue=1+e*this.widthMultiplier,this.phase+=this.speed,this.phase>Math.PI*2&&(this.phase-=Math.PI*2)}getModulatorWave(){if(!this.active)return this._idleArray;const t=this._ampModValue,i=this._widthModValue,e=new Array(this.barTotal),r=Math.PI*2;for(let a=0;a<this.barTotal;a++){const M=a/this.barTotal*r*i;e[a]=Math.sin(this.phase+M)*.5*t+.5}return e}}const _=({getLevels:n,brainwaveID:t})=>{console.log("Visualizer: brainwaveID",t);const i=H.useRef(null),e=H.useRef(null),r=H.useRef(null),a=H.useRef(!1),u=H.useMemo(()=>P.getColors(t),[t]);H.useEffect(()=>{if(e.current&&e.current.setBrainwave(t),a.current=!1,i.current){const{p5:s}=i.current,d=s.height,l=P.getColors(t).barColors;i.current.resetAllBars(t,d,l)}},[t]);const M=(s,d)=>{s.createCanvas(s.windowWidth,s.windowHeight).parent(d),s.frameRate(8),s.noSmooth();const l=2,w=11,c=Math.floor(s.width/(l+w));r.current=c,i.current=new E(s,t,c,l,w,s.height,u.barColors),e.current||(e.current=new O(c),e.current.setBrainwave(t))},f=s=>{const d=P.getColors(t).bgColors,l=s.drawingContext.createLinearGradient(0,0,0,s.height);if(l.addColorStop(0,d[0]),l.addColorStop(.5,d[1]),l.addColorStop(1,d[2]),s.drawingContext.fillStyle=l,s.noStroke(),s.rect(0,0,s.width,s.height),a.current=!0,!i.current||!n||!e.current)return;const w=n();let c=[0,16],o=!1;switch(t){case h.DELTA:c=[0,4],o=!0;break;case h.THETA:c=[2,8],o=!0;break;case h.ALPHA:c=[2,10],o=!0;break;case h.BETA:c=[4,12],o=!1;break;case h.GAMMA:c=[6,16],o=!0;break;default:c=[0,16],o=!0;break}const p=k.processMeters(()=>w,i.current.bars.length,c,o);e.current.update();const S=e.current.getModulatorWave();i.current.updateAndDraw(p,S)},g=s=>{s.resizeCanvas(s.windowWidth,s.windowHeight)};return H.createElement(V,{setup:M,draw:f,windowResized:g})},y=async()=>{console.log("APP: Init ToneJS and Audio Engine");const n=new m.Context({latencyHint:"playback"});m.setContext(n),console.log("AUDIO: Tone.Context: Latency Hint:",m.getContext().latencyHint,"| Sample Rate:",m.getContext().sampleRate),m.getContext().rawContext.suspend(),await m.start(),console.log("AUDIO: Tone started",m.getContext().state,m);const{default:t}=await Promise.resolve().then(()=>require("./AudioEngine-CX22r7su.cjs"));return new t(m)},R={init:y};exports.SongFrequencies=W;exports.SongIDs=h;exports.Visualizer=_;exports.default=R;