summaryrefslogtreecommitdiff
path: root/client/lib/hall.js
blob: b1fa69935ab8028e3dae1350a6af3f4ba97615d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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 }