summaryrefslogtreecommitdiff
path: root/client/lib/hall.js
diff options
context:
space:
mode:
Diffstat (limited to 'client/lib/hall.js')
-rw-r--r--client/lib/hall.js81
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