80 lines
No EOL
1.7 KiB
Python
80 lines
No EOL
1.7 KiB
Python
import math
|
|
TAU = 2 * math.pi
|
|
|
|
class SoundNode:
|
|
|
|
def __init__(self, name, room):
|
|
|
|
self.name = name
|
|
self.room = room
|
|
self.room.nodes.append(self)
|
|
|
|
self.amp_cache = dict() # {tick: {freq: amp}}
|
|
|
|
self.air_in = []
|
|
self.wire_in = []
|
|
|
|
self.start_location = (0, 0, 0)
|
|
|
|
self.tick_done = False
|
|
|
|
def location(self, t):
|
|
|
|
# Location of the soundnote (x,y,z) in meters
|
|
# at time t.
|
|
|
|
return self.start_location
|
|
|
|
def distance_to_node(self, other_node, t):
|
|
|
|
loc = self.location(t)
|
|
other_loc = other_node.location(t)
|
|
|
|
return (loc[0]-other_loc[0])**2 + (loc[1]-other_loc[1])**2 + (loc[2]-other_loc[2])**2
|
|
|
|
|
|
def fill_amp_cache(self, t):
|
|
|
|
self.amp_cache[t] = dict()
|
|
|
|
def sample_freqs_by_wire(self, source_node, current_t):
|
|
|
|
if current_t in source_node.amp_cache:
|
|
return source_node.amp_cache[current_t]
|
|
|
|
return dict()
|
|
|
|
def sample_freqs_by_air(self, source_node, current_t):
|
|
|
|
dist = self.distance_to_node(source_node, current_t)
|
|
sample_t = current_t - int(dist / self.room.speed_of_sound)
|
|
|
|
if sample_t in source_node.amp_cache:
|
|
return source_node.amp_cache[sample_t]
|
|
|
|
return dict()
|
|
|
|
def add_air_output(self, out_node):
|
|
|
|
if not self in out_node.air_in:
|
|
out_node.air_in.append(self)
|
|
|
|
def add_wire_output(self, out_node):
|
|
|
|
if not self in out_node.wire_in:
|
|
out_node.wire_in.append(self)
|
|
|
|
"""
|
|
|
|
def amp_at_tick(self, f, t):
|
|
|
|
return self.frequency_max_rel_amp(f, t) * math.sin(self.room.sine_multiplier * f * t)
|
|
|
|
def amp_at_tick_by_air(self, f, t, node):
|
|
|
|
dist = self.distance_to_node(node, t)
|
|
t = t - int(dist / self.room.speed_of_sound)
|
|
|
|
return self.frequency_max_rel_amp(f, t) * math.sin(self.room.sine_multiplier * f * t)
|
|
"""
|
|
|