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 }