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)
const player = sound.play(freq, time || 0, pan < 0.5 ? speaker.panLeft : speaker.panRight)
return { speaker, player }
}
}
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 }
|