1from abc import ABCMeta, abstractmethod
2
3from pyglet import event
4from pyglet.util import with_metaclass
5
6
7class DeviceState:
8    ACTIVE = "active"
9    DISABLED = "disabled"
10    MISSING = "missing"
11    UNPLUGGED = "unplugged"
12
13
14class DeviceFlow:
15    OUTPUT = "output"
16    INPUT = "input"
17    INPUT_OUTPUT = "input/output"
18
19
20class AudioDevice:
21    """Base class for a platform independent audio device.
22       _platform_state and _platform_flow is used to make device state numbers."""
23    _platform_state = {}  # Must be defined by the parent.
24    _platform_flow = {}  # Must be defined by the parent.
25
26    def __init__(self, dev_id, name, description, flow, state):
27        self.id = dev_id
28        self.flow = flow
29        self.state = state
30        self.name = name
31        self.description = description
32
33    def __repr__(self):
34        return "{}(name={}, state={}, flow={})".format(
35            self.__class__.__name__, self.name, self._platform_state[self.state], self._platform_flow[self.flow])
36
37
38class AbstractAudioDeviceManager(with_metaclass(ABCMeta, event.EventDispatcher, object)):
39
40    def __del__(self):
41        """Required to remove handlers before exit, as it can cause problems with the event system's weakrefs."""
42        self.remove_handlers(self)
43
44    @abstractmethod
45    def get_default_output(self):
46        """Returns a default active output device or None if none available."""
47        pass
48
49    @abstractmethod
50    def get_default_input(self):
51        """Returns a default active input device or None if none available."""
52        pass
53
54    @abstractmethod
55    def get_output_devices(self):
56        """Returns a list of all active output devices."""
57        pass
58
59    @abstractmethod
60    def get_input_devices(self):
61        """Returns a list of all active input devices."""
62        pass
63
64    @abstractmethod
65    def get_all_devices(self):
66        """Returns a list of all audio devices, no matter what state they are in."""
67        pass
68
69    def on_device_state_changed(self, device, old_state, new_state):
70        """Event, occurs when the state of a device changes, provides old state and new state."""
71        pass
72
73    def on_device_added(self, device):
74        """Event, occurs when a new device is added to the system."""
75        pass
76
77    def on_device_removed(self, device):
78        """Event, occurs when an existing device is removed from the system."""
79        pass
80
81    def on_default_changed(self, device):
82        """Event, occurs when the default audio device changes."""
83        pass
84
85
86AbstractAudioDeviceManager.register_event_type('on_device_state_changed')
87AbstractAudioDeviceManager.register_event_type('on_device_added')
88AbstractAudioDeviceManager.register_event_type('on_device_removed')
89AbstractAudioDeviceManager.register_event_type('on_default_changed')
90