diff options
Diffstat (limited to 'client/lib/hall.js')
| -rw-r--r-- | client/lib/hall.js | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/client/lib/hall.js b/client/lib/hall.js new file mode 100644 index 0000000..b1fa699 --- /dev/null +++ b/client/lib/hall.js @@ -0,0 +1,81 @@ +import Tone from 'tone' +import output from './output' +import { clamp, choice } from './util' + +const SPEED_OF_SOUND = 0.0029154519 // ms/m + +const reverb = new Tone.Freeverb({ + roomSize: 0.8, + dampening: 12000, +}).connect(output) + +function db_per_meter(distance){ + return 1+20*(Math.log(1/distance)/Math.log(10)) +} +function db_to_percentage(db){ + return Math.pow(10, db/10) +} + +class Hall { + constructor(props) { + let speakers = this.speakers = [] + let gain, gainEl + let delay, delayEl, z + for (let i = 0; i < props.speakers; i++) { + speakers.push(new Speaker({ + speakers: props.speakers, + length: props.length, + i: i, + })) + } + } + getSpeaker(i){ + if (i < 1 && i !== 0) { + i *= this.speakers.length + } + return this.speakers[Math.floor(i) % this.speakers.length] + } + play(sound, i, freq, pan, time){ + const speaker = this.getSpeaker(i) + sound.play(freq, time || 0, pan < 0.5 ? speaker.panLeft : speaker.panRight) + return speaker + } +} + +class Speaker { + constructor(props){ + const z = props.length * (props.i + 0.5) / props.speakers + 3 + const reverb_z = props.length * (props.i + 0.5 + props.speakers - 4) / props.speakers + const z_db = db_per_meter(z) + const reverb_db = db_per_meter(reverb_z) + + this.z = z + + this.pan = Math.atan(3/this.z) + this.panLeft = new Tone.Panner(-this.pan) + this.panRight = new Tone.Panner(-this.pan) + + this.gain = db_to_percentage(z_db + 8) + this.reverbGain = db_to_percentage(reverb_db + 15) + + this.delay = z * SPEED_OF_SOUND + console.log(z, this.gain.toFixed(4), this.reverbGain.toFixed(4), this.pan) + + this.input = new Tone.Delay(this.delay) + this.dryOutput = new Tone.Gain (this.gain) + this.wetOutput = new Tone.Gain (this.reverbGain) + + this.panLeft.connect(this.dryOutput) + this.panLeft.connect(this.wetOutput) + this.panRight.connect(this.dryOutput) + this.panRight.connect(this.wetOutput) + + this.input.connect(this.dryOutput) + this.input.connect(this.wetOutput) + + this.dryOutput.connect(output) + this.wetOutput.connect(reverb) + } +} + +export { Hall, Speaker }
\ No newline at end of file |
