-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathomi_audio_utils.py
73 lines (66 loc) · 2.39 KB
/
omi_audio_utils.py
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
# WIP helper utilitilies to support Audio Preview -- humbletim 2021.12.14
import bpy
import aud
class RuntimeComponent:
"""
container for associating non-persistant python values to blender objects at RuntimeComponent
"""
@classmethod
def hash(cls, object):
return str(object.as_pointer())
@staticmethod
def object_query(haystack, attr, needle):
"""
usage: result = object_query(bpy.data.objects, 'attribute_name', attribute_value)
"""
if needle is None: return None
id = RuntimeComponent.hash(needle)
return [c for c in haystack if RuntimeComponent.hash(getattr(c, attr, None)) == id][0]
def __init__(self):
self.map = {}
def get(self, pair, defaultValue=None):
return self.map.get(self.hash(pair), defaultValue)
def remove(self, pair):
return self.set(pair, None)
def set(self, pair, sound):
id = self.hash(pair)
cur = self.map.get(id, None)
self.map[id] = sound
return cur
class AudioPlayback:
handles = RuntimeComponent()
def isPlaying(self):
return AudioPlayback.handles.get(self)
def togglePlayback(self):
if self.isPlaying():
self.stop()
else:
self.play()
def play(self):
object = RuntimeComponent.object_query(bpy.data.objects, 'OMI_audio_pair', self)
cam = bpy.data.objects["Camera"]
device = aud.Device()
device.listener_location = cam.location
device.listener_orientation = cam.rotation_quaternion
print("PLAYING", object, self.source, self.emitter)
sound = aud.Sound(self.source.filename)
# see https://docs.blender.org/api/current/aud.html
# TODO: "aud" supports lots of OpenAL parameters
# (including stuff like cone_angle_inner...)
handle = device.play(sound)
handle.volume = self.emitter.gain
handle.location = object.location
handle.orientation = object.rotation_quaternion
AudioPlayback.handles.set(self, handle)
def stop(self):
handle = AudioPlayback.handles.remove(self)
if handle:
handle.stop()
def json_serializable(cls):
def as_dict(self):
yield OrderedDict(
(name, value) for name, value in zip(
self._fields,
iter(super(cls, self).__iter__())))
cls.__iter__ = as_dict
return cls